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 utfbyte, utfchar, utfvalues = utf.byte, utf.char, utf.values local format, gsub = string.format, string.gsub local tostring = tostring local tokens = tokens local newtoken = newtoken local tex = tex local context = context local commands = commands tokens.collectors = tokens.collectors or { } local collectors = tokens.collectors collectors.data = collectors.data or { } local collectordata = collectors.data collectors.registered = collectors.registered or { } local registered = collectors.registered local report = logs.reporter("tokens","collectors") if newtoken then -- todo: -- -- register : macros that will be expanded (only for demo-ing) -- flush : print back to tex -- test : fancy stuff local get_next = newtoken.get_next local create = newtoken.create function collectors.install(tag,end_cs) local data, d = { }, 0 collectordata[tag] = data end_cs = gsub(end_cs,"^\\","") while true do local t = get_next() if t.csname == end_cs then context[end_cs]() return else d = d + 1 data[d] = t end end end local simple = { letter = "letter", other_char = "other" } function collectors.show(data) -- We no longer have methods as we only used (in demos) method a -- so there is no need to burden the core with this. We have a -- different table anyway. if type(data) == "string" then data = collectordata[data] end if not data then return end local ctx_NC = context.NC local ctx_NR = context.NR local ctx_bold = context.bold local ctx_verbatim = context.verbatim context.starttabulate { "|Tl|Tc|Tl|" } ctx_NC() ctx_bold("cmd") ctx_NC() ctx_bold("meaning") ctx_NC() ctx_bold("properties") ctx_NC() ctx_NR() context.HL() for i=1,#data do local token = data[i] local cmdname = token.cmdname local simple = simple[cmdname] ctx_NC() ctx_verbatim(simple or cmdname) ctx_NC() ctx_verbatim(simple and utfchar(token.mode) or token.csname) ctx_NC() if token.active then context("active ") end if token.expandable then context("expandable ") end if token.protected then context("protected ") end ctx_NC() ctx_NR() end context.stoptabulate() end local function printlist(data) if data and #data > 0 then report("not supported (yet): printing back to tex") end end tokens.printlist = printlist -- will change to another namespace function collectors.flush(tag) printlist(collectordata[tag]) end function collectors.test(tag,handle) report("not supported (yet): testing") end function collectors.register(name) report("not supported (yet): registering") end else -- 1 = command, 2 = modifier (char), 3 = controlsequence id local create = token.create local csname_id = token.csname_id local command_id = token.command_id local command_name = token.command_name local get_next = token.get_next local expand = token.expand local csname_name = token.csname_name local function printlist(data) if data and #data > 0 then callbacks.push('token_filter', function () callbacks.pop('token_filter') -- tricky but the nil assignment helps return data end) end end tokens.printlist = printlist -- will change to another namespace function collectors.flush(tag) printlist(collectordata[tag]) end function collectors.register(name) registered[csname_id(name)] = name end local call = command_id("call") local letter = command_id("letter") local other = command_id("other_char") function collectors.install(tag,end_cs) local data, d = { }, 0 collectordata[tag] = data end_cs = gsub(end_cs,"^\\","") local endcs = csname_id(end_cs) while true do local t = get_next() local a, b = t[1], t[3] if b == endcs then context[end_cs]() return elseif a == call and registered[b] then expand() else d = d + 1 data[d] = t end end end function collectors.show(data) -- We no longer have methods as we only used (in demos) method a -- so there is no need to burden the core with this. if type(data) == "string" then data = collectordata[data] end if not data then return end local ctx_NC = context.NC local ctx_NR = context.NR local ctx_bold = context.bold local ctx_verbatim = context.verbatim context.starttabulate { "|T|Tr|cT|Tr|T|" } ctx_NC() ctx_bold("cmd") ctx_NC() ctx_bold("chr") ctx_NC() ctx_NC() ctx_bold("id") ctx_NC() ctx_bold("name") ctx_NC() ctx_NR() context.HL() for i=1,#data do local token = data[i] local cmd = token[1] local chr = token[2] local id = token[3] local name = command_name(token) ctx_NC() ctx_verbatim(name) ctx_NC() if tonumber(chr) >= 0 then ctx_verbatim(chr) end ctx_NC() if cmd == letter or cmd == other then ctx_verbatim(utfchar(chr)) end ctx_NC() if id > 0 then ctx_verbatim(id) end ctx_NC() if id > 0 then ctx_verbatim(csname_name(token) or "") end ctx_NC() ctx_NR() end context.stoptabulate() end function collectors.test(tag,handle) local t, w, tn, wn = { }, { }, 0, 0 handle = handle or collectors.defaultwords local tagdata = collectordata[tag] for k=1,#tagdata do local v = tagdata[k] if v[1] == letter then wn = wn + 1 w[wn] = v[2] else if wn > 0 then handle(t,w) wn = 0 end tn = tn + 1 t[tn] = v end end if wn > 0 then handle(t,w) end collectordata[tag] = t end end -- Interfacing: commands.collecttokens = collectors.install commands.showtokens = collectors.show commands.flushtokens = collectors.flush commands.testtokens = collectors.test commands.registertoken = collectors.register -- Redundant: -- function collectors.test(tag) -- printlist(collectordata[tag]) -- end -- For old times sake: collectors.dowithwords = collectors.test -- This is only used in old articles ... will move to a module: local create = newtoken and newtoken.create or token.create tokens.vbox = create("vbox") tokens.hbox = create("hbox") tokens.vtop = create("vtop") tokens.bgroup = create(utfbyte("{"),1) tokens.egroup = create(utfbyte("}"),2) tokens.letter = function(chr) return create(utfbyte(chr),11) end tokens.other = function(chr) return create(utfbyte(chr),12) end tokens.letters = function(str) local t, n = { }, 0 for chr in utfvalues(str) do n = n + 1 t[n] = create(chr, 11) end return t end function collectors.defaultwords(t,str) if t then local n = #t n = n + 1 ; t[n] = tokens.bgroup n = n + 1 ; t[n] = create("red") for i=1,#str do n = n + 1 ; t[n] = tokens.other('*') end n = n + 1 ; t[n] = tokens.egroup end end