diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
commit | 8d8d528d2ad52599f11250cfc567fea4f37f2a8b (patch) | |
tree | 94286bc131ef7d994f9432febaf03fe23d10eef8 /tex/context/modules/mkiv/x-cals.lua | |
parent | f5aed2e51223c36c84c5f25a6cad238b2af59087 (diff) | |
download | context-8d8d528d2ad52599f11250cfc567fea4f37f2a8b.tar.gz |
2016-01-12 16:26:00
Diffstat (limited to 'tex/context/modules/mkiv/x-cals.lua')
-rw-r--r-- | tex/context/modules/mkiv/x-cals.lua | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/tex/context/modules/mkiv/x-cals.lua b/tex/context/modules/mkiv/x-cals.lua new file mode 100644 index 000000000..3af6106d8 --- /dev/null +++ b/tex/context/modules/mkiv/x-cals.lua @@ -0,0 +1,221 @@ +if not modules then modules = { } end modules ['x-cals'] = { + version = 1.001, + comment = "companion to x-cals.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next +local format, lower = string.format, string.lower +local xmlsprint, xmlcprint, xmlcollected, xmlelements = xml.sprint, xml.cprint, xml.collected, xml.elements +local n_todimen, s_todimen = number.todimen, string.todimen + +-- there is room for speedups as well as cleanup (using context functions) + +local cals = { } +moduledata.cals = cals +lxml.mathml = cals -- for the moment + +cals.ignore_widths = false +cals.shrink_widths = false +cals.stretch_widths = false + +-- the following flags only apply to columns that have a specified width +-- +-- proportional : shrink or stretch proportionally to the width +-- equal : shrink or stretch equaly distributed +-- n < 1 : shrink or stretch proportionally to the width but multiplied by n +-- +-- more clever things, e.g. the same but applied to unspecified widths +-- has to happen at the core-ntb level (todo) + +local halignments = { + left = "flushleft", + right = "flushright", + center = "middle", + centre = "middle", + justify = "normal", +} + +local valignments = { + top = "high", + bottom = "low", + middle = "lohi", +} + +local function adapt(widths,b,w,delta,sum,n,what) + if b == "equal" then + delta = delta/n + for k, v in next, w do + widths[k] = n_todimen(v - delta) + end + elseif b == "proportional" then + delta = delta/sum + for k, v in next, w do + widths[k] = n_todimen(v - v*delta) + end + elseif type(b) == "number" and b < 1 then + delta = b*delta/sum + for k, v in next, w do + widths[k] = n_todimen(v - v*delta) + end + end +end + +local function getspecs(root, pattern, names, widths) + -- here, but actually we need this in core-ntb.tex + -- but ideally we need an mkiv enhanced core-ntb.tex + local ignore_widths = cals.ignore_widths +-- local shrink_widths = at.option == "shrink" or cals.shrink_widths +-- local stretch_widths = at.option == "stretch" or cals.stretch_widths + local shrink_widths = cals.shrink_widths + local stretch_widths = cals.stretch_widths + for e in xmlcollected(root,pattern) do + local at = e.at + local column = at.colnum + if column then + if not ignore_widths then + local width = at.colwidth + if width then + widths[tonumber(column)] = lower(width) + end + end + local name = at.colname + if name then + names[name] = tonumber(column) + end + end + end + if ignore_width then + -- forget about it + elseif shrink_widths or stretch_widths then + local sum, n, w = 0, 0, { } + for _, v in next, widths do + n = n + 1 + v = (type(v) == "string" and s_todimen(v)) or v + if v then + w[n] = v + sum = sum + v + end + end + local hsize = tex.hsize + if type(hsize) == "string" then + hsize = s_todimen(hsize) + end + local delta = sum - hsize + if shrink_widths and delta > 0 then + adapt(widths,shrink_widths,w,delta,sum,n,"shrink") + elseif stretch_widths and delta < 0 then + adapt(widths,stretch_widths,w,delta,sum,n,"stretch") + end + end +end + +local function getspans(root, pattern, names, spans) + for e in xmlcollected(root,pattern) do + local at = e.at + local name, namest, nameend = at.colname, names[at.namest or "?"], names[at.nameend or "?"] + if name and namest and nameend then + spans[name] = tonumber(nameend) - tonumber(namest) + 1 + end + end +end + +local bTR, eTR, bTD, eTD = context.bTR, context.eTR, context.bTD, context.eTD + +function cals.table(root,namespace) + + local prefix = (namespace or "cals") .. ":" + + local prefix = namespace and namespace ~= "" and (namespace .. ":") or "" + local p = "/" .. prefix + + local tgroupspec = p .. "tgroup" + local colspec = p .. "colspec" + local spanspec = p .. "spanspec" + local hcolspec = p .. "thead" .. p .. "colspec" + local bcolspec = p .. "tbody" .. p .. "colspec" + local fcolspec = p .. "tfoot" .. p .. "colspec" + local entryspec = p .. "entry" .. "|" .. prefix .. "entrytbl" -- shouldn't that be p ? + local hrowspec = p .. "thead" .. p .. "row" + local browspec = p .. "tbody" .. p .. "row" + local frowspec = p .. "tfoot" .. p .. "row" + + local function tablepart(root, xcolspec, xrowspec, before, after) -- move this one outside + before() + local at = root.at + local pphalign, ppvalign = at.align, at.valign + local names, widths, spans = { }, { }, { } + getspecs(root, colspec , names, widths) + getspecs(root, xcolspec, names, widths) + getspans(root, spanspec, names, spans) + for r, d, k in xmlelements(root,xrowspec) do + bTR() + local dk = d[k] + local at = dk.at + local phalign, pvalign = at.align or pphalign, at.valign or ppvalign -- todo: __p__ test + local col = 1 + for rr, dd, kk in xmlelements(dk,entryspec) do + local dk = dd[kk] + if dk.tg == "entrytbl" then + -- bTD(function() cals.table(dk) end) + bTD() + context("{") + cals.table(dk) + context("}") + eTD() + col = col + 1 + else + local at = dk.at + local b, e, s, m = names[at.namest or "?"], names[at.nameend or "?"], spans[at.spanname or "?"], at.morerows + local halign, valign = at.align or phalign, at.valign or pvalign + if b and e then + s = e - b + 1 + end + if halign then + halign = halignments[halign] + end + if valign then + valign = valignments[valign] + end + local width = widths[col] + if s or m or halign or valign or width then -- currently only english interface ! + bTD { + nx = s or 1, + ny = (m or 0) + 1, + align = format("{%s,%s}",halign or "flushleft",valign or "high"), + width = width or "fit", + } + else + bTD { + align = "{flushleft,high}", + width = "fit", -- else problems with vertical material + } + end + xmlcprint(dk) + eTD() + col = col + (s or 1) + end + end + eTR() + end + after() + end + + for tgroup in lxml.collected(root,tgroupspec) do + context.directsetup("cals:table:before") + lxml.directives.before(root,"cdx") -- "cals:table" + context.bgroup() + lxml.directives.setup(root,"cdx") -- "cals:table" + context.bTABLE() + tablepart(tgroup, hcolspec, hrowspec, context.bTABLEhead, context.eTABLEhead) + tablepart(tgroup, bcolspec, browspec, context.bTABLEbody, context.eTABLEbody) + tablepart(tgroup, fcolspec, frowspec, context.bTABLEfoot, context.eTABLEfoot) + context.eTABLE() + context.egroup() + lxml.directives.after(root,"cdx") -- "cals:table" + context.directsetup("cals:table:after") + end + +end |