From 85b7bc695629926641c7cb752fd478adfdf374f3 Mon Sep 17 00:00:00 2001 From: Marius Date: Sun, 4 Jul 2010 15:32:09 +0300 Subject: stable 2010-05-24 13:10 --- tex/context/base/toks-ini.lua | 326 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 tex/context/base/toks-ini.lua (limited to 'tex/context/base/toks-ini.lua') diff --git a/tex/context/base/toks-ini.lua b/tex/context/base/toks-ini.lua new file mode 100644 index 000000000..ec60402d8 --- /dev/null +++ b/tex/context/base/toks-ini.lua @@ -0,0 +1,326 @@ +if not modules then modules = { } end modules ['toks-ini'] = { + version = 1.001, + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 +local format, gsub, texsprint = string.format, string.gsub, tex.sprint + +local ctxcatcodes = tex.ctxcatcodes + +--[[ldx-- +

This code is experimental and needs a cleanup. The visualizers will move to +a module.

+--ldx]]-- + +-- 1 = command, 2 = modifier (char), 3 = controlsequence id +-- +-- callback.register('token_filter', token.get_next) +-- +-- token.get_next() +-- token.expand() +-- token.create() +-- token.csname_id() +-- token.csname_name(v) +-- token.command_id() +-- token.command_name(v) +-- token.is_expandable() +-- token.is_activechar() +-- token.lookup(v) + +-- actually, we can use token registers to store tokens + +tokens = tokens or { } + +tokens.vbox = token.create("vbox") +tokens.hbox = token.create("hbox") +tokens.vtop = token.create("vtop") +tokens.bgroup = token.create(utf.byte("{"), 1) +tokens.egroup = token.create(utf.byte("}"), 2) + +tokens.letter = function(chr) return token.create(utf.byte(chr), 11) end +tokens.other = function(chr) return token.create(utf.byte(chr), 12) end + +tokens.letters = function(str) + local t = { } + for chr in string.utfvalues(str) do + t[#t+1] = token.create(chr, 11) + end + return t +end + +collectors = collectors or { } +collectors.data = collectors.data or { } + +function tex.printlist(data) + callbacks.push('token_filter', function () + callbacks.pop('token_filter') -- tricky but the nil assignment helps + return data + end) +end + +function collectors.flush(tag) + tex.printlist(collectors.data[tag]) +end + +function collectors.test(tag) + tex.printlist(collectors.data[tag]) +end + +collectors.registered = { } + +function collectors.register(name) + collectors.registered[token.csname_id(name)] = name +end + +--~ function collectors.install(tag,end_cs) +--~ collectors.data[tag] = { } +--~ local data = collectors.data[tag] +--~ local call = token.command_id("call") +--~ local relax = token.command_id("relax") +--~ local endcs = token.csname_id(end_cs) +--~ local expand = collectors.registered +--~ local get = token.get_next -- so no callback! +--~ while true do +--~ local t = get() +--~ local a, b = t[1], t[3] +--~ if a == relax and b == endcs then +--~ return +--~ elseif a == call and expand[b] then +--~ token.expand() +--~ else +--~ data[#data+1] = t +--~ end +--~ end +--~ end + +function collectors.install(tag,end_cs) + collectors.data[tag] = { } + local data = collectors.data[tag] + local call = token.command_id("call") + local endcs = token.csname_id(end_cs) + local expand = collectors.registered + local get = token.get_next + while true do + local t = get() + local a, b = t[1], t[3] + if b == endcs then + tex.print('\\' ..end_cs) + return + elseif a == call and expand[b] then + token.expand() + else + data[#data+1] = t + end + end +end + +function collectors.handle(tag,handle,flush) + collectors.data[tag] = handle(collectors.data[tag]) + if flush then + collectors.flush(tag) + end +end + +collectors.show_methods = { } + +function collectors.show(tag, method) + if type(tag) == "table" then + collectors.show_methods[method or 'a'](tag) + else + collectors.show_methods[method or 'a'](collectors.data[tag]) + end +end + +commands = commands or { } + +commands.letter = token.command_id("letter") +commands.other = token.command_id("other_char") + +function collectors.default_words(t,str) + t[#t+1] = tokens.bgroup + t[#t+1] = token.create("red") + for i=1,#str do + t[#t+1] = tokens.other('*') + end + t[#t+1] = tokens.egroup +end + +function collectors.with_words(tag,handle) + local t, w = { }, { } + handle = handle or collectors.default_words + local tagdata = collectors.data[tag] + for k=1,#tagdata do + local v = tagdata[k] + if v[1] == commands.letter then + w[#w+1] = v[2] + else + if #w > 0 then + handle(t,w) + w = { } + end + t[#t+1] = v + end + end + if #w > 0 then + handle(t,w) + end + collectors.data[tag] = t +end + +function collectors.show_token(t) + if t then + local cmd, chr, id, cs, name = t[1], t[2], t[3], nil, token.command_name(t) or "" + if cmd == commands.letter or cmd == commands.other then + return format("%s-> %s -> %s", name, chr, utf.char(chr)) + elseif id > 0 then + cs = token.csname_name(t) or nil + if cs then + return format("%s-> %s", name, cs) + elseif tonumber(chr) < 0 then + return format("%s-> %s", name, id) + else + return format("%s-> (%s,%s)", name, chr, id) + end + else + return format("%s", name) + end + else + return "no node" + end +end + +function collectors.trace() + local t = token.get_next() + texio.write_nl(collectors.show_token(t)) + return t +end + +collectors.show_methods.a = function(data) -- no need to store the table, just pass directly + local template = "\\NC %s\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR " + texsprint(ctxcatcodes, "\\starttabulate[|T|Tr|cT|Tr|T|]") + texsprint(ctxcatcodes, format(template,"cmd","chr","","id","name")) + texsprint(ctxcatcodes, "\\HL") + for _,v in next, data do + local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", "" + local name = gsub(token.command_name(v) or "","_","\\_") + if id > 0 then + cs = token.csname_name(v) or "" + if cs ~= "" then cs = "\\string " .. cs end + else + id = "" + end + if cmd == commands.letter or cmd == commands.other then + sym = "\\char " .. chr + end + if tonumber(chr) < 0 then + texsprint(ctxcatcodes, format(template, name, "", sym, id, cs)) + else + texsprint(ctxcatcodes, format(template, name, chr, sym, id, cs)) + end + end + texsprint(ctxcatcodes, "\\stoptabulate") +end + +collectors.show_methods.b_c = function(data,swap) -- no need to store the table, just pass directly + local template = "\\NC %s\\NC %s\\NC %s\\NC\\NR" + if swap then + texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tl|Tr|]") + else + texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tr|Tl|]") + end + texsprint(ctxcatcodes, format(template,"cmd","chr","name")) + texsprint(ctxcatcodes, "\\HL") + for _,v in next, data do + local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", "" + local name = gsub(token.command_name(v) or "","_","\\_") + if id > 0 then + cs = token.csname_name(v) or "" + end + if cmd == commands.letter or cmd == commands.other then + sym = "\\char " .. chr + elseif cs ~= "" then + if token.is_activechar(v) then + sym = "\\string " .. cs + else + sym = "\\string\\" .. cs + end + end + if swap then + texsprint(ctxcatcodes, format(template, name, sym, chr)) + elseif tonumber(chr) < 0 then + texsprint(ctxcatcodes, format(template, name, "", sym)) + else + texsprint(ctxcatcodes, format(template, name, chr, sym)) + end + end + texsprint(ctxcatcodes, "\\stoptabulate") +end + +-- Even more experimental ... + +collectors.show_methods.b = function(tag) collectors.show_methods.b_c(tag,false) end +collectors.show_methods.c = function(tag) collectors.show_methods.b_c(tag,true ) end + +collectors.remapper = { + -- namespace +} + +collectors.remapper.data = { + -- user mappings +} + +function collectors.remapper.store(tag,class,key) + local s = collectors.remapper.data[class] + if not s then + s = { } + collectors.remapper.data[class] = s + end + s[key] = collectors.data[tag] + collectors.data[tag] = nil +end + +function collectors.remapper.convert(tag,toks) + local data = collectors.remapper.data[tag] + local leftbracket, rightbracket = utf.byte('['), utf.byte(']') + local skipping = 0 + -- todo: math + if data then + local t = { } + for s=1,#toks do + local tok = toks[s] + local one, two = tok[1], tok[2] + if one == 11 or one == 12 then + if two == leftbracket then + skipping = skipping + 1 + t[#t+1] = tok + elseif two == rightbracket then + skipping = skipping - 1 + t[#t+1] = tok + elseif skipping == 0 then + local new = data[two] + if new then + if #new > 1 then + for n=1,#new do + t[#t+1] = new[n] + end + else + t[#t+1] = new[1] + end + else + t[#t+1] = tok + end + else + t[#t+1] = tok + end + else + t[#t+1] = tok + end + end + return t + else + return toks + end +end -- cgit v1.2.3