diff options
author | Hans Hagen <pragma@wxs.nl> | 2010-01-14 18:25:00 +0100 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2010-01-14 18:25:00 +0100 |
commit | 45d11a2f318b118a2592b9db7eb530a4cf613a00 (patch) | |
tree | 060a66d60c1e5e7c3326e5776476ee90e2cb1e43 | |
parent | 3dbcef73aec79246dfc4238eb7af28d3fa54e1f3 (diff) | |
download | context-45d11a2f318b118a2592b9db7eb530a4cf613a00.tar.gz |
beta 2010.01.14 18:25
-rw-r--r-- | scripts/context/lua/luatools.lua | 179 | ||||
-rw-r--r-- | scripts/context/lua/mtx-watch.lua | 18 | ||||
-rw-r--r-- | scripts/context/lua/mtxrun.lua | 445 | ||||
-rw-r--r-- | scripts/context/stubs/mswin/luatools.lua | 179 | ||||
-rw-r--r-- | scripts/context/stubs/mswin/mtxrun.lua | 445 | ||||
-rwxr-xr-x | scripts/context/stubs/unix/luatools | 179 | ||||
-rwxr-xr-x | scripts/context/stubs/unix/mtxrun | 445 | ||||
-rw-r--r-- | tex/context/base/buff-ini.lua | 22 | ||||
-rw-r--r-- | tex/context/base/cont-new.tex | 2 | ||||
-rw-r--r-- | tex/context/base/context-base.lmx | 3 | ||||
-rw-r--r-- | tex/context/base/context.tex | 2 | ||||
-rw-r--r-- | tex/context/base/font-syn.lua | 57 | ||||
-rw-r--r-- | tex/context/base/grph-inc.lua | 35 | ||||
-rw-r--r-- | tex/context/base/grph-inc.mkiv | 2 | ||||
-rw-r--r-- | tex/context/base/l-aux.lua | 4 | ||||
-rw-r--r-- | tex/context/base/l-os.lua | 169 | ||||
-rw-r--r-- | tex/context/base/l-table.lua | 2 | ||||
-rw-r--r-- | tex/context/base/l-url.lua | 4 | ||||
-rw-r--r-- | tex/context/base/lxml-aux.lua | 253 | ||||
-rw-r--r-- | tex/context/base/lxml-tab.lua | 17 | ||||
-rw-r--r-- | tex/generic/context/luatex-fonts-merged.lua | 4 |
21 files changed, 1529 insertions, 937 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua index 9f34bea72..5fcc30d3c 100644 --- a/scripts/context/lua/luatools.lua +++ b/scripts/context/lua/luatools.lua @@ -530,7 +530,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1755,6 +1755,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1798,63 +1800,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if name == "linux" then + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit = lpeg.R("09","AF","af") local plus = lpeg.P("+") local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("") local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("") local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("") local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua index d897d6beb..fa4cd0eab 100644 --- a/scripts/context/lua/mtx-watch.lua +++ b/scripts/context/lua/mtx-watch.lua @@ -13,16 +13,13 @@ local format, concat, difftime, time = string.format, table.concat, os.difftime, local pairs, ipairs, next, type = pairs, ipairs, next, type function scripts.watch.save_exa_modes(joblog,ctmname) - if joblog then + local values = joblog and joblog.values + if values then local t= { } t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n" t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>" - if joblog.values then - for k, v in pairs(joblog.values) do - t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v)) - end - else - t[#t+1] = "<!-- no modes -->" + for k, v in pairs(joblog.values) do + t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v)) end t[#t+1] = "</exa:variables>" io.savedata(ctmname,concat(t,"\n")) @@ -147,11 +144,12 @@ function scripts.watch.watch() joblog.status = "no command" end -- pcall, when error sleep + again + -- todo: just one log file and append io.savedata(name, table.serialize(joblog,true)) - if logpath ~= "" then - local name = os.uuid() .. ".lua" + if logpath and logpath ~= "" then + local name = file.join(logpath,os.uuid() .. ".lua") io.savedata(name, table.serialize(joblog,true)) - logs.report("watch", "saving joblog ".. name) + logs.report("watch", "saving joblog in " .. name) end end end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 051cd0fa8..0b2a9cd02 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -539,7 +539,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1764,6 +1764,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1807,63 +1809,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture + end + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end - if name == "linux" then + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings) else errorstr = "invalid xml file - parsed text" end - else + 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 if errorstr and errorstr ~= "" then result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) + local settings = xmldata.settings + settings.parent_root = xmldata -- to be tested + -- settings.no_root = true + local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) + return xc +end + --[[ldx-- <p>Packaging data in an xml like table is done with the following function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = { local trace_manipulations = false trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert local type = type local insert, remove = table.insert, table.remove local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) - local settings = xmldata.settings - settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true - local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) --- for k,v in pairs(xc) do print(k,tostring(v)) end - return xc +local function report(what,pattern,c,e) + logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) end local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse) local collected = xmlparseapply({ root },pattern) if collected then if reverse then @@ -5932,7 +6032,7 @@ end xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle) local collected = xmlparseapply({ root },pattern) if collected and handle then for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace) end --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p> --ldx]]-- local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d) end end -function xml.inject_element(root, pattern, element, prepend) - if root and element then - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element then - if element.ri then - element = element.dt[element.ri].dt - else - element = element.dt - end - -- we need to re-index - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r, d, k = e.__p__, r.dt, e.ni - local edt - if r.ri then - edt = r.dt[r.ri].dt - else - edt = d and d[k] and d[k].dt - end - if edt then - local be, af - if prepend then - be, af = xmlcopy(element), edt -be.__p__ = e - - else - be, af = edt, xmlcopy(element) -af.__p__ = e - end - for i=1,#af do - be[#be+1] = af[i] - end - if r.ri then - r.dt[r.ri].dt = be - else - d[k].dt = be - end - else - -- r.dt = element.dt -- todo - end -xml.redo_ni(d) - end - end - end +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 -- we assume a table end + if element.error then + return whatever -- string + end + if element then + --~ if element.ri then + --~ element = element.dt[element.ri].dt + --~ else + --~ element = element.dt + --~ end + end + return element end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie - if root and element then - if pattern == "/" then - xml.inject_element(root, pattern, element, before) - else - local matches, collect = { }, nil - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] - end - if element then - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r = e.__p__ - local d = r.dt - local k = e.ni - if not before then - k = k + 1 - end - local ce = xmlcopy(element) -ce.__p__ = r - if element.tg then - insert(d,k,ce) -- untested - else - -- maybe bugged - local edt = ce.dt - if edt then - for i=1,#edt do -local edti = edt[i] - insert(d,k,edti) -if type(edti) == "table" then - edti.__p__ = r -end - k = k + 1 - end - end - end -xml.redo_ni(d) - end - end - end +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 end end -xml.insert_element_after = xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after = xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) - logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern) local collected = xmlparseapply({ root },pattern) if collected then for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern) local p = e.__p__ if p then if trace_manipulations then - report('deleting',pattern,c,tostring(e)) -- fails + report('deleting',pattern,c,e) end local d = p.dt remove(d,e.ni) -xml.redo_ni(d) + xml.redo_ni(d) -- can be made faster and inlined end end end end -function xml.replace_element(root, pattern, element) - if type(element) == "string" then ---~ element = xmlconvert(element,true) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ 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 + d[e.ni] = copiedelement(element,p) + xml.redo_ni(d) -- probably not needed + end + end end - if element then - local collected = xmlparseapply({ 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 - d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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 + for i=1,#af do + be[#be+1] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be + end + xml.redo_ni(d) + end + end + end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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)) + xml.redo_ni(d) end end end +xml.insert_element = insert_element +xml.insert_element_after = insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element = inject_element +xml.inject_element_after = inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end + local function include(xmldata,pattern,attribute,recursive,loaddata) -- parse="text" (default: xml), encoding="" (todo) -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata) --~ local settings = xmldata.settings --~ settings.parent_root = xmldata -- to be tested --~ local xi = xmlconvert(data,settings) - local xi = xml.inheritedconvert(data,xmldata) + local xi = xmlinheritedconvert(data,xmldata) if not xi then epdt[ek.ni] = "" -- xml.empty(d,k) else diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua index 9f34bea72..5fcc30d3c 100644 --- a/scripts/context/stubs/mswin/luatools.lua +++ b/scripts/context/stubs/mswin/luatools.lua @@ -530,7 +530,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1755,6 +1755,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1798,63 +1800,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if name == "linux" then + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit = lpeg.R("09","AF","af") local plus = lpeg.P("+") local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("") local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("") local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("") local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 051cd0fa8..0b2a9cd02 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -539,7 +539,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1764,6 +1764,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1807,63 +1809,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture + end + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end - if name == "linux" then + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings) else errorstr = "invalid xml file - parsed text" end - else + 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 if errorstr and errorstr ~= "" then result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) + local settings = xmldata.settings + settings.parent_root = xmldata -- to be tested + -- settings.no_root = true + local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) + return xc +end + --[[ldx-- <p>Packaging data in an xml like table is done with the following function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = { local trace_manipulations = false trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert local type = type local insert, remove = table.insert, table.remove local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) - local settings = xmldata.settings - settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true - local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) --- for k,v in pairs(xc) do print(k,tostring(v)) end - return xc +local function report(what,pattern,c,e) + logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) end local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse) local collected = xmlparseapply({ root },pattern) if collected then if reverse then @@ -5932,7 +6032,7 @@ end xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle) local collected = xmlparseapply({ root },pattern) if collected and handle then for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace) end --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p> --ldx]]-- local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d) end end -function xml.inject_element(root, pattern, element, prepend) - if root and element then - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element then - if element.ri then - element = element.dt[element.ri].dt - else - element = element.dt - end - -- we need to re-index - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r, d, k = e.__p__, r.dt, e.ni - local edt - if r.ri then - edt = r.dt[r.ri].dt - else - edt = d and d[k] and d[k].dt - end - if edt then - local be, af - if prepend then - be, af = xmlcopy(element), edt -be.__p__ = e - - else - be, af = edt, xmlcopy(element) -af.__p__ = e - end - for i=1,#af do - be[#be+1] = af[i] - end - if r.ri then - r.dt[r.ri].dt = be - else - d[k].dt = be - end - else - -- r.dt = element.dt -- todo - end -xml.redo_ni(d) - end - end - end +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 -- we assume a table end + if element.error then + return whatever -- string + end + if element then + --~ if element.ri then + --~ element = element.dt[element.ri].dt + --~ else + --~ element = element.dt + --~ end + end + return element end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie - if root and element then - if pattern == "/" then - xml.inject_element(root, pattern, element, before) - else - local matches, collect = { }, nil - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] - end - if element then - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r = e.__p__ - local d = r.dt - local k = e.ni - if not before then - k = k + 1 - end - local ce = xmlcopy(element) -ce.__p__ = r - if element.tg then - insert(d,k,ce) -- untested - else - -- maybe bugged - local edt = ce.dt - if edt then - for i=1,#edt do -local edti = edt[i] - insert(d,k,edti) -if type(edti) == "table" then - edti.__p__ = r -end - k = k + 1 - end - end - end -xml.redo_ni(d) - end - end - end +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 end end -xml.insert_element_after = xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after = xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) - logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern) local collected = xmlparseapply({ root },pattern) if collected then for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern) local p = e.__p__ if p then if trace_manipulations then - report('deleting',pattern,c,tostring(e)) -- fails + report('deleting',pattern,c,e) end local d = p.dt remove(d,e.ni) -xml.redo_ni(d) + xml.redo_ni(d) -- can be made faster and inlined end end end end -function xml.replace_element(root, pattern, element) - if type(element) == "string" then ---~ element = xmlconvert(element,true) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ 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 + d[e.ni] = copiedelement(element,p) + xml.redo_ni(d) -- probably not needed + end + end end - if element then - local collected = xmlparseapply({ 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 - d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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 + for i=1,#af do + be[#be+1] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be + end + xml.redo_ni(d) + end + end + end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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)) + xml.redo_ni(d) end end end +xml.insert_element = insert_element +xml.insert_element_after = insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element = inject_element +xml.inject_element_after = inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end + local function include(xmldata,pattern,attribute,recursive,loaddata) -- parse="text" (default: xml), encoding="" (todo) -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata) --~ local settings = xmldata.settings --~ settings.parent_root = xmldata -- to be tested --~ local xi = xmlconvert(data,settings) - local xi = xml.inheritedconvert(data,xmldata) + local xi = xmlinheritedconvert(data,xmldata) if not xi then epdt[ek.ni] = "" -- xml.empty(d,k) else diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools index 9f34bea72..5fcc30d3c 100755 --- a/scripts/context/stubs/unix/luatools +++ b/scripts/context/stubs/unix/luatools @@ -530,7 +530,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1755,6 +1755,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1798,63 +1800,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if name == "linux" then + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit = lpeg.R("09","AF","af") local plus = lpeg.P("+") local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("") local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("") local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("") local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 051cd0fa8..0b2a9cd02 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -539,7 +539,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k @@ -1764,6 +1764,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -1807,63 +1809,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture + end + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end - if name == "linux" then + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings) else errorstr = "invalid xml file - parsed text" end - else + 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 if errorstr and errorstr ~= "" then result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) + local settings = xmldata.settings + settings.parent_root = xmldata -- to be tested + -- settings.no_root = true + local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) + return xc +end + --[[ldx-- <p>Packaging data in an xml like table is done with the following function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = { local trace_manipulations = false trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert local type = type local insert, remove = table.insert, table.remove local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) - local settings = xmldata.settings - settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true - local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) --- for k,v in pairs(xc) do print(k,tostring(v)) end - return xc +local function report(what,pattern,c,e) + logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) end local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse) local collected = xmlparseapply({ root },pattern) if collected then if reverse then @@ -5932,7 +6032,7 @@ end xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle) local collected = xmlparseapply({ root },pattern) if collected and handle then for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace) end --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p> --ldx]]-- local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d) end end -function xml.inject_element(root, pattern, element, prepend) - if root and element then - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element then - if element.ri then - element = element.dt[element.ri].dt - else - element = element.dt - end - -- we need to re-index - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r, d, k = e.__p__, r.dt, e.ni - local edt - if r.ri then - edt = r.dt[r.ri].dt - else - edt = d and d[k] and d[k].dt - end - if edt then - local be, af - if prepend then - be, af = xmlcopy(element), edt -be.__p__ = e - - else - be, af = edt, xmlcopy(element) -af.__p__ = e - end - for i=1,#af do - be[#be+1] = af[i] - end - if r.ri then - r.dt[r.ri].dt = be - else - d[k].dt = be - end - else - -- r.dt = element.dt -- todo - end -xml.redo_ni(d) - end - end - end +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 -- we assume a table end + if element.error then + return whatever -- string + end + if element then + --~ if element.ri then + --~ element = element.dt[element.ri].dt + --~ else + --~ element = element.dt + --~ end + end + return element end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie - if root and element then - if pattern == "/" then - xml.inject_element(root, pattern, element, before) - else - local matches, collect = { }, nil - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] - end - if element then - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r = e.__p__ - local d = r.dt - local k = e.ni - if not before then - k = k + 1 - end - local ce = xmlcopy(element) -ce.__p__ = r - if element.tg then - insert(d,k,ce) -- untested - else - -- maybe bugged - local edt = ce.dt - if edt then - for i=1,#edt do -local edti = edt[i] - insert(d,k,edti) -if type(edti) == "table" then - edti.__p__ = r -end - k = k + 1 - end - end - end -xml.redo_ni(d) - end - end - end +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 end end -xml.insert_element_after = xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after = xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) - logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern) local collected = xmlparseapply({ root },pattern) if collected then for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern) local p = e.__p__ if p then if trace_manipulations then - report('deleting',pattern,c,tostring(e)) -- fails + report('deleting',pattern,c,e) end local d = p.dt remove(d,e.ni) -xml.redo_ni(d) + xml.redo_ni(d) -- can be made faster and inlined end end end end -function xml.replace_element(root, pattern, element) - if type(element) == "string" then ---~ element = xmlconvert(element,true) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ 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 + d[e.ni] = copiedelement(element,p) + xml.redo_ni(d) -- probably not needed + end + end end - if element then - local collected = xmlparseapply({ 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 - d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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 + for i=1,#af do + be[#be+1] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be + end + xml.redo_ni(d) + end + end + end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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)) + xml.redo_ni(d) end end end +xml.insert_element = insert_element +xml.insert_element_after = insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element = inject_element +xml.inject_element_after = inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end + local function include(xmldata,pattern,attribute,recursive,loaddata) -- parse="text" (default: xml), encoding="" (todo) -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata) --~ local settings = xmldata.settings --~ settings.parent_root = xmldata -- to be tested --~ local xi = xmlconvert(data,settings) - local xi = xml.inheritedconvert(data,xmldata) + local xi = xmlinheritedconvert(data,xmldata) if not xi then epdt[ek.ni] = "" -- xml.empty(d,k) else diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index 9d8ad8104..faac4ecfb 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -278,21 +278,15 @@ buffers.content = content function buffers.collect(names,separator) -- no print -- maybe we should always store a buffer as table so - -- that we can pass if directly + -- that we can pass it directly + if type(names) == "string" then + names = aux.settings_to_array(names) + end local t = { } - if type(names) == "table" then - for i=1,#names do - local c = content(names[i],separator) - if c ~= "" then - t[#t+1] = c - end - end - else - for name in gmatch(names,"[^,%s]+") do - local c = content(name,separator) - if c ~= "" then - t[#t+1] = c - end + for i=1,#names do + local c = content(names[i],separator) + if c ~= "" then + t[#t+1] = c end end return concat(t,separator or "\r") -- "\n" is safer due to comments and such diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 1bfc24608..65784070b 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2010.01.08 23:58} +\newcontextversion{2010.01.14 18:25} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context-base.lmx b/tex/context/base/context-base.lmx index a6781e4f6..fd27927bf 100644 --- a/tex/context/base/context-base.lmx +++ b/tex/context/base/context-base.lmx @@ -20,6 +20,9 @@ <style type="text/css"> <?lmx-include context.css ?> </style> + <?lua if v('styles') then for k, v in ipairs(v('styles')) do ?> + <link rel="StyleSheet" href="<?lua p(v) ?>" type="text/css" /> + <?lua end end ?> </head> <?lua if v('action') then ?> <form action="<?lua pv(action) ?>" enctype="multi-part/form-data" method="post"> diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 0906b2e4e..fb2f62aa7 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2010.01.08 23:58} +\edef\contextversion{2010.01.14 18:25} %D For those who want to use this: diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index b56ea7917..c2c96f33e 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -38,7 +38,7 @@ fonts.names.data = fonts.names.data or { } local names = fonts.names local filters = fonts.names.filters -names.version = 1.101 +names.version = 1.102 names.basename = "names" names.saved = false names.loaded = false @@ -156,7 +156,7 @@ function fontloader.fullinfo(...) end end -filters.otf = fontloader.fullinfo +filters.otf = fontloader.fullinfo function filters.afm(name) -- we could parse the afm file as well, and then report an error but @@ -348,12 +348,10 @@ local function check_name(data,result,filename,suffix,subfont) if not familyname then familyname = a_name end - fontname = fontname or fullname or familyname or basename + fontname = fontname or fullname or familyname or file.basename(filename) fullname = fullname or fontname familyname = familyname or fontname - -- register - local index = #specifications + 1 - specifications[index] = { + specifications[#specifications + 1] = { filename = filename, format = lower(suffix), subfont = subfont, @@ -370,12 +368,6 @@ local function check_name(data,result,filename,suffix,subfont) maxsize = result.design_range_top or 0, designsize = result.design_size or 0, } - local family = families[familyname] - if not family then - families[familyname] = { index } - else - family[#family+1] = index - end end local function cleanupkeywords() @@ -465,6 +457,21 @@ local function collecthashes() return nofmappings, noffallbacks end +local function collectfamilies() + local data = names.data + local specifications = data.specifications + local families = data.families + for index=1,#specifications do + local familyname = specifications[index].familyname + local family = families[familyname] + if not family then + families[familyname] = { index } + else + family[#family+1] = index + end + end +end + local function checkduplicate(where) -- fails on "Romantik" but that's a border case anyway local data = names.data local mapping = data[where] @@ -539,20 +546,20 @@ local function unpackreferences() v[i] = specifications[v[i]] end end - end - local mappings = data.mappings - if mappings then - for _, m in next, mappings do - for k, v in next, m do - m[k] = specifications[v] + local mappings = data.mappings + if mappings then + for _, m in next, mappings do + for k, v in next, m do + m[k] = specifications[v] + end end end - end - local fallbacks = data.fallbacks - if fallbacks then - for _, f in next, fallbacks do - for k, v in next, f do - f[k] = specifications[v] + local fallbacks = data.fallbacks + if fallbacks then + for _, f in next, fallbacks do + for k, v in next, f do + f[k] = specifications[v] + end end end end @@ -713,6 +720,7 @@ function names.identify() resetdata() analysefiles() rejectclashes() + collectfamilies() collectstatistics() cleanupkeywords() collecthashes() @@ -1088,6 +1096,7 @@ local function collect(stage,found,done,name,weight,style,width,all) if trace_names then logs.report("fonts","resolving name '%s', weight '%s', style '%s', width '%s'",name or "?",tostring(weight),tostring(style),tostring(width)) end +--~ print(name,table.serialize(family)) if weight and weight ~= "" then if style and style ~= "" then if width and width ~= "" then diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index c6019c2cd..352f071f7 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -37,6 +37,7 @@ run TeX code from within Lua. Some more functionality will move to Lua. local format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch local texsprint, texbox, texwd, texht, texdp = tex.sprint, tex.box, tex.wd, tex.ht, tex.dp +local contains = table.contains local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables @@ -154,12 +155,12 @@ local function register(tag,target,what) figures.formats[target] = data end local d = data[tag] -- list or pattern - if d and not table.contains(d,what) then + if d and not contains(d,what) then d[#d+1] = what -- suffix or patternspec else data[tag] = { what } end - if not table.contains(figures.order,target) then + if not contains(figures.order,target) then figures.order[#figures.order+1] = target end figures.setlookups() @@ -187,8 +188,9 @@ function figures.setpaths(locationset,pathlist) last_locationset = locationset end if h[iv["global"]] then - for s in gmatch(pathlist,"([^, ]+)") do - if not table.contains(t,s) then + -- for s in gmatch(pathlist,",* *([^,]+)") do + for _, s in ipairs(aux.settings_to_array(pathlist)) do + if not contains(t,s) then t[#t+1] = s end end @@ -379,6 +381,8 @@ local function register(askedname,specification) return specification end +local resolve_too = true + local function locate(request) -- name, format, cache local askedname = resolvers.clean_path(request.name) local foundname = figures.found[askedname] @@ -413,7 +417,7 @@ local function locate(request) -- name, format, cache end end if format then - local foundname = figures.exists(askedname,format) -- not askedformat + local foundname = figures.exists(askedname,format,resolve_too) -- not askedformat if foundname then return register(askedname, { askedname = askedname, @@ -426,7 +430,7 @@ local function locate(request) -- name, format, cache end if askedpath then -- path and type given, todo: strip pieces of path - if figures.exists(askedname,askedformat) then + if figures.exists(askedname,askedformat,resolve_too) then return register(askedname, { askedname = askedname, fullname = askedname, @@ -438,7 +442,9 @@ local function locate(request) -- name, format, cache -- type given for _, path in ipairs(figures.paths) do local check = path .. "/" .. askedname - if figures.exists(check,askedformat) then + -- we pass 'true' as it can be an url as well, as the type + -- is given we don't waste much time + if figures.exists(check,askedformat,resolve_too) then return register(check, { askedname = askedname, fullname = check, @@ -467,7 +473,7 @@ local function locate(request) -- name, format, cache local list = figures.formats[format].list or { format } for _, suffix in ipairs(list) do local check = file.addsuffix(askedname,suffix) - if figures.exists(check,format) then + if figures.exists(check,format,resolve_too) then return register(askedname, { askedname = askedname, fullname = check, @@ -489,7 +495,12 @@ local function locate(request) -- name, format, cache local name = file.replacesuffix(askedname,suffix) for _, path in ipairs(figures.paths) do local check = path .. "/" .. name - if figures.exists(check,format) then + local isfile = url.hashed(check).scheme == "file" + if not isfile then + if trace_figures then + commands.writestatus("figures","warning: skipping path %s",path) + end + elseif figures.exists(check,format,resolve_too) then return register(askedname, { askedname = askedname, fullname = check, @@ -509,7 +520,7 @@ local function locate(request) -- name, format, cache local list = figures.formats[format].list or { format } for _, suffix in ipairs(list) do local check = path .. "/" .. file.replacesuffix(askedbase,suffix) - if figures.exists(check,format) then + if figures.exists(check,format,resolve_too) then return register(askedname, { askedname = askedname, fullname = check, @@ -581,8 +592,8 @@ function figures.identify(data) end return data end -function figures.exists(askedname,format) - return (figures.existers[format] or figures.existers.generic)(askedname) +function figures.exists(askedname,format,resolve) + return (figures.existers[format] or figures.existers.generic)(askedname,resolve) end function figures.check(data) data = data or figures.current() diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv index c2576ef30..6961262d0 100644 --- a/tex/context/base/grph-inc.mkiv +++ b/tex/context/base/grph-inc.mkiv @@ -64,7 +64,7 @@ %D macro picks up the list. \def\setfigurepathlist - {\ctxlua{figures.setpaths("\@@exlocation","\@@exdirectory")}} + {\ctxlua{figures.setpaths("\@@exlocation",\!!bs\@@exdirectory\!!es)}} %D Variables: diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua index 1ff5c086e..e55f59758 100644 --- a/tex/context/base/l-aux.lua +++ b/tex/context/base/l-aux.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -98,6 +100,8 @@ local pattern = lpeg.Ct(value*(separator*value)^0) aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache + function aux.settings_to_array(str) if not str or str == "" then return { } diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua index b60dfb7fa..0b35fa4e1 100644 --- a/tex/context/base/l-os.lua +++ b/tex/context/base/l-os.lua @@ -43,6 +43,12 @@ end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + function os.launch(str) if os.type == "windows" then os.execute("start " .. str) -- os.spawn ? @@ -51,10 +57,6 @@ function os.launch(str) end end -if not os.setenv then - function os.setenv() return false end -end - if not os.times then -- utime = user time -- stime = system time @@ -86,63 +88,153 @@ end -- no need for function anymore as we have more clever code and helpers now -os.platform = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - os.platform = "mswin-64" - else - os.platform = "mswin" +osmt.__index = function(t,k) + return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v end - os.libsuffix = 'dll' - os.binsuffix = 'exe' -else - local architecture = os.getenv("HOSTTYPE") or "" - if architecture == "" then - architecture = os.resultof("uname -m") or "" + + function os.getenv(k) + return env[k] or getenv(k) end - if architecture == "" then - local architecture = os.resultof("echo $HOSTTYPE") + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture end - if name == "linux" then + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture + end + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" if find(architecture,"x86_64") then - os.platform = "linux-64" + platform = "linux-64" elseif find(architecture,"ppc") then - os.platform = "linux-ppc" + platform = "linux-ppc" else - os.platform = "linux" + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then -- a rather inconsistent mess + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if architecture == "" then + architecture = os.getenv("HOSTTYPE") or "" + end + if architecture == "" then + architecture = os.resultof("echo $HOSTTYPE") or "" end - elseif name == "macosx" then if find(architecture,"i386") then - os.platform = "osx-intel" + platform = "osx-intel" elseif find(architecture,"x86_64") then - os.platform = "osx-64" + platform = "osx-64" else - os.platform = "osx-ppc" + platform = "osx-ppc" end - elseif name == "sunos" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"sparc") then - os.platform = "solaris-sparc" + platform = "solaris-sparc" else -- if architecture == 'i86pc' - os.platform = "solaris-intel" + platform = "solaris-intel" end - elseif name == "freebsd" then + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" if find(architecture,"amd64") then - os.platform = "freebsd-amd64" + platform = "freebsd-amd64" else - os.platform = "freebsd" + platform = "freebsd" end - else - os.platform = 'linux' + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + end -- beware, we set the randomseed --- -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -151,7 +243,6 @@ end -- -- as we don't call this function too often there is not so much risk on repetition - local t = { 8, 9, "a", "b" } function os.uuid() diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua index 1382f83a3..e8f72ed31 100644 --- a/tex/context/base/l-table.lua +++ b/tex/context/base/l-table.lua @@ -29,7 +29,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua index 1d282a178..5290df2fc 100644 --- a/tex/context/base/l-url.lua +++ b/tex/context/base/l-url.lua @@ -32,7 +32,9 @@ local hexdigit = lpeg.R("09","AF","af") local plus = lpeg.P("+") local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("") local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("") local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("") local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("") diff --git a/tex/context/base/lxml-aux.lua b/tex/context/base/lxml-aux.lua index 79b0653a0..2017e6493 100644 --- a/tex/context/base/lxml-aux.lua +++ b/tex/context/base/lxml-aux.lua @@ -11,25 +11,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = { local trace_manipulations = false trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert local type = type local insert, remove = table.insert, table.remove local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) - local settings = xmldata.settings - settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true - local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) --- for k,v in pairs(xc) do print(k,tostring(v)) end - return xc +local function report(what,pattern,c,e) + logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) end local function withelements(e,handle,depth) @@ -85,7 +75,7 @@ end xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse) local collected = xmlparseapply({ root },pattern) if collected then if reverse then @@ -103,7 +93,7 @@ end xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle) local collected = xmlparseapply({ root },pattern) if collected and handle then for c=1,#collected do @@ -154,7 +144,7 @@ function xml.collect_tags(root, pattern, nonamespace) end --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p> --ldx]]-- local no_root = { no_root = true } @@ -168,120 +158,44 @@ function xml.redo_ni(d) end end -function xml.inject_element(root, pattern, element, prepend) - if root and element then - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element then - if element.ri then - element = element.dt[element.ri].dt - else - element = element.dt - end - -- we need to re-index - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r, d, k = e.__p__, r.dt, e.ni - local edt - if r.ri then - edt = r.dt[r.ri].dt - else - edt = d and d[k] and d[k].dt - end - if edt then - local be, af - if prepend then - be, af = xmlcopy(element), edt -be.__p__ = e - - else - be, af = edt, xmlcopy(element) -af.__p__ = e - end - for i=1,#af do - be[#be+1] = af[i] - end - if r.ri then - r.dt[r.ri].dt = be - else - d[k].dt = be - end - else - -- r.dt = element.dt -- todo - end -xml.redo_ni(d) - end - end - end +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 -- we assume a table + end + if element.error then + return whatever -- string + end + if element then + --~ if element.ri then + --~ element = element.dt[element.ri].dt + --~ else + --~ element = element.dt + --~ end + end + return element end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie - if root and element then - if pattern == "/" then - xml.inject_element(root, pattern, element, before) - else - local matches, collect = { }, nil - if type(element) == "string" then ---~ element = xmlconvert(element,no_root) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] - end - if element then - local collected = xmlparseapply({ root },pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local r = e.__p__ - local d = r.dt - local k = e.ni - if not before then - k = k + 1 - end - local ce = xmlcopy(element) -ce.__p__ = r - if element.tg then - insert(d,k,ce) -- untested - else - -- maybe bugged - local edt = ce.dt - if edt then - for i=1,#edt do -local edti = edt[i] - insert(d,k,edti) -if type(edti) == "table" then - edti.__p__ = r -end - k = k + 1 - end - end - end -xml.redo_ni(d) - end - end - end +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 end end -xml.insert_element_after = xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after = xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) - logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern) local collected = xmlparseapply({ root },pattern) if collected then for c=1,#collected do @@ -289,43 +203,90 @@ function xml.delete_element(root, pattern) local p = e.__p__ if p then if trace_manipulations then - report('deleting',pattern,c,tostring(e)) -- fails + report('deleting',pattern,c,e) end local d = p.dt remove(d,e.ni) -xml.redo_ni(d) + xml.redo_ni(d) -- can be made faster and inlined end end end end -function xml.replace_element(root, pattern, element) - if type(element) == "string" then ---~ element = xmlconvert(element,true) - element = xml.inheritedconvert(element,root) - end - if element and element.ri then - element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ 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 + d[e.ni] = copiedelement(element,p) + xml.redo_ni(d) -- probably not needed + end + end end - if element then - local collected = xmlparseapply({ 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 - d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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 + for i=1,#af do + be[#be+1] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be end + xml.redo_ni(d) end end end end +local function insert_element(root,pattern,whatever,before) -- todo: element als functie + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + 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)) + xml.redo_ni(d) + end + end +end + +xml.insert_element = insert_element +xml.insert_element_after = insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element = inject_element +xml.inject_element_after = inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end + local function include(xmldata,pattern,attribute,recursive,loaddata) -- parse="text" (default: xml), encoding="" (todo) -- attribute = attribute or 'href' @@ -358,7 +319,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata) --~ local settings = xmldata.settings --~ settings.parent_root = xmldata -- to be tested --~ local xi = xmlconvert(data,settings) - local xi = xml.inheritedconvert(data,xmldata) + local xi = xmlinheritedconvert(data,xmldata) if not xi then epdt[ek.ni] = "" -- xml.empty(d,k) else diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua index f4ab351e8..300b47126 100644 --- a/tex/context/base/lxml-tab.lua +++ b/tex/context/base/lxml-tab.lua @@ -541,12 +541,14 @@ local function xmlconvert(data, settings) else errorstr = "invalid xml file - parsed text" end - else + 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 if errorstr and errorstr ~= "" then result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -583,6 +585,19 @@ end xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) + local settings = xmldata.settings + settings.parent_root = xmldata -- to be tested + -- settings.no_root = true + local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) + return xc +end + --[[ldx-- <p>Packaging data in an xml like table is done with the following function. Maybe it will go away (when not used).</p> diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 3d48a017d..5248cfd85 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua --- merge date : 01/11/10 15:01:58 +-- merge date : 01/14/10 18:30:13 do -- begin closure to overcome local limits and interference @@ -601,7 +601,7 @@ end function table.keys(t) local k = { } - for key,_ in next, t do + for key, _ in next, t do k[#k+1] = key end return k |