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.lua148
1 files changed, 110 insertions, 38 deletions
diff --git a/Master/texmf-dist/tex/context/base/buff-ini.lua b/Master/texmf-dist/tex/context/base/buff-ini.lua
index 70328f0f198..7098679ca17 100644
--- a/Master/texmf-dist/tex/context/base/buff-ini.lua
+++ b/Master/texmf-dist/tex/context/base/buff-ini.lua
@@ -7,63 +7,73 @@ if not modules then modules = { } end modules ['buff-ini'] = {
}
local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end)
+local trace_grab = false trackers.register("buffers.grab", function(v) trace_grab = v end)
local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end)
-local report_buffers = logs.reporter("buffers","usage")
+local report_buffers = logs.reporter("buffers","usage")
+local report_grabbing = logs.reporter("buffers","grabbing")
local concat = table.concat
local type, next = type, next
-local sub, format, count, splitlines = string.sub, string.format, string.count, string.splitlines
+local sub, format, match, find = string.sub, string.format, string.match, string.find
+local count, splitlines = string.count, string.splitlines
local variables = interfaces.variables
local settings_to_array = utilities.parsers.settings_to_array
-local texprint, ctxcatcodes = tex.print, tex.ctxcatcodes
+
+local ctxcatcodes = tex.ctxcatcodes
+local txtcatcodes = tex.txtcatcodes
buffers = { }
local buffers = buffers
local context = context
-local data = { }
-
-function buffers.raw(name)
- return data[name] or ""
-end
+local cache = { }
local function erase(name)
- data[name] = nil
+ cache[name] = nil
end
-local function assign(name,str)
- data[name] = str
+local function assign(name,str,catcodes)
+ cache[name] = { data = str, catcodes = catcodes }
end
local function append(name,str)
- data[name] = (data[name] or "") .. str
+ local buffer = cache[name]
+ if buffer then
+ buffer.data = buffer.data .. str
+ else
+ cache[name] = { data = str }
+ end
end
local function exists(name)
- return data[name] ~= nil
+ return cache[name]
end
-local function getcontent(name) -- == raw
- return data[name] or ""
+local function getcontent(name)
+ local buffer = name and cache[name]
+ return buffer and buffer.data or ""
end
local function getlines(name)
- local d = name and data[name]
- return d and splitlines(d)
+ local buffer = name and cache[name]
+ return buffer and splitlines(buffer.data)
end
local function collectcontent(names,separator) -- no print
if type(names) == "string" then
names = settings_to_array(names)
end
- if #names == 1 then
+ local nnames = #names
+ if nnames == 0 then
+ return getcontent("") -- default buffer
+ elseif nnames == 1 then
return getcontent(names[1])
else
local t, n = { }, 0
- for i=1,#names do
+ for i=1,nnames do
local c = getcontent(names[i])
if c ~= "" then
n = n + 1
@@ -74,6 +84,7 @@ local function collectcontent(names,separator) -- no print
end
end
+buffers.raw = getcontent
buffers.erase = erase
buffers.assign = assign
buffers.append = append
@@ -100,15 +111,31 @@ local function countnesting(b,e)
return p
end
-local counters = { }
-local nesting = 0
+local counters = { }
+local nesting = 0
+local autoundent = true
+local continue = false
-function commands.grabbuffer(name,begintag,endtag,bufferdata) -- maybe move \\ to call
+-- Beware: the first character of bufferdata has to be discarded as it's there to
+-- prevent gobbling of newlines in the case of nested buffers. The last one is
+-- a newlinechar and is removed too.
+--
+-- An \n is unlikely to show up as \r is the endlinechar but \n is more generic
+-- for us.
+
+function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes) -- maybe move \\ to call
local dn = getcontent(name)
if dn == "" then
nesting = 0
+ continue = false
+ end
+ if trace_grab then
+ if #bufferdata > 30 then
+ report_grabbing("%s => |%s..%s|",name,sub(bufferdata,1,10),sub(bufferdata,-10,#bufferdata))
+ else
+ report_grabbing("%s => |%s|",name,bufferdata)
+ end
end
- -- nesting = nesting + count(bufferdata,"\\"..begintag) - count(bufferdata,"\\"..endtag)
local counter = counters[begintag]
if not counter then
counter = countnesting(begintag,endtag)
@@ -117,20 +144,46 @@ function commands.grabbuffer(name,begintag,endtag,bufferdata) -- maybe move \\ t
nesting = nesting + lpegmatch(counter,bufferdata)
local more = nesting > 0
if more then
- dn = dn .. bufferdata .. endtag
+ dn = dn .. sub(bufferdata,2,-1) .. endtag
nesting = nesting - 1
+ continue = true
else
- if dn == "" then
- dn = sub(bufferdata,1,-2)
+ if continue then
+ dn = dn .. sub(bufferdata,2,-2) -- no \r, \n is more generic
else
- dn = dn .. "\n" .. sub(bufferdata,1,-2) -- no \r, \n is more generic
+ if dn == "" then
+ dn = sub(bufferdata,2,-2)
+ else
+ dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic
+ end
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
+ end
end
- assign(name,dn)
+ assign(name,dn,catcodes)
commands.testcase(more)
end
@@ -142,13 +195,13 @@ local function prepared(name,list) -- list is optional
list = name
end
if not name or name == "" then
- name = tex.jobname .. "-" .. list .. ".tmp"
+ name = list
end
local content = collectcontent(list,nil) or ""
if content == "" then
content = "empty buffer"
end
- return name, content
+ return tex.jobname .. "-" .. name .. ".tmp", content
end
local capsule = "\\starttext\n%s\n\\stoptext\n"
@@ -177,16 +230,31 @@ function commands.savebuffer(list,name) -- name is optional
end
function commands.getbuffer(name)
- local str = data[name]
- if str and str ~= "" then
+ local str = getcontent(name)
+ if str ~= "" then
context.viafile(str)
end
end
-function commands.getbuffermkvi(name)
+function commands.getbuffermkvi(name) -- rather direct !
context.viafile(resolvers.macros.preprocessed(getcontent(name)))
end
+function commands.gettexbuffer(name)
+ local buffer = name and cache[name]
+ if buffer and buffer.data ~= "" then
+ context.pushcatcodetable()
+ if buffer.catcodes == txtcatcodes then
+ context.setcatcodetable(txtcatcodes)
+ else
+ context.setcatcodetable(ctxcatcodes)
+ end
+ -- context(function() context.viafile(buffer.data) end)
+ context.getbuffer { name } -- viafile flushes too soon
+ context.popcatcodetable()
+ end
+end
+
function commands.getbufferctxlua(name)
local ok = loadstring(getcontent(name))
if ok then
@@ -200,10 +268,14 @@ function commands.doifelsebuffer(name)
commands.testcase(exists(name))
end
--- This only used for mp buffers and is a kludge. Don't
--- change the texprint into texsprint as it fails because
--- "p<nl>enddef" becomes "penddef" then.
+-- This only used for mp buffers and is a kludge. Don't change the
+-- texprint into texsprint as it fails because "p<nl>enddef" becomes
+-- "penddef" then.
+
+-- function commands.feedback(names)
+-- texprint(ctxcatcodes,splitlines(collectcontent(names)))
+-- end
-function commands.feedback(names)
- texprint(ctxcatcodes,splitlines(collectcontent(names)))
+function commands.feedback(names) -- bad name, maybe rename to injectbuffercontent
+ context.printlines(collectcontent(names))
end