diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
commit | 8fc3039c82d48605b5ca8b2eda3f4fdd755681e1 (patch) | |
tree | 3cd9bbdd599bc4d1ac0409e167fee2136e4c0ec9 /Master/texmf-dist/tex/context/base/strc-ini.lua | |
parent | 850fc99b7cd3ae7a20065531fe866ff7bae642ec (diff) |
this is context 2009.08.19 17:10
git-svn-id: svn://tug.org/texlive/trunk@14827 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-ini.lua | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-ini.lua b/Master/texmf-dist/tex/context/base/strc-ini.lua new file mode 100644 index 00000000000..06f5ff82f82 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/strc-ini.lua @@ -0,0 +1,282 @@ +if not modules then modules = { } end modules ['strc-ini'] = { + version = 1.001, + comment = "companion to strc-ini.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ + +The restructuring is the (intermediate) result of quite some experiments. I started +with the basic structure, followed by lists, numbers, enumerations, itemgroups +and floats. All these have something in common, like pagenumbers and section +prefixes. I played with some generic datastructure (in order to save space) but +the code at both the lua and tex end then quickly becomes messy due to the fact +that access to variables is too different. So, eventually I ended up with +dedicated structures combined with sharing data. In lua this is quite efficient +because tables are referenced. However, some precautions are to be taken in +order to keep the utility file small. Utility data and process data share much +but it does not make sense to store all processdata. + +]]-- + +local format, concat, match = string.format, table.concat, string.match +local count, texwrite, texprint, texsprint = tex.count, tex.write, tex.print, tex.sprint +local type, next, tonumber, tostring = type, next, tonumber, tostring + +local ctxcatcodes = tex.ctxcatcodes + +-- move this + +commands = commands or { } + +function commands.first_in_list(str) + local first = match(str,"^([^,]+),") + texsprint(ctxcatcodes,first or str) +end + +-- -- -- namespace -- -- -- + +structure = structure or { } + +-- -- -- cache -- -- -- + +structure.shares = structure.shares or { } +structure.shares.cache = structure.shares.cache or { } + +local shares = structure.shares +local cache = shares.cache + +function shares.put(data) + cache[#cache+1] = data + return #cache +end + +function shares.get(n) -- n can be string + n = tonumber(n) or -1 + return cache[n] +end + +-- -- -- specials -- -- -- + +-- we can store information and get back a reference; this permits +-- us to store rather raw data in references + +local specials = { } structure.specials = specials + +specials.collected = specials.collected or { } +specials.tobesaved = specials.collected or { } + +local collected, tobesaved = specials.collected, specials.tobesaved + +local function initializer() + collected, tobesaved = specials.collected, specials.tobesaved +end + +if job then + job.register('structure.specials.collected', structure.specials.tobesaved, initializer) +end + +function specials.store(class,data) + if class and data then + local s = tobesaved[class] + if not s then + s = { } + tobesaved[class] = s + end + s[#s+1] = data + texwrite(#s) + else + texwrite(0) + end +end + +function specials.retrieve(class,n) + if class and n then + local c = collected[class] + return c and c[n] + end +end + +-- -- -- helpers -- -- -- + +structure.helpers = structure.helpers or { } + +local helpers = structure.helpers + +function helpers.touserdata(str) + local hash = str and str ~= "" and aux.settings_to_hash(str) + if hash and next(hash) then + return hash + end +end + +local function simplify(d,nodefault) + if d then + local t = { } + for k, v in next, d do + local tv = type(v) + if tv == "table" then + if next(v) then t[k] = simplify(v) end + elseif tv == "string" then + if v ~= "" and v ~= "default" then t[k] = v end + elseif tv == "boolean" then + if v then t[k] = v end + else + t[k] = v + end + end +--~ print(table.serialize(d,"before")) +--~ print(table.serialize(t,"after")) + return next(t) and t + elseif nodefault then + return nil + else + return { } + end +end + +helpers.simplify = simplify + +function helpers.merged(...) + local h, t = { ... }, { } + for k=1, #h do + local v = h[k] + if v and v ~= "" and not t[k] then + t[k] = v + end + end + return t +end + +local tag = "ctx:tocentry" + +function helpers.title(title,metadata) + if title and title ~= "" then + if metadata then + if metadata.coding == "xml" then + buffers.set(tag,format("<?xml version='1.0'?><%s>%s</%s>",tag,title,tag)) + texsprint(ctxcatcodes,format("\\xmlprocessbuffer{%s}{%s}{}",metadata.xmlroot or "main",tag)) + else + texsprint(metadata.catcodes,title) + end + else + texsprint(title) -- no catcode switch + end + end +end + +-- -- -- processors -- -- -- syntax: processor->data + +local processors = { } structure.processors = processors + +local registered = { } + +function processors.register(p) + registered[p] = true +end + +function processors.reset(p) + registered[p] = nil +end + +local splitter = lpeg.splitat("->",true) + +function processors.split(str) + local p, s = splitter:match(str) + if registered[p] then + return p, s + else + return false, str + end +end + +function processors.sprint(catcodes,str,fnc,...) + local p, s = splitter:match(str) + if registered[p] then + texsprint(catcodes,format("\\applyprocessor{%s}{%s}",p,(fnc and fnc(s,...)) or s)) + else + texsprint(catcodes,(fnc and fnc(str,...)) or str) + end +end + +function processors.apply(str) + local p, s = splitter:match(str) + if registered[p] then + return format("\\applyprocessor{%s}{%s}",p,s) + else + return str + end +end + +-- -- -- sets -- -- -- + +structure.sets = structure.sets or { } +structure.sets.setlist = structure.sets.setlist or { } + +storage.register("structure/sets/setlist", structure.sets.setlist, "structure.sets.setlist") + +local sets = structure.sets +local setlist = sets.setlist + +function sets.define(namespace,name,values,default,numbers) + local dn = setlist[namespace] + if not dn then + dn = { } + setlist[namespace] = dn + end + if values == "" then + dn[name] = { { }, default } + else + local split = aux.settings_to_array(values) + if numbers then + -- convert to numbers (e.g. for reset) + for i=1,#split do + split[i] = tonumber(split[i]) or 0 + end + end + dn[name] = { split, default } + end +end + +function sets.getall(namespace,block,name) + local ds = setlist[namespace] + if not ds then + return { } + else + local dn + if block and block ~= "" then + dn = ds[block..":"..name] or ds[name] or ds[block] or ds.default + else + dn = ds[name] or ds.default + end + return (dn and dn[1]) or { } + end +end + +function sets.get(namespace,block,name,level,default) -- check if name is passed + local ds = setlist[namespace] + if not ds then + return default + end + local dn + if name and name ~= "" then + if block and block ~= "" then + dn = ds[block..":"..name] or ds[name] or ds[block] or ds.default + else + dn = ds[name] or ds.default + end + else + if block and block ~= "" then + dn = ds[block] or ds[block..":default"] or ds.default + else + dn = ds.default + end + end + if not dn then + return default + end + local dl = dn[1][level] + return dl or dn[2] or default +end |