summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/buff-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/buff-ini.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/buff-ini.lua193
1 files changed, 139 insertions, 54 deletions
diff --git a/Master/texmf-dist/tex/context/base/buff-ini.lua b/Master/texmf-dist/tex/context/base/buff-ini.lua
index 7098679ca17..475d23efe84 100644
--- a/Master/texmf-dist/tex/context/base/buff-ini.lua
+++ b/Master/texmf-dist/tex/context/base/buff-ini.lua
@@ -13,21 +13,27 @@ local trace_visualize = false trackers.register("buffers.visualize", function(v
local report_buffers = logs.reporter("buffers","usage")
local report_grabbing = logs.reporter("buffers","grabbing")
+local context, commands = context, commands
+
local concat = table.concat
-local type, next = type, next
-local sub, format, match, find = string.sub, string.format, string.match, string.find
-local count, splitlines = string.count, string.splitlines
+local type, next, load = type, next, load
+local sub, format = string.sub, string.format
+local splitlines, validstring = string.splitlines, string.valid
+local P, Cs, patterns, lpegmatch = lpeg.P, lpeg.Cs, lpeg.patterns, lpeg.match
-local variables = interfaces.variables
+local variables = interfaces.variables
local settings_to_array = utilities.parsers.settings_to_array
+local formatters = string.formatters
+
+local v_yes = variables.yes
-local ctxcatcodes = tex.ctxcatcodes
-local txtcatcodes = tex.txtcatcodes
+local catcodenumbers = catcodes.numbers
-buffers = { }
+local ctxcatcodes = catcodenumbers.ctxcatcodes
+local txtcatcodes = catcodenumbers.txtcatcodes
+buffers = buffers or { }
local buffers = buffers
-local context = context
local cache = { }
@@ -84,6 +90,44 @@ local function collectcontent(names,separator) -- no print
end
end
+local function loadcontent(names) -- no print
+ if type(names) == "string" then
+ names = settings_to_array(names)
+ end
+ local nnames = #names
+ local ok = false
+ if nnames == 0 then
+ ok = load(getcontent("")) -- default buffer
+ elseif nnames == 1 then
+ ok = load(getcontent(names[1]))
+ else
+ -- lua 5.2 chunked load
+ local i = 0
+ ok = load(function()
+ while true do
+ i = i + 1
+ if i > nnames then
+ return nil
+ end
+ local c = getcontent(names[i])
+ if c == "" then
+ -- would trigger end of load
+ else
+ return c
+ end
+ end
+ end)
+ end
+ if ok then
+ return ok()
+ elseif nnames == 0 then
+ report_buffers("invalid lua code in default buffer")
+ else
+ report_buffers("invalid lua code in buffer %a",concat(names,","))
+ end
+end
+
+
buffers.raw = getcontent
buffers.erase = erase
buffers.assign = assign
@@ -92,22 +136,24 @@ buffers.exists = exists
buffers.getcontent = getcontent
buffers.getlines = getlines
buffers.collectcontent = collectcontent
+buffers.loadcontent = loadcontent
-- the context interface
commands.erasebuffer = erase
commands.assignbuffer = assign
-local P, patterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match
+local anything = patterns.anything
+local alwaysmatched = patterns.alwaysmatched
local function countnesting(b,e)
local n
local g = P(b) / function() n = n + 1 end
+ P(e) / function() n = n - 1 end
- + patterns.anything
- local p = patterns.alwaysmatched / function() n = 0 end
+ + anything
+ local p = alwaysmatched / function() n = 0 end
* g^0
- * patterns.alwaysmatched / function() return n end
+ * alwaysmatched / function() return n end
return p
end
@@ -123,6 +169,67 @@ local continue = false
-- An \n is unlikely to show up as \r is the endlinechar but \n is more generic
-- for us.
+-- This fits the way we fetch verbatim: the indentatio before the sentinel
+-- determines the stripping.
+
+-- str = [[
+-- test test test test test test test
+-- test test test test test test test
+-- test test test test test test test
+--
+-- test test test test test test test
+-- test test test test test test test
+-- test test test test test test test
+-- ]]
+
+-- local function undent(str)
+-- local margin = match(str,"[\n\r]( +)[\n\r]*$") or ""
+-- local indent = #margin
+-- if indent > 0 then
+-- local lines = splitlines(str)
+-- local ok = true
+-- local pattern = "^" .. margin
+-- for i=1,#lines do
+-- local l = lines[i]
+-- if find(l,pattern) then
+-- lines[i] = sub(l,indent+1)
+-- else
+-- ok = false
+-- break
+-- end
+-- end
+-- if ok then
+-- return concat(lines,"\n")
+-- end
+-- end
+-- return str
+-- end
+
+-- how about tabs
+
+local getmargin = (Cs(P(" ")^1)*P(-1)+1)^1
+local eol = patterns.eol
+local whatever = (P(1)-eol)^0 * eol^1
+
+local strippers = { }
+
+local function undent(str) -- new version, needs testing
+ local margin = lpegmatch(getmargin,str)
+ if type(margin) ~= "string" then
+ return str
+ end
+ local indent = #margin
+ if indent == 0 then
+ return str
+ end
+ local stripper = strippers[indent]
+ if not stripper then
+ stripper = Cs((P(margin)/"" * whatever + eol^1)^1)
+ strippers[indent] = stripper
+ end
+ return lpegmatch(stripper,str) or str
+end
+
function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes) -- maybe move \\ to call
local dn = getcontent(name)
if dn == "" then
@@ -150,47 +257,27 @@ function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes) -- maybe
else
if continue then
dn = dn .. sub(bufferdata,2,-2) -- no \r, \n is more generic
+ elseif dn == "" then
+ dn = sub(bufferdata,2,-2)
else
- if dn == "" then
- dn = sub(bufferdata,2,-2)
- else
- dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic
- end
+ dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic
end
local last = sub(dn,-1)
if last == "\n" or last == "\r" then -- \n is unlikely as \r is the endlinechar
dn = sub(dn,1,-2)
end
if autoundent then
- local margin = match(dn,"[\n\r]( +)[\n\r]*$") or ""
- local indent = #margin
- if indent > 0 then
- local lines = splitlines(dn)
- local ok = true
- local pattern = "^" .. margin
- for i=1,#lines do
- local l = lines[i]
- if find(l,pattern) then
- lines[i] = sub(l,indent+1)
- else
- ok = false
- break
- end
- end
- if ok then
- dn = concat(lines,"\n")
- end
- end
+ dn = undent(dn)
end
end
assign(name,dn,catcodes)
- commands.testcase(more)
+ commands.doifelse(more)
end
-- The optional prefix hack is there for the typesetbuffer feature and
-- in mkii we needed that (this hidden feature is used in a manual).
-local function prepared(name,list) -- list is optional
+local function prepared(name,list,prefix) -- list is optional
if not list or list == "" then
list = name
end
@@ -201,7 +288,12 @@ local function prepared(name,list) -- list is optional
if content == "" then
content = "empty buffer"
end
- return tex.jobname .. "-" .. name .. ".tmp", content
+ if prefix then
+ local name = file.addsuffix(name,"tmp")
+ return tex.jobname .. "-" .. name, content
+ else
+ return name, content
+ end
end
local capsule = "\\starttext\n%s\n\\stoptext\n"
@@ -215,29 +307,29 @@ function commands.runbuffer(name,list,encapsulate)
local data = io.loaddata(name)
if data ~= content then
if trace_run then
- report_buffers("changes in '%s', processing forced",name)
+ report_buffers("changes in %a, processing forced",name)
end
io.savedata(name,content)
os.execute(format(command,name))
elseif trace_run then
- report_buffers("no changes in '%s', not processed",name)
+ report_buffers("no changes in %a, not processed",name)
end
end
-function commands.savebuffer(list,name) -- name is optional
- local name, content = prepared(name,list)
+function commands.savebuffer(list,name,prefix) -- name is optional
+ local name, content = prepared(name,list,prefix==v_yes)
io.savedata(name,content)
end
function commands.getbuffer(name)
local str = getcontent(name)
if str ~= "" then
- context.viafile(str)
+ context.viafile(str,formatters["buffer.%s"](validstring(name,"noname")))
end
end
function commands.getbuffermkvi(name) -- rather direct !
- context.viafile(resolvers.macros.preprocessed(getcontent(name)))
+ context.viafile(resolvers.macros.preprocessed(getcontent(name)),formatters["buffer.%s.mkiv"](validstring(name,"noname")))
end
function commands.gettexbuffer(name)
@@ -255,17 +347,10 @@ function commands.gettexbuffer(name)
end
end
-function commands.getbufferctxlua(name)
- local ok = loadstring(getcontent(name))
- if ok then
- ok()
- else
- report_buffers("invalid lua code in buffer '%s'",name)
- end
-end
+commands.getbufferctxlua = loadcontent
function commands.doifelsebuffer(name)
- commands.testcase(exists(name))
+ commands.doifelse(exists(name))
end
-- This only used for mp buffers and is a kludge. Don't change the