From 3d7afaa86d4d170aacd4d287e70149d22172bf4f Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 9 May 2008 19:33:00 +0200 Subject: stable 2008.05.09 19:33 --- scripts/context/lua/luatools.lua | 66 ++++-- scripts/context/lua/mtx-chars.lua | 11 +- scripts/context/lua/mtx-context.lua | 101 +++++++-- scripts/context/lua/mtx-update.lua | 4 +- scripts/context/lua/mtxrun.lua | 403 +++++++++++++++++++++++++++++------- scripts/context/ruby/base/tex.rb | 3 +- scripts/context/stubs/unix/context | 2 +- 7 files changed, 472 insertions(+), 118 deletions(-) (limited to 'scripts') diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua index 213922fb3..b092c5050 100644 --- a/scripts/context/lua/luatools.lua +++ b/scripts/context/lua/luatools.lua @@ -430,14 +430,16 @@ function lpeg.splitter(pattern, action) return (((1-lpeg.P(pattern))^1)/action+1)^0 end +local crlf = lpeg.P("\r\n") +local cr = lpeg.P("\r") +local lf = lpeg.P("\n") +local space = lpeg.S(" \t\f\v") +local newline = crlf + cr + lf +local spacing = space^0 * newline -local crlf = lpeg.P("\r\n") -local cr = lpeg.P("\r") -local lf = lpeg.P("\n") -local space = lpeg.S(" \t\f\v") -local newline = crlf + cr + lf -local spacing = space^0 * newline -local content = lpeg.Cs((1-spacing)^1) * spacing^-1 * (spacing * lpeg.Cc(""))^0 +local empty = spacing * lpeg.Cc("") +local nonempty = lpeg.Cs((1-spacing)^1) * spacing^-1 +local content = (empty + nonempty)^1 local capture = lpeg.Ct(content^0) @@ -1704,6 +1706,10 @@ end file.readdata = io.loaddata file.savedata = io.savedata +function file.copy(oldname,newname) + file.savedata(newname,io.loaddata(oldname)) +end + -- filename : l-url.lua -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL @@ -1939,21 +1945,27 @@ if lfs then do P(1) )^0 ) - local function glob(str) - local split = pattern:match(str) - if split then - local t = { } - local action = action or function(name) t[#t+1] = name end - local root, path, base = split[1], split[2], split[3] - local recurse = base:find("**") - local start = root .. path - local result = filter:match(start .. base) ---~ print(str, start, result) ---~ print(start, result) - glob_pattern(start,result,recurse,action) + local function glob(str,t) + if type(str) == "table" then + local t = t or { } + for _, s in ipairs(str) do + glob(s,t) + end return t else - return { } + local split = pattern:match(str) + if split then + local t = t or { } + local action = action or function(name) t[#t+1] = name end + local root, path, base = split[1], split[2], split[3] + local recurse = base:find("**") + local start = root .. path + local result = filter:match(start .. base) + glob_pattern(start,result,recurse,action) + return t + else + return { } + end end end @@ -5615,14 +5627,24 @@ if texconfig and not texlua then input.logger('= ' .. tag .. ' closer (' .. unicode.utfname[u] .. ')',filename) input.show_close(filename) end, +--~ getline = function(n) +--~ local line = t.lines[n] +--~ if not line or line == "" then +--~ return "" +--~ else +--~ local translator = input.filters.utf_translator +--~ return (translator and translator(line)) or line +--~ end +--~ end, reader = function(self) self = self or t local current, lines = self.current, self.lines if current >= #lines then return nil else - self.current = current + 1 - local line = lines[self.current] + current = current + 1 + self.current = current + local line = lines[current] if line == "" then return "" else diff --git a/scripts/context/lua/mtx-chars.lua b/scripts/context/lua/mtx-chars.lua index 77c74cf51..a05ab9f08 100644 --- a/scripts/context/lua/mtx-chars.lua +++ b/scripts/context/lua/mtx-chars.lua @@ -106,7 +106,7 @@ scripts.chars.banner_utf_2 = [[ scripts.chars.banner_utf_3 = [[ -% named characters mapped onto utf +% named characters mapped onto utf (\\char is needed for accents) ]] @@ -145,10 +145,15 @@ function scripts.chars.makeencoutf() f:write(scripts.chars.banner_utf_3) for i=1,#list do local code = list[i] - if code > 0x7F and code <= 0xFFFF then + if code > 0x5B and code <= 0xFFFF then local chr = characters.data[code] if chr.contextname then - f:write(format("\\def\\%s{%s} %% %s\n", chr.contextname:rpadd(length," "), char(code),chr.description)) + local ch = char(code) +--~ if ch:find("[~#$%%^&{}\\]") then + f:write(format("\\def\\%s{\\char\"%04X } %% %s: %s\n", chr.contextname:rpadd(length," "), code, chr.description, ch)) +--~ else +--~ f:write(format("\\def\\%s{%s} %% %s\n", chr.contextname:rpadd(length," "), ch,chr.description)) +--~ end end end end diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index a2ea27a9b..ae0ee1b8e 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -40,9 +40,9 @@ function input.locate_format(name) -- move this to core / luat-xxx if fmtname ~= "" then barename = fmtname:gsub("%.%a+$","") local luaname, lucname = barename .. ".lua", barename .. ".luc" - if io.exists(lucname) then + if lfs.isfile(lucname) then return barename, luaname - elseif io.exists(luaname) then + elseif lfs.isfile(luaname) then return barename, luaname end end @@ -196,12 +196,12 @@ do -- mtxrun should resolve kpse: and file: local usedname = ctxdata.ctxname - local found = io.exists(usedname) + local found = lfs.isfile(usedname) if not found then for _, path in pairs(ctxdata.locations) do local fullname = file.join(path,ctxdata.ctxname) - if io.exists(fullname) then + if lfs.isfile(fullname) then usedname, found = fullname, true break end @@ -344,7 +344,7 @@ do end end end - if io.exists(newfile) then + if lfs.isfile(newfile) then file.syncmtimes(oldfile,newfile) ctxdata.prepfiles[oldfile] = true else @@ -353,7 +353,7 @@ do end else input.report("old file needs no preprocessing") - ctxdata.prepfiles[oldfile] = io.exists(newfile) + ctxdata.prepfiles[oldfile] = lfs.isfile(newfile) end end end @@ -611,6 +611,68 @@ function scripts.context.ctx() scripts.context.run(ctxdata) end +function scripts.context.version() + local name = input.find_file(instance,"context.tex") + if name ~= "" then + input.report(string.format("main context file: %s",name)) + local data = io.loaddata(name) + if data then + local version = data:match("\\edef\\contextversion{(.-)}") + if version then + input.report(string.format("current version : %s",version)) + else + input.report("context version: unknown, no timestamp found") + end + else + input.report("context version: unknown, load error") + end + else + input.report("main context file: unknown, 'context.tex' not found") + end +end + +function scripts.context.touch() + if environment.argument("expert") then + local function touch(name,pattern) + local name = input.find_file(instance,name) + local olddata = io.loaddata(name) + if olddata then + local oldversion, newversion = "", os.date("%Y.%M.%d %H:%m") + local newdata, ok = olddata:gsub(pattern,function(pre,mid,post) + oldversion = mid + return pre .. newversion .. post + end) + if ok > 0 then + local backup = file.replacesuffix(name,"tmp") + os.remove(backup) + os.rename(name,backup) + io.savedata(name,newdata) + return true, oldversion, newversion, name + else + return false + end + end + end + local done, oldversion, newversion, foundname = touch("context.tex", "(\\edef\\contextversion{)(.-)(})") + if done then + input.report(string.format("old version : %s", oldversion)) + input.report(string.format("new version : %s", newversion)) + input.report(string.format("touched file: %s", foundname)) + local ok, _, _, foundname = touch("cont-new.tex", "(\\newcontextversion{)(.-)(})") + if ok then + input.report(string.format("touched file: %s", foundname)) + end + end + end +end + +function scripts.context.timed(action) + input.starttiming(scripts.context) + action() + input.stoptiming(scripts.context) + input.report("total runtime: " .. input.elapsedtime(scripts.context)) +end + banner = banner .. " | context tools " messages.help = [[ @@ -618,30 +680,41 @@ messages.help = [[ --make create context formats formats --generate generate file database etc. --ctx=name use ctx file +--version report installed context version --autopdf open pdf file afterwards + +--expert expert options ]] -input.verbose = true +messages.expert = [[ +expert options: also provide --expert -input.starttiming(scripts.context) +--touch update context version (remake needed afterwards) +]] + +input.verbose = true if environment.argument("once") then scripts.context.multipass.nofruns = 1 end if environment.argument("run") then - scripts.context.run() + scripts.context.timed(scripts.context.run) elseif environment.argument("make") then - scripts.context.make() + scripts.context.timed(scripts.context.make) elseif environment.argument("ctx") then - scripts.context.ctx() + scripts.context.timed(scripts.context.ctx) +elseif environment.argument("version") then + scripts.context.version() +elseif environment.argument("touch") then + scripts.context.touch() elseif environment.argument("help") then input.help(banner,messages.help) +elseif environment.argument("expert") then + input.help(banner,messages.expert) elseif environment.files[1] then - scripts.context.run() + scripts.context.timed(scripts.context.run) else input.help(banner,messages.help) end -input.stoptiming(scripts.context) -input.report("total runtime: " .. input.elapsedtime(scripts.context)) diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua index 4908db4da..581774f1e 100644 --- a/scripts/context/lua/mtx-update.lua +++ b/scripts/context/lua/mtx-update.lua @@ -220,9 +220,9 @@ function scripts.update.synchronize() local archives, command = table.concat(archive," "), "" local normalflags, deleteflags = states.get("rsync.flags.normal"), states.get("rsync.flags.delete") if true then -- environment.argument("keep") or destination:find("%.$") then - command = string.format("%s %s %s'%s' %s", bin, normalflags, url, archives, destination) + command = string.format("%s %s %s'%s' '%s'", bin, normalflags, url, archives, destination) else - command = string.format("%s %s %s %s'%s' %s", bin, normalflags, deleteflags, url, archives, destination) + command = string.format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) end logs.report("mtx update", string.format("running command: %s",command)) if not fetched[command] then diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index de5f53975..63605b42f 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -444,14 +444,16 @@ function lpeg.splitter(pattern, action) return (((1-lpeg.P(pattern))^1)/action+1)^0 end +local crlf = lpeg.P("\r\n") +local cr = lpeg.P("\r") +local lf = lpeg.P("\n") +local space = lpeg.S(" \t\f\v") +local newline = crlf + cr + lf +local spacing = space^0 * newline -local crlf = lpeg.P("\r\n") -local cr = lpeg.P("\r") -local lf = lpeg.P("\n") -local space = lpeg.S(" \t\f\v") -local newline = crlf + cr + lf -local spacing = space^0 * newline -local content = lpeg.Cs((1-spacing)^1) * spacing^-1 * (spacing * lpeg.Cc(""))^0 +local empty = spacing * lpeg.Cc("") +local nonempty = lpeg.Cs((1-spacing)^1) * spacing^-1 +local content = (empty + nonempty)^1 local capture = lpeg.Ct(content^0) @@ -1718,6 +1720,10 @@ end file.readdata = io.loaddata file.savedata = io.savedata +function file.copy(oldname,newname) + file.savedata(newname,io.loaddata(oldname)) +end + -- filename : l-dir.lua -- comment : split off from luat-lib @@ -1848,21 +1854,27 @@ if lfs then do P(1) )^0 ) - local function glob(str) - local split = pattern:match(str) - if split then - local t = { } - local action = action or function(name) t[#t+1] = name end - local root, path, base = split[1], split[2], split[3] - local recurse = base:find("**") - local start = root .. path - local result = filter:match(start .. base) ---~ print(str, start, result) ---~ print(start, result) - glob_pattern(start,result,recurse,action) + local function glob(str,t) + if type(str) == "table" then + local t = t or { } + for _, s in ipairs(str) do + glob(s,t) + end return t else - return { } + local split = pattern:match(str) + if split then + local t = t or { } + local action = action or function(name) t[#t+1] = name end + local root, path, base = split[1], split[2], split[3] + local recurse = base:find("**") + local start = root .. path + local result = filter:match(start .. base) + glob_pattern(start,result,recurse,action) + return t + else + return { } + end end end @@ -2147,6 +2159,8 @@ if not modules then modules = { } end modules ['l-xml'] = { -- RJ: key=value ... lpeg.Ca(lpeg.Cc({}) * (pattern-producing-key-and-value / rawset)^0) +-- some code may move to l-xmlext + --[[ldx--

The parser used here is inspired by the variant discussed in the lua book, but handles comment and processing instructions, has a different structure, provides @@ -2353,9 +2367,10 @@ do end local resolved = (namespace == "" and xmlns[#xmlns]) or nsremap[namespace] or namespace top = stack[#stack] - setmetatable(top, mt) dt = top.dt - dt[#dt+1] = { ns=namespace or "", rn=resolved, tg=tag, at=at, dt={}, __p__ = top } + local t = { ns=namespace or "", rn=resolved, tg=tag, at=at, dt={}, __p__ = top } + dt[#dt+1] = t + setmetatable(t, mt) at = { } if at.xmlns then remove(xmlns) @@ -2521,7 +2536,7 @@ do return root and not root.error end - xml.error_handler = (logs and logs.report) or print + xml.error_handler = (logs and logs.report) or (input and input.report) or print end @@ -2699,7 +2714,7 @@ do handle("<" .. ens .. ":" .. etg .. " " .. concat(ats," ") .. "/>") else -- handle(format("<%s:%s/>",ens,etg)) - handle("<" .. ens .. ":" .. "/>") + handle("<" .. ens .. ":" .. etg .. "/>") end end else @@ -2881,6 +2896,10 @@ will explain more about its usage in other documents.

do + xml.functions = xml.functions or { } + + local functions = xml.functions + local actions = { [10] = "stay", [11] = "parent", @@ -2903,19 +2922,72 @@ do [40] = "processing instruction", } - local function make_expression(str) --could also be an lpeg - str = str:gsub("@([a-zA-Z%-_]+)", "(a['%1'] or '')") - str = str:gsub("position%(%)", "i") - str = str:gsub("text%(%)", "t") - str = str:gsub("!=", "~=") - str = str:gsub("([^=!~<>])=([^=!~<>])", "%1==%2") - str = str:gsub("([a-zA-Z%-_]+)%(", "functions.%1(") - return str, loadstring(format("return function(functions,i,a,t) return %s end", str))() + --~ local function make_expression(str) --could also be an lpeg + --~ str = str:gsub("@([a-zA-Z%-_]+)", "(a['%1'] or '')") + --~ str = str:gsub("position%(%)", "i") + --~ str = str:gsub("text%(%)", "t") + --~ str = str:gsub("!=", "~=") + --~ str = str:gsub("([^=!~<>])=([^=!~<>])", "%1==%2") + --~ str = str:gsub("([a-zA-Z%-_]+)%(", "functions.%1(") + --~ return str, loadstring(format("return function(functions,i,a,t) return %s end", str))() + --~ end + + -- a rather dumb lpeg + + local P, S, R, C, V, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc + + local lp_position = P("position()") / "id" + local lp_text = P("text()") / "tx" + local lp_name = P("name()") / "((rt.ns~='' and rt.ns..':'..rt.tg) or '')" + local lp_tag = P("tag()") / "(rt.tg or '')" + local lp_ns = P("ns()") / "(rt.ns or '')" + local lp_noequal = P("!=") / "~=" + P("<=") + P(">=") + P("==") + local lp_doequal = P("=") / "==" + local lp_attribute = P("@") / "" * Cc("(at['") * R("az","AZ","--","__")^1 * Cc("'] or '')") + + local lp_function = C(R("az","AZ","--","__")^1) * P("(") / function(t) + if functions[t] then + return "functions." .. t .. "(" + else + return "functions.error(" + end end - local map = { } + local lparent = lpeg.P("(") + local rparent = lpeg.P(")") + local noparent = 1 - (lparent+rparent) + local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent} + local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) - local P, S, R, C, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V +--~ local value = P { "(" * C(((1 - S("()")) + V(1))^0) * ")" } + + local lp_special = (C(P("name")+P("text")+P("tag"))) * value / function(t,s) + if functions[t] then + if s then + return "functions." .. t .. "(rt,k," .. s ..")" + else + return "functions." .. t .. "(rt,k)" + end + else + return "functions.error(" .. t .. ")" + end + end + + local converter = lpeg.Cs ( ( + lp_position + + lp_text + lp_name + -- fast one + lp_special + + lp_noequal + lp_doequal + + lp_attribute + + lp_function + + 1 )^1 ) + + local function make_expression(str) + str = converter:match(str) + return str, loadstring(format("return function(functions,id,at,tx,rt,k) return %s end", str))() + end + + local map = { } local space = S(' \r\n\t') local squote = S("'") @@ -2935,8 +3007,10 @@ do local bar = P('|') local hat = P('^') local valid = R('az', 'AZ', '09') + S('_-') - local name_yes = C(valid^1) * colon * C(valid^1 + star) -- permits ns:* - local name_nop = C(P(true)) * C(valid^1) +--~ local name_yes = C(valid^1 + star) * colon * C(valid^1 + star) -- permits ns:* *:tg *:* +--~ local name_nop = C(P(true)) * C(valid^1) + local name_yes = C(valid^1 + star) * colon * C(valid^1 + star) -- permits ns:* *:tg *:* + local name_nop = Cc("*") * C(valid^1) local name = name_yes + name_nop local number = C((S('+-')^0 * R('09')^1)) / tonumber local names = (bar^0 * name)^1 @@ -2998,8 +3072,10 @@ do local expression = (is_one * is_expression)/ function(...) map[#map+1] = { 31, true, ... } end local dont_expression = (is_none * is_expression)/ function(...) map[#map+1] = { 31, false, ... } end - local self_expression = ( is_expression)/ function(...) map[#map+1] = { 31, true, "", "*", ... } end - local dont_self_expression = (exclam * is_expression)/ function(...) map[#map+1] = { 31, true, "", "*", ... } end + local self_expression = ( is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end + map[#map+1] = { 31, true, "*", "*", ... } end + local dont_self_expression = (exclam * is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end + map[#map+1] = { 31, false, "*", "*", ... } end local instruction = (instructiontag * text ) / function(...) map[#map+1] = { 40, ... } end local nothing = (empty ) / function( ) map[#map+1] = { 15 } end -- 15 ? @@ -3127,8 +3203,10 @@ do function xml.xshow(e,...) -- also handy when report is given, use () to isolate first e local t = { ... } local report = (type(t[#t]) == "function" and t[#t]) or fallbackreport - if not e then + if e == nil then report("\n") + elseif type(e) ~= "table" then + report(tostring(e)) elseif e.tg then report(tostring(e) .. "\n") else @@ -3155,8 +3233,6 @@ advance what we want to do with the found element the handle gets three argument functions.

--ldx]]-- -xml.functions = { } - do local functions = xml.functions @@ -3167,11 +3243,84 @@ do functions.lower = string.lower functions.number = tonumber functions.boolean = toboolean - functions.oneof = function(s,...) -- slow + + functions.oneof = function(s,...) -- slow local t = {...} for i=1,#t do if s == t[i] then return true end end return false end + functions.error = function(str) + xml.error_handler("unknown function in lpath expression",str) + return false + end + functions.text = function(root,k,n) -- unchecked, maybe one deeper + local t = type(t) + if t == "string" then + return t + else -- todo n + local rdt = root.dt + return (rdt and rdt[k]) or root[k] or "" + end + end + functions.name = function(root,k,n) +-- way too fuzzy + local found + if not k or not n then + local ns, tg = root.ns, root.tg + if not tg then + for i=1,#root do + local e = root[i] + if type(e) == "table" then + found = e + break + end + end + elseif ns == "" then + return tg + else + return ns .. ":" .. tg + end + elseif n == 0 then + local e = root[k] + if type(e) ~= "table" then + found = e + end + elseif n < 0 then + for i=k-1,1,-1 do + local e = root[i] + if type(e) == "table" then + if n == -1 then + found = e + break + else + n = n + 1 + end + end + end + else + for i=k+1,#root,1 do + local e = root[i] + if type(e) == "table" then + if n == 1 then + found = e + break + else + n = n - 1 + end + end + end + end + if found then + local ns, tg = found.ns, found.tg + if ns ~= "" then + return ns .. ":" .. tg + else + return tg + end + else + return "" + end + end - local function traverse(root,pattern,handle,reverse,index,parent,wildcard) + local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- multiple only for tags, not for namespaces if not root then -- error return false elseif pattern == false then -- root @@ -3198,11 +3347,15 @@ do local rootdt = root.dt for k=1,#rootdt do local e = rootdt[k] - local ns, tg = (e.rn or e.ns), e.tg - local matched = ns == action[3] and tg == action[4] - if not action[2] then matched = not matched end - if matched then - if handle(root,rootdt,k) then return false end + local tg = e.tg + if e.tg then + local ns = e.rn or e.ns + local ns_a, tg_a = action[3], action[4] + local matched = (ns_a == "*" or ns == ns_a) and (tg_a == "*" or tg == tg_a) + if not action[2] then matched = not matched end + if matched then + if handle(root,rootdt,k) then return false end + end end end elseif command == 11 then -- parent @@ -3245,8 +3398,14 @@ do if tg then idx = idx + 1 if command == 30 then - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local ns_a, tg_a = action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end if matched then n = n + dn @@ -3264,57 +3423,102 @@ do else local matched, multiple = false, false if command == 20 then -- match - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local ns_a, tg_a = action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end elseif command == 21 then -- match one of multiple = true for i=3,#action,2 do - if ns == action[i] and tg == action[i+1] then matched = true break end + local ns_a, tg_a = action[i], action[i+1] + if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then + matched = true + break + end end if not action[2] then matched = not matched end elseif command == 22 then -- eq - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end - if not action[2] then matched = not matched end + local ns_a, tg_a = action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end matched = matched and e.at[action[6]] == action[7] elseif command == 23 then -- ne - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local ns_a, tg_a = action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end matched = mached and e.at[action[6]] ~= action[7] elseif command == 24 then -- one of eq multiple = true for i=3,#action-2,2 do - if ns == action[i] and tg == action[i+1] then matched = true break end + local ns_a, tg_a = action[i], action[i+1] + if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then + matched = true + break + end end if not action[2] then matched = not matched end matched = matched and e.at[action[#action-1]] == action[#action] elseif command == 25 then -- one of ne multiple = true for i=3,#action-2,2 do - if ns == action[i] and tg == action[i+1] then matched = true break end + local ns_a, tg_a = action[i], action[i+1] + if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then + matched = true + break + end end if not action[2] then matched = not matched end matched = matched and e.at[action[#action-1]] ~= action[#action] elseif command == 27 then -- has attribute - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local ns_a, tg_a = action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end matched = matched and e.at[action[5]] elseif command == 28 then -- has value - local edt = e.dt - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local edt, ns_a, tg_a = e.dt, action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end matched = matched and edt and edt[1] == action[5] elseif command == 31 then - local edt = e.dt - local tg_a = action[4] - if tg == tg_a then matched = ns == action[3] elseif tg_a == '*' then matched, multiple = ns == action[3], true else matched = false end + local edt, ns_a, tg_a = e.dt, action[3], action[4] + if tg == tg_a then + matched = ns_a == "*" or ns == ns_a + elseif tg_a == '*' then + matched, multiple = ns_a == "*" or ns == ns_a, true + else + matched = false + end if not action[2] then matched = not matched end if matched then - matched = action[6](functions,idx,e.at or { },edt[1]) + matched = action[6](functions,idx,e.at or { },edt[1],rootdt,k) end end if matched then -- combine tg test and at test @@ -3490,7 +3694,7 @@ do end function xml.filters.text(root,pattern,arguments) -- ?? why index, tostring slow local dtk, rt, dt, dk = xml.filters.index(root,pattern,arguments) - if dtk then + if dtk then -- n local dtkdt = dtk.dt if not dtkdt then return "", rt, dt, dk @@ -3503,6 +3707,22 @@ do return "", rt, dt, dk end end + function xml.filters.tag(root,pattern,n) + local tag = "" + xml.traverse(root, xml.lpath(pattern), function(r,d,k) + tag = xml.functions.tag(d,k,n and tonumber(n)) + return true + end) + return tag + end + function xml.filters.name(root,pattern,n) + local tag = "" + xml.traverse(root, xml.lpath(pattern), function(r,d,k) + tag = xml.functions.name(d,k,n and tonumber(n)) + return true + end) + return tag + end --[[ldx--

For splitting the filter function from the path specification, we can @@ -3514,13 +3734,15 @@ do local P, S, R, C, V, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc - local name = (R("az","AZ")+R("_-"))^1 - local path = C(((1-P('/'))^0 * P('/'))^1) + local slash = P('/') + local name = (R("az","AZ","--","__"))^1 + local path = C(((1-slash)^0 * slash)^1) local argument = P { "(" * C(((1 - S("()")) + V(1))^0) * ")" } local action = Cc(1) * path * C(name) * argument local attribute = Cc(2) * path * P('@') * C(name) + local direct = Cc(3) * Cc("../*") * slash^0 * C(name) * argument - local parser = action + attribute + local parser = direct + action + attribute local filters = xml.filters local attribute_filter = xml.filters.attributes @@ -3528,7 +3750,7 @@ do function xml.filter(root,pattern) local kind, a, b, c = parser:match(pattern) - if kind == 1 then + if kind == 1 or kind == 3 then return (filters[b] or default_filter)(root,a,c) elseif kind == 2 then return attribute_filter(root,a,b) @@ -3568,12 +3790,14 @@ do

The following functions collect elements and texts.

--ldx]]-- + -- still somewhat bugged + function xml.collect_elements(root, pattern, ignorespaces) local rr, dd = { }, { } traverse(root, lpath(pattern), function(r,d,k) local dk = d and d[k] if dk then - if ignorespaces and type(dk) == "string" and dk:find("^%s*$") then + if ignorespaces and type(dk) == "string" and dk:find("[^%S]") then -- ignore else local n = #rr+1 @@ -3606,6 +3830,24 @@ do return t end + function xml.collect_tags(root, pattern, nonamespace) + local t = { } + xml.traverse(root, xml.lpath(pattern), function(r,d,k) + local dk = d and d[k] + if dk and type(dk) == "table" then + local ns, tg = e.ns, e.tg + if nonamespace then + t[#t+1] = tg -- if needed we can return an extra table + elseif ns == "" then + t[#t+1] = tg + else + t[#t+1] = ns .. ":" .. tg + end + end + end) + return #t > 0 and {} + end + --[[ldx--

Often using an iterators looks nicer in the code than passing handler functions. The book describes how to use coroutines for that @@ -4166,6 +4408,17 @@ end end --~ --~ ]] +--~ x = xml.convert([[ +--~ 0102xx03OK +--~ ]]) +--~ xml.xshow(xml.first(x,"b[tag(2) == 'x']")) +--~ xml.xshow(xml.first(x,"b[tag(1) == 'x']")) +--~ xml.xshow(xml.first(x,"b[tag(-1) == 'x']")) +--~ xml.xshow(xml.first(x,"b[tag(-2) == 'x']")) + +--~ print(xml.filter(x,"b/tag(2)")) +--~ print(xml.filter(x,"b/tag(1)")) + -- filename : l-utils.lua -- comment : split off from luat-lib diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb index bf2f92547..582ff640c 100644 --- a/scripts/context/ruby/base/tex.rb +++ b/scripts/context/ruby/base/tex.rb @@ -930,7 +930,8 @@ end case str.chomp when /^\%/o then # next - when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then + # when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then + when /\\(starttekst|stoptekst|startonderdeel|startoverzicht)/o then setvariable('texformats','nl') ; break when /\\(stelle|verwende|umgebung|benutze)/o then setvariable('texformats','de') ; break diff --git a/scripts/context/stubs/unix/context b/scripts/context/stubs/unix/context index a9d71ce9c..c7341904f 100755 --- a/scripts/context/stubs/unix/context +++ b/scripts/context/stubs/unix/context @@ -1,3 +1,3 @@ #!/bin/sh -mtxrun --script context $@ +mtxrun --script context "$@" -- cgit v1.2.3