diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/core-buf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/core-buf.lua | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/core-buf.lua b/Master/texmf-dist/tex/context/base/core-buf.lua new file mode 100644 index 00000000000..7c0164cf555 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/core-buf.lua @@ -0,0 +1,471 @@ +-- filename : core-buf.lua +-- comment : companion to core-buf.tex +-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL +-- copyright: PRAGMA ADE / ConTeXt Development Team +-- license : see context related readme files + +-- ctx lua reference model / hooks and such +-- to be optimized + +-- redefine buffers.get + +if not versions then versions = { } end versions['core-buf'] = 1.001 + +if unicode and not utf then utf = unicode.utf8 end + +buffers = { } +buffers.data = { } +buffers.hooks = { } +buffers.flags = { } +buffers.commands = { } + +-- if needed we can make 'm local + +local concat, texsprint, texprint = table.concat, tex.sprint, tex.print + +function buffers.erase(name) + buffers.data[name] = nil +end + +function buffers.set(name, str) + buffers.data[name] = { str } -- CHECK THIS +end + +function buffers.append(name, str) + buffers.data[name] = (buffers.data[name] or "") .. str +end + +buffers.flags.store_as_table = true + +-- to be sorted out: crlf + \ ; slow now + +function buffers.grab(name,begintag,endtag,data) + if not buffers.data[name] or buffers.data[name] == "" then + buffers.data[name] = "" + buffers.level = 0 + end + buffers.level = buffers.level + data:count("\\"..begintag) - data:count("\\"..endtag) + local more = buffers.level>0 + if more then + buffers.data[name] = buffers.data[name] .. data .. endtag + buffers.level = buffers.level - 1 + else + if buffers.data[name] == "" then + buffers.data[name] = data:sub(1,#data-1) + else + buffers.data[name] = buffers.data[name] .. "\n" .. data:sub(1,#data-1) + end + buffers.data[name] = buffers.data[name]:gsub("[\010\013]$","") + if buffers.flags.store_as_table then + buffers.data[name] = buffers.data[name]:splitlines() + end + end + cs.testcase(more) +end + +function buffers.exists(name) + return buffers.data[name] ~= nil +end + +function buffers.doifelsebuffer(name) + cs.testcase(buffers.data[name] ~= nil) +end + +buffers.flags.optimize_verbatim = true +buffers.flags.count_empty_lines = false + +buffers.commands.no_break = "\\doverbatimnobreak" +buffers.commands.do_break = "\\doverbatimgoodbreak" +buffers.commands.begin_of_line_command = "\\doverbatimbeginofline" +buffers.commands.end_of_line_command = "\\doverbatimendofline" +buffers.commands.empty_line_command = "\\doverbatimemptyline" + +function buffers.verbatimbreak(n,m) + if buffers.flags.optimize_verbatim then + if n == 2 or n == m then + texsprint(buffers.commands.no_break) + else + texsprint(buffers.commands.do_break) + end + end +end + +function buffers.strip(lines) + local first, last = 1, #lines + for i=first,last do + if #lines[i] == 0 then + first = first + 1 + else + break + end + end + for i=last,first,-1 do + if #lines[i] == 0 then + last = last - 1 + else + break + end + end + return first, last, last - first + 1 +end + +function buffers.type(name) + local lines = buffers.data[name] + local action = buffers.typeline + if lines then + if type(lines) == "string" then + lines = lines:splitlines() + end + local line, n = 0, 0 + local first, last, m = buffers.strip(lines) + for i=first,last do + n, line = action(lines[i], n, m, line) + end + end +end + +--~ function buffers.typefile(name) +--~ local t = input.openfile(name) +--~ local action = buffers.typeline +--~ if t then +--~ local line, n, m = 0, 0, t.noflines +--~ while true do +--~ str = t.reader(t) +--~ if str then +--~ n, line = action(str, n, m, line) +--~ else +--~ break +--~ end +--~ end +--~ t.close() +--~ end +--~ end + +function buffers.typefile(name) + local t = input.openfile(name) + local action = buffers.typeline + if t then + local lines = { } + while true do + local str = t.reader() + if str then + lines[#lines+1] = str + else + break + end + end + t.close() + local line, n = 0, 0 + local first, last, m = buffers.strip(lines) + for i=first,last do + n, line = action(lines[i], n, m, line) + end + end +end + +function buffers.typeline(str,n,m,line) + n = n + 1 + buffers.verbatimbreak(n,m) + if str:find("%S") then + line = line + 1 + buffers.hooks.begin_of_line(line) + buffers.hooks.flush_line(buffers.hooks.line(str)) + buffers.hooks.end_of_line() + else + if buffers.flags.count_empty_lines then + line = line + 1 + end + buffers.hooks.empty_line(line) + end + return n, line +end + +function buffers.save(name) + if not name or name == "" then + name = tex.jobname + end + local b, f = buffers.data[name], tex.jobname .. "-" .. name .. ".tmp" + b = (b and type(b) == "table" and table.join(b,"\n")) or b or "" + io.savedata(f,b) +end + +-- todo, use more locals + +function buffers.get(name) + local b = buffers.data[name] + if b then + if type(b) == "table" then + for i=1,#b do + texprint(b[i]) + end + else + string.piecewise(b, " *[\010\013]", texprint) -- hm, can be faster + end + end +end + +function buffers.content(name) -- no print + local b = buffers.data[name] + if b then + if type(b) == "table" then + return concat(b," ") + else + return b + end + else + return "" + end +end + +function buffers.collect(names,separator) -- no print + local t = { } + if type(names) == "table" then + for i=1,#names do + local c = buffers.content(names[i]) + if c ~= "" then + t[#t+1] = c + end + end + else + for name in names:gmatch("[^,]+") do + local c = buffers.content(name) + if c ~= "" then + t[#t+1] = c + end + end + end + return concat(t,separator or " ") -- maybe this will change to "\n" +end + +function buffers.inspect(name) + local b = buffers.data[name] + if b then + if type(b) == "table" then + for _,v in ipairs(b) do + if v == "" then + texsprint(tex.ctxcatcodes,"[crlf]\\par ") + else + texsprint(tex.ctxcatcodes,(b:gsub("(.)",function(c) + return " [" .. string.byte(c) .. "] " + end)) .. "\\par") + end + end + else + texsprint(tex.ctxcatcodes,(b:gsub("(.)",function(c) + return " [" .. string.byte(c) .. "] " + end))) + end + end +end + +-- maybe just line(n,str) empty(n,str) + +buffers.visualizers = { } +buffers.visualizers.default = { } +buffers.visualizers.tex = { } +buffers.visualizers.mp = { } + +buffers.visualizers.escapetoken = nil +buffers.visualizers.tablength = 7 + +buffers.visualizers.enabletab = false +buffers.visualizers.enableescape = false + +function buffers.visualizers.reset() + buffers.visualizers.enabletab = false + buffers.visualizers.enableescape = false + buffers.currentvisualizer = 'default' +end + +buffers.currentvisualizer = 'default' + +function buffers.setvisualizer(str) + buffers.currentvisualizer = string.lower(str) + if not buffers.visualizers[buffers.currentvisualizer] then + buffers.currentvisualizer = 'default' + end +end + +function buffers.doifelsevisualizer(str) + cs.testcase((str ~= "") and (buffers.visualizers[string.lower(str)] ~= nil)) +end + +-- calling routines, don't change + +function buffers.hooks.flush_line(str,nesting) + if buffers.visualizers[buffers.currentvisualizer].flush_line then + buffers.visualizers[buffers.currentvisualizer].flush_line(str,nesting) +--~ elseif nesting then +--~ buffers.visualizers.flush_nested(str,false) -- no real nesting + else + buffers.visualizers.default.flush_line(str,nesting) + end +end + +function buffers.hooks.begin_of_line(n) + if buffers.visualizers[buffers.currentvisualizer].begin_of_line then + buffers.visualizers[buffers.currentvisualizer].begin_of_line(n) + else + buffers.visualizers.default.begin_of_line(n) + end +end + +function buffers.hooks.end_of_line() + if buffers.visualizers[buffers.currentvisualizer].end_of_line then + buffers.visualizers[buffers.currentvisualizer].end_of_line() + else + buffers.visualizers.default.end_of_line(str) + end +end + +function buffers.hooks.empty_line() + if buffers.visualizers[buffers.currentvisualizer].empty_line then + buffers.visualizers[buffers.currentvisualizer].empty_line() + else + buffers.visualizers.default.empty_line() + end +end + +function buffers.hooks.line(str) + if buffers.visualizers[buffers.currentvisualizer].line then + return buffers.visualizers[buffers.currentvisualizer].line(str) + else + return buffers.visualizers.default.line(str) + end +end + +-- defaults + +function buffers.visualizers.default.flush_line(str) + texsprint(tex.ctxcatcodes,buffers.escaped(str)) +end + +function buffers.visualizers.default.begin_of_line(n) + texsprint(tex.ctxcatcodes, buffers.commands.begin_of_line_command .. "{" .. n .. "}") +end + +function buffers.visualizers.default.end_of_line() + texsprint(tex.ctxcatcodes,buffers.commands.end_of_line_command) +end + +function buffers.visualizers.default.empty_line() + texsprint(tex.ctxcatcodes,buffers.commands.empty_line_command) +end + +function buffers.visualizers.default.line(str) + return str +end + +-- special one + +buffers.commands.nested = "\\switchslantedtype " + +-- todo : utf + faster + +function buffers.visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess + local result, c, nested, i = "", "", 0, 1 + local sb, ss, sf = string.byte, string.sub, string.find + while i < #str do -- slow + c = ss(str,i,i+1) + if c == "<<" then + nested = nested + 1 + if enable then + result = result .. "{" .. buffers.commands.nested + else + result = result .. "{" + end + i = i + 2 + elseif c == ">>" then + if nested > 0 then + nested = nested - 1 + result = result .. "}" + end + i = i + 2 + else + c = ss(str,i,i) + if c == " " then + result = result .. "\\obs " + elseif sf(c,"%a") then + result = result .. c + else + result = result .. "\\char" .. sb(c) .. " " + end + i = i + 1 + end + end + result = result .. "\\char" .. sb(ss(str,i,i)) .. " " .. string.rep("}",nested) + texsprint(tex.ctxcatcodes,result) +end + +-- handy helpers +-- +-- \sop[color] switch_of_pretty +-- \bop[color] begin_of_pretty +-- \eop end_of_pretty +-- \obs obeyedspace +-- \char <n> special characters + +buffers.currentcolors = { } + +function buffers.change_state(n, state, result) + if n then + if state ~= n then + if state > 0 then + result[#result+1] = "\\sop[" .. buffers.currentcolors[n] .. "]" + else + result[#result+1] = "\\bop[" .. buffers.currentcolors[n] .. "]" + end + return n + end + elseif state > 0 then + result[#result+1] = "\\eop " + return 0 + end + return state +end + +function buffers.finish_state(state, result) + if state > 0 then + result[#result+1] = "\\eop " + return 0 + else + return state + end +end + +buffers.open_nested = string.rep("\\char"..string.byte('<').." ",2) +buffers.close_nested = string.rep("\\char"..string.byte('>').." ",2) + +function buffers.replace_nested(result) + return (string.gsub(result:gsub(buffers.open_nested,"{"),buffers.close_nested,"}")) +end + +function buffers.flush_result(result,nested) + if nested then + texsprint(tex.ctxcatcodes,buffers.replace_nested(concat(result,""))) + else + texsprint(tex.ctxcatcodes,concat(result,"")) + end +end + +function buffers.escaped(str) + local sb, sf = utf.byte, utf.find + return (utf.gsub(str,"(.)", function(c) + if sf(c,"^(%a%d)$") then + return c + elseif c == " " then + return "\\obs " + else + return "\\char" .. sb(c) .. " " + end + end)) +end + +function buffers.escaped_chr(ch) + local b = utf.byte(ch) + if b == 32 then + return "\\obs " + else + return "\\char" .. b .. " " + end +end |