From 84c5ae8992fff7184ebc669a1eb654a92d55951c Mon Sep 17 00:00:00 2001
From: Hans Hagen
Date: Fri, 11 Apr 2008 00:07:00 +0200
Subject: stable 2008.04.11 00:07
---
scripts/context/lua/luatools.lua | 147 +++++--
scripts/context/lua/mtx-context.lua | 4 +
scripts/context/lua/mtxrun.lua | 406 +++++++++--------
scripts/context/lua/scite-ctx.lua | 843 ++++++++++++++++++++++++++++++++++++
scripts/context/perl/makempy.pl | 2 +-
5 files changed, 1178 insertions(+), 224 deletions(-)
create mode 100644 scripts/context/lua/scite-ctx.lua
(limited to 'scripts')
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index 2d146149e..b38d0c4c1 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -1845,19 +1845,68 @@ dir = { }
if lfs then do
+--~ local attributes = lfs.attributes
+--~ local walkdir = lfs.dir
+--~
+--~ local function glob_pattern(path,patt,recurse,action)
+--~ local ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+--~ if ok and type(scanner) == "function" then
+--~ if not path:find("/$") then path = path .. '/' end
+--~ for name in scanner do
+--~ local full = path .. name
+--~ local mode = attributes(full,'mode')
+--~ if mode == 'file' then
+--~ if name:find(patt) then
+--~ action(full)
+--~ end
+--~ elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then
+--~ glob_pattern(full,patt,recurse,action)
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ dir.glob_pattern = glob_pattern
+--~
+--~ local function glob(pattern, action)
+--~ local t = { }
+--~ local action = action or function(name) t[#t+1] = name end
+--~ local path, patt = pattern:match("^(.*)/*%*%*/*(.-)$")
+--~ local recurse = path and patt
+--~ if not recurse then
+--~ path, patt = pattern:match("^(.*)/(.-)$")
+--~ if not (path and patt) then
+--~ path, patt = '.', pattern
+--~ end
+--~ end
+--~ patt = patt:gsub("([%.%-%+])", "%%%1")
+--~ patt = patt:gsub("%*", ".*")
+--~ patt = patt:gsub("%?", ".")
+--~ patt = "^" .. patt .. "$"
+--~ -- print('path: ' .. path .. ' | pattern: ' .. patt .. ' | recurse: ' .. tostring(recurse))
+--~ glob_pattern(path,patt,recurse,action)
+--~ return t
+--~ end
+--~
+--~ dir.glob = glob
+
local attributes = lfs.attributes
local walkdir = lfs.dir
local function glob_pattern(path,patt,recurse,action)
- local ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+ local ok, scanner
+ if path == "/" then
+ ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe
+ else
+ ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+ end
if ok and type(scanner) == "function" then
if not path:find("/$") then path = path .. '/' end
for name in scanner do
-print(name)
local full = path .. name
local mode = attributes(full,'mode')
if mode == 'file' then
- if name:find(patt) then
+ if full:find(patt) then
action(full)
end
elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then
@@ -1871,29 +1920,72 @@ print(name)
local function glob(pattern, action)
local t = { }
- local action = action or function(name) table.insert(t,name) end
- local path, patt = pattern:match("^(.*)/*%*%*/*(.-)$")
- local recurse = path and patt
- if not recurse then
- path, patt = pattern:match("^(.*)/(.-)$")
- if not (path and patt) then
- path, patt = '.', pattern
- end
- end
- patt = patt:gsub("([%.%-%+])", "%%%1")
- patt = patt:gsub("%*", ".*")
- patt = patt:gsub("%?", ".")
- patt = "^" .. patt .. "$"
- -- print('path: ' .. path .. ' | pattern: ' .. patt .. ' | recurse: ' .. tostring(recurse))
+ local path, rest, patt, recurse
+ local action = action or function(name) t[#t+1] = name end
+ local pattern = pattern:gsub("^%*%*","./**")
+ local pattern = pattern:gsub("/%*/","/**/")
+ path, rest = pattern:match("^(/)(.-)$")
+ if path then
+ path = path
+ else
+ path, rest = pattern:match("^([^/]*)/(.-)$")
+ end
+ if rest then
+ patt = rest:gsub("([%.%-%+])", "%%%1")
+ end
+ patt = patt:gsub("%*", "[^/]*")
+ patt = patt:gsub("%?", "[^/]")
+ patt = patt:gsub("%[%^/%]%*%[%^/%]%*", ".*")
+ if path == "" then path = "." end
+ recurse = patt:find("%.%*/") ~= nil
glob_pattern(path,patt,recurse,action)
return t
end
+ local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
+
+ local pattern = Ct {
+ [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3),
+ [2] = C(((1-S("*?/"))^0 * P("/"))^0),
+ [3] = C(P(1)^0)
+ }
+
+ local filter = Cs ( (
+ P("**") / ".*" +
+ P("*") / "[^/]*" +
+ P("?") / "[^/]" +
+ P(".") / "%." +
+ P("+") / "%+" +
+ P("-") / "%-" +
+ P(1)
+ )^0 )
+
+ 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)
+ glob_pattern(start,result,recurse,action)
+ return t
+ else
+ return { }
+ end
+ end
+
dir.glob = glob
- -- todo: speedup
+ --~ list = dir.glob("**/*.tif")
+ --~ list = dir.glob("/**/*.tif")
+ --~ list = dir.glob("./**/*.tif")
+ --~ list = dir.glob("oeps/**/*.tif")
+ --~ list = dir.glob("/oeps/**/*.tif")
- local function globfiles(path,recurse,func,files)
+ local function globfiles(path,recurse,func,files) -- func == pattern or function
if type(func) == "string" then
local s = func -- alas, we need this indirect way
func = function(name) return name:find(s) end
@@ -1935,23 +2027,6 @@ print(name)
--~ mkdirs(".","/a/b/c")
--~ mkdirs("a","b","c")
---~ function dir.mkdirs(...)
---~ local pth, err, lst = "", false, table.concat({...},"/")
---~ for _, s in ipairs(lst:split("/")) do
---~ if pth == "" then
---~ pth = (s == "" and "/") or s
---~ else
---~ pth = pth .. "/" .. s
---~ end
---~ if s == "" then
---~ -- can be network path
---~ elseif not lfs.isdir(pth) then
---~ lfs.mkdir(pth)
---~ end
---~ end
---~ return pth, not err
---~ end
-
local make_indeed = true -- false
if string.find(os.getenv("PATH"),";") then
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index e0aa7d086..a2ea27a9b 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -625,6 +625,10 @@ input.verbose = true
input.starttiming(scripts.context)
+if environment.argument("once") then
+ scripts.context.multipass.nofruns = 1
+end
+
if environment.argument("run") then
scripts.context.run()
elseif environment.argument("make") then
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index aa78a553e..f08c0f812 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -176,7 +176,7 @@ end
--~ split = lpeg.Ct(c*(p*c)^0)
--~ splitters[separator] = split
--~ end
---~ return lpeg.match(split,self) -- split:match(self)
+--~ return split:match(self)
--~ else
--~ return { }
--~ end
@@ -429,6 +429,8 @@ if not versions then versions = { } end versions['l-lpeg'] = 1.001
--~ lpeg.whitespace = lpeg.S(' \r\n\f\t')^1
--~ lpeg.nonwhitespace = lpeg.P(1-lpeg.whitespace)^1
+local hash = { }
+
function lpeg.anywhere(pattern) --slightly adapted from website
return lpeg.P { lpeg.P(pattern) + 1 * lpeg.V(1) }
end
@@ -444,6 +446,20 @@ function lpeg.splitter(pattern, action)
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 content = lpeg.Cs((1-spacing)^1) * spacing^-1 * (spacing * lpeg.Cc(""))^0
+
+local capture = lpeg.Ct(content^0)
+
+function string:splitlines()
+ return capture:match(self)
+end
+
-- filename : l-table.lua
-- comment : split off from luat-lib
@@ -517,15 +533,6 @@ function table.prepend(t, list)
end
end
---~ function table.merge(t, ...)
---~ for _, list in ipairs({...}) do
---~ for k,v in pairs(list) do
---~ t[k] = v
---~ end
---~ end
---~ return t
---~ end
-
function table.merge(t, ...) -- first one is target
t = t or {}
local lst = {...}
@@ -537,16 +544,6 @@ function table.merge(t, ...) -- first one is target
return t
end
---~ function table.merged(...)
---~ local tmp = { }
---~ for _, list in ipairs({...}) do
---~ for k,v in pairs(list) do
---~ tmp[k] = v
---~ end
---~ end
---~ return tmp
---~ end
-
function table.merged(...)
local tmp, lst = { }, {...}
for i=1,#lst do
@@ -557,15 +554,6 @@ function table.merged(...)
return tmp
end
---~ function table.imerge(t, ...)
---~ for _, list in ipairs({...}) do
---~ for _, v in ipairs(list) do
---~ t[#t+1] = v
---~ end
---~ end
---~ return t
---~ end
-
function table.imerge(t, ...)
local lst = {...}
for i=1,#lst do
@@ -577,16 +565,6 @@ function table.imerge(t, ...)
return t
end
---~ function table.imerged(...)
---~ local tmp = { }
---~ for _, list in ipairs({...}) do
---~ for _,v in pairs(list) do
---~ tmp[#tmp+1] = v
---~ end
---~ end
---~ return tmp
---~ end
-
function table.imerged(...)
local tmp, lst = { }, {...}
for i=1,#lst do
@@ -734,7 +712,6 @@ do
end
if n == #t then
local tt = { }
- -- for _,v in ipairs(t) do
for i=1,#t do
local v = t[i]
local tv = type(v)
@@ -789,7 +766,7 @@ do
local inline = compact and table.serialize_inline
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
- for k,v in ipairs(root) do -- NOT: for k=1,#root do
+ for k,v in ipairs(root) do -- NOT: for k=1,#root do (why)
if not first then first = k end
last = last + 1
end
@@ -971,7 +948,8 @@ end
do
local function flatten(t,f,complete)
- for _,v in ipairs(t) do
+ for i=1,#t do
+ local v = t[i]
if type(v) == "table" then
if complete or type(v[1]) == "table" then
flatten(v,f,complete)
@@ -1437,7 +1415,7 @@ do
local one = lpeg.C(1-lpeg.S(''))^1
function number.toset(n)
- return lpeg.match(one,tostring(n))
+ return one:match(tostring(n))
end
end
@@ -1839,17 +1817,53 @@ if lfs then do
else
path, rest = pattern:match("^([^/]*)/(.-)$")
end
- patt = rest:gsub("([%.%-%+])", "%%%1")
+ if rest then
+ patt = rest:gsub("([%.%-%+])", "%%%1")
+ end
patt = patt:gsub("%*", "[^/]*")
patt = patt:gsub("%?", "[^/]")
patt = patt:gsub("%[%^/%]%*%[%^/%]%*", ".*")
if path == "" then path = "." end
- -- print(pattern, path, patt)
- recurse = patt:find("%.%*/")
+ recurse = patt:find("%.%*/") ~= nil
glob_pattern(path,patt,recurse,action)
return t
end
+ local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
+
+ local pattern = Ct {
+ [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3),
+ [2] = C(((1-S("*?/"))^0 * P("/"))^0),
+ [3] = C(P(1)^0)
+ }
+
+ local filter = Cs ( (
+ P("**") / ".*" +
+ P("*") / "[^/]*" +
+ P("?") / "[^/]" +
+ P(".") / "%." +
+ P("+") / "%+" +
+ P("-") / "%-" +
+ P(1)
+ )^0 )
+
+ 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)
+ glob_pattern(start,result,recurse,action)
+ return t
+ else
+ return { }
+ end
+ end
+
dir.glob = glob
--~ list = dir.glob("**/*.tif")
@@ -2162,6 +2176,8 @@ xml.trace_lpath = false
xml.trace_print = false
xml.trace_remap = false
+local format, concat = string.format, table.concat
+
-- todo: some things per xml file, liek namespace remapping
--[[ldx--
@@ -2172,7 +2188,7 @@ find based solution where we loop over an array of patterns. Less code and
much cleaner.
--ldx]]--
-xml.xmlns = { }
+xml.xmlns = xml.xmlns or { }
do
@@ -2312,9 +2328,9 @@ do
local toclose = remove(stack)
top = stack[#stack]
if #stack < 1 then
- errorstr = string.format("nothing to close with %s %s", tag, xml.check_error(top,toclose) or "")
+ errorstr = format("nothing to close with %s %s", tag, xml.check_error(top,toclose) or "")
elseif toclose.tg ~= tag then -- no namespace check
- errorstr = string.format("unable to close %s with %s %s", toclose.tg, tag, xml.check_error(top,toclose) or "")
+ errorstr = format("unable to close %s with %s %s", toclose.tg, tag, xml.check_error(top,toclose) or "")
end
dt = top.dt
dt[#dt+1] = toclose
@@ -2438,8 +2454,10 @@ do
errorstr = "empty xml file"
elseif not grammar:match(data) then
errorstr = "invalid xml file"
+ else
+ errorstr = ""
end
- if errorstr then
+ if errorstr and errorstr ~= "" then
result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } }, error = true }
setmetatable(stack, mt)
if xml.error_handler then xml.error_handler("load",errorstr) end
@@ -2449,7 +2467,9 @@ do
if not no_root then
result = { special = true, ns = "", tg = '@rt@', dt = result.dt, at={} }
setmetatable(result, mt)
- for k,v in ipairs(result.dt) do
+ local rdt = result.dt
+ for k=1,#rdt do
+ local v = rdt[k]
if type(v) == "table" and not v.special then -- always table -)
result.ri = k -- rootindex
break
@@ -2560,138 +2580,141 @@ do
local fallbackhandle = (tex and tex.sprint) or io.write
- function xml.serialize(e, handle, textconverter, attributeconverter, specialconverter, nocommands)
+ local function serialize(e, handle, textconverter, attributeconverter, specialconverter, nocommands)
if not e then
- -- quit
- elseif not nocommands and e.command and xml.command then
- xml.command(e)
- else
- handle = handle or fallbackhandle
- local etg = e.tg
- if etg then
- -- local format = string.format
- if e.special then
- local edt = e.dt
- local spc = specialconverter and specialconverter[etg]
- if spc then
- local result = spc(edt[1])
- if result then
- handle(result)
- else
- -- no need to handle any further
+ return
+ elseif not nocommands then
+ local ec = e.command
+ if ec then
+ local xc = xml.command
+ if xc then
+ xc(e,ec)
+ return
+ end
+ end
+ end
+ handle = handle or fallbackhandle
+ local etg = e.tg
+ if etg then
+ if e.special then
+ local edt = e.dt
+ local spc = specialconverter and specialconverter[etg]
+ if spc then
+ local result = spc(edt[1])
+ if result then
+ handle(result)
+ else
+ -- no need to handle any further
+ end
+ elseif etg == "@pi@" then
+ -- handle(format("%s?>",edt[1]))
+ handle("" .. edt[1] .. "?>") -- maybe table.join(edt)
+ elseif etg == "@cm@" then
+ -- handle(format("",edt[1]))
+ handle("")
+ elseif etg == "@cd@" then
+ -- handle(format("",edt[1]))
+ handle("")
+ elseif etg == "@dd@" then
+ -- handle(format("",edt[1]))
+ handle("")
+ elseif etg == "@rt@" then
+ serialize(edt,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ else
+ local ens, eat, edt, ern = e.ns, e.at, e.dt, e.rn
+ local ats = eat and next(eat) and { }
+ if ats then
+ if attributeconverter then
+ for k,v in pairs(eat) do
+ ats[#ats+1] = format('%s=%q',k,attributeconverter(v))
+ end
+ else
+ for k,v in pairs(eat) do
+ ats[#ats+1] = format('%s=%q',k,v)
end
- elseif etg == "@pi@" then
- -- handle(format("%s?>",edt[1]))
- handle("" .. edt[1] .. "?>") -- maybe table.join(edt)
- elseif etg == "@cm@" then
- -- handle(format("",edt[1]))
- handle("")
- elseif etg == "@cd@" then
- -- handle(format("",edt[1]))
- handle("")
- elseif etg == "@dd@" then
- -- handle(format("",edt[1]))
- handle("")
- elseif etg == "@rt@" then
- xml.serialize(edt,handle,textconverter,attributeconverter,specialconverter,nocommands)
end
- else
- local ens, eat, edt, ern = e.ns, e.at, e.dt, e.rn
- local ats = eat and next(eat) and { }
+ end
+ if ern and xml.trace_remap then
if ats then
- local format = string.format
- if attributeconverter then
- for k,v in pairs(eat) do
- ats[#ats+1] = format('%s=%q',k,attributeconverter(v))
- end
- else
- for k,v in pairs(eat) do
- ats[#ats+1] = format('%s=%q',k,v)
- end
- end
+ ats[#ats+1] = format("xmlns:remapped='%s'",ern)
+ else
+ ats = { format("xmlns:remapped='%s'",ern) }
end
- if ern and xml.trace_remap then
+ end
+ if ens ~= "" then
+ if edt and #edt > 0 then
if ats then
- ats[#ats+1] = string.format("xmlns:remapped='%s'",ern)
+ -- handle(format("<%s:%s %s>",ens,etg,concat(ats," ")))
+ handle("<" .. ens .. ":" .. etg .. " " .. concat(ats," ") .. ">")
else
- ats = { string.format("xmlns:remapped='%s'",ern) }
+ -- handle(format("<%s:%s>",ens,etg))
+ handle("<" .. ens .. ":" .. etg .. ">")
end
- end
- if ens ~= "" then
- if edt and #edt > 0 then
- if ats then
- -- handle(format("<%s:%s %s>",ens,etg,table.concat(ats," ")))
- handle("<" .. ens .. ":" .. etg .. " " .. table.concat(ats," ") .. ">")
- else
- -- handle(format("<%s:%s>",ens,etg))
- handle("<" .. ens .. ":" .. etg .. ">")
- end
- local serialize = xml.serialize
- for i=1,#edt do
- local e = edt[i]
- if type(e) == "string" then
- if textconverter then
- handle(textconverter(e))
- else
- handle(e)
- end
+ for i=1,#edt do
+ local e = edt[i]
+ if type(e) == "string" then
+ if textconverter then
+ handle(textconverter(e))
else
- serialize(e,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ handle(e)
end
- end
- -- handle(format("%s:%s>",ens,etg))
- handle("" .. ens .. ":" .. etg .. ">")
- else
- if ats then
- -- handle(format("<%s:%s %s/>",ens,etg,table.concat(ats," ")))
- handle("<" .. ens .. ":" .. etg .. " " .. table.concat(ats," ") .. "/>")
else
- -- handle(format("<%s:%s/>",ens,etg))
- handle("<" .. ens .. ":" .. "/>")
+ serialize(e,handle,textconverter,attributeconverter,specialconverter,nocommands)
end
end
+ -- handle(format("%s:%s>",ens,etg))
+ handle("" .. ens .. ":" .. etg .. ">")
else
- if edt and #edt > 0 then
- if ats then
- -- handle(format("<%s %s>",etg,table.concat(ats," ")))
- handle("<" .. etg .. " " .. table.concat(ats," ") .. ">")
- else
- -- handle(format("<%s>",etg))
- handle("<" .. etg .. ">")
- end
- local serialize = xml.serialize
- for i=1,#edt do
- serialize(edt[i],handle,textconverter,attributeconverter,specialconverter,nocommands)
- end
- -- handle(format("%s>",etg))
- handle("" .. etg .. ">")
+ if ats then
+ -- handle(format("<%s:%s %s/>",ens,etg,concat(ats," ")))
+ handle("<" .. ens .. ":" .. etg .. " " .. concat(ats," ") .. "/>")
else
- if ats then
- -- handle(format("<%s %s/>",etg,table.concat(ats," ")))
- handle("<" .. etg .. " " .. table.concat(ats," ") .. "/>")
- else
- -- handle(format("<%s/>",etg))
- handle("<" .. etg .. "/>")
- end
+ -- handle(format("<%s:%s/>",ens,etg))
+ handle("<" .. ens .. ":" .. "/>")
end
end
- end
- elseif type(e) == "string" then
- if textconverter then
- handle(textconverter(e))
else
- handle(e)
+ if edt and #edt > 0 then
+ if ats then
+ -- handle(format("<%s %s>",etg,concat(ats," ")))
+ handle("<" .. etg .. " " .. concat(ats," ") .. ">")
+ else
+ -- handle(format("<%s>",etg))
+ handle("<" .. etg .. ">")
+ end
+ for i=1,#edt do
+ serialize(edt[i],handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ -- handle(format("%s>",etg))
+ handle("" .. etg .. ">")
+ else
+ if ats then
+ -- handle(format("<%s %s/>",etg,concat(ats," ")))
+ handle("<" .. etg .. " " .. concat(ats," ") .. "/>")
+ else
+ -- handle(format("<%s/>",etg))
+ handle("<" .. etg .. "/>")
+ end
+ end
end
+ end
+ elseif type(e) == "string" then
+ if textconverter then
+ handle(textconverter(e))
else
- local serialize = xml.serialize
- for i=1,#e do
- serialize(e[i],handle,textconverter,attributeconverter,specialconverter,nocommands)
- end
+ handle(e)
+ end
+ else
+ for i=1,#e do
+ serialize(e[i],handle,textconverter,attributeconverter,specialconverter,nocommands)
end
end
end
- function xml.checkbom(root)
+ xml.serialize = serialize
+
+ function xml.checkbom(root) -- can be made faster
if root.ri then
local dt, found = root.dt, false
for k,v in ipairs(dt) do
@@ -2707,24 +2730,24 @@ do
end
end
-end
-
---[[ldx--
-At the cost of some 25% runtime overhead you can first convert the tree to a string
-and then handle the lot.
---ldx]]--
+ --[[ldx--
+ At the cost of some 25% runtime overhead you can first convert the tree to a string
+ and then handle the lot.
+ --ldx]]--
-function xml.tostring(root) -- 25% overhead due to collecting
- if root then
- if type(root) == 'string' then
- return root
- elseif next(root) then
- local result = { }
- xml.serialize(root,function(s) result[#result+1] = s end)
- return table.concat(result,"")
+ function xml.tostring(root) -- 25% overhead due to collecting
+ if root then
+ if type(root) == 'string' then
+ return root
+ elseif next(root) then
+ local result = { }
+ serialize(root,function(s) result[#result+1] = s end)
+ return concat(result,"")
+ end
end
-end
- return ""
+ return ""
+ end
+
end
--[[ldx--
@@ -2852,14 +2875,14 @@ do
[40] = "processing instruction",
}
- local function make_expression(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(string.format("return function(functions,i,a,t) return %s end", str))()
+ return str, loadstring(format("return function(functions,i,a,t) return %s end", str))()
end
local map = { }
@@ -2945,6 +2968,9 @@ 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 instruction = (instructiontag * text ) / function(...) map[#map+1] = { 40, ... } end
local nothing = (empty ) / function( ) map[#map+1] = { 15 } end -- 15 ?
local crap = (1-slash)^1
@@ -2970,6 +2996,7 @@ do
dont_match_and_eq + dont_match_and_ne +
match_and_eq + match_and_ne +
dont_expression + expression +
+dont_self_expression + self_expression +
has_attribute + has_value +
dont_match_one_of + match_one_of +
dont_match + match +
@@ -2981,7 +3008,7 @@ do
followup = ((slash + parenttag + childtag + selftag)^0 * selector)^1,
}
- function compose(str)
+ local function compose(str)
if not str or str == "" then
-- wildcard
return true
@@ -3003,7 +3030,7 @@ do
-- root
return false
end
- elseif #map == 2 and m == 12 and map[2][1] == 20 then
+ elseif #map == 2 and m == 12 and map[2][1] == 20 then
-- return { { 29, map[2][2], map[2][3], map[2][4], map[2][5] } }
map[2][1] = 29
return { map[2] }
@@ -3011,6 +3038,7 @@ do
if m ~= 11 and m ~= 12 and m ~= 13 and m ~= 14 and m ~= 15 and m ~= 16 then
table.insert(map, 1, { 16 })
end
+ -- print((table.serialize(map)):gsub("[ \n]+"," "))
return map
end
end
@@ -3045,7 +3073,7 @@ do
report(" -: wildcard\n")
else
if type(pattern) == "string" then
- report(string.format("pattern: %s\n",pattern))
+ report(format("pattern: %s\n",pattern))
end
for k,v in ipairs(lp) do
if #v > 1 then
@@ -3058,9 +3086,9 @@ do
t[#t+1] = (vv and "==") or "<>"
end
end
- report(string.format("%2i: %s %s -> %s\n", k,v[1],actions[v[1]],table.join(t," ")))
+ report(format("%2i: %s %s -> %s\n", k,v[1],actions[v[1]],table.join(t," ")))
else
- report(string.format("%2i: %s %s\n", k,v[1],actions[v[1]]))
+ report(format("%2i: %s %s\n", k,v[1],actions[v[1]]))
end
end
end
@@ -3181,7 +3209,7 @@ do
start, stop, step = stop, start, -1
end
local idx = 0
- for k=start,stop,step do
+ for k=start,stop,step do -- we used to have functions for all but a case is faster
local e = rootdt[k]
local ns, tg = e.rn or e.ns, e.tg
if tg then
@@ -3256,15 +3284,19 @@ do
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
if matched then
- matched = action[6](functions,idx,e.at,edt[1])
+ matched = action[6](functions,idx,e.at or { },edt[1])
end
end
if matched then -- combine tg test and at test
if index == #pattern then
if handle(root,rootdt,root.ri or k) then return false end
---~ if wildcard and multiple then
-if wildcard or multiple then
- if not traverse(e,pattern,handle,reverse,index,root,true) then return false end
+ if wildcard then
+ if multiple then
+ if not traverse(e,pattern,handle,reverse,index,root,true) then return false end
+ else
+ -- maybe or multiple; anyhow, check on (section|title) vs just section and title in example in lxml
+ if not traverse(e,pattern,handle,reverse,index,root) then return false end
+ end
end
else
if not traverse(e,pattern,handle,reverse,index+1,root) then return false end
diff --git a/scripts/context/lua/scite-ctx.lua b/scripts/context/lua/scite-ctx.lua
new file mode 100644
index 000000000..1b8329289
--- /dev/null
+++ b/scripts/context/lua/scite-ctx.lua
@@ -0,0 +1,843 @@
+-- version : 1.0.0 - 07/2005 (2008: lua 5.1)
+-- author : Hans Hagen - PRAGMA ADE - www.pragma-ade.com
+-- copyright : public domain or whatever suits
+-- remark : part of the context distribution, my first lua code
+
+-- todo: name space for local functions
+
+-- loading: scite-ctx.properties
+
+-- # environment variable
+-- #
+-- # CTXSPELLPATH=t:/spell
+-- #
+-- # auto language detection
+-- #
+-- # % version =1.0 language=uk
+-- #
+
+-- ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua
+--
+-- # extension.$(file.patterns.context)=scite-ctx.lua
+-- # extension.$(file.patterns.example)=scite-ctx.lua
+--
+-- # ext.lua.reset=1
+-- # ext.lua.auto.reload=1
+-- # ext.lua.startup.script=t:/lua/scite-ctx.lua
+--
+-- ctx.menulist.default=\
+-- wrap=wrap_text|\
+-- unwrap=unwrap_text|\
+-- sort=sort_text|\
+-- document=document_text|\
+-- quote=quote_text|\
+-- compound=compound_text|\
+-- check=check_text
+--
+-- ctx.spellcheck.language=auto
+-- ctx.spellcheck.wordsize=4
+-- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH)
+--
+-- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt
+--
+-- ctx.spellcheck.wordfile.uk=spell-uk.txt
+-- ctx.spellcheck.wordfile.nl=spell-nl.txt
+-- ctx.spellcheck.wordsize.uk=4
+-- ctx.spellcheck.wordsize.nl=4
+--
+-- command.name.21.*=CTX Action List
+-- command.subsystem.21.*=3
+-- command.21.*=show_menu $(ctx.menulist.default)
+-- command.groupundo.21.*=yes
+-- command.shortcut.21.*=Shift+F11
+--
+-- command.name.22.*=CTX Check Text
+-- command.subsystem.22.*=3
+-- command.22.*=check_text
+-- command.groupundo.22.*=yes
+-- command.shortcut.22.*=Ctrl+L
+--
+-- command.name.23.*=CTX Wrap Text
+-- command.subsystem.23.*=3
+-- command.23.*=wrap_text
+-- command.groupundo.23.*=yes
+-- command.shortcut.23.*=Ctrl+M
+--
+-- # command.21.*=check_text
+-- # command.21.*=dofile e:\context\lua\scite-ctx.lua
+
+-- generic functions
+
+local crlf = "\n"
+
+function traceln(str)
+ trace(str .. crlf)
+ io.flush()
+end
+
+function table.found(tab, str)
+ local l, r, p
+ if #str == 0 then
+ return false
+ else
+ l, r = 1, #tab
+ while l <= r do
+ p = math.floor((l+r)/2)
+ if str < tab[p] then
+ r = p - 1
+ elseif str > tab[p] then
+ l = p + 1
+ else
+ return true
+ end
+ end
+ return false
+ end
+end
+
+function string:grab(delimiter)
+ local list = {}
+ for snippet in self:gmatch(delimiter) do
+ list[#list+1] = snippet
+ end
+ return list
+end
+
+function string:is_empty()
+ return not self:find("%S")
+end
+
+function string:expand()
+ return (self:gsub("ENV%((%w+)%)", os.envvar))
+end
+
+function string:strip()
+ return (self:gsub("^%s*(.-)%s*$", "%1"))
+end
+
+do
+
+ local lower, gsub, sub = string.lower, string.gsub, string.sub
+
+ function table.alphasort(list,i)
+ if i and i > 0 then
+ local function alphacmp(a,b)
+ return lower(gsub(sub(a,i),'0',' ')) < lower(gsub(sub(b,i),'0',' '))
+ end
+ table.sort(list,alphacmp)
+ else
+ local function alphacmp(a,b)
+ return a:lower() < b:lower()
+ end
+ table.sort(list,alphacmp)
+ end
+ end
+
+end
+
+function io.exists(filename)
+ local ok, result, message = pcall(io.open,filename)
+ if result then
+ io.close(result)
+ return true
+ else
+ return false
+ end
+end
+
+function os.envvar(str)
+ local s = os.getenv(str)
+ if s ~= '' then
+ return s
+ end
+ s = os.getenv(str:upper())
+ if s ~= '' then
+ return s
+ end
+ s = os.getenv(str:lower())
+ if s ~= '' then
+ return s
+ end
+end
+
+-- support functions, maybe editor namespace
+
+-- function column_of_position(position)
+-- local line = editor:LineFromPosition(position)
+-- local oldposition = editor.CurrentPos
+-- local column = 0
+-- editor:GotoPos(position)
+-- while editor.CurrentPos ~= 0 and line == editor:LineFromPosition(editor.CurrentPos) do
+-- editor:CharLeft()
+-- column = column + 1
+-- end
+-- editor:GotoPos(oldposition)
+-- if line > 0 then
+-- return column -1
+-- else
+-- return column
+-- end
+-- end
+
+-- function line_of_position(position)
+-- return editor:LineFromPosition(position)
+-- end
+
+function extend_to_start()
+ local selectionstart = editor.SelectionStart
+ local selectionend = editor.SelectionEnd
+ local line = editor:LineFromPosition(selectionstart)
+ if line > 0 then
+ while line == editor:LineFromPosition(selectionstart-1) do
+ selectionstart = selectionstart - 1
+ editor:SetSel(selectionstart,selectionend)
+ end
+ else
+ selectionstart = 0
+ end
+ editor:SetSel(selectionstart,selectionend)
+ return selectionstart
+end
+
+function extend_to_end() -- editor:LineEndExtend() does not work
+ local selectionstart = editor.SelectionStart
+ local selectionend = editor.SelectionEnd
+ local line = editor:LineFromPosition(selectionend)
+ while line == editor:LineFromPosition(selectionend+1) do
+ selectionend = selectionend + 1
+ editor:SetSel(selectionstart,selectionend)
+ end
+ editor:SetSel(selectionstart,selectionend)
+ return selectionend
+end
+
+function getfiletype()
+ local firstline = editor:GetLine(0)
+ if editor.Lexer == SCLEX_TEX then
+ return 'tex'
+ elseif editor.Lexer == SCLEX_XML then
+ return 'xml'
+ elseif firstline:find("^%%") then
+ return 'tex'
+ elseif firstline:find("^<%?xml") then
+ return 'xml'
+ else
+ return 'unknown'
+ end
+end
+
+-- inspired by LuaExt's scite_Files
+
+function get_dir_list(mask)
+ local f
+ if props['PLAT_GTK'] and props['PLAT_GTK'] ~= "" then
+ f = io.popen('ls -1 ' .. mask)
+ else
+ mask = mask:gsub('/','\\')
+ local tmpfile = 'scite-ctx.tmp'
+ local cmd = 'dir /b "' .. mask .. '" > ' .. tmpfile
+ os.execute(cmd)
+ f = io.open(tmpfile)
+ end
+ local files = {}
+ if not f then -- path check added
+ return files
+ end
+ for line in f:lines() do
+ files[#files+1] = line
+ end
+ f:close()
+ return files
+end
+
+-- banner
+
+do
+
+ print("loading scite-ctx.lua definition file\n")
+ print("- see scite-ctx.properties for configuring info\n")
+ print("- ctx.spellcheck.wordpath set to " .. props['ctx.spellcheck.wordpath'])
+ if (props['ctx.spellcheck.wordpath']:lower()):find("ctxspellpath") then
+ if os.getenv('ctxspellpath') then
+ print("- ctxspellpath set to " .. os.getenv('CTXSPELLPATH'))
+ else
+ print("- 'ctxspellpath is not set")
+ end
+ print("- ctx.spellcheck.wordpath expands to " .. string.expand(props['ctx.spellcheck.wordpath']))
+ end
+ print("\n- ctx.wraptext.length is set to " .. props['ctx.wraptext.length'])
+ if props['ctx.helpinfo'] ~= '' then
+ print("\n- key bindings:\n")
+ print(((string.strip(props['ctx.helpinfo'])):gsub("%s*\|%s*","\n")))
+ end
+ print("\n- recognized first lines:\n")
+ print("xml ", 2)
+
+function wrap_text()
+
+ -- We always go to the end of a line, so in fact some of
+ -- the variables set next are not needed.
+
+ local length = props["ctx.wraptext.length"]
+
+ if length == '' then length = 80 else length = tonumber(length) end
+
+ local startposition = editor.SelectionStart
+ local endposition = editor.SelectionEnd
+
+ if startposition == endposition then return end
+
+ editor:LineEndExtend()
+
+ startposition = editor.SelectionStart
+ endposition = editor.SelectionEnd
+
+ -- local startline = line_of_position(startposition)
+ -- local endline = line_of_position(endposition)
+ -- local startcolumn = column_of_position(startposition)
+ -- local endcolumn = column_of_position(endposition)
+ --
+ -- editor:SetSel(startposition,endposition)
+
+ local startline = props['SelectionStartLine']
+ local endline = props['SelectionEndLine']
+ local startcolumn = props['SelectionStartColumn'] - 1
+ local endcolumn = props['SelectionEndColumn'] - 1
+
+ local replacement = { }
+ local templine = ''
+ local indentation = string.rep(' ',startcolumn)
+ local selection = editor:GetSelText()
+
+ selection = selection:gsub("[\n\r][\n\r]","\n")
+ selection = selection:gsub("\n\n+",' ' .. magicstring .. ' ')
+ selection = selection:gsub("^%s",'')
+
+ for snippet in selection:gmatch("%S+") do
+ if snippet == magicstring then
+ replacement[#replacement+1] = templine
+ replacement[#replacement+1] = ""
+ templine = ''
+ elseif #templine + #snippet > length then
+ replacement[#replacement+1] = templine
+ templine = indentation .. snippet
+ elseif #templine == 0 then
+ templine = indentation .. snippet
+ else
+ templine = templine .. ' ' .. snippet
+ end
+ end
+
+ replacement[#replacement+1] = templine
+ replacement[1] = replacement[1]:gsub("^%s+",'')
+
+ if endcolumn == 0 then
+ replacement[#replacement+1] = ""
+ end
+
+ editor:ReplaceSel(table.concat(replacement,"\n"))
+
+end
+
+function unwrap_text()
+
+ local startposition = editor.SelectionStart
+ local endposition = editor.SelectionEnd
+
+ if startposition == endposition then return end
+
+ editor:HomeExtend()
+ editor:LineEndExtend()
+
+ startposition = editor.SelectionStart
+ endposition = editor.SelectionEnd
+
+ local magicstring = string.rep("", 2)
+ local selection = string.gsub(editor:GetSelText(),"[\n\r][\n\r]+", ' ' .. magicstring .. ' ')
+ local replacement = ''
+
+ for snippet in selection:gmatch("%S+") do
+ if snippet == magicstring then
+ replacement = replacement .. "\n"
+ else
+ replacement = replacement .. snippet .. "\n"
+ end
+ end
+
+ if endcolumn == 0 then replacement = replacement .. "\n" end
+
+ editor:ReplaceSel(replacement)
+
+end
+
+function sort_text()
+
+ local startposition = editor.SelectionStart
+ local endposition = editor.SelectionEnd
+
+ if startposition == endposition then return end
+
+ -- local startcolumn = column_of_position(startposition)
+ -- local endcolumn = column_of_position(endposition)
+ --
+ -- editor:SetSel(startposition,endposition)
+
+ local startline = props['SelectionStartLine']
+ local endline = props['SelectionEndLine']
+ local startcolumn = props['SelectionStartColumn'] - 1
+ local endcolumn = props['SelectionEndColumn'] - 1
+
+ startposition = extend_to_start()
+ endposition = extend_to_end()
+
+ local selection = string.gsub(editor:GetSelText(), "%s*$", '')
+
+ list = string.grab(selection,"[^\n\r]+")
+ table.alphasort(list, startcolumn)
+ local replacement = table.concat(list, "\n")
+
+ editor:GotoPos(startposition)
+ editor:SetSel(startposition,endposition)
+
+ if endcolumn == 0 then replacement = replacement .. "\n" end
+
+ editor:ReplaceSel(replacement)
+
+end
+
+function document_text()
+
+ local startposition = editor.SelectionStart
+ local endposition = editor.SelectionEnd
+
+ if startposition == endposition then return end
+
+ startposition = extend_to_start()
+ endposition = extend_to_end()
+
+ editor:SetSel(startposition,endposition)
+
+ local filetype = getfiletype()
+
+ local replacement = ''
+ for i = editor:LineFromPosition(startposition), editor:LineFromPosition(endposition) do
+ local str = editor:GetLine(i)
+ if filetype == 'xml' then
+ if str:find("^<%!%-%- .* %-%->%s*$") then
+ replacement = replacement .. str:gsub("^<%!%-%- (.*) %-%->(%s*)$","%1\n")
+ elseif not str:is_empty() then
+ replacement = replacement .. '\n"
+ else
+ replacement = replacement .. str
+ end
+ else
+ if str:find("^%%D%s+$") then
+ replacement = replacement .. "\n"
+ elseif str:find("^%%D ") then
+ replacement = replacement .. str:gsub("^%%D ",'')
+ else
+ replacement = replacement .. '%D ' .. str
+ end
+ end
+ end
+
+ editor:ReplaceSel(replacement:gsub("[\n\r]$",''))
+
+end
+
+function quote_text()
+
+ local filetype, leftquotation, rightquotation = getfiletype(), '', ''
+
+ if filetype == 'xml' then
+ leftquotation, rightquotation = "", ""
+ leftquote, rightquote = "", ""
+ else
+ leftquotation, rightquotation = "\\quotation {", "}"
+ leftquote, rightquote = "\\quote {", "}"
+ end
+
+ local replacement = editor:GetSelText()
+ replacement = replacement.gsub("\`\`(.-)\'\'", leftquotation .. "%1" .. rightquotation)
+ replacement = replacement.gsub("\"(.-)\"", leftquotation .. "%1" .. rightquotation)
+ replacement = replacement.gsub("\`(.-)\'", leftquote .. "%1" .. rightquote )
+ replacement = replacement.gsub("\'(.-)\'", leftquote .. "%1" .. rightquote )
+ editor:ReplaceSel(replacement)
+
+end
+
+function compound_text()
+
+ local filetype = getfiletype()
+
+ if filetype == 'xml' then
+ editor:ReplaceSel(string.gsub(editor:GetSelText(),"(>[^<%-][^<%-]+)([-\/])(%w%w+)","%1%3"))
+ else
+ editor:ReplaceSel(string.gsub(editor:GetSelText(),"([^\|])([-\/]+)([^\|])","%1|%2|%3"))
+ end
+
+end
+
+-- written while listening to Alanis Morissette's acoustic
+-- Jagged Little Pill and Tori Amos' Beekeeper after
+-- reinstalling on my good old ATH-7
+
+local language = props["ctx.spellcheck.language"]
+local wordsize = props["ctx.spellcheck.wordsize"]
+local wordpath = props["ctx.spellcheck.wordpath"]
+
+if language == '' then language = 'uk' end
+if wordsize == '' then wordsize = 4 else wordsize = tonumber(wordsize) end
+
+local wordfile = ""
+local wordlist = {}
+local worddone = 0
+
+-- we use wordlist as a hash so that we can add entries without the
+-- need to sort and also use a fast (built in) search
+
+-- function kpsewhich_file(filename,filetype,progname)
+-- local progflag, typeflag = '', ''
+-- local tempname = os.tmpname()
+-- if progname then
+-- progflag = " --progname=" .. progname .. " "
+-- end
+-- if filetype then
+-- typeflag = " --format=" .. filetype .. " "
+-- end
+-- local command = "kpsewhich" .. progflag .. typeflag .. " " .. filename .. " > " .. tempname
+-- os.execute(command)
+-- for line in io.lines(tempname) do
+-- return string.gsub(line, "\s*$", '')
+-- end
+-- end
+
+function check_text()
+
+ local dlanguage = props["ctx.spellcheck.language"]
+ local dwordsize = props["ctx.spellcheck.wordsize"]
+ local dwordpath = props["ctx.spellcheck.wordpath"]
+
+ if dlanguage ~= '' then dlanguage = tostring(language) end
+ if dwordsize ~= '' then dwordsize = tonumber(wordsize) end
+
+ local firstline, skipfirst = editor:GetLine(0), false
+ local filetype, wordskip, wordgood = getfiletype(), '', ''
+
+ if filetype == 'tex' then
+ wordskip = "\\"
+ elseif filetype == 'xml' then
+ wordskip = "<"
+ wordgood = ">"
+ end
+
+ if props["ctx.spellcheck.language"] == 'auto' then
+ if filetype == 'tex' then
+ -- % version =1.0 language=uk
+ firstline = firstline:gsub("^%%%s*",'')
+ firstline = firstline:gsub("%s*$",'')
+ for key, val in firstline:gmatch("(%w+)=(%w+)") do
+ if key == "language" then
+ language = val
+ traceln("auto document language " .. "'" .. language .. "' (tex)")
+ end
+ end
+ skipfirst = true
+ elseif filetype == 'xml' then
+ --
+ firstline = firstline:gsub("^%<%?xml%s*", '')
+ firstline = firstline:gsub("%s*%?%>%s*$", '')
+ for key, val in firstline:gmatch("(%w+)=[\"\'](.-)[\"\']") do
+ if key == "language" then
+ language = val
+ traceln("auto document language " .. "'" .. language .. "' (xml)")
+ end
+ end
+ skipfirst = true
+ end
+ end
+
+ local fname = props["ctx.spellcheck.wordfile." .. language]
+ local fsize = props["ctx.spellcheck.wordsize." .. language]
+
+ if fsize ~= '' then wordsize = tonumber(fsize) end
+
+ if fname ~= '' and fname ~= wordfile then
+ wordfile, worddone, wordlist = fname, 0, {}
+ for filename in wordfile:gmatch("[^%,]+") do
+ if wordpath ~= '' then
+ filename = string.expand(wordpath) .. '/' .. filename
+ end
+ if io.exists(filename) then
+ traceln("loading " .. filename)
+ for line in io.lines(filename) do
+ if not line:find("^[\%\#\-]") then
+ str = line:gsub("%s*$", '')
+ rawset(wordlist,str,true)
+ worddone = worddone + 1
+ end
+ end
+ else
+ traceln("unknown file '" .. filename .."'")
+ end
+ end
+ traceln(worddone .. " words loaded")
+ end
+
+ reset_text()
+
+ if worddone == 0 then
+ traceln("no (valid) language or wordfile specified")
+ else
+ traceln("start checking")
+ if wordskip ~= '' then
+ traceln("ignoring " .. wordskip .. "..." .. wordgood)
+ end
+ local i, j, lastpos, startpos, endpos, snippet, len, first = 0, 0, -1, 0, 0, '', 0, 0
+ local ok, skip, ch = false, false, ''
+ if skipfirst then first = #firstline end
+ for k = first, editor.TextLength do
+ ch = editor:textrange(k,k+1)
+ if wordgood ~= '' and ch == wordgood then
+ skip = false
+ elseif ch == wordskip then
+ skip = true
+ end
+ if ch:find("%w") and not ch:find("%d") then
+ if not skip then
+ if ok then
+ endpos = k
+ else
+ startpos = k
+ endpos = k
+ ok = true
+ end
+ end
+ elseif ok and not skip then
+ len = endpos - startpos + 1
+ if len >= wordsize then
+ snippet = editor:textrange(startpos,endpos+1)
+ i = i + 1
+ if wordlist[snippet] or wordlist[snippet:lower()] then -- table.found(wordlist,snippet)
+ j = j + 1
+ else
+ editor:StartStyling(startpos,INDICS_MASK)
+ editor:SetStyling(len,INDIC2_MASK) -- INDIC0_MASK+2
+ end
+ end
+ ok = false
+ elseif wordgood == '' then
+ skip = (ch == wordskip)
+ end
+ end
+ traceln(i .. " words checked, " .. (i-j) .. " errors")
+ end
+
+end
+
+function reset_text()
+ editor:StartStyling(0,INDICS_MASK)
+ editor:SetStyling(editor.TextLength,INDIC_PLAIN)
+end
+
+-- menu
+
+local menuactions = {}
+local menufunctions = {}
+
+function UserListShow(menutrigger, menulist)
+ local menuentries = {}
+ local list = string.grab(menulist,"[^%|]+")
+ menuactions = {}
+ for i=1, #list do
+ if list[i] ~= '' then
+ for key, val in list[i]:gmatch("%s*(.+)=(.+)%s*") do
+ menuentries[#menuentries+1] = key
+ menuactions[key] = val
+ end
+ end
+ end
+ local menustring = table.concat(menuentries,'|')
+ if menustring == "" then
+ traceln("There are no templates defined for this file type.")
+ else
+ editor.AutoCSeparator = string.byte('|')
+ editor:UserListShow(menutrigger,menustring)
+ editor.AutoCSeparator = string.byte(' ')
+ end
+end
+
+function OnUserListSelection(trigger,choice)
+ if menufunctions[trigger] and menuactions[choice] then
+ return menufunctions[trigger](menuactions[choice])
+ else
+ return false
+ end
+end
+
+-- main menu
+
+local menutrigger = 12
+
+function show_menu(menulist)
+ UserListShow(menutrigger, menulist)
+end
+
+function process_menu(action)
+ if not action:find("%(%)$") then
+ assert(loadstring(action .. "()"))()
+ else
+ assert(loadstring(action))()
+ end
+end
+
+menufunctions[12] = process_menu
+
+-- templates
+
+local templatetrigger = 13
+
+local ctx_template_paths = { "./ctx-templates", "../ctx-templates", "../../ctx-templates" }
+local ctx_auto_templates = false
+local ctx_template_list = ""
+
+local ctx_path_list = {}
+local ctx_path_done = {}
+local ctx_path_name = {}
+
+function ctx_list_loaded(path)
+ return ctx_path_list[path] and #ctx_path_list[path] > 0
+end
+
+function insert_template(templatelist)
+ if props["ctx.template.scan"] == "yes" then
+ local path = props["FileDir"]
+ local rescan = props["ctx.template.rescan"] == "yes"
+ local suffix = props["ctx.template.suffix." .. props["FileExt"]] -- alas, no suffix expansion here
+ local current = path .. "+" .. props["FileExt"]
+ if rescan then
+ print("re-scanning enabled")
+ end
+ ctx_template_list = ""
+ if not ctx_path_done[path] or rescan then
+ local pattern = "*.*"
+ for i, pathname in ipairs(ctx_template_paths) do
+ print("scanning " .. path:gsub("\\","/") .. "/" .. pathname)
+ ctx_path_name[path] = pathname
+ ctx_path_list[path] = get_dir_list(pathname .. "/" .. pattern)
+ if ctx_list_loaded(path) then
+ print("finished locating template files")
+ break
+ end
+ end
+ if ctx_list_loaded(path) then
+ print(#ctx_path_list[path] .. " template files found")
+ else
+ print("no template files found")
+ end
+ end
+ if ctx_list_loaded(path) then
+ ctx_template_list = ""
+ local pattern = "%." .. suffix .. "$"
+ local n = 0
+ for j, filename in ipairs(ctx_path_list[path]) do
+ if filename:find(pattern) then
+ n = n + 1
+ local menuname = filename:gsub("%..-$","")
+ if ctx_template_list ~= "" then
+ ctx_template_list = ctx_template_list .. "|"
+ end
+ ctx_template_list = ctx_template_list .. menuname .. "=" .. ctx_path_name[path] .. "/" .. filename
+ end
+ end
+ if not ctx_path_done[path] then
+ print(n .. " suitable template files found")
+ end
+ end
+ ctx_path_done[path] = true
+ if ctx_template_list == "" then
+ ctx_auto_templates = false
+ else
+ ctx_auto_templates = true
+ templatelist = ctx_template_list
+ end
+ else
+ ctx_auto_templates = false
+ end
+ if templatelist ~= "" then
+ UserListShow(templatetrigger, templatelist)
+ end
+end
+
+
+-- ctx.template.[whatever].[filetype]
+-- ctx.template.[whatever].data.[filetype]
+-- ctx.template.[whatever].file.[filetype]
+-- ctx.template.[whatever].list.[filetype]
+
+function process_template_one(action)
+ local text = nil
+ if ctx_auto_templates then
+ local f = io.open(action,"r")
+ if f then
+ text = string.gsub(f:read("*all"),"\n$","")
+ f:close()
+ else
+ print("unable to auto load template file " .. text)
+ text = nil
+ end
+ end
+ if not text or text == "" then
+ text = props["ctx.template." .. action .. ".file"]
+ if not text or text == "" then
+ text = props["ctx.template." .. action .. ".data"]
+ if not text or text == "" then
+ text = props["ctx.template." .. action]
+ end
+ else
+ local f = io.open(text,"r")
+ if f then
+ text = string.gsub(f:read("*all"),"\n$","")
+ f:close()
+ else
+ print("unable to load template file " .. text)
+ text = nil
+ end
+ end
+ end
+ if text then
+ text = text:gsub("\\n","\n")
+ local pos = text:find("%?")
+ text = text:gsub("%?","")
+ editor:insert(editor.CurrentPos,text)
+ if pos then
+ editor.CurrentPos = editor.CurrentPos + pos - 1
+ editor.SelectionStart = editor.CurrentPos
+ editor.SelectionEnd = editor.CurrentPos
+ editor:GotoPos(editor.CurrentPos)
+ end
+ end
+end
+
+menufunctions[13] = process_template_one
+menufunctions[14] = process_template_two
+
+-- command.name.26.*=Open Logfile
+-- command.subsystem.26.*=3
+-- command.26.*=open_log
+-- command.save.before.26.*=2
+-- command.groupundo.26.*=yes
+-- command.shortcut.26.*=Ctrl+E
+
+function open_log()
+ scite.Open(props['FileName'] .. ".log")
+end
diff --git a/scripts/context/perl/makempy.pl b/scripts/context/perl/makempy.pl
index f263dd425..7cba2e1a6 100644
--- a/scripts/context/perl/makempy.pl
+++ b/scripts/context/perl/makempy.pl
@@ -289,7 +289,7 @@ sub construct_mpy_file
{ error("unable to open $mpyfile file") }
print MPY "% mpochecksum : $mpochecksum\n" ;
my $copying = my $n = 0 ;
- while ()
+ while () # a simple sub is faster
{ if (s/beginfig/begingraphictextfig/o)
{ print MPY $_ ; $copying = 1 ; ++$n }
elsif (s/endfig/endgraphictextfig/o)
--
cgit v1.2.3