diff options
Diffstat (limited to 'tex')
38 files changed, 2489 insertions, 204 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 83f314934..541b6a783 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 50ad1776c..20cad141b 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{foregroundcolor} \setinterfaceconstant{foregroundstyle}{foregroundstyle} \setinterfaceconstant{format}{formatieren} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{rahmen} \setinterfaceconstant{framecolor}{rahmenfarbe} \setinterfaceconstant{framecorner}{rahmenwinkel} diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii index 4463d7ca9..325d5890b 100644 --- a/tex/context/base/mkii/mult-en.mkii +++ b/tex/context/base/mkii/mult-en.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{foregroundcolor} \setinterfaceconstant{foregroundstyle}{foregroundstyle} \setinterfaceconstant{format}{format} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{frame} \setinterfaceconstant{framecolor}{framecolor} \setinterfaceconstant{framecorner}{framecorner} diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii index b68dc4baf..efd5f442b 100644 --- a/tex/context/base/mkii/mult-fr.mkii +++ b/tex/context/base/mkii/mult-fr.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{couleurpremierplan} \setinterfaceconstant{foregroundstyle}{stylepremierplan} \setinterfaceconstant{format}{formatter} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{cadre} \setinterfaceconstant{framecolor}{couleurcadre} \setinterfaceconstant{framecorner}{coincadre} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index 42e27d824..5b2ecaa13 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{coloreprimopiano} \setinterfaceconstant{foregroundstyle}{foregroundstyle} \setinterfaceconstant{format}{format} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{cornice} \setinterfaceconstant{framecolor}{colorecornice} \setinterfaceconstant{framecorner}{angolocornice} diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index 344433d16..dfd241c38 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{voorgrondkleur} \setinterfaceconstant{foregroundstyle}{voorgrondletter} \setinterfaceconstant{format}{formatteer} +\setinterfaceconstant{fractions}{breuken} \setinterfaceconstant{frame}{kader} \setinterfaceconstant{framecolor}{kaderkleur} \setinterfaceconstant{framecorner}{kaderhoek} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 6548de555..4275e3874 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{رنگپیشزمینه} \setinterfaceconstant{foregroundstyle}{سبکپیشزمینه} \setinterfaceconstant{format}{شمایل} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{قالب} \setinterfaceconstant{framecolor}{رنگقالب} \setinterfaceconstant{framecorner}{گوشهقالب} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index 0ad8eb569..9926be0ce 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -803,6 +803,7 @@ \setinterfaceconstant{foregroundcolor}{foregroundcolor} \setinterfaceconstant{foregroundstyle}{foregroundstyle} \setinterfaceconstant{format}{format} +\setinterfaceconstant{fractions}{fractions} \setinterfaceconstant{frame}{frame} \setinterfaceconstant{framecolor}{culoareframe} \setinterfaceconstant{framecorner}{coltframe} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 49bc48b60..ea60d4a45 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.02.26 16:09} +\newcontextversion{2016.03.01 14:03} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 6533fb6ee..44d760fb3 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.02.26 16:09} +\edef\contextversion{2016.03.01 14:03} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/m-newcolumnsets.mkiv b/tex/context/base/mkiv/m-newcolumnsets.mkiv new file mode 100644 index 000000000..e0fe60f3f --- /dev/null +++ b/tex/context/base/mkiv/m-newcolumnsets.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=m-newcolumnsets, +%D version=2016.02.29, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=New Columnsets, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module will eventually be replaced by \type {m-oldcolumnsets}. + +\ifdefined \definepagegrid + \expandafter \endinput +\else + \loadmarkfile{page-cst} +\fi + +% \let\definecolumnset \definepagegrid +% \let\setupcolumnset \setuppagegrid +% \let\setupcolumnsetlines \setuppagegridlines +% \let\setupcolumnsetstart \setuppagegridstart +% \let\startcolumnset \startpagegrid +% \let\stopcolumnset \stoppagegrid +% \let\definecolumnsetspan \definepagegridspan +% \let\setupcolumnsetspan \setuppagegridspan +% \let\startcolumnsetspan \startpagegridspan +% \let\stopcolumnsetspan \stoppagegridspan +% \let\columnsetspanwidth \pagegridspanwidth +% \let\definecolumnsetarea \definepagegridarea +% \let\setupcolumnsetarea \setuppagegridarea +% \let\setupcolumnsetareatext\setuppagegridareatext + +\endinput + diff --git a/tex/context/base/mkiv/m-newotf.mkiv b/tex/context/base/mkiv/m-newotf.mkiv deleted file mode 100644 index 267d124fa..000000000 --- a/tex/context/base/mkiv/m-newotf.mkiv +++ /dev/null @@ -1,89 +0,0 @@ -%D \module -%D [ file=m-newotf, -%D version=2015.07.08, -%D title=\CONTEXT\ Extra Modules, -%D subtitle=Experimental OTF Loader, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% \endinput - -%D This module will go away as soon as we use the new loader code by default. -%D That will happen after extensive testing. Generic support will happen after -%D that. - -\unprotect - -\startluacode - local files = { - "font-otj", - "font-otr", - "font-cff", - "font-ttf", - "font-dsp", - "font-oup", - "font-otl", - "font-ots", - "font-oto", - "font-otd", - "font-otc", - "font-osd", - "font-map", - "font-fbk", - "font-gds", - } - local report = logs.reporter("newotf") - local findfile = resolvers.findfile - local addsuffix = file.addsuffix - report() - if fonts.handlers.otf.version >= 3.000 then - report("replacing new font loader code by experimental code") - else - report("replacing old font loader code by new loader code") - end - report() - for i=1,#files do - local foundfile = findfile(addsuffix(files[i],"lua")) - if foundfile and foundfile ~= "" then - report("loading %a",foundfile) - dofile(foundfile) - end - end - report() - - -- needed for testing: - - local nuts = nodes.nuts - local copy_node = nuts.copy - local kern = nuts.pool.register(nuts.pool.kern()) - local setfield = nuts.setfield - - nuts.setattr(kern,attributes.private('fontkern'),1) -- we can have several, attributes are shared - - nodes.injections.installnewkern(function(k) - local c = copy_node(kern) - setfield(c,"kern",k) - return c - end) - - directives.register("nodes.injections.fontkern", function(v) setfield(kern,"subtype",v and 0 or 1) end) - - local fonts = fonts - local handlers = fonts.handlers - local otf = handlers.otf -- brrr - local afm = handlers.afm -- brrr - local getters = fonts.getters - - getters.kern .opentype = otf.getkern - getters.substitution.opentype = otf.getsubstitution - getters.alternate .opentype = otf.getalternate - getters.multiple .opentype = otf.getmultiple - -\stopluacode - -\protect \endinput diff --git a/tex/context/base/mkiv/m-oldotf.mkiv b/tex/context/base/mkiv/m-oldotf.mkiv index 418d0bc2a..96554a75d 100644 --- a/tex/context/base/mkiv/m-oldotf.mkiv +++ b/tex/context/base/mkiv/m-oldotf.mkiv @@ -11,12 +11,6 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -% \endinput - -%D This module will go away as soon as we use the new loader code by default. -%D That will happen after extensive testing. Generic support will happen after -%D that. - \unprotect \startluacode diff --git a/tex/context/base/mkiv/math-frc.mkiv b/tex/context/base/mkiv/math-frc.mkiv index 785e8ea8e..16ea6e9e1 100644 --- a/tex/context/base/mkiv/math-frc.mkiv +++ b/tex/context/base/mkiv/math-frc.mkiv @@ -393,9 +393,6 @@ % $$ {{a}\abovewithdelims()#1pt{b}} $$ % } -% \unexpanded\def\dfrac #1#2{{\displaystyle {{#1}\normalover {#2}}}} -% \unexpanded\def\tfrac #1#2{{\textstyle {{#1}\normalover {#2}}}} - \definemathfraction[i:frac] [\c!alternative=\v!inner,\c!mathstyle=] % was script and then small but nothing needed \definemathfraction[i:tfrac][\c!alternative=\v!inner,\c!mathstyle=\s!text] % was script (before luatex fix) \definemathfraction[i:sfrac][\c!alternative=\v!inner,\c!mathstyle=\s!scriptscript] @@ -427,6 +424,25 @@ \unexpanded\def\sfrac{\csname\inlineordisplaymath id:sfrac\endcsname} \unexpanded\def\dfrac{\csname\inlineordisplaymath id:dfrac\endcsname} +\definemathfraction[ams] [\c!strut=\v!no,\c!alternative=\v!outer] +\definemathfraction[i:ams:frac][ams][\c!mathstyle={\s!cramped,\s!text}] +\definemathfraction[d:ams:frac][ams][\c!mathstyle={\s!cramped,\s!display}] + +\unexpanded\def\ctxfrac{\csname\inlineordisplaymath id:frac\endcsname} +\unexpanded\def\amsfrac{\csname\inlineordisplaymath id:ams:frac\endcsname} + +% \appendtoks +% \doifelse{\mathfractionparameter\c!option}{ams}% +% {\let\frac\amsfrac}% +% {\let\frac\ctxfrac}% +% \to \everysetupmathfraction + +\appendtoks + \doifelse{\mathematicsparameter\c!fractions}{ams}% + {\let\frac\amsfrac}% + {\let\frac\ctxfrac}% +\to \everysetupmathematics + % \definemathfraction[ddfrac][\c!mathstyle=\s!display] % \definemathfraction[ttfrac][\c!mathstyle=\s!text] % \definemathfraction[ssfrac][\c!mathstyle=\s!script] diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index a8f19c567..f4d0a01a9 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -6463,6 +6463,10 @@ return { }, }, ["constants"]={ + ["fractions"]={ + ["en"]="fractions", + ["nl"]="breuken", + }, ["action"]={ ["cs"]="akce", ["de"]="aktion", diff --git a/tex/context/base/mkiv/page-cst.lua b/tex/context/base/mkiv/page-cst.lua new file mode 100644 index 000000000..782bbebfc --- /dev/null +++ b/tex/context/base/mkiv/page-cst.lua @@ -0,0 +1,1454 @@ +if not modules then modules = { } end modules ["page-cst"] = { + version = 1.001, + comment = "companion to page-cst.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: check what is used + +local next, type = next, type +local ceil, floor, odd, round = math.ceil, math.floor, math.odd, math.round +local lower = string.lower +local copy = table.copy + +local trace_state = false trackers.register("columnsets.trace", function(v) trace_state = v end) +local trace_detail = false trackers.register("columnsets.detail", function(v) trace_detail = v end) +local trace_cells = false trackers.register("columnsets.cells", function(v) trace_cells = v end) + +local report = logs.reporter("column sets") + +local setmetatableindex = table.setmetatableindex + +local properties = nodes.properties + +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes +local rulecodes = nodes.rulecodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local insert_code = nodecodes.ins +local mark_code = nodecodes.mark +local rule_code = nodecodes.rule + +local topskip_code = gluecodes.topskip +local lineskip_code = gluecodes.lineskip +local baselineskip_code = gluecodes.baselineskip +local userskip_code = gluecodes.userskip + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local hpack = nuts.hpack +local vpack = nuts.vpack +local freenode = nuts.free +local flushlist = nuts.flush_list +local removenode = nuts.remove + +local getfield = nuts.getfield +local setfield = nuts.setfield +local setlink = nuts.setlink +local setlist = nuts.setlist +local setnext = nuts.setnext +local setprev = nuts.setprev +local setsubtype = nuts.setsubtype +local setbox = nuts.setbox + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getlist = nuts.getlist +local getsubtype = nuts.getsubtype +local takebox = nuts.takebox +local takelist = nuts.takelist +local splitbox = nuts.splitbox +local getskip = nuts.getskip +local getattribute = nuts.getattribute +local copylist = nuts.copy_list + +local getbox = nuts.getbox +local getcount = tex.getcount +local getdimen = tex.getdimen + +local texsetbox = tex.setbox +local texsetcount = tex.setcount +local texsetdimen = tex.setdimen + +local theprop = nuts.theprop + +local nodepool = nuts.pool + +local new_hlist = nodepool.hlist +local new_vlist = nodepool.vlist +local new_kern = nodepool.kern +local new_trace_rule = nodepool.rule +local new_empty_rule = nodepool.emptyrule + +local context = context +local implement = interfaces.implement + +local variables = interfaces.variables +local v_here = variables.here +local v_fixed = variables.fixed +local v_top = variables.top +local v_bottom = variables.bottom +local v_repeat = variables["repeat"] +local v_left = variables.left +local v_right = variables.right +local v_yes = variables.yes +local v_page = variables.page +local v_first = variables.first +local v_last = variables.last +local v_wide = variables.wide + +pagebuilders = pagebuilders or { } -- todo: pages.builders +pagebuilders.columnsets = pagebuilders.columnsets or { } +local columnsets = pagebuilders.columnsets + +local data = { [""] = { } } + +-- todo: use state + +local function setstate(t,start) + if start or not t.firstcolumn then + t.firstcolumn = odd(getcount("realpageno")) and 1 or 2 + end + if t.firstcolumn > 1 then + t.firstcolumn = 1 + t.lastcolumn = t.nofleft + t.state = "left" + else + t.firstcolumn = t.nofleft + 1 + t.lastcolumn = t.firstcolumn + t.nofright - 1 + t.state = "right" + end + t.currentcolumn = t.firstcolumn + t.currentrow = 1 +end + +function columnsets.define(t) + local name = t.name + local nofleft = t.nofleft or 1 + local nofright = t.nofright or 1 + local nofcolumns = nofleft + nofright + local dataset = data[name] or { } + data[name] = dataset + dataset.nofleft = nofleft + dataset.nofright = nofright + dataset.nofcolumns = nofcolumns + dataset.nofrows = t.nofrows or 1 + dataset.distance = t.distance or getdimen("bodyfontsize") + dataset.maxwidth = t.maxwidth or getdimen("makeupwidth") + dataset.lineheight = t.lineheight or getdimen("globalbodyfontstrutheight") + dataset.linedepth = t.linedepth or getdimen("globalbodyfontstrutdepth") + -- + dataset.cells = { } + dataset.currentcolumn = 1 + dataset.currentrow = 1 + -- + dataset.lines = dataset.lines or setmetatableindex("table") + dataset.start = dataset.start or setmetatableindex("table") + -- + dataset.page = 1 + -- + local distances = dataset.distances or setmetatableindex(function(t,k) + return dataset.distance + end) + dataset.distances = distances + -- + local widths = dataset.widths or setmetatableindex(function(t,k) + return dataset.width + end) + dataset.widths = widths + -- + local width = t.width + if not width or width == 0 then + local dl = 0 + local dr = 0 + for i=1,nofleft-1 do + dl = dl + distances[i] + end + for i=1,nofright-1 do + dr = dr + distances[nofleft+i] + end + local nl = nofleft + local nr = nofright + local wl = dataset.maxwidth + local wr = wl + for i=1,nofleft do + local w = rawget(widths,i) + if w then + nl = nl - 1 + wl = wl - w + end + end + for i=1,nofright do + local w = rawget(widths,nofleft+i) + if w then + nr = nr - 1 + wr = wr - w + end + end + dl = (wl - dl) / nl + dr = (wr - dr) / nr + if dl > dr then + report("using %s page column width %p in columnset %a","right",dr,name) + width = dr + elseif dl < dr then + report("using %s page column width %p in columnset %a","left",dl,name) + width = dl + else + width = dl + end + end + -- report("width %p, nleft %i, nright %i",width,nofleft,nofright) + width = round(width) + dataset.width = width + local spans = { } + dataset.spans = spans + for i=1,nofleft do + local s = { } + local d = 0 + for j=1,nofleft-i+1 do + d = d + width + s[j] = round(d) + d = d + distances[j] + end + spans[i] = s + end + for i=1,nofright do + local s = { } + local d = 0 + for j=1,nofright-i+1 do + d = d + width + s[j] = round(d) + d = d + distances[j] + end + spans[nofleft+i] = s + end + -- + local spreads = copy(spans) + dataset.spreads = spreads + local gap = 2 * getdimen("backspace") + for l=1,nofleft do + local s = spreads[l] + local n = #s + local o = s[n] + gap + for r=1,nofright do + n = n + 1 + s[n] = s[r] + o + end + end + -- + texsetdimen("d_page_grid_column_width",dataset.width) + -- + setstate(dataset,true) + -- + return dataset +end + +local function check(dataset) + local cells = dataset.cells + local page = dataset.page + local offset = odd(page) and dataset.nofleft or 0 + local start = dataset.start + local list = rawget(start,page) + if list then + for c, n in next, list do + local column = cells[offset + c] + if column then + for r=1,n do + column[r] = true + end + end + end + start[page] = nil + end + local lines = dataset.lines + local list = rawget(lines,page) + local rows = dataset.nofrows + if list then + for c, n in next, list do + local column = cells[offset + c] + if column then + if n > 0 then + for r=n+1,rows do + column[r] = true + end + elseif n < 0 then + for r=rows,rows+n+1,-1 do + column[r] = true + end + end + end + end + lines[page] = nil + end +end + +local function erase(dataset,all) + local cells = dataset.cells + local nofrows = dataset.nofrows + local first = 1 + local last = dataset.nofcolumns + -- + if not all then + first = dataset.firstcolumn or first + last = dataset.lastcolumn or last + end + for c=first,last do + local column = { } + for r=1,nofrows do + if column[r] then + report("slot (%i,%i) is not empty",c,r) + end + column[r] = false -- not used + end + cells[c] = column + end +end + +function columnsets.reset(t) + local dataset = columnsets.define(t) + erase(dataset,true) + check(dataset) +end + +function columnsets.prepareflush(name) + local dataset = data[name] + local cells = dataset.cells + local firstcolumn = dataset.firstcolumn + local lastcolumn = dataset.lastcolumn + local nofrows = dataset.nofrows + local lineheight = dataset.lineheight + local linedepth = dataset.linedepth + local widths = dataset.widths + local height = (lineheight+linedepth)*nofrows -- - linedepth + -- + local columns = { } + dataset.columns = columns + -- + for c=firstcolumn,lastcolumn do + local column = cells[c] + for r=1,nofrows do + local cell = column[r] + if (cell == false) or (cell == true) then + if trace_cells then + column[r] = new_trace_rule(65536*2,lineheight,linedepth) + else + column[r] = new_empty_rule(0,lineheight,linedepth) + end + end + end + for r=1,nofrows-1 do + setlink(column[r],column[r+1]) + end + local v = new_vlist(column[1]) + setfield(v,"height",height) +-- setfield(v,"depth",linedepth) + setfield(v,"width",widths[c]) + columns[c] = v + end + -- + texsetcount("c_page_grid_first_column",firstcolumn) + texsetcount("c_page_grid_last_column",lastcolumn) +end + +function columnsets.flushcolumn(name,column) + local dataset = data[name] + local columns = dataset.columns + local packed = columns[column] + setbox("b_page_grid_column",packed) + columns[column] = nil +end + +function columnsets.finishflush(name) + local dataset = data[name] + local cells = dataset.cells + local firstcolumn = dataset.firstcolumn + local lastcolumn = dataset.lastcolumn + local nofrows = dataset.nofrows + for c=firstcolumn,lastcolumn do + local column = { } + for r=1,nofrows do + column[r] = false -- not used + end + cells[c] = column + end + dataset.page = dataset.page + 1 + check(dataset) + setstate(dataset) +end + +function columnsets.block(t) + local dataset = data[t.name] + local cells = dataset.cells + local nofcolumns = dataset.nofcolumns + local nofrows = dataset.nofrows + -- + local c = t.c or 0 + local r = t.r or 0 + if c == 0 or r == 0 or c > nofcolumns or r > nofrows then + return + end + local nc = t.nc or 0 + local nr = t.nr or 0 + if nc == 0 then + return + end + if nr == 0 then + return + end + local rr = r + nr - 1 + local cc = c + nc - 1 + if rr > nofrows then + rr = nofrows + end + if cc > nofcolumns then + cc = nofcolumns + end + for i=c,cc do + local column = cells[i] + for j=r,rr do + column[j] = true + end + end +end + +local function here(c,r,nr,nofcolumns,nofrows,cells,width,spans) + local rr = r + nr - 1 + if rr > nofrows then + return false + end + local cc = 0 + local wd = spans[c] + local wc = 0 + local nc = 0 + for i=c,nofcolumns do + nc = nc + 1 + wc = wd[nc] + if not wc then + break + elseif wc >= width then + cc = i + break + end + end + if cc == 0 or cc > nofcolumns then + -- report("needed %p, no slot free at (%i,%i)",width,c,r) + return false + end + for i=c,cc do + local column = cells[i] + for j=r,rr do + if column[j] then + -- report("width %p, needed %p, checking (%i,%i) x (%i,%i), %s",width,wc,c,r,nc,nr,"quit") + return false + end + end + end + -- report("width %p, needed %p, checking (%i,%i) x (%i,%i), %s",width,wc,c,r,nc,nr,"match") + return c, r, nc +end + +local methods = { + [v_here] = here, + [v_fixed] = here, + tblr = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for j=1,nofrows-nr+1 do + for i=c,nofcolumns do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + lrtb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=1,nofrows-nr+1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + tbrl = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for j=1,nofrows-nr+1 do + for i=nofcolumns,c,-1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + rltb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=nofcolumns,c,-1 do + for j=1,nofrows-nr+1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + btlr = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for j=nofrows-nr+1,1,-1 do + for i=c,nofcolumns do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + lrbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=nofrows-nr+1,1,-1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + btrl = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for j=nofrows-nr+1,1,-1 do + for i=nofcolumns,c,-1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + rlbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=nofcolumns,c,-1 do + for j=nofrows-nr+1,1,-1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + fxtb = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=r,nofrows-nr+1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + r = 1 + end + end + end, + fxbt = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=nofrows-nr+1,r,-1 do + if not cells[i][j] then + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + r = 1 + end + end, + [v_top] = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=1,nofrows-nr+1 do + if cells[i][j] then + break + else + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, + [v_bottom] = function(c,r,nr,nofcolumns,nofrows,cells,width,spans) + for i=c,nofcolumns do + for j=1,nofrows-nr+1 do + if cells[i][j] then + break + else + local c, r, cc = here(i,j,nr,nofcolumns,nofrows,cells,width,spans) + if c then + return c, r, cc + end + end + end + end + end, +} + +local threshold = 50 + +function columnsets.check(t) + local dataset = data[t.name] + local cells = dataset.cells + local nofcolumns = dataset.nofcolumns + local nofrows = dataset.nofrows + local widths = dataset.widths + local lineheight = dataset.lineheight + local linedepth = dataset.linedepth + local distances = dataset.distances + local spans = dataset.spans + -- + local method = lower(t.method or "tblr") + local boxwidth = t.width or 0 + local boxheight = t.height or 0 + local boxnumber = t.box + local box = boxnumber and getbox(boxnumber) + -- + if boxwidth > 0 and boxheight > 0 then + -- we're ok + elseif box then + boxwidth = getfield(box,"width") + boxheight = getfield(box,"height") + getfield(box,"depth") + else + report("empty box") + return + end + -- + local c = t.c or 0 + local r = t.r or 0 + if c == 0 then + c = dataset.currentcolumn + end + if r == 0 then + r = dataset.currentrow + end + if c == 0 or r == 0 or c > nofcolumns or r > nofrows then + texsetcount("c_page_grid_reserved_state",5) + return + end +-- report("checking width %p, height %p, depth %p, slot (%i,%i)",boxwidth,boxheight,boxdepth,c,r) + local nr = ceil(boxheight/(lineheight+linedepth)) + -- + local action = methods[method] + local cfound = false + local rfound = false + local lastcolumn = dataset.lastcolumn + -- if t.option == v_wide then + -- lastcolumn = nofcolumns + -- spans = dataset.spreads + -- end + if action then + cfound, rfound, nc = action(c,r,nr,lastcolumn,nofrows,cells,boxwidth-threshold,spans) + end + if not cfound and method ~= v_here then + cfound, rfound, nc = here(c,r,nr,lastcolumn,nofrows,cells,boxwidth-threshold,spans) + end + if cfound then + local ht = nr*(lineheight+linedepth) + local wd = spans[cfound][nc] + dataset.reserved_ht = ht + dataset.reserved_wd = wd + dataset.reserved_c = cfound + dataset.reserved_r = rfound + dataset.reserved_nc = nc + dataset.reserved_nr = nr + texsetcount("c_page_grid_reserved_state",0) + texsetdimen("d_page_grid_reserved_height",ht) + texsetdimen("d_page_grid_reserved_width",wd) + -- report("using (%i,%i) x (%i,%i) @ (%p,%p)",cfound,rfound,nc,nr,wd,ht) + else + dataset.reserved_ht = false + dataset.reserved_wd = false + dataset.reserved_c = false + dataset.reserved_r = false + dataset.reserved_nc = false + dataset.reserved_nr = false + texsetcount("c_page_grid_reserved_state",4) + -- texsetdimen("d_page_grid_reserved_height",0) + -- texsetdimen("d_page_grid_reserved_width",0) + -- report("no slot found") + end +end + +function columnsets.put(t) + local dataset = data[t.name] + local cells = dataset.cells + local widths = dataset.widths + local lineheight = dataset.lineheight + local linedepth = dataset.linedepth + local boxnumber = t.box + local box = boxnumber and takebox(boxnumber) + -- + local c = t.c or dataset.reserved_c + local r = t.r or dataset.reserved_r + if not c or not r then + -- report("no reserved slot (%i,%i)",c,r) + return + end + local lastc = c + dataset.reserved_nc - 1 + local lastr = r + dataset.reserved_nr - 1 + -- + for i=c,lastc do + local column = cells[i] + for j=r,lastr do + column[j] = true + end + end + cells[c][r] = box + setfield(box,"height",lineheight) + setfield(box,"depth",linedepth) + setfield(box,"width",widths[c]) + dataset.reserved_c = false + dataset.reserved_r = false + dataset.reserved_nc = false + dataset.reserved_nr = false + -- +end + +local function findgap(dataset) + local cells = dataset.cells + local nofcolumns = dataset.nofcolumns + local nofrows = dataset.nofrows + local currentrow = dataset.currentrow + local currentcolumn = dataset.currentcolumn + -- + local foundc = 0 + local foundr = 0 + local foundn = 0 + for c=currentcolumn,dataset.lastcolumn do + local column = cells[c] +foundn = 0 + for r=currentrow,nofrows do + if not column[r] then + if foundc == 0 then + foundc = c + foundr = r + end + foundn = foundn + 1 + elseif foundn > 0 then + return foundc, foundr, foundn + end + end + if foundn > 0 then + return foundc, foundr, foundn + end + currentrow = 1 + end +end + +-- we can enforce grid snapping + +-- local function checkroom(head,available,row) +-- if row == 1 then +-- while head do +-- local id = getid(head) +-- if id == glue_code then +-- head = getnext(head) +-- else +-- break +-- end +-- end +-- end +-- local used = 0 +-- local line = false +-- while head do +-- local id = getid(head) +-- if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code +-- used = used + getfield(head,"height") + getfield(head,"depth") +-- line = true +-- elseif id == glue_code then +-- if line then +-- break +-- end +-- used = used + getfield(head,"width") +-- elseif id == kern_code then +-- used = used + getfield(head,"kern") +-- elseif id == penalty_code then +-- end +-- if used > available then +-- break +-- end +-- head = getnext(head) +-- end +-- return line, used +-- end + +local function checkroom(head,available,row) + if row == 1 then + while head do + local id = getid(head) + if id == glue_code then + head = getnext(head) + else + break + end + end + end + local used = 0 + local line = false + while head do + local id = getid(head) + if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code + used = used + getfield(head,"height") + getfield(head,"depth") + line = true + if used > available then + break + end + elseif id == glue_code then + if line then + break + end + used = used + getfield(head,"width") + if used > available then + break + end + elseif id == kern_code then + used = used + getfield(head,"kern") + if used > available then + break + end + elseif id == penalty_code then + -- not good enough ... we need to look bakck too + if getfield(head,"penalty") >= 10000 then + line = false + else + break + end + end + head = getnext(head) + end + return line, used +end + +-- we could preroll on a cheap copy .. in fact, a split loop normally works on +-- a copy ... then we could also stepsise make the height smaller .. slow but nice + +-- local function findslice(dataset,head,available,column,row) +-- local used = 0 +-- local first = nil +-- local last = nil +-- local line = false +-- local lineheight = dataset.lineheight +-- local linedepth = dataset.linedepth +-- if row == 1 then +-- while head do +-- local id = getid(head) +-- if id == glue_code then +-- head = removenode(head,head,true) +-- else +-- break +-- end +-- end +-- end +-- while head do +-- -- no direction yet, if so use backend code +-- local id = getid(head) +-- local hd = 0 +-- if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code +-- hd = getfield(head,"height") + getfield(head,"depth") +-- elseif id == glue_code then +-- hd = getfield(head,"width") +-- elseif id == kern_code then +-- hd = getfield(head,"kern") +-- elseif id == penalty_code then +-- end +-- if used + hd > available then +-- if first then +-- setnext(last) +-- setprev(head) +-- return used, first, head +-- else +-- return 0 +-- end +-- else +-- if not first then +-- first = head +-- end +-- used = used + hd +-- last = head +-- head = getnext(head) +-- end +-- end +-- return used, first +-- end + +-- todo +-- +-- first = takelist(done) +-- head = takelist(rest) +-- local tail = nuts.tail(first) +-- if false then +-- local disc = tex.lists.split_discards_head +-- if disc then +-- disc = tonut(disc) +-- setlink(tail,disc) +-- tail = nuts.tail(disc) +-- tex.lists.split_discards_head = nil +-- end +-- end +-- setlink(tail,head) + +-- We work on a copy because we need to keep properties. We can make faster copies +-- by only doing a one-level deep copy. + +local function findslice(dataset,head,available,column,row) + local first = nil + local lineheight = dataset.lineheight + local linedepth = dataset.linedepth + local linetotal = lineheight + linedepth + local slack = 65536 -- 1pt + local copy = copylist(head) + local attempts = 0 + local usedsize = available + while true do + attempts = attempts + 1 + texsetbox("scratchbox",tonode(new_vlist(copy))) + local done = splitbox("scratchbox",usedsize,"additional") + local used = getfield(done,"height") + local rest = takebox("scratchbox") + if used > (usedsize+slack) then + if trace_detail then + report("at (%i,%i) available %p, used %p, overflow %p",column,row,usedsize,used,used-usedsize) + end + -- flush copy + flushlist(takelist(done)) + flushlist(takelist(rest)) + -- check it we can try again + usedsize = usedsize - linetotal + if usedsize > linetotal then + copy = copylist(head) + else + return 0, nil, head + end + else + -- flush copied box + flushlist(takelist(done)) + flushlist(takelist(rest)) + -- deal with real data + texsetbox("scratchbox",tonode(new_vlist(head))) + done = splitbox("scratchbox",usedsize,"additional") + rest = takebox("scratchbox") + used = getfield(done,"height") + if attempts > 1 then + used = available + end + first = takelist(done) + head = takelist(rest) + -- return result + return used, first, head + end + end +end + +local nofcolumngaps = 0 + +function columnsets.add(name,box) + local dataset = data[name] + local cells = dataset.cells + local nofcolumns = dataset.nofcolumns + local nofrows = dataset.nofrows + local currentrow = dataset.currentrow + local currentcolumn = dataset.currentcolumn + local lineheight = dataset.lineheight + local linedepth = dataset.linedepth + local widths = dataset.widths + -- + local b = getbox(box) + local l = getlist(b) +-- dataset.rest = l + if l then + setlist(b,nil) + local hd = lineheight + linedepth + while l do + local foundc, foundr, foundn = findgap(dataset) + if foundc then + local available = foundn * hd + local used, first, last = findslice(dataset,l,available,foundc,foundr) + if first then + local v + if used == available or (foundr+foundn > nofrows) then + v = vpack(first,available,"exactly") + else + v = new_vlist(first) + end + nofcolumngaps = nofcolumngaps + 1 + -- getmetatable(v).columngap = nofcolumngaps + properties[v] = { columngap = nofcolumngaps } + -- report("setting gap %a at (%i,%i)",nofcolumngaps,foundc,foundr) + setfield(v,"height",lineheight) + setfield(v,"depth",linedepth) + setfield(v,"width",widths[currentcolumn]) + local column = cells[foundc] + -- + column[foundr] = v + used = used - hd + if used > 0 then + for r=foundr+1,foundr+foundn-1 do + used = used - hd + foundr = foundr + 1 + column[r] = true + if used <= 0 then + break + end + end + end + currentcolumn = foundc + currentrow = foundr + dataset.currentcolumn = currentcolumn + dataset.currentrow = currentrow + l = last + dataset.rest = l + else + local column = cells[foundc] + for i=foundr,foundr+foundn-1 do + column[i] = true + end + l = last + end + else + dataset.rest = l + return -- save and flush + end + end + end +end + +do + + -- A split approach is more efficient than a context(followup) inside + -- followup itself as we need less (internal) housekeeping. + + local followup = nil + local splitter = lpeg.splitter("*",tonumber) + + columnsets["noto"] = function(t) + return followup() + end + + columnsets["goto"] = function(name,target) + local dataset = data[name] + local nofcolumns = dataset.nofcolumns + if target == v_yes or target == "" then + local currentcolumn = dataset.currentcolumn + followup = function() + context(dataset.currentcolumn == currentcolumn and 1 or 0) + end + return followup() + end + if target == v_first then + if dataset.currentcolumn > 1 then + target = v_page + else + return context(0) + end + end + if target == v_page then + if dataset.currentcolumn == 1 and dataset.currentrow == 1 then + return context(0) + else + local currentpage = dataset.page + followup = function() + context(dataset.page == currentpage and 1 or 0) + end + return followup() + end + end + if target == v_last then + target = dataset.nofcolumns + if dataset.currentcolumn ~= target then + followup = function() + context(dataset.currentcolumn ~= target and 1 or 0) + end + return followup() + end + return + end + local targetpage = tonumber(target) + if targetpage then + followup = function() + context(dataset.currentcolumn ~= targetpage and 1 or 0) + end + return followup() + end + local targetcolumn, targetrow = lpeg.match(splitter,target) + if targetcolumn and targetrow then + if dataset.currentcolumn ~= targetcolumn and dataset.currentrow ~= targetrow then + followup = function() + if dataset.currentcolumn ~= targetcolumn then + context(1) + return + end + if dataset.currentcolumn == targetcolumn then + context(dataset.currentrow ~= targetrow and 1 or 0) + else + context(0) + end + end + return followup() + end + end + end + +end + +function columnsets.currentcolumn(name) + local dataset = data[name] + context(dataset.currentcolumn) +end + +function columnsets.flushrest(name,box) + local dataset = data[name] + local rest = dataset.rest + if rest then + dataset.rest = nil + setbox("global",box,new_vlist(rest)) + end +end + +function columnsets.setvsize(name) + local dataset = data[name] + local c, r, n = findgap(dataset) + if n then + dataset.currentcolumn = c + dataset.currentrow = r + else + dataset.currentcolumn = 1 + dataset.currentrow = 1 + n = 0 + end + local gap = n*(dataset.lineheight+dataset.linedepth) + texsetdimen("d_page_grid_gap_height",gap) + -- can be integrated + -- report("state %a, n %a, column %a, row %a",dataset.state,n,dataset.currentcolumn,dataset.currentrow) +end + +function columnsets.sethsize(name) + local dataset = data[name] + texsetdimen("d_page_grid_column_width",dataset.widths[dataset.currentcolumn]) +end + +function columnsets.sethspan(name,span) + -- no checking if there is really space, so we assume it can be + -- placed which makes spans a very explicit feature + local dataset = data[name] + local column = dataset.currentcolumn + local available = dataset.lastcolumn - column + 1 + if span > available then + span = available + end + local width = dataset.spans[column][span] + texsetdimen("d_page_grid_span_width",width) +end + +function columnsets.setlines(t) + local dataset = data[t.name] + dataset.lines[t.page][t.column] = t.value +end + +function columnsets.setstart(t) + local dataset = data[t.name] + dataset.start[t.page][t.column] = t.value +end + +function columnsets.setproperties(t) + local dataset = data[t.name] + local column = t.column + dataset.distances[column] = t.distance + dataset.widths[column] = t.width +end + +local areas = { } + +function columnsets.registerarea(t) + -- maybe metatable with values + areas[#areas+1] = t +end + +-- state : repeat | start + +local ctx_page_grid_set_area = context.protected.page_grid_set_area + +function columnsets.flushareas(name) + local nofareas = #areas + if nofareas == 0 then + return + end + local dataset = data[name] + local page = dataset.page + if odd(page) then + -- report("checking %i areas",#areas) + local kept = { } + for i=1,nofareas do + local area = areas[i] + -- local page = area.page -- maybe use page counter in columnset + -- local type = area.type + local okay = false + -- + local nofcolumns = area.nc + local nofrows = area.nr + local column = area.c + local row = area.r + columnsets.block { + name = name, + c = column, + r = row, + nc = nofcolumns, + nr = nofrows, + } + local left = 0 + local start = dataset.nofleft + 1 + local overflow = (column + nofcolumns - 1) - dataset.nofleft + local height = nofrows * (dataset.lineheight + dataset.linedepth) + local width = dataset.spreads[column][nofcolumns] + -- report("span, width %p, overflow %i",width,overflow) + if overflow > 0 then + local used = nofcolumns - overflow + left = dataset.spreads[column][used] + getdimen("backspace") + end + ctx_page_grid_set_area(name,area.name,column,row,width,height,start,left) -- or via counters / dimens + if area.state ~= v_repeat then + area = nil + end + if area then + kept[#kept+1] = area + end + end + areas = kept + end +end + +function columnsets.setarea(t) + local dataset = data[t.name] + local cells = dataset.cells + local box = takebox(t.box) + local column = t.c + local row = t.r + if column and row then + setfield(box,"height",dataset.lineheight) + setfield(box,"depth",dataset.linedepth) + setfield(box,"width",dataset.widths[column]) + cells[column][row] = box + end +end + +-- The interface. + +interfaces.implement { + name = "definecolumnset", + actions = columnsets.define, + arguments = { { + { "name", "string" }, + } } +} + +interfaces.implement { + name = "resetcolumnset", + actions = columnsets.reset, + arguments = { { + { "name", "string" }, + { "nofleft", "integer" }, + { "nofright", "integer" }, + { "nofrows", "integer" }, + { "lineheight", "dimension" }, + { "linedepth", "dimension" }, + { "width", "dimension" }, + { "distance", "dimension" }, + { "maxwidth", "dimension" }, + } } +} + +interfaces.implement { + name = "preparecolumnsetflush", + actions = columnsets.prepareflush, + arguments = { "string" }, +} + +interfaces.implement { + name = "finishcolumnsetflush", + actions = columnsets.finishflush, + arguments = { "string" }, +} + +interfaces.implement { + name = "flushcolumnsetcolumn", + actions = columnsets.flushcolumn, + arguments = { "string" ,"integer" }, +} + +interfaces.implement { + name = "setvsizecolumnset", + actions = columnsets.setvsize, + arguments = { "string" }, +} + +interfaces.implement { + name = "sethsizecolumnset", + actions = columnsets.sethsize, + arguments = { "string" }, +} + +interfaces.implement { + name = "sethsizecolumnspan", + actions = columnsets.sethspan, + arguments = { "string" ,"integer" }, +} + +interfaces.implement { + name = "flushcolumnsetrest", + actions = columnsets.flushrest, + arguments = { "string", "integer" }, +} + +interfaces.implement { + name = "blockcolumnset", + actions = columnsets.block, + arguments = { { + { "name", "string" }, + { "c", "integer" }, + { "r", "integer" }, + { "nc", "integer" }, + { "nr", "integer" }, + { "box", "integer" }, + } } +} + +interfaces.implement { + name = "checkcolumnset", + actions = columnsets.check, + arguments = { { + { "name", "string" }, + { "method", "string" }, + { "c", "integer" }, + { "r", "integer" }, + { "box", "integer" }, + { "width", "dimension" }, + { "height", "dimension" }, + { "option", "string" }, + } } +} + +interfaces.implement { + name = "putincolumnset", + actions = columnsets.put, + arguments = { { + { "name", "string" }, + { "c", "integer" }, + { "r", "integer" }, + { "box", "integer" }, + } } +} + +interfaces.implement { + name = "addtocolumnset", + actions = columnsets.add, + arguments = { "string", "integer" }, +} + +interfaces.implement { + name = "setcolumnsetlines", + actions = columnsets.setlines, + arguments = { { + { "name", "string" }, + { "page", "integer" }, + { "column", "integer" }, + { "value", "integer" }, + } } +} + +interfaces.implement { + name = "setcolumnsetstart", + actions = columnsets.setstart, + arguments = { { + { "name", "string" }, + { "page", "integer" }, + { "column", "integer" }, + { "value", "integer" }, + } } +} + +interfaces.implement { + name = "setcolumnsetproperties", + actions = columnsets.setproperties, + arguments = { { + { "name", "string" }, + { "column", "integer" }, + { "distance", "dimension" }, + { "width", "dimension" }, + } } +} + +interfaces.implement { + name = "registercolumnsetarea", + actions = columnsets.registerarea, + arguments = { { + { "name", "string" }, + { "type", "string" }, + { "page", "integer" }, + { "state", "string" }, + { "c", "integer" }, + { "r", "integer" }, + { "nc", "integer" }, + { "nr", "integer" }, + } } +} + +interfaces.implement { + name = "flushcolumnsetareas", + actions = columnsets.flushareas, + arguments = "string", +} + +interfaces.implement { + name = "setcolumnsetarea", + actions = columnsets.setarea, + arguments = { { + { "name", "string" }, + { "c", "integer" }, + { "r", "integer" }, + { "box", "integer" }, + } } +} + +interfaces.implement { + name = "columnsetgoto", + actions = columnsets["goto"], + arguments = { "string" , "string" }, +} + +interfaces.implement { + name = "columnsetnoto", + actions = columnsets["noto"], +} + +interfaces.implement { + name = "columnsetcurrentcolumn", + actions = columnsets.currentcolumn, + arguments = "string", +} diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv new file mode 100644 index 000000000..4559ec33f --- /dev/null +++ b/tex/context/base/mkiv/page-cst.mkiv @@ -0,0 +1,778 @@ +%D \module +%D [ file=page-cst, +%D version=2016.12.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Page Grids (aka Column Sets), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo : markings per column + +%D This module is work in progress and in due time it will replace +%D columnsets. + +\writestatus{loading}{ConTeXt Page Macros / Page Grids} + +\registerctxluafile{page-cst}{1.001} + +\unprotect + +% maybe some protected def ([esc]) + +%D Columnsets are kind of special. They are mostly meant for special products with +%D magazine like properties. They are normally not mixed with single column layouts +%D and not all features of \CONTEXT\ might cooperate well with a mechanism like +%D this. We use the name page grid because (as with other reimplementations of +%D \MKII\ features in \MKIV, we need another namespace in order to migrate stepwise. +%D +%D This implementation is not neccessarily better than the previous one but it might +%D be easier to extend it. It should be a bit more efficient. +%D +%D When writing this code I occasionally needed a motivational musical time||out and +%D watching the latest Snarky Puppy DVD brought me the musically and visually videos +%D of Jacob Collier (Piano, voice, anything) on YouTube (and yes, music keeps amazing +%D me). It's definitely more fun to watch that than to write code like this. + +\definesystemconstant{pagegrid} + +\installcorenamespace{pagegrid} + +\installframedcommandhandler \??pagegrid {pagegrid} \??pagegrid + +\setuppagegrid + [\c!distance=1.5\bodyfontsize, + \c!n=\plustwo, + \c!nleft=\pagegridparameter\c!n, + \c!nright=\pagegridparameter\c!n, + %\c!align=, % inherit + %\c!separator=\v!none, + %\c!setups=, + \c!lines=\layoutparameter\c!lines, + \c!frame=\v!off, + \c!strut=\v!no, + \c!offset=\v!overlay, + \c!alternative=\v!local, + \c!width=\v!auto, + \c!page=, + \c!direction=\v!normal, % todo + \c!maxheight=\textheight, + \c!maxwidth=\makeupwidth] + +\appendtoks % could become an option + \setuevalue{\e!start\currentpagegrid}{\startpagegrid[\currentpagegrid]}% + \setuevalue{\e!stop \currentpagegrid}{\stoppagegrid}% + \clf_definecolumnset { + name {\currentpagegrid}% + }% +\to \everydefinepagegrid + +\newdimen \d_page_grid_column_width +\newdimen \d_page_grid_max_height +\newdimen \d_page_grid_max_width +\newdimen \d_page_grid_distance + +\newdimen \d_page_grid_reserved_height +\newdimen \d_page_grid_reserved_width +\newcount \c_page_grid_reserved_state + +\newdimen \d_page_grid_gap_height + +\newcount \c_page_grid_n_of_left +\newcount \c_page_grid_n_of_right +\newcount \c_page_grid_n_of_rows +\newcount \c_page_grid_first_column +\newcount \c_page_grid_last_column + +\newbox \b_page_grid_collected +\newbox \b_page_grid_column_rest +\newbox \b_page_grid_column + +\unexpanded\def\setuppagegridlines{\doquadrupleempty\page_grid_setup_lines} +\unexpanded\def\setuppagegridstart{\doquadrupleempty\page_grid_setup_start} + +\def\page_grid_setup_lines[#1][#2][#3][#4]% id page col value + {\clf_setcolumnsetlines{name {#1} page #2 column #3 value #4}} + +\def\page_grid_setup_start[#1][#2][#3][#4]% id page col value + {\clf_setcolumnsetstart{name {#1} page #2 column #3 value #4}} + +\unexpanded\def\page_grid_check + {\dorecurse{\numexpr\pagegridparameter\c!nleft+\pagegridparameter\c!nright} + {\page_grid_check_column{##1}}} + +\unexpanded\def\page_grid_check_column#1% + {\chaintocurrentpagegrid{\currentpagegrid:#1}% + \edef\p_distance{\namedpagegridparameter{\currentpagegrid:#1}\c!distance}% + \edef\p_width {\namedpagegridparameter{\currentpagegrid:#1}\c!width}% + \clf_setcolumnsetproperties {% + name {\currentpagegrid} + column \numexpr#1\relax + \ifx\p_distance\empty\else + distance \p_distance + \fi + \ifx\p_width\empty\else\ifx\p_width\v!auto\else + width \p_width + \fi\fi + }} + +\appendtoks + \dorecurse{\numexpr\pagegridparameter\c!nleft+\pagegridparameter\c!nright} + {\chaintocurrentpagegrid{\currentpagegrid:#1}}% +\to \everydefinepagegrid + +\unexpanded\def\startpagegrid + {\bgroup + \dodoubleempty\page_grid_start} + +\def\page_grid_start_dummy[#1][#2]% + {\let\page_grid_stop\egroup} + +\def\page_grid_start[#1][#2]% + {\let\page_grid_start\page_grid_start_dummy + \ifsecondargument + \edef\currentpagegrid{#1}% + \setupcurrentpagegrid[#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\let\currentpagegrid\empty + \setupcurrentpagegrid[#1]}% + {\def\currentpagegrid{#1}}% + \else + \let\currentpagegrid\empty + \fi\fi + \usepageparameter\pagegridparameter + \c_page_grid_n_of_left \pagegridparameter\c!nleft\relax + \c_page_grid_n_of_right\pagegridparameter\c!nright\relax + \c_page_grid_n_of_rows \pagegridparameter\c!lines\relax + \d_page_grid_max_width \pagegridparameter\c!maxwidth\relax + \d_page_grid_max_height\pagegridparameter\c!maxheight\relax + \d_page_grid_distance \pagegridparameter\c!distance\relax + % + \ifcase\c_page_grid_n_of_rows + \getrawnoflines{\dimexpr\d_page_grid_max_height-\strutheight+\topskip\relax}% + \c_page_grid_n_of_rows\noflines + \fi + \edef\p_width{\pagegridparameter\c!width}% + \insidecolumnstrue % will be different flag in addition + \clf_resetcolumnset { + name {\currentpagegrid} + nofrows \c_page_grid_n_of_rows + nofleft \c_page_grid_n_of_left + nofright \c_page_grid_n_of_right + lineheight \strutht + linedepth \strutdp + \ifx\p_width\v!auto + % sets \d_page_grid_column_width + \else + width \p_width + \fi + distance \d_page_grid_distance + maxwidth \d_page_grid_max_width + }% + % + \page_grid_check + % + \clf_flushcolumnsetareas{\currentpagegrid}\relax + \setupoutputroutine[\s!pagegrid]% + \page_grid_command_set_hsize + \page_grid_command_set_vsize + }%\begingroup} + +\unexpanded\def\stoppagegrid + {\page_grid_stop} + +\def\page_grid_stop + {\endgraf % needed, else wrong vsize in one par case + \vfill % otherwise weird \placenotes[endnotes] + \page_otr_command_set_vsize % needed + \penalty\c_page_otr_eject_penalty + \page_grid_command_flush_page + \page_otr_fill_and_eject_page + \page_otr_command_set_vsize % needed + \egroup + \page_otr_command_set_vsize + \page_otr_command_set_hsize} + +\unexpanded\def\reservepagegrid[#1]% + {\begingroup + \letdummyparameter\c!c\plusone + \letdummyparameter\c!r\plusone + \letdummyparameter\c!nc\plusone + \letdummyparameter\c!nr\plusone + \getdummyparameters[#1]% + \clf_blockcolumnset { + name {\currentpagegrid} + c \dummyparameter\c!c + r \dummyparameter\c!r + nc \dummyparameter\c!nc + nr \dummyparameter\c!nr + }% + \endgroup} + +\unexpanded\def\setpagegrid + {\dosingleempty\page_grid_set} + +\unexpanded\def\page_grid_set[#1]% + {\begingroup + \letdummyparameter\c!c\zerocount + \letdummyparameter\c!r\zerocount + \letdummyparameter\c!option\v!none + \getdummyparameters[#1]% + \dowithnextboxcs\page_grid_set_indeed\hbox} + +\def\page_grid_set_indeed + {\clf_checkcolumnset { + name {\currentpagegrid} + c \dummyparameter\c!c + r \dummyparameter\c!r + box \nextbox + option {\dummyparameter\c!option} + }% + \ifcase\c_page_grid_reserved_state + \setbox\nextbox\vpack to \d_page_grid_reserved_height \bgroup + \vss + \hpack to \d_page_grid_reserved_width \bgroup + \box\nextbox + \hss + \egroup + \vss + \egroup + \wd\nextbox\d_page_grid_reserved_width + \clf_putincolumnset { + name {\currentpagegrid} + box \nextbox + }% + \fi + \endgroup} + +\unexpanded\def\page_grid_command_set_vsize + {\clf_setvsizecolumnset{\currentpagegrid}% + \ifdim\d_page_grid_gap_height<\lineheight + \page_grid_command_flush_page + \page_otr_fill_and_eject_page + \fi + \global\vsize\d_page_grid_gap_height + \pagegoal\vsize} + +\unexpanded\def\page_grid_command_set_hsize + {\clf_sethsizecolumnset{\currentpagegrid}% + \hsize\d_page_grid_column_width + \textwidth\d_page_grid_column_width} + +\unexpanded\def\page_grid_command_routine + {\ifvoid\normalpagebox \else + \clf_addtocolumnset{\currentpagegrid}\normalpagebox + \fi + \page_grid_command_set_vsize + \page_grid_command_flush_saved_floats + \page_grid_command_set_vsize + \ifdim\d_page_grid_gap_height<\lineheight + \page_grid_command_flush_page + \fi + \page_grid_command_set_vsize + \clf_flushcolumnsetrest {\currentpagegrid}\normalpagebox + \ifvoid\normalpagebox \else + \unvbox\normalpagebox + \fi} + +\installoutputroutine\synchronizepagegrid + {\ifvoid\normalpagebox\else + \clf_addtocolumnset{\currentpagegrid}\normalpagebox + \page_grid_command_set_vsize + \clf_flushcolumnsetrest{\currentpagegrid}\normalpagebox + \ifvoid\normalpagebox \else + \unvbox\normalpagebox + \fi + \fi} + +% todo line numbers and marks + +\unexpanded\def\page_grid_command_flush_page_column#1% + {\scratchcounter#1\relax + \clf_flushcolumnsetcolumn{\currentpagegrid}\scratchcounter + \anch_mark_column_box\b_page_grid_column + \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\scratchcounter\b_page_grid_column + \ifnum\scratchcounter>\c_page_grid_n_of_left + \advance\scratchcounter-\c_page_grid_n_of_left + \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_right\plustwo + \else + \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_left\plustwo + \fi + \begingroup + \edef\currentpagegrid{\currentpagegrid:#1}% + \inheritedpagegridframedbox\box\b_page_grid_column + \endgroup} + +\unexpanded\def\page_grid_command_flush_page + {\deactivatecolor % puzzling, try ungrouped color \red or so + \setbox\b_page_grid_collected\hpack\bgroup + \clf_preparecolumnsetflush{\currentpagegrid}% + \letpagegridparameter\c!region\currentpagegrid + \doifelse{\pagegridparameter\c!direction}\v!reverse + {\dostepwiserecurse\c_page_grid_last_column\c_page_grid_first_column\minusone + {\page_grid_command_flush_page_column{##1}% + \ifnum##1>\plusone + \kern\namedpagegridparameter{\currentpagegrid:##1}\c!distance\relax + \fi}}% + {\dostepwiserecurse\c_page_grid_first_column\c_page_grid_last_column\plusone + {\page_grid_command_flush_page_column{##1}% + \ifnum##1<\c_page_grid_last_column + \kern\namedpagegridparameter{\currentpagegrid:##1}\c!distance\relax + \fi}}% + \clf_finishcolumnsetflush{\currentpagegrid}% + \egroup + \page_otr_construct_and_shipout\box\b_page_grid_collected + \clf_flushcolumnsetareas{\currentpagegrid}\relax + \page_grid_command_flush_saved_floats} + +% slow but robust + +\unexpanded\def\page_grid_command_next_progress + {\strut + \page_otr_flush_all_floats + \page_otr_eject_page + \ifcase\clf_columnsetnoto\else + \expandafter\page_grid_command_next_progress + \fi} + +\unexpanded\def\page_grid_command_handle_column + {\ifcase\clf_columnsetgoto{\currentpagegrid}{\page_breaks_columns_current_option}\relax\else + \expandafter\page_grid_command_next_progress + \fi} + +\installcolumnbreakmethod\s!pagegrid\s!unknown {\page_grid_command_handle_column} +\installcolumnbreakmethod\s!pagegrid\v!yes {\page_grid_command_handle_column} + +\unexpanded\def\page_grid_command_next_page + {\ifcase\clf_columnsetgoto{\currentpagegrid}{\v!page}\relax\else + \page_grid_command_flush_page + \fi} + +\unexpanded\def\page_grid_command_next_page_and_inserts +% {\page_otr_eject_page_and_flush_inserts} + {\page_otr_flush_all_floats + \page_grid_command_next_page} + +\let\page_grid_command_package_contents\page_one_command_package_contents + +\unexpanded\def\page_grid_command_flush_saved_floats + {\ifconditional\c_page_floats_flushing \else + \ifconditional\c_page_floats_some_waiting + \page_grid_command_flush_saved_floats_indeed + \fi + \fi} + +\unexpanded\def\page_grid_command_flush_saved_floats_indeed + {\page_floats_flush\s!text\plusone + \clf_checkcolumnset { + name {\currentpagegrid} + method {\floatmethod} + width \wd\floatbox + height \ht\floatbox + }% + \ifcase\c_page_grid_reserved_state + \page_grid_place_float_here_indeed + \page_grid_command_set_vsize % needed + \ifconditional\c_page_floats_some_waiting + \doubleexpandafter\page_grid_command_flush_saved_floats_indeed + \fi + \else + \page_floats_resave\s!text + \fi} + +% needs checking + +\unexpanded\def\page_grid_command_flush_floats + {\wait\global\settrue\c_page_floats_flushing + \ifconditional\c_page_floats_some_waiting + \par + \page_grid_command_flush_floats_indeed + \fi + \global\savednoffloats\zerocount + \global\setfalse\c_page_floats_some_waiting + \global\setfalse\c_page_floats_flushing} + +\def\page_grid_command_flush_floats_indeed % much in common with OTRSET + {\wait\ifconditional\c_page_floats_some_waiting + \ifconditional\c_page_floats_pack_flushed + \setfalse\c_page_floats_center_box % not needed as we do call directly + \page_floats_collect\s!text\hsize\emwidth + \global\setbox\floatbox\hbox to \hsize + {\hfil + \dorecurse\nofcollectedfloats + {\ifcase\columndirection % nog document wide + \page_floats_flush\s!text\plusone + \else + \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}% + \fi + \ifdim\wd\floatbox>\makeupwidth % \hsize + \hbox to \makeupwidth{\hss\box\floatbox\hss}% + \else + \box\floatbox + \fi + \ifnum\recurselevel<\nofcollectedfloats + \hfil + \fi}% + \hfil}% + \else + \page_floats_get + \fi + \doplacefloatbox + \expandafter\page_grid_command_flush_floats_indeed + \fi} + +% so far + +\unexpanded\def\page_grid_command_check_if_float_fits + {\clf_checkcolumnset { + name {\currentpagegrid} + method {\floatmethod} + % c \zerocount + % r \zerocount + box \floatbox + }% + \ifcase\c_page_grid_reserved_state + \global\settrue\c_page_floats_room + \else + \global\setfalse\c_page_floats_room + \fi} + +\unexpanded\def\page_grid_place_float_here_indeed + {\setbox\floatbox\vpack to \d_page_grid_reserved_height \bgroup + \vss + \hpack to \d_page_grid_reserved_width \bgroup + % \hss % no + \box\floatbox + \hss + \egroup + \vss + \egroup + \clf_putincolumnset { + name {\currentpagegrid} + box \floatbox + }} + +\def\page_grid_place_float_slot + {% safeguard + \ifx\floatmethod\empty + \let\floatmethod\v!here + \fi + % synchronize + \penalty\c_page_otr_eject_penalty + % push + \setbox\savedfloatbox\box\floatbox + \page_grid_command_flush_saved_floats + \setbox\floatbox\box\savedfloatbox + % pop + \ifconditional\c_page_floats_some_waiting + \page_floats_save\s!text + \nonoindentation + \else + \clf_checkcolumnset { + name {\currentpagegrid} + method {\floatmethod} + \ifx\floatcolumn\empty \else + c \floatcolumn + \fi + \ifx\floatrow\empty \else + r \floatrow + \fi + box \floatbox + }% + \ifcase\c_page_grid_reserved_state + \page_grid_place_float_here_indeed + \else + \page_floats_save\s!text + \nonoindentation + \fi + \fi} + +\def\page_grid_place_float_fixed % todo: fallback on here + {\ifx\floatcolumn\empty + \let\floatmethod\v!here + \else\ifx\floatrow\empty + \let\floatmethod\v!here + \else + \let\floatmethod\v!fixed + \fi\fi + \page_grid_place_float_slot} + +\def\page_grid_place_float_force + {% synchronize + \penalty\c_page_otr_eject_penalty + \clf_checkcolumnset { + name {\currentpagegrid} + method {\floatmethod} + box \floatbox + }% + \ifcase\c_page_grid_reserved_state + \page_grid_place_float_here_indeed + \else + \page_floats_save\s!text + \nonoindentation + \fi} + +\def\page_grid_place_float_page {\page_grid_place_float_slot} % todo: fallback on here + +\def\page_grid_place_float_here {\let\floatmethod\v!here\page_grid_place_float_slot} +\def\page_grid_place_float_top {\page_grid_place_float_slot} +\def\page_grid_place_float_bottom{\page_grid_place_float_slot} + +\installfloatmethod \s!pagegrid \v!here \page_grid_place_float_here +\installfloatmethod \s!pagegrid \v!force \page_grid_place_float_force % todo +%installfloatmethod \s!pagegrid \v!left +%installfloatmethod \s!pagegrid \v!right +%installfloatmethod \s!pagegrid \v!text +\installfloatmethod \s!pagegrid \v!top \page_grid_place_float_top +\installfloatmethod \s!pagegrid \v!bottom \page_grid_place_float_bottom +%installfloatmethod \s!pagegrid \v!auto +%installfloatmethod \s!pagegrid \v!margin +%installfloatmethod \s!pagegrid \v!opposite +\installfloatmethod \s!pagegrid \v!page \page_grid_place_float_page +%installfloatmethod \s!pagegrid \v!leftpage +%installfloatmethod \s!pagegrid \v!rightpage +%installfloatmethod \s!pagegrid \v!inmargin +%installfloatmethod \s!pagegrid \v!inleft +%installfloatmethod \s!pagegrid \v!inright +%installfloatmethod \s!pagegrid \v!leftmargin +%installfloatmethod \s!pagegrid \v!rightmargin +%installfloatmethod \s!pagegrid \v!leftedge +%installfloatmethod \s!pagegrid \v!rightedge +%installfloatmethod \s!pagegrid \v!somewhere +%installfloatmethod \s!pagegrid \v!backspace +%installfloatmethod \s!pagegrid \v!cutspace +\installfloatmethod \s!pagegrid \s!tblr \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!lrtb \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!tbrl \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!rltb \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!fxtb \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!btlr \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!lrbt \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!btrl \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!rlbt \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!fxbt \page_grid_place_float_slot +\installfloatmethod \s!pagegrid \s!fixd \page_grid_place_float_fixed + +% + +\unexpanded\def\page_grid_command_side_float_output + {} % nothing, reset anyway + +\unexpanded\def\page_grid_command_flush_side_floats + {\page_sides_forget_floats} + +\unexpanded\def\page_grid_command_synchronize_side_floats + {\page_sides_forget_floats} + +\unexpanded\def\page_grid_command_synchronize_hsize + {\page_grid_command_set_hsize} + +\defineoutputroutine + [\s!pagegrid] + [\s!page_otr_command_routine =\page_grid_command_routine, + \s!page_otr_command_package_contents =\page_grid_command_package_contents, + \s!page_otr_command_set_vsize =\page_grid_command_set_vsize, + \s!page_otr_command_set_hsize =\page_grid_command_set_hsize, % tricky, goes wrong + \s!page_otr_command_next_page =\page_grid_command_next_page, + \s!page_otr_command_next_page_and_inserts =\page_grid_command_next_page_and_inserts, + \s!page_otr_command_synchronize_hsize =\page_grid_command_synchronize_hsize, + % \s!page_otr_command_set_top_insertions =\page_grid_command_set_top_insertions, + % \s!page_otr_command_set_bottom_insertions =\page_grid_command_set_bottom_insertions, + % \s!page_otr_command_flush_top_insertions =\page_grid_command_flush_top_insertions, + % \s!page_otr_command_flush_bottom_insertions =\page_grid_command_flush_bottom_insertions, + % \s!page_otr_command_set_float_hsize =\page_grid_command_set_float_hsize, + \s!page_otr_command_check_if_float_fits =\page_grid_command_check_if_float_fits, + % \s!page_otr_command_flush_float_box =\page_grid_command_flush_float_box, + \s!page_otr_command_synchronize_side_floats =\page_grid_command_synchronize_side_floats, + \s!page_otr_command_side_float_output =\page_grid_command_side_float_output, + \s!page_otr_command_flush_floats =\page_grid_command_flush_floats, + \s!page_otr_command_flush_side_floats =\page_grid_command_flush_side_floats, + \s!page_otr_command_flush_saved_floats =\page_grid_command_flush_saved_floats + % \s!page_otr_command_flush_margin_blocks =\page_grid_command_flush_margin_blocks, % not used + ] + +% spans + +\installcorenamespace{pagegridspan} + +\installframedcommandhandler \??pagegridspan {pagegridspan} \??pagegridspan + +\setuppagegridspan + [\c!frame=\v!off, + \c!before=, + \c!after=, + \c!offset=\v!overlay, + \c!location=\v!left, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + \c!n=\plustwo, + \c!nlines=\zerocount, + \c!align=\v!normal, + \c!width=\d_page_grid_span_width, + \c!indenting=, + \c!indentnext=\v!yes, + \c!default=\v!here, + \c!alternative=\v!a] + +\newdimen\d_page_grid_span_width + +\unexpanded\def\startpagegridspan + {\dotripleempty\page_grid_span_start} + +\def\page_grid_span_start[#1][#2][#3]% [#3] gobbles space + {\endgraf % else rubish output if forgotten + \synchronizepagegrid + \bgroup + \forgetall + \edef\currentpagegridspan{#1}% + \clf_sethsizecolumnspan{\currentpagegrid}\pagegridspanparameter\c!n\relax + \setbox\scratchbox\hbox\bgroup\inheritedpagegridspanframed\bgroup + \usepagegridspanstyleandcolor\c!style\c!color + \pagegridspanparameter\c!before + \ignorespaces} + +\unexpanded\def\stoppagegridspan + {\removeunwantedspaces + \par + \verticalstrut + \kern-2\struttotal + \verticalstrut + \endgraf + \pagegridspanparameter\c!after + \egroup\egroup + \setpagegrid{\box\scratchbox}% + % todo: push into slot + \egroup + \endgraf} + +\def\pagegridspanwidth#1% assumes equal distances + {\the\dimexpr + #1\d_page_grid_column_width + +#1\d_page_grid_distance + - \d_page_grid_distance + \relax} + +% areas + +\installcorenamespace{pagegridarea} + +\installframedcommandhandler \??pagegridarea {pagegridarea} \??pagegridarea + +\setuppagegridarea + [\c!x=\plusone, + \c!y=\plusone, + \c!nx=\plusone, + \c!ny=\plusone, + \c!clipoffset=2\lineheight, + \c!leftoffset=\zeropoint, + \c!rightoffset=\zeropoint, + \c!offset=\v!overlay, + \c!strut=\v!no, + \c!frame=\v!off, + %\c!type=\v!next, + \c!align=\v!normal, + \c!page=\plusone, + \c!state=\v!stop] + +% type: both fixed left right next (not now), then better +% lefttext and righttext or so + +\appendtoks + % \edef\p_type{}% + % \ifx\p_type\v!next + % \doifelseoddpage + % {\letpagegridareaparameter\c!type\v!right}% + % {\letpagegridareaparameter\c!type\v!left}% + % \fi + \clf_registercolumnsetarea { + name {\currentpagegridarea} + % type {\p_type} + % page \pagegridareaparameter\c!page + state {\pagegridareaparameter\c!state} + c \pagegridareaparameter\c!x + r \pagegridareaparameter\c!y + nc \pagegridareaparameter\c!nx + nr \pagegridareaparameter\c!ny + }% +\to \everydefinepagegridarea + +\unexpanded\def\setuppagegridareatext + {\dodoubleargument\page_grid_set_area_text} + +\def\page_grid_set_area_text[#1][#2]% + {\edef\currentpagegridarea{#1}% + \setpagegridareaparameter\c!text{#2}} + +% maybe move the left/right correction to the tex end or the offset to lua + +\unexpanded\def\page_grid_set_area#1#2#3#4#5#6#7#8% can be optimized + {\begingroup + \edef\currentpagegridarea{#2}% + \setpagegridareaparameter\c!width {#5\scaledpoint}% + \setpagegridareaparameter\c!height{#6\scaledpoint}% + \setbox\nextbox\hpack\bgroup\inheritedpagegridareaframed\bgroup + \usepagegridareastyleandcolor\c!style\c!color + \ignorespaces + \pagegridareaparameter\c!text + \egroup\egroup + % + \scratchdimen#8\scaledpoint + \ifdim\scratchdimen>\zeropoint + \setbox\scratchbox\vbox\bgroup + \clip + [ \c!offset=\pagegridareaparameter\c!clipoffset,% + \c!rightoffset=\pagegridareaparameter\c!rightoffset,% + \c!width=\scratchdimen,% + % \c!height= + ]% + {\copy\nextbox}% + \egroup + \clf_setcolumnsetarea{name {#1} box \scratchbox c #3 r #4}% + \setbox\scratchbox\vbox\bgroup + \hskip-\layoutparameter\c!backspace % todo: #9 + \clip + [ \c!offset=\pagegridareaparameter\c!clipoffset,% + \c!leftoffset=\pagegridareaparameter\c!rightoffset,% + \c!hoffset=\scratchdimen,% + \c!width=\dimexpr\wd\nextbox-\scratchdimen\relax,% + % \c!height= + ]% + {\box\nextbox}% + \egroup + \clf_setcolumnsetarea{name {#1} box \scratchbox c #7 r #4}% + \else + \setbox\scratchbox\vbox\bgroup + \box\nextbox % wrapping needed + \egroup + \clf_setcolumnsetarea{name {#1} box \scratchbox c #3 r #4}% + \fi + \endgroup} + +\let\setpagegridarea\page_grid_set_area + +% state start | repeat + +% for now (transition) + +\let\definecolumnset \definepagegrid +\let\setupcolumnset \setuppagegrid +\let\setupcolumnsetlines \setuppagegridlines +\let\setupcolumnsetstart \setuppagegridstart +\let\startcolumnset \startpagegrid +\let\stopcolumnset \stoppagegrid +\let\definecolumnsetspan \definepagegridspan +\let\setupcolumnsetspan \setuppagegridspan +\let\startcolumnsetspan \startpagegridspan +\let\stopcolumnsetspan \stoppagegridspan +\let\columnsetspanwidth \pagegridspanwidth +\let\definecolumnsetarea \definepagegridarea +\let\setupcolumnsetarea \setuppagegridarea +\let\setupcolumnsetareatext\setuppagegridareatext + +\protect + diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua index 1124d80f9..5b18d9823 100644 --- a/tex/context/base/mkiv/page-lin.lua +++ b/tex/context/base/mkiv/page-lin.lua @@ -40,6 +40,8 @@ local v_next = variables.next local v_page = variables.page local v_no = variables.no +local properties = nodes.properties + local nodecodes = nodes.nodecodes local skipcodes = nodes.skipcodes local whatcodes = nodes.whatcodes @@ -346,74 +348,131 @@ end -- store first and last per page -- maybe just set marks directly +local function findcolumngap(list) + -- we assume wrapped boxes, only one with numbers + local n = list + while n do + local id = getid(n) + if id == hlist_code or id == vlist_code then + local p = properties[n] + if p and p.columngap then + if trace_numbers then + report_lines("first column gap %a",p.columngap) + end + return n + else + local list = getlist(n) + if list then + local okay = findcolumngap(list) + if okay then + return okay + end + end + end + end + n = getnext(n) + end +end + function boxed.stage_one(n,nested) current_list = { } local box = getbox(n) - if box then - local list = getlist(box) - if not list then - return - end - if nested then - local id = getid(box) - if id == vlist_code then - if listisnumbered(list) then - -- ok - else - list = findnumberedlist(list) + if not box then + return + end + local list = getlist(box) + if not list then + return + end + local last_a = nil + local last_v = -1 + local skip = false + + local function check() + for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found + local subtype = getsubtype(n) + if subtype ~= line_code then + -- go on + elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then + -- skip funny hlists -- todo: check line subtype + else + local a = lineisnumbered(n) + if a then + if last_a ~= a then + local da = data[a] + local ma = da.method + if ma == v_next then + skip = true + elseif ma == v_page then + da.start = 1 -- eventually we will have a normal counter + end + last_a = a + if trace_numbers then + report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no) + end + end + if getattr(n,a_displaymath) then + if is_display_math(n) then + check_number(n,a,skip) + end + else + local v = getattr(list,a_verbatimline) + if not v or v ~= last_v then + last_v = v + check_number(n,a,skip) + else + check_number(n,a,skip,true) + end + end + skip = false end - else -- hlist + end + end + end + + if nested == 0 then + if list then + check() + end + elseif nested == 1 then + local id = getid(box) + if id == vlist_code then + if listisnumbered(list) then + -- ok + else list = findnumberedlist(list) end + else -- hlist + list = findnumberedlist(list) end - -- we assume we have a vlist if list then - local last_a = nil - local last_v = -1 - local skip = false - for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found - local subtype = getsubtype(n) - if subtype ~= line_code then - -- go on - elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then - -- skip funny hlists -- todo: check line subtype - else - local a = lineisnumbered(n) - if a then - if last_a ~= a then - local da = data[a] - local ma = da.method - if ma == v_next then - skip = true - elseif ma == v_page then - da.start = 1 -- eventually we will have a normal counter - end - last_a = a - if trace_numbers then - report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no) - end - end - if getattr(n,a_displaymath) then - if is_display_math(n) then - check_number(n,a,skip) - end - else - local v = getattr(list,a_verbatimline) - if not v or v ~= last_v then - last_v = v - check_number(n,a,skip) - else - check_number(n,a,skip,true) - end - end - skip = false - end + check() + end + elseif nested == 2 then + list = findcolumngap(list) + -- we assume we have a vlist + if not list then + return + end + for n in traverse_id(vlist_code,list) do + local p = properties[n] + if p and p.columngap then + if trace_numbers then + report_lines("found column gap %a",p.columngap) + end + list = getlist(n) + if list then + check() end end end + else + -- bad call end end +-- column attribute + function boxed.stage_two(n,m) if #current_list > 0 then m = m or lines.scratchbox @@ -452,7 +511,7 @@ end implement { name = "linenumbersstageone", actions = boxed.stage_one, - arguments = { "integer", "boolean" } + arguments = { "integer", "integer" } } implement { diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi index 290984779..5756d870b 100644 --- a/tex/context/base/mkiv/page-lin.mkvi +++ b/tex/context/base/mkiv/page-lin.mkvi @@ -310,7 +310,6 @@ \b_page_lines_number #box\relax \c_page_lines_column #column\relax \c_page_lines_last_column#max\relax - \c_page_lines_nesting #nesting\relax \fullrestoreglobalbodyfont \let\makelinenumber\page_lines_make_number % used at lua end \setbox\b_page_lines_scratch\vbox @@ -318,7 +317,7 @@ \offinterlineskip \clf_linenumbersstageone \b_page_lines_number - \ifcase\c_page_lines_nesting false\else true\fi + #nesting% \relax}% \clf_linenumbersstagetwo \b_page_lines_number diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index c54606451..f2ddb16ea 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -1758,7 +1758,13 @@ {\dotripleempty\spac_vspacing_define_amount} \def\spac_vspacing_define_amount[#1][#2][#3]% can be combined - {\setvalue{\??vspacingamount#1}{\ifgridsnapping#3\else#2\fi}% + {\ifthirdargument + \setvalue{\??vspacingamount#1}{\ifgridsnapping#3\else#2\fi}% + \else\ifsecondargument + \setvalue{\??vspacingamount#1}{\ifgridsnapping\lineheight\else#2\fi}% + \else + \setvalue{\??vspacingamount#1}{\lineheight}% + \fi\fi \clf_vspacingsetamount{#1}} % \installcorenamespace{vspacingamountnormal} diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 7c90060c8..ed06b4547 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 2f6007d38..a8fc8f408 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/strc-con.mkvi b/tex/context/base/mkiv/strc-con.mkvi index be6e9d359..25e26bf73 100644 --- a/tex/context/base/mkiv/strc-con.mkvi +++ b/tex/context/base/mkiv/strc-con.mkvi @@ -135,7 +135,7 @@ \dodoubleempty\strc_constructions_start_regular} \unexpanded\def\strc_constructions_start_regular[#1][#2]% - {\strc_constructions_register[\c!label={\constructionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1][#2]% + {\strc_constructions_register[#2][\c!label={\constructionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_constructions_stop @@ -877,14 +877,14 @@ \let\currentconstructionlistentry\!!zerocount -\def\strc_constructions_register +\unexpanded\def\strc_constructions_register {\clf_doifelselisthasentry\numexpr\currentconstructionlistentry\relax \strc_constructions_register_nop \strc_constructions_register_yes} % \def\strc_constructions_register{\strc_constructions_register_yes} -\def\strc_constructions_register_nop[#1][#2]% #1=interfaced-settings, #2=optional user data +\def\strc_constructions_register_nop[#1][#2]% #1=optional user data #2=interfaced-settings %{\writestatus{constructions}{reusing \currentconstruction: \number\currentconstructionlistentry}} {} @@ -898,9 +898,9 @@ \let\currentconstructionsynchronize\relax \let\currentconstructionattribute \attributeunsetvalue -\def\strc_constructions_register_yes[#1][#2]% #1=interfaced-settings, #2=optional user data +\def\strc_constructions_register_yes[#1][#2]% #1=optional user data #2=interfaced-settings {\begingroup % similar to structure so we might generalize this - \setupcurrentconstruction[#1]% % xdef's will become edef's + \setupcurrentconstruction[#2]% % xdef's will become edef's \xdef\currentconstructionexpansion {\constructionparameter\c!expansion}% \xdef\currentconstructionxmlsetup {\constructionparameter\c!xmlsetup}% \xdef\currentconstructioncatcodes {\constructionparameter\s!catcodes}% @@ -1008,7 +1008,7 @@ \or % symbol \fi - userdata {\detokenize{#2}} + userdata {\detokenize{#1}} \relax % \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}% \clf_setinternalreference @@ -1033,6 +1033,10 @@ {\edef\currentconstructionattribute {\clf_getinternallistreference#1}% \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}} +\def\reinstatecachedconstructionnumberentry#1% was xdef | #1 = cached index can be different from real + {\edef\currentconstructionattribute {\clf_getinternalcachedlistreference#1}% destination + \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}} + \installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}} % Helpers: diff --git a/tex/context/base/mkiv/strc-des.mkvi b/tex/context/base/mkiv/strc-des.mkvi index 83daba0fe..4376d9cdc 100644 --- a/tex/context/base/mkiv/strc-des.mkvi +++ b/tex/context/base/mkiv/strc-des.mkvi @@ -107,7 +107,7 @@ {\doifelseassignment{#1}\strc_descriptions_start_yes_assignment\strc_descriptions_start_yes_reference[#1]} \unexpanded\def\strc_descriptions_start_yes_assignment[#1]% todo userdata - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_start_yes_reference @@ -124,11 +124,11 @@ \strc_descriptions_start_yes_normal[#1]}} \unexpanded\def\strc_descriptions_start_yes_titled_indeed[#1]#2% todo userdata - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_start_yes_normal[#1]% todo userdata - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_start_nop @@ -145,11 +145,11 @@ \strc_descriptions_start_nop_normal}}% \unexpanded\def\strc_descriptions_start_nop_titled_indeed#1% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_start_nop_normal - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=]% \csname\??constructionstarthandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_stop @@ -171,7 +171,7 @@ \fi} \unexpanded\def\strc_descriptions_yes_titled[#1]#2% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]% \csname\??constructioncommandhandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_yes_titled[#1]% @@ -181,11 +181,11 @@ \strc_descriptions_yes_normal[#1]}} \unexpanded\def\strc_descriptions_yes_titled_indeed[#1]#2% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]% \csname\??constructioncommandhandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_yes_normal[#1]% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title=,\c!bookmark=,\c!list=]% \csname\??constructioncommandhandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_nop @@ -202,11 +202,11 @@ \strc_descriptions_nop_normal}} \unexpanded\def\strc_descriptions_nop_titled_indeed#1% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#1},\c!bookmark=,\c!list=]% \csname\??constructioncommandhandler\currentconstructionhandler\endcsname} \unexpanded\def\strc_descriptions_nop_normal - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=]% \csname\??constructioncommandhandler\currentconstructionhandler\endcsname} %D Handlers: diff --git a/tex/context/base/mkiv/strc-lst.lua b/tex/context/base/mkiv/strc-lst.lua index 79f4dfc39..770947e32 100644 --- a/tex/context/base/mkiv/strc-lst.lua +++ b/tex/context/base/mkiv/strc-lst.lua @@ -286,7 +286,7 @@ function lists.discard(n) -- maybe an error message elseif n == #cached then cached[n] = nil - n = n -1 + n = n - 1 while n > 0 and cached[n] == false do cached[n] = nil -- collect garbage n = n - 1 @@ -330,7 +330,7 @@ function lists.enhance(n) local kind = metadata.kind local name = metadata.name if trace_lists then - report_lists("enhancing %a, name %a",n,name) + report_lists("enhancing %a, name %a, page %a",n,name,references.realpage or 0) end -- if references then -- -- is this used ? diff --git a/tex/context/base/mkiv/strc-not.lua b/tex/context/base/mkiv/strc-not.lua index bf14092d1..024366438 100644 --- a/tex/context/base/mkiv/strc-not.lua +++ b/tex/context/base/mkiv/strc-not.lua @@ -32,7 +32,7 @@ lists.enhancers = lists.enhancers or { } storage.register("structures/notes/states", notes.states, "structures.notes.states") local notestates = notes.states -local notedata = { } +local notedata = table.setmetatableindex("table") local variables = interfaces.variables local context = context @@ -51,10 +51,6 @@ local function store(tag,n) end -- local nd = notedata[tag] - if not nd then - nd = { } - notedata[tag] = nd - end local nnd = #nd + 1 nd[nnd] = n local state = notestates[tag] @@ -66,7 +62,7 @@ local function store(tag,n) end state.start = state.start or nnd end - return #nd + return nnd end notes.store = store @@ -79,25 +75,22 @@ implement { local function get(tag,n) -- tricky ... only works when defined local nd = notedata[tag] + if not n then + n = #nd + end + nd = nd[n] if nd then - n = n or #nd - nd = nd[n] - if nd then - if trace_notes then - report_notes("getting note %a of %a with listindex %a",n,tag,nd) - end - -- is this right? --- local newdata = lists.collected[nd] - local newdata = lists.cached[nd] --- local newdata = lists.tobesaved[nd] - return newdata + if trace_notes then + report_notes("getting note %a of %a with listindex %a",n,tag,nd) end + -- is this right? + local newdata = lists.cached[nd] + return newdata end end local function getn(tag) - local nd = notedata[tag] - return nd and #nd or 0 + return #notedata[tag] end notes.get = get @@ -319,7 +312,6 @@ local function getdeltapage(tag,n) if li then local references = li.references if references then - -- local symb = structures.references.collected[""]["symb:"..tag..":"..n] local symb = structures.references.collected[""]["*"..(references.internal or 0)] local notepage = references.realpage or 0 diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi index 43de7e108..f0e7ccbab 100644 --- a/tex/context/base/mkiv/strc-not.mkvi +++ b/tex/context/base/mkiv/strc-not.mkvi @@ -236,7 +236,7 @@ \doifelsenextoptionalcs\strc_notations_command_yes\strc_notations_command_nop} \unexpanded\def\strc_notations_command_nop#title% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]% \csname\??constructionnotehandler\currentconstructionhandler\endcsname \strc_constructions_finalize \normalexpanded{\endgroup\noteparameter\c!next}} @@ -245,13 +245,13 @@ {\doifelseassignment{#optional}\strc_notations_command_assignment\strc_notations_command_argument[#optional]} \unexpanded\def\strc_notations_command_assignment[#settings]% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings]% \csname\??constructionnotehandler\currentconstructionhandler\endcsname \strc_constructions_finalize \normalexpanded{\endgroup\noteparameter\c!next}} \unexpanded\def\strc_notations_command_argument[#reference]#title% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]% \csname\??constructionnotehandler\currentconstructionhandler\endcsname \strc_constructions_finalize \normalexpanded{\endgroup\noteparameter\c!next}} @@ -270,13 +270,13 @@ \doifelsenextoptionalcs\strc_pickup_yes\strc_pickup_nop} \unexpanded\def\strc_notations_start_yes[#reference]#title% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]% \csname\??constructionnotehandler\currentconstructionhandler\endcsname \strc_constructions_finalize \normalexpanded{\endgroup\noteparameter\c!next}} \unexpanded\def\strc_notations_start_nop#title% - {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]% \csname\??constructionnotehandler\currentconstructionhandler\endcsname \strc_constructions_finalize \normalexpanded{\endgroup\noteparameter\c!next}} @@ -1260,7 +1260,7 @@ % as we can have collected notes (e.g. in tables) we need to recover % \currentdescriptionattribute and \currentdescriptionsynchronize % - \reinstateconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table) + \reinstatecachedconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table) % \dontcomplain %begingroup diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua index a937a345b..b42727bce 100644 --- a/tex/context/base/mkiv/strc-ref.lua +++ b/tex/context/base/mkiv/strc-ref.lua @@ -2059,12 +2059,25 @@ function references.getinternallistreference(n) -- n points into list (todo: reg return i and destinationattributes[i] or 0 end +function references.getinternalcachedlistreference(n) -- n points into list (todo: registers) + local l = lists.cached[n] + local i = l and l.references.internal + return i and destinationattributes[i] or 0 +end + implement { name = "getinternallistreference", actions = { references.getinternallistreference, context }, arguments = "integer" } +implement { + name = "getinternalcachedlistreference", + actions = { references.getinternalcachedlistreference, context }, + arguments = "integer" +} + + -- function references.getcurrentmetadata(tag) diff --git a/tex/context/interface/common/keys-cs.xml b/tex/context/interface/common/keys-cs.xml index 26222f49d..b69efb667 100644 --- a/tex/context/interface/common/keys-cs.xml +++ b/tex/context/interface/common/keys-cs.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='foregroundcolor'/> <cd:constant name='foregroundstyle' value='foregroundstyle'/> <cd:constant name='format' value='formatovat'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='ramecek'/> <cd:constant name='framecolor' value='barvaramecku'/> <cd:constant name='framecorner' value='rohramecku'/> diff --git a/tex/context/interface/common/keys-de.xml b/tex/context/interface/common/keys-de.xml index a08e04169..1268ed988 100644 --- a/tex/context/interface/common/keys-de.xml +++ b/tex/context/interface/common/keys-de.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='foregroundcolor'/> <cd:constant name='foregroundstyle' value='foregroundstyle'/> <cd:constant name='format' value='formatieren'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='rahmen'/> <cd:constant name='framecolor' value='rahmenfarbe'/> <cd:constant name='framecorner' value='rahmenwinkel'/> diff --git a/tex/context/interface/common/keys-en.xml b/tex/context/interface/common/keys-en.xml index e1bf9c021..0d3be2223 100644 --- a/tex/context/interface/common/keys-en.xml +++ b/tex/context/interface/common/keys-en.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='foregroundcolor'/> <cd:constant name='foregroundstyle' value='foregroundstyle'/> <cd:constant name='format' value='format'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='frame'/> <cd:constant name='framecolor' value='framecolor'/> <cd:constant name='framecorner' value='framecorner'/> diff --git a/tex/context/interface/common/keys-fr.xml b/tex/context/interface/common/keys-fr.xml index 66b75045d..5b764f99a 100644 --- a/tex/context/interface/common/keys-fr.xml +++ b/tex/context/interface/common/keys-fr.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='couleurpremierplan'/> <cd:constant name='foregroundstyle' value='stylepremierplan'/> <cd:constant name='format' value='formatter'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='cadre'/> <cd:constant name='framecolor' value='couleurcadre'/> <cd:constant name='framecorner' value='coincadre'/> diff --git a/tex/context/interface/common/keys-it.xml b/tex/context/interface/common/keys-it.xml index 6f12a415a..3278d2c58 100644 --- a/tex/context/interface/common/keys-it.xml +++ b/tex/context/interface/common/keys-it.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='coloreprimopiano'/> <cd:constant name='foregroundstyle' value='foregroundstyle'/> <cd:constant name='format' value='format'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='cornice'/> <cd:constant name='framecolor' value='colorecornice'/> <cd:constant name='framecorner' value='angolocornice'/> diff --git a/tex/context/interface/common/keys-nl.xml b/tex/context/interface/common/keys-nl.xml index e61900d7e..b64176707 100644 --- a/tex/context/interface/common/keys-nl.xml +++ b/tex/context/interface/common/keys-nl.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='voorgrondkleur'/> <cd:constant name='foregroundstyle' value='voorgrondletter'/> <cd:constant name='format' value='formatteer'/> + <cd:constant name='fractions' value='breuken'/> <cd:constant name='frame' value='kader'/> <cd:constant name='framecolor' value='kaderkleur'/> <cd:constant name='framecorner' value='kaderhoek'/> diff --git a/tex/context/interface/common/keys-pe.xml b/tex/context/interface/common/keys-pe.xml index cd05529b7..feab7b509 100644 --- a/tex/context/interface/common/keys-pe.xml +++ b/tex/context/interface/common/keys-pe.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='رنگپیشزمینه'/> <cd:constant name='foregroundstyle' value='سبکپیشزمینه'/> <cd:constant name='format' value='شمایل'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='قالب'/> <cd:constant name='framecolor' value='رنگقالب'/> <cd:constant name='framecorner' value='گوشهقالب'/> diff --git a/tex/context/interface/common/keys-ro.xml b/tex/context/interface/common/keys-ro.xml index 511ffa767..f801b0be2 100644 --- a/tex/context/interface/common/keys-ro.xml +++ b/tex/context/interface/common/keys-ro.xml @@ -809,6 +809,7 @@ <cd:constant name='foregroundcolor' value='foregroundcolor'/> <cd:constant name='foregroundstyle' value='foregroundstyle'/> <cd:constant name='format' value='format'/> + <cd:constant name='fractions' value='fractions'/> <cd:constant name='frame' value='frame'/> <cd:constant name='framecolor' value='culoareframe'/> <cd:constant name='framecorner' value='coltframe'/> diff --git a/tex/context/modules/mkiv/m-visual.mkiv b/tex/context/modules/mkiv/m-visual.mkiv index 36a69a2cb..ee48836ed 100644 --- a/tex/context/modules/mkiv/m-visual.mkiv +++ b/tex/context/modules/mkiv/m-visual.mkiv @@ -25,6 +25,7 @@ \definecolor[fakeparindentcolor][blue] \newif\iffakebaseline \fakebaselinetrue +\newif\iffaketrigger \faketriggerfalse \unexpanded\def\fakerule#1% {\strut @@ -89,7 +90,8 @@ \def\dofakewords#1% {\bgroup \dorecurse{#1} - {\getrandomcount\scratchcounter{1}{5}% + {\iffaketrigger\char\zerocount\fi % so that e.g. line numbering works + \getrandomcount\scratchcounter{1}{5}% \dorecurse\scratchcounter {\getrandomdimen\scratchdimen{.5em}{1.25em}% \fakerule\scratchdimen}% diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 3dec0ec46..809b7ff2f 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 02/26/16 16:09:21 +-- merge date : 03/01/16 14:03:56 do -- begin closure to overcome local limits and interference |