diff options
author | Hans Hagen <pragma@wxs.nl> | 2008-04-11 00:07:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2008-04-11 00:07:00 +0200 |
commit | 84c5ae8992fff7184ebc669a1eb654a92d55951c (patch) | |
tree | 4b2cd86ca0d8bfc4fa6ec3930a983bb3bbf444a9 /scripts | |
parent | 55bcf0e607bb8af553581e74293687ed635bf877 (diff) | |
download | context-84c5ae8992fff7184ebc669a1eb654a92d55951c.tar.gz |
stable 2008.04.11 00:07
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/context/lua/luatools.lua | 147 | ||||
-rw-r--r-- | scripts/context/lua/mtx-context.lua | 4 | ||||
-rw-r--r-- | scripts/context/lua/mtxrun.lua | 406 | ||||
-rw-r--r-- | scripts/context/lua/scite-ctx.lua | 843 | ||||
-rw-r--r-- | scripts/context/perl/makempy.pl | 2 |
5 files changed, 1178 insertions, 224 deletions
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.</p> --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("<!--%s-->",edt[1])) + handle("<!--" .. edt[1] .. "-->") + elseif etg == "@cd@" then + -- handle(format("<![CDATA[%s]]>",edt[1])) + handle("<![CDATA[" .. edt[1] .. "]]>") + elseif etg == "@dd@" then + -- handle(format("<!DOCTYPE %s>",edt[1])) + handle("<!DOCTYPE " .. edt[1] .. ">") + 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("<!--%s-->",edt[1])) - handle("<!--" .. edt[1] .. "-->") - elseif etg == "@cd@" then - -- handle(format("<![CDATA[%s]]>",edt[1])) - handle("<![CDATA[" .. edt[1] .. "]]>") - elseif etg == "@dd@" then - -- handle(format("<!DOCTYPE %s>",edt[1])) - handle("<!DOCTYPE " .. edt[1] .. ">") - 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-- -<p>At the cost of some 25% runtime overhead you can first convert the tree to a string -and then handle the lot.</p> ---ldx]]-- + --[[ldx-- + <p>At the cost of some 25% runtime overhead you can first convert the tree to a string + and then handle the lot.</p> + --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 +-- # <?xml 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 <?xml version='1.0' language='nl'") + print("tex % language=nl") + +end + +-- text functions + +-- written while listening to Talk Talk + +local magicstring = string.rep("<ctx-crlf/>", 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("<multiplelines/>", 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 .. '<!-- ' .. str:gsub("(%s*)$",'') .. " -->\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 = "<quotation>", "</quotation>" + leftquote, rightquote = "<quotation>", "</quote>" + 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<compound token='%2'/>%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 + -- <?xml version='1.0' language='uk' ?> + 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 (<TMP>) + while (<TMP>) # a simple sub is faster { if (s/beginfig/begingraphictextfig/o) { print MPY $_ ; $copying = 1 ; ++$n } elsif (s/endfig/endgraphictextfig/o) |