diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2010-05-24 14:05:02 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2010-05-24 14:05:02 +0000 |
commit | 57ea7dad48fbf2541c04e434c31bde655ada3ac4 (patch) | |
tree | 1f8b43bc7cb92939271e1f5bec610710be69097f /Master/texmf-dist/tex/context/base/buff-ini.lua | |
parent | 6ee41e1f1822657f7f23231ec56c0272de3855e3 (diff) |
here is context 2010.05.24 13:05
git-svn-id: svn://tug.org/texlive/trunk@18445 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/buff-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/buff-ini.lua | 382 |
1 files changed, 314 insertions, 68 deletions
diff --git a/Master/texmf-dist/tex/context/base/buff-ini.lua b/Master/texmf-dist/tex/context/base/buff-ini.lua index f02963d6a06..6b1af8f96f3 100644 --- a/Master/texmf-dist/tex/context/base/buff-ini.lua +++ b/Master/texmf-dist/tex/context/base/buff-ini.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['buff-ini'] = { version = 1.001, - comment = "companion to core-buf.tex", + comment = "companion to core-buf.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -20,16 +20,24 @@ buffers.visualizers = { } -- if needed we can make 'm local +local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) +local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end) + local utf = unicode.utf8 local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.print, tex.write local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub local type, next = type, next -local byte, sub, find, char, gsub, rep, lower = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower +local huge = math.huge +local byte, sub, find, char, gsub, rep, lower, format, gmatch, match = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format, string.gmatch, string.match local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables +local lpegmatch = lpeg.match + +local data, flags, hooks, visualizers = buffers.data, buffers.flags, buffers.hooks, buffers.visualizers -local data, commands, flags, hooks, visualizers = buffers.data, buffers.commands, buffers.flags, buffers.hooks, buffers.visualizers +visualizers.defaultname = variables.typing function buffers.raw(name) return data[name] or { } @@ -47,6 +55,7 @@ function buffers.append(name, str) data[name] = (data[name] or "") .. str end + buffers.flags.store_as_table = true -- to be sorted out: crlf + \ ; slow now @@ -65,11 +74,11 @@ function buffers.grab(name,begintag,endtag,bufferdata) buffers.level = buffers.level - 1 else if dn == "" then - dn = bufferdata:sub(1,#bufferdata-1) + dn = sub(bufferdata,1,#bufferdata-1) else - dn = dn .. "\n" .. bufferdata:sub(1,#bufferdata-1) + dn = dn .. "\n" .. sub(bufferdata,1,#bufferdata-1) end - dn = dn:gsub("[\010\013]$","") + dn = gsub(dn,"[\010\013]$","") if flags.store_as_table then dn = dn:splitlines() end @@ -104,23 +113,25 @@ function buffers.verbatimbreak(n,m) if flags.optimize_verbatim then if n == 2 or n == m then texsprint(no_break_command) - else + elseif n > 1 then texsprint(do_break_command) end end end -function buffers.strip(lines) - local first, last = 1, #lines +function buffers.strip(lines,first,last) + local first, last = first or 1, last or #lines for i=first,last do - if #lines[i] == 0 then + local li = lines[i] + if #li == 0 or find(li,"^%s*$") then first = first + 1 else break end end for i=last,first,-1 do - if #lines[i] == 0 then + local li = lines[i] + if #li == 0 or find(li,"^%s*$") then last = last - 1 else break @@ -129,15 +140,62 @@ function buffers.strip(lines) return first, last, last - first + 1 end -function buffers.type(name) +function buffers.range(lines,first,last,range) -- 1,3 1,+3 fromhere,tothere + local first, last = first or 1, last or #lines + local what = aux.settings_to_array(range) + local r_first, r_last = what[1], what[2] + local f, l = tonumber(r_first), tonumber(r_last) + if r_first then + if f then + if f > first then + first = f + end + else + for i=first,last do + if find(lines[i],r_first) then + first, strip = i + 1 + break + end + end + end + end + if r_last then + if l then + if find(r_last,"^[%+]") then -- 1,+3 + l = first + l + end + if l < last then + last = l + end + else + for i=first,last do + if find(lines[i],r_last) then + last = i - 1 + break + end + end + end + end + return first, last +end + +function buffers.type(name,realign,range) local lines = data[name] local action = buffers.typeline if lines then if type(lines) == "string" then lines = lines:splitlines() + data[name] = lines + end + if realign then + lines = buffers.realign(lines,realign) end local line, n = 0, 0 local first, last, m = buffers.strip(lines) + if range then + first, last = buffers.range(lines,first,last,range) + first, last = buffers.strip(lines,first,last) + end hooks.begin_of_display() for i=first,last do n, line = action(lines[i], n, m, line) @@ -153,16 +211,34 @@ function buffers.loaddata(filename) -- this one might go away if not str then ok, str, n = resolvers.loaders.tex(file.addsuffix(filename,'tex')) end - return str or "" end -function buffers.typefile(name) -- still somewhat messy, since name can be be suffixless +function buffers.loaddata(filename) -- this one might go away + local foundname = resolvers.findtexfile(filename) or "" + if foundname == "" then + foundname = resolvers.findtexfile(file.addsuffix(filename,'tex')) or "" + end + if foundname == "" then + return "" + else + return resolvers.loadtexfile(foundname) + end +end + +function buffers.typefile(name,realign,range) -- still somewhat messy, since name can be be suffixless local str = buffers.loaddata(name) if str and str~= "" then local lines = str:splitlines() + if realign then + lines = buffers.realign(lines,realign) + end local line, n, action = 0, 0, buffers.typeline local first, last, m = buffers.strip(lines) hooks.begin_of_display() + if range then + first, last = buffers.range(lines,first,last,range) + first, last = buffers.strip(lines,first,last) + end for i=first,last do n, line = action(lines[i], n, m, line) end @@ -173,7 +249,7 @@ end function buffers.typeline(str,n,m,line) n = n + 1 buffers.verbatimbreak(n,m) - if str:find("%S") then + if find(str,"%S") then line = line + 1 hooks.begin_of_line(line) hooks.flush_line(hooks.line(str)) @@ -187,28 +263,51 @@ function buffers.typeline(str,n,m,line) return n, line end -function buffers.save(name,list,encapsulate) - if not name or name == "" then - name = tex.jobname - end - if list then - -- ok - else +-- 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 + if not list or list == "" then list = name - name = tex.jobname .. "-" .. name .. ".tmp" end - local content = buffers.collect(list) + if not name or name == "" then + name = tex.jobname .. "-" .. list .. ".tmp" + end + local content = buffers.collect(list,nil) or "" if content == "" then content = "empty buffer" end - if encapsulate then - io.savedata(name, "\\starttext\n"..content.."\n\\stoptext\n") - else - io.savedata(name, content) + return name, content +end + +local capsule = "\\starttext\n%s\n\\stoptext\n" +local command = "context %s" + +function buffers.save(name,list,encapsulate) -- list is optional + local name, content = prepared(name,list) + io.savedata(name, (encapsulate and format(capsule,content)) or content) +end + +function commands.savebuffer(list,name) -- name is optional + buffers.save(name,list) +end + +function buffers.run(name,list,encapsulate) + local name, content = prepared(name,list) + local data = io.loaddata(name) + content = (encapsulate and format(capsule,content)) or content + if data ~= content then + if trace_run then + commands.writestatus("buffers","changes in '%s', processing forced",name) + end + io.savedata(name,content) + os.execute(format(command,name)) + elseif trace_run then + commands.writestatus("buffers","no changes in '%s', not processed",name) end end -local printer = (lpeg.linebyline/texprint)^0 +local printer = (lpeg.patterns.textline/texprint)^0 function buffers.get(name) local b = buffers.data[name] @@ -218,7 +317,7 @@ function buffers.get(name) texprint(b[i]) end else - printer:match(b) + lpegmatch(printer,b) end end end @@ -240,21 +339,15 @@ buffers.content = content function buffers.collect(names,separator) -- no print -- maybe we should always store a buffer as table so - -- that we can pass if directly + -- that we can pass it directly + if type(names) == "string" then + names = aux.settings_to_array(names) + end local t = { } - if type(names) == "table" then - for i=1,#names do - local c = content(names[i],separator) - if c ~= "" then - t[#t+1] = c - end - end - else - for name in names:gmatch("[^,%s]+") do - local c = content(name,separator) - if c ~= "" then - t[#t+1] = c - end + for i=1,#names do + local c = content(names[i],separator) + if c ~= "" then + t[#t+1] = c end end return concat(t,separator or "\r") -- "\n" is safer due to comments and such @@ -274,11 +367,12 @@ function buffers.inspect(name) local b = data[name] if b then if type(b) == "table" then - for _,v in ipairs(b) do + for k=1,#b do + local v = b[k] if v == "" then texsprint(ctxcatcodes,"[crlf]\\par ") -- space ? else - texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte)),"\\par") + texsprint(ctxcatcodes,(gsub(v,"(.)",tobyte)),"\\par") end end else @@ -289,42 +383,90 @@ end -- maybe just line(n,str) empty(n,str) -visualizers.handlers = visualizers.handlers or { } -visualizers.escapetoken = nil -visualizers.tablength = 7 -visualizers.enabletab = true -- false -visualizers.enableescape = false -visualizers.obeyspace = true +visualizers.tablength = 7 +visualizers.enabletab = true -- false +visualizers.obeyspace = true + +function buffers.settablength(tablength) + visualizers.tablength = tablength and tonumber(tablength) or 7 +end + +visualizers.handlers = visualizers.handlers or { } local handlers = visualizers.handlers function buffers.newvisualizer(name) + name = lower(name) local handler = { } handlers[name] = handler return handler end function buffers.getvisualizer(name) - return handlers[name] + name = lower(name) + return handlers[name] or buffers.loadvisualizer(name) end -local default = buffers.newvisualizer("default") +function buffers.loadvisualizer(name) + name = lower(name) + local hn = handlers[name] + if hn then + return hn + else + environment.loadluafile("pret-" .. name) + local hn = handlers[name] + if not hn then + -- hn = buffers.newvisualizer(name) + hn = handlers[visualizers.defaultname] + handlers[name] = hn + if trace_visualize then + logs.report("buffers","mapping '%s' visualizer onto '%s'",name,visualizers.defaultname) + end + elseif trace_visualize then + logs.report("buffers","loading '%s' visualizer",name) + end + return hn + end +end + +-- was "default", should be set at tex end (todo) + +local default = buffers.newvisualizer(visualizers.defaultname) + +--~ print(variables.typing) os.exit() + +-- will become cleaner local currentvisualizer, currenthandler function buffers.setvisualizer(str) currentvisualizer = lower(str) currenthandler = handlers[currentvisualizer] - if not currenthandler then - currentvisualizer = 'default' + if currenthandler then + -- if trace_visualize then + -- logs.report("buffers","enabling specific '%s' visualizer",currentvisualizer) + -- end + else + currentvisualizer = visualizers.defaultname currenthandler = handlers.default + -- if trace_visualize then + -- logs.report("buffers","enabling default visualizer '%s'",currentvisualizer) + -- end end if currenthandler.reset then currenthandler.reset() end end -buffers.setvisualizer("default") +function buffers.resetvisualizer() + currentvisualizer = visualizers.defaultname + currenthandler = handlers.default + if currenthandler.reset then + currenthandler.reset() + end +end + +buffers.setvisualizer(visualizers.defaultname) function visualizers.reset() end @@ -351,10 +493,15 @@ function hooks.end_of_inline() (currenthandler.end_of_inline or default.end_of_inline)() end - function hooks.flush_line(str,nesting) - str = gsub(str," *[\n\r]+ *"," ") ; -- semi colon needed - (currenthandler.flush_line or default.flush_line)(str,nesting) + local fl = currenthandler.flush_line + if fl then + str = gsub(str," *[\n\r]+ *"," ") ; -- semi colon needed + fl(str,nesting) + else + -- gsub done later + default.flush_line(str,nesting) + end end function hooks.flush_inline(str,nesting) @@ -419,11 +566,11 @@ function default.line(str) end function default.flush_line(str) - str = str:gsub(" *[\n\r]+ *"," ") + str = gsub(str," *[\n\r]+ *"," ") if visualizers.obeyspace then for c in utfcharacters(str) do if c == " " then - texsprint(ctxcatcodes,"\\obs ") + texsprint(ctxcatcodes,"\\obs") else texwrite(c) end @@ -454,13 +601,14 @@ end -- special one -commands.nested = "\\switchslantedtype " +buffers.commands.nested = "\\switchslantedtype " -- todo : utf + faster, direct print and such. no \\char, vrb catcodes, see end function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess - str = str:gsub(" *[\n\r]+ *"," ") + str = gsub(str," *[\n\r]+ *"," ") local result, c, nested, i = "", "", 0, 1 + local commands = buffers.commands -- otherwise wrong commands while i < #str do -- slow c = sub(str,i,i+1) if c == "<<" then @@ -481,7 +629,7 @@ function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess c = sub(str,i,i) if c == " " then result = result .. "\\obs " - elseif c:find("%a") then + elseif find(c,"%a") then result = result .. c else result = result .. "\\char" .. byte(c) .. " " @@ -546,6 +694,106 @@ function buffers.flush_result(result,nested) end end +-- new + +function buffers.realign(name,forced_n) -- no, auto, <number> + local n, d + if type(name) == "string" then + d = data[name] + if type(d) == "string" then + d = d:splitlines() + end + else + d = name -- already a buffer + end + forced_n = (forced_n == variables.auto and huge) or tonumber(forced_n) + if forced_n then + for i=1, #d do + local spaces = find(d[i],"%S") + if not spaces then + -- empty line + elseif not n then + n = spaces + elseif spaces == 0 then + n = 0 + break + elseif n > spaces then + n = spaces + end + end + if n > 0 then + if n > forced_n then + n = forced_n + end + for i=1,#d do + d[i] = sub(d[i],n) + end + end + end + return d +end + +-- escapes: buffers.set_escape("tex","/BTEX","/ETEX") + +local function flush_escaped_line(str,pattern,flushline) + while true do + local a, b, c = match(str,pattern) + if a and a ~= "" then + flushline(a) + end + if b and b ~= "" then + texsprint(ctxcatcodes,"{",b,"}") + end + if c then + if c == "" then + break + else + str = c + end + else + flushline(str) + break + end + end +end + +function buffers.set_escape(name,pair) + if pair and pair ~= "" then + local visualizer = buffers.getvisualizer(name) + visualizer.normal_flush_line = visualizer.normal_flush_line or visualizer.flush_line + if pair == variables.no then + visualizer.flush_line = visualizer.normal_flush_line or visualizer.flush_line + if trace_visualize then + logs.report("buffers","resetting escape range for visualizer '%s'",name) + end + else + local start, stop + if pair == variables.yes then + start, stop = "/BTEX", "/ETEX" + else + pair = string.split(pair,",") + start, stop = string.esc(pair[1] or ""), string.esc(pair[2] or "") + end + if start ~= "" then + local pattern + if stop == "" then + pattern = "^(.-)" .. start .. "(.*)(.*)$" + else + pattern = "^(.-)" .. start .. "(.-)" .. stop .. "(.*)$" + end + function visualizer.flush_line(str) + flush_escaped_line(str,pattern,visualizer.normal_flush_line) + end + if trace_visualize then + logs.report("buffers","setting escape range for visualizer '%s' to %s -> %s",name,start,stop) + end + elseif trace_visualize then + logs.report("buffers","problematic escape specification '%s' for visualizer '%s'",pair,name) + end + end + end +end + -- THIS WILL BECOME A FRAMEWORK: the problem with prety printing is that -- we deal with snippets and therefore we need tolerant parsing @@ -587,6 +835,4 @@ end --~ str = [[test 123 test $oeps$]] ---~ pattern:match(str) - - +--~ lpegmatch(pattern,str) |