diff options
Diffstat (limited to 'tex/context/base/mkiv/supp-box.lmt')
-rw-r--r-- | tex/context/base/mkiv/supp-box.lmt | 1335 |
1 files changed, 0 insertions, 1335 deletions
diff --git a/tex/context/base/mkiv/supp-box.lmt b/tex/context/base/mkiv/supp-box.lmt deleted file mode 100644 index 41013da9a..000000000 --- a/tex/context/base/mkiv/supp-box.lmt +++ /dev/null @@ -1,1335 +0,0 @@ -if not modules then modules = { } end modules ['supp-box'] = { - version = 1.001, - optimize = true, - comment = "companion to supp-box.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- this is preliminary code, use insert_before etc - -local report_hyphenation = logs.reporter("languages","hyphenation") - -local tonumber, next, type = tonumber, next, type - -local lpegmatch = lpeg.match - -local tex = tex -local context = context -local nodes = nodes - -local implement = interfaces.implement - -local nodecodes = nodes.nodecodes - -local disc_code = nodecodes.disc -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local penalty_code = nodecodes.penalty -local glyph_code = nodecodes.glyph -local par_code = nodecodes.par - -local indent_code = nodes.listcodes.indent - -local hmode_code = tex.modelevels.horizontal - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - ------ getfield = nuts.getfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getboth = nuts.getboth -local getdisc = nuts.getdisc -local getid = nuts.getid -local getsubtype = nuts.getsubtype -local getlist = nuts.getlist -local getattribute = nuts.getattribute -local getbox = nuts.getbox -local getdirection = nuts.getdirection -local getwidth = nuts.getwidth -local getheight = nuts.getheight -local getdepth = nuts.getdepth -local getwhd = nuts.getwhd -local takebox = nuts.takebox - ------ setfield = nuts.setfield -local setlink = nuts.setlink -local setboth = nuts.setboth -local setnext = nuts.setnext -local setprev = nuts.setprev -local setbox = nuts.setbox -local setlist = nuts.setlist -local setdisc = nuts.setdisc -local setwidth = nuts.setwidth -local setheight = nuts.setheight -local setdepth = nuts.setdepth -local setshift = nuts.setshift -local setsplit = nuts.setsplit -local setattrlist = nuts.setattrlist -local setwhd = nuts.setwhd -local setglue = nuts.setglue - -local flush_node = nuts.flush_node -local flush_list = nuts.flush_list -local copy_node = nuts.copy -local copy_list = nuts.copy_list -local find_tail = nuts.tail -local getdimensions = nuts.dimensions -local hpack = nuts.hpack -local vpack = nuts.vpack -local traverse_id = nuts.traverse_id -local traverse = nuts.traverse -local free = nuts.free -local findtail = nuts.tail -local reverse = nuts.reverse -local effective_glue= nuts.effective_glue - -local nextdisc = nuts.traversers.disc -local nextdir = nuts.traversers.dir -local nexthlist = nuts.traversers.hlist - -local listtoutf = nodes.listtoutf - -local nodepool = nuts.pool -local new_penalty = nodepool.penalty -local new_hlist = nodepool.hlist -local new_glue = nodepool.glue - -local setlistcolor = nodes.tracers.colors.setlist - -local texget = tex.get -local texgetbox = tex.getbox -local texsetdimen = tex.setdimen -local texgetnest = tex.getnest - -local function hyphenatedlist(head,usecolor) - local current = head and tonut(head) - while current do - local id = getid(current) - local prev, next = getboth(current) - if id == disc_code then - local pre, post, replace = getdisc(current) - if not usecolor then - -- nothing fancy done - elseif pre and post then - setlistcolor(pre,"darkmagenta") - setlistcolor(post,"darkcyan") - elseif pre then - setlistcolor(pre,"darkyellow") - elseif post then - setlistcolor(post,"darkyellow") - end - if replace then - flush_list(replace) - end - setdisc(current) - if pre then - setlink(prev,new_penalty(10000),pre) - setlink(find_tail(pre),current) - end - if post then - setlink(current,new_penalty(10000),post) - setlink(find_tail(post),next) - end - elseif id == vlist_code or id == hlist_code then - hyphenatedlist(getlist(current)) - end - current = next - end -end - -implement { - name = "hyphenatedlist", - arguments = { "integer", "boolean" }, - actions = function(n,color) - local b = texgetbox(n) - if b then - hyphenatedlist(b.list,color) - end - end -} - --- local function hyphenatedhack(head,pre) --- pre = tonut(pre) --- for n in nextdisc, tonut(head) do --- local hyphen = getfield(n,"pre") --- if hyphen then --- flush_list(hyphen) --- end --- setfield(n,"pre",copy_list(pre)) --- end --- end --- --- commands.hyphenatedhack = hyphenatedhack - -local function checkedlist(list) - if type(list) == "number" then - return getlist(getbox(tonut(list))) - else - return tonut(list) - end -end - -implement { - name = "showhyphenatedinlist", - arguments = "integer", - actions = function(n) - -- we just hyphenate (as we pass a hpack) .. a bit too much casting but ... - local l = languages.hyphenators.handler(tonode(checkedlist(n))) - report_hyphenation("show: %s",listtoutf(l,false,true)) - end -} - -local function applytochars(current,doaction,noaction,nested) - while current do - local id = getid(current) - if nested and (id == hlist_code or id == vlist_code) then - context.beginhbox() - applytochars(getlist(current),doaction,noaction,nested) - context.endhbox() - elseif id ~= glyph_code then - noaction(tonode(copy_node(current))) - else - doaction(tonode(copy_node(current))) - end - current = getnext(current) - end -end - -local function applytowords(current,doaction,noaction,nested) - local start - while current do - local id = getid(current) - if id == glue_code then - if start then - doaction(tonode(copy_list(start,current))) - start = nil - end - noaction(tonode(copy_node(current))) - elseif nested and (id == hlist_code or id == vlist_code) then - context.beginhbox() - applytowords(getlist(current),doaction,noaction,nested) - context.egroup() - elseif not start then - start = current - end - current = getnext(current) - end - if start then - doaction(tonode(copy_list(start))) - end -end - -local methods = { - char = applytochars, - characters = applytochars, - word = applytowords, - words = applytowords, -} - -implement { - name = "applytobox", - arguments = { - { - { "box", "integer" }, - { "command" }, - { "method" }, - { "nested", "boolean" }, - } - }, - actions = function(specification) - local list = checkedlist(specification.box) - local action = methods[specification.method or "char"] - if list and action then - action(list,context[specification.command or "ruledhbox"],context,specification.nested) - end - end -} - -local split_char = lpeg.Ct(lpeg.C(1)^0) -local split_word = lpeg.tsplitat(lpeg.patterns.space) -local split_line = lpeg.tsplitat(lpeg.patterns.eol) - -local function processsplit(specification) - local str = specification.data or "" - local command = specification.command or "ruledhbox" - local method = specification.method or "word" - local spaced = specification.spaced - if command then - command = context[command] - end - if method == "char" or method == "character" then - if spaced then - spaced = context.space - end - local words = lpegmatch(split_char,str) - for i=1,#words do - local word = words[i] - if word == " " then - if spaced then - spaced() - end - elseif command then - command(word) - else - context(word) - end - end - elseif method == "word" then - if spaced then - spaced = context.space - end - local words = lpegmatch(split_word,str) - for i=1,#words do - local word = words[i] - if spaced and i > 1 then - spaced() - end - if command then - command(word) - else - context(word) - end - end - elseif method == "line" then - if spaced then - spaced = context.par - end - local words = lpegmatch(split_line,str) - for i=1,#words do - local word = words[i] - if spaced and i > 1 then - spaced() - end - if command then - command(word) - else - context(word) - end - end - else - context(str) - end -end - -implement { - name = "processsplit", - actions = processsplit, - arguments = { - { - { "data" }, - { "command" }, - { "method" }, - { "spaced", "boolean" }, - } - } -} - -local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator") - -implement { - name = "vboxlisttohbox", - arguments = { "integer", "integer", "dimen" }, - actions = function(original,target,inbetween) - local current = getlist(getbox(original)) - local head = nil - local tail = nil - while current do - local id = getid(current) - local next = getnext(current) - if id == hlist_code then - local list = getlist(current) - if head then - if inbetween > 0 then - local n = new_glue(0,0,inbetween) - setlink(tail,n) - tail = n - end - setlink(tail,list) - else - head = list - end - tail = find_tail(list) - -- remove last separator - if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then - local temp = tail - local prev = getprev(tail) - if next then - local list = getlist(tail) - setlink(prev,list) - setlist(tail) - tail = find_tail(list) - else - tail = prev - end - flush_node(temp) - end - -- done - setnext(tail) - setlist(current) - end - current = next - end - local result = new_hlist() - setlist(result,head) - setbox(target,result) - -- setbox(target,new_hlist(head)) - end -} - -implement { - name = "hboxtovbox", - arguments = "integer", - actions = function(n) - local b = getbox(n) - local factor = texget("baselineskip",false) / texget("hsize") - setdepth(b,0) - setheight(b,getwidth(b) * factor) - end -} - -implement { - name = "boxtostring", - arguments = "integer", - actions = function(n) - context.puretext(nodes.toutf(texgetbox(n).list)) -- helper is defined later - end -} - -local function getnaturaldimensions(n) - local w = 0 - local h = 0 - local d = 0 - local l = getlist(getbox(n)) - if l then - w, h, d = getdimensions(l) - end - texsetdimen("lastnaturalboxwd",w) - texsetdimen("lastnaturalboxht",h) - texsetdimen("lastnaturalboxdp",d) - return w, h, d -end - -implement { - name = "getnaturaldimensions", - arguments = "integer", - actions = getnaturaldimensions -} - -implement { - name = "naturalwd", - arguments = "integer", - actions = function(n) - getnaturaldimensions(n) - context.lastnaturalboxwd(false) - end -} - -implement { - name = "getnaturalwd", - arguments = "integer", - actions = function(n) - local w = 0 - local h = 0 - local d = 0 - local l = getlist(getbox(n)) - if l then - w, h, d = getdimensions(l) - end - context("\\dimexpr%i\\scaledpoint\\relax",w) - end -} - -local function setboxtonaturalwd(n) - local old = takebox(n) - local new = hpack(getlist(old)) - setlist(old,nil) - flush_node(old) - setbox(n,new) -end - -implement { - name = "setnaturalwd", - arguments = "integer", - actions = setboxtonaturalwd -} - -nodes.setboxtonaturalwd = setboxtonaturalwd - -local doifelse = commands.doifelse - -do - - local dirvalues = nodes.dirvalues - local lefttoright_code = dirvalues.lefttoright - local righttoleft_code = dirvalues.righttoleft - - local function firstdirinbox(n) - local b = getbox(n) - if b then - local l = getlist(b) - if l then - for d in nextdir, l do - return getdirection(d) - end - for h in nexthlist, l do - return getdirection(h) - end - end - end - return lefttoright_code - end - - nodes.firstdirinbox = firstdirinbox - - implement { - name = "doifelserighttoleftinbox", - arguments = "integer", - actions = function(n) - doifelse(firstdirinbox(n) == righttoleft_code) - end - } - -end - --- new (handy for mp) .. might move to its own module - -do - - local takebox = nuts.takebox - local flush_list = nuts.flush_list - local copy_list = nuts.copy_list - local getwhd = nuts.getwhd - local setbox = nuts.setbox - local new_hlist = nuts.pool.hlist - - local boxes = { } - nodes.boxes = boxes - local cache = table.setmetatableindex("table") - local report = logs.reporter("boxes","cache") - local trace = false - - trackers.register("nodes.boxes",function(v) trace = v end) - - function boxes.save(category,name,b) - name = tonumber(name) or name - local b = takebox(b) - if trace then - report("category %a, name %a, %s (%s)",category,name,"save",b and "content" or "empty") - end - cache[category][name] = b or false - end - - function boxes.savenode(category,name,n) - name = tonumber(name) or name - if trace then - report("category %a, name %a, %s (%s)",category,name,"save",n and "content" or "empty") - end - cache[category][name] = tonut(n) or false - end - - function boxes.found(category,name) - name = tonumber(name) or name - return cache[category][name] and true or false - end - - function boxes.direct(category,name,copy) - name = tonumber(name) or name - local c = cache[category] - local b = c[name] - if not b then - -- do nothing, maybe trace - elseif copy then - b = copy_list(b) - else - c[name] = false - end - if trace then - report("category %a, name %a, %s (%s)",category,name,"direct",b and "content" or "empty") - end - if b then - return tonode(b) - end - end - - function boxes.restore(category,name,box,copy) - name = tonumber(name) or name - local c = cache[category] - local b = takebox(box) - if b then - flush_list(b) - end - local b = c[name] - if not b then - -- do nothing, maybe trace - elseif copy then - b = copy_list(b) - else - c[name] = false - end - if trace then - report("category %a, name %a, %s (%s)",category,name,"restore",b and "content" or "empty") - end - setbox(box,b or nil) - end - - function boxes.dimensions(category,name) - name = tonumber(name) or name - local b = cache[category][name] - if b then - return getwhd(b) - else - return 0, 0, 0 - end - end - - function boxes.reset(category,name) - name = tonumber(name) or name - local c = cache[category] - if name and name ~= "" then - local b = c[name] - if b then - flush_list(b) - c[name] = false - end - if trace then - report("category %a, name %a, reset",category,name) - end - else - for k, b in next, c do - if b then - flush_list(b) - end - end - cache[category] = { } - if trace then - report("category %a, reset",category) - end - end - end - - implement { - name = "putboxincache", - arguments = { "string", "string", "integer" }, - actions = boxes.save, - } - - implement { - name = "getboxfromcache", - arguments = { "string", "string", "integer" }, - actions = boxes.restore, - } - - implement { - name = "directboxfromcache", - arguments = "2 strings", - actions = { boxes.direct, context }, - -- actions = function(category,name) local b = boxes.direct(category,name) if b then context(b) end end, - } - - implement { - name = "directcopyboxfromcache", - arguments = { "string", "string", true }, - actions = { boxes.direct, context }, - -- actions = function(category,name) local b = boxes.direct(category,name,true) if b then context(b) end end, - } - - implement { - name = "copyboxfromcache", - arguments = { "string", "string", "integer", true }, - actions = boxes.restore, - } - - implement { - name = "doifelseboxincache", - arguments = "2 strings", - actions = { boxes.found, doifelse }, - } - - implement { - name = "resetboxesincache", - arguments = "string", - actions = boxes.reset, - } - -end - -implement { - name = "lastlinewidth", - actions = function() - local head = tex.lists.page_head - -- list dimensions returns 3 value but we take the first - context(head and getdimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0) - end -} - -implement { - name = "shiftbox", - arguments = { "integer", "dimension" }, - actions = function(n,d) - setshift(getbox(n),d) - end, -} - -implement { name = "vpackbox", arguments = "integer", actions = function(n) setbox(n,(vpack(takebox(n)))) end } -implement { name = "hpackbox", arguments = "integer", actions = function(n) setbox(n,(hpack(takebox(n)))) end } - -implement { name = "vpackedbox", arguments = "integer", actions = function(n) context(vpack(takebox(n))) end } -implement { name = "hpackedbox", arguments = "integer", actions = function(n) context(hpack(takebox(n))) end } - -implement { - name = "scangivendimensions", - public = true, - protected = true, - arguments = { - { - { "width", "dimension" }, - { "height", "dimension" }, - { "depth", "dimension" }, - }, - }, - actions = function(t) - texsetdimen("givenwidth", t.width or 0) - texsetdimen("givenheight",t.height or 0) - texsetdimen("givendepth", t.depth or 0) - end, -} - -local function stripglue(list) - local done = false - local first = list - while first do - local id = getid(first) - if id == glue_code or id == penalty_code then - first = getnext(first) - else - break - end - end - if first and first ~= list then - -- we have discardables - setsplit(getprev(first),first) - flush_list(list) - list = first - done = true - end - if list then - local tail = findtail(list) - local last = tail - while last do - local id = getid(last) - if id == glue_code or id == penalty_code then - last = getprev(last) - else - break - end - end - if last ~= tail then - -- we have discardables - flush_list(getnext(last)) - setnext(last) - done = true - end - end - return list, done -end - -local function limitate(t) -- don't pack the result ! - local text = t.text - if text then - text = tonut(text) - else - return - end - local sentinel = t.sentinel - if sentinel then - sentinel = tonut(sentinel) - local s = getlist(sentinel) - setlist(sentinel) - free(sentinel) - sentinel = s - else - return tonode(text) - end - local width = getwidth(text) - local list = getlist(text) - local done = false - if t.strip then - list, done = stripglue(list) - if not list then - setlist(text) - setwidth(text,0) - return text - elseif done then - width = getdimensions(list) - setlist(text,list) - end - end - local left = t.left or 0 - local right = t.right or 0 - local total = left + right - if total < width then - local last = nil - local first = nil - local maxleft = left - local maxright = right - local swidth = getwidth(sentinel) - if maxright > 0 then - maxleft = maxleft - swidth/2 - maxright = maxright - swidth/2 - else - maxleft = maxleft - swidth - end - for n in traverse_id(glue_code,list) do - local width = getdimensions(list,n) - if width > maxleft then - if not last then - last = n - end - break - else - last = n - end - end - if last and maxright > 0 then - for n in traverse_id(glue_code,last) do - local width = getdimensions(n) - if width < maxright then - first = n - break - else - first = n - end - end - end - if last then - local rest = getnext(last) - if rest then - local tail = findtail(sentinel) - if first and getid(first) == glue_code and getid(tail) == glue_code then - setwidth(first,0) - end - if last and getid(last) == glue_code and getid(sentinel) == glue_code then - setwidth(last,0) - end - if first and first ~= last then - local prev = getprev(first) - if prev then - setnext(prev) - end - setlink(tail,first) - end - setlink(last,sentinel) - setprev(rest) - flush_list(rest) - end - end - end - setlist(text) - free(text) - - if t.freeze then - local l = hpack(list,total,"exactly") - for n in traverse_id(glue_code,list) do - setglue(n,(effective_glue(n,l))) - end - setlist(l) - flush_node(l) - end - - return tonode(list) -end - -implement { - name = "limitated", - public = true, - protected = true, - arguments = { - { - { "left", "dimension" }, - { "right", "dimension" }, - { "text", "hbox" }, - { "sentinel", "hbox" }, - { "strip", "boolean" }, - { "freeze", "boolean" }, - } - }, - actions = function(t) - context.dontleavehmode() - context(limitate(t)) - end, -} - --- only in lmtx: - -implement { - name = "widthuptohere", - public = true, - usage = "value", - actions = function() - local n = texgetnest() - local w = 0 - if n.mode == hmode_code then - local h = hpack(getnext(tonut(n.head))) - w = getwidth(h) - setlist(h) - free(h) - end - return tokens.values.dimension, w - end, -} - -implement { - name = "doifelseindented", - public = true, - protected = true, - actions = function() - local n = texgetnest() - local b = false - if n.mode == hmode_code then - n = tonut(n.head) - while n do - n = getnext(n) - if n then - local id = getid(n) - if id == hlist_code then - if getsubtype(n) == indent_code then - b = getwidth(n) > 0 - break - end - elseif id ~= par_code then - break - end - end - end - end - commands.doifelse(b) - end, -} - -implement { - name = "noflinesinbox", - public = true, - protected = false, - arguments = "integer", - actions = function(n) - local c = 0 - local b = getbox(n) - if b then - b = getlist(b) - if b then - for n, id in traverse(b) do - if id == hlist_code or id == vlist_code then - c = c + 1 - end - end - end - end - context(c) - end, -} - -do - - local takebox = tex.takebox - - implement { - name = "thebox", - public = true, - arguments = "integer", - actions = function(n) - context(takebox(n)) - end - } - -end - --- only in lmtx - -implement { - name = "reversevboxcontent", - protected = true, - public = true, - arguments = "integer", - actions = function(n) - local b = getbox(n) - local l = b and getid(b) == vlist_code and getlist(b) - if l and getnext(l) then - setlist(b,reverse(l)) -- no re-vpack here! - end - end -} - --- only in lmtx - -do - - local scaninteger = tokens.scanners.integer - local scanbox = tokens.scanners.box - local scandimen = tokens.scanners.dimen - - local setsubtype = nuts.setsubtype - local removenode = nuts.remove - local getnormalizedline = nuts.getnormalizedline -- we can optimize this - local getdimensions = nuts.dimensions - local getrangedimensions = nuts.rangedimensions - - local setprop = nuts.setprop - local getprop = nuts.getprop - - local listcodes = nodes.listcodes - local line_code = listcodes.line - local equation_code = listcodes.equation - local unknown_code = listcodes.unknown - - local values = tokens.values - local dimension_value = values.dimension - local cardinal_value = values.cardinal - local direct_value = values.direct - - -- todo: make helper that formats - - local reporterror = logs.texerrormessage - - -- The first variant did a linear lookup but for large boxes and lots of - -- analysis that is not nice. Okay, in practice performance is quite ok - -- (milliseconds for thousands of access) but still ... the next is nicer - -- and it's part of the experimental fun stuff anyway. - - local function countlines(box) - local prop = getprop(box,"boxlines") - if not prop then - local line = 0 - local list = getlist(box) - prop = { } - if list then - for n, subtype in nexthlist, list do - if subtype == line_code then -- or subtype == equation_code then - line = line + 1 - prop[line] = n - end - end - end - setprop(box,"boxlines",prop) - end - return prop - end - - local function boxlinecount(what) - local n = scaninteger() - local box = getbox(n) - if what == "value" then - return cardinal_value, box and #countlines(box) or 0 - end - end - - local function findline() - local n = scaninteger() - local line = scaninteger() - local box = getbox(n) - if box then - local prop = getprop(box,"boxlines") - if not prop then - prop = countlines(box) - end - local found = prop[line] - if found then - local props = getprop(found,"lineproperties") - if not props then - props = getnormalizedline(found) - props.width, props.height, props.depth = getwhd(found) - setprop(found,"lineproperties",props) - end - return props, line, found, box - end - end - reporterror("no line %i in box %i",line,n) - end - - local function findrange() - local n = scaninteger() - local first = scaninteger() - local last = scaninteger() - local box = getbox(n) - if box then - local prop = getprop(box,"boxlines") - if not prop then - prop = countlines(box) - end - if first > 0 and last <= #prop then - for i = first, last do - local found = prop[i] - local props = getprop(found,"lineproperties") - if not props then - props = getnormalizedline(found) - props.width, props.height, props.depth = getwhd(found) - setprop(found,"lineproperties",props) - end - end - return prop, first, last, box - end - end - reporterror("no lines %i - %i in box %i",first,last,n) - end - - local function getline(props,line,found,box,value) - local p, n = getboth(found) - local temp = new_hlist() - setsubtype(temp,getsubtype(found)) - setwhd(temp,getwhd(found)) - if found == getlist(box) then - setlink(temp,n) - setlist(box,temp) - else - setlink(p,temp,n) - end - getprop(box,"boxlines")[line] = temp - setboth(found) - setsubtype(found, unknown_code) - if value then - return direct_value, found - else - context(tonode(found)) - end - end - - local function copyline(props,line,found,box,value) - found = copy_node(found) - setsubtype(found, unknown_code) - if value then - return direct_value, found - else - context(tonode(found)) - end - end - - local function setline(props,line,found,box) - local p, n = getboth(found) - local temp = scanbox() - if temp then - temp = tonut(temp) - if found == getlist(box) then - setlink(temp,n) - setlist(box,temp) - else - setlink(p,temp,n) - end - flush_node(found) - getprop(box,"boxlines")[line] = temp - end - end - - local function naturaldimensions(p,l,found) - if not p.naturalwidth then - p.naturalwidth, p.naturalheight, p.naturaldepth = getdimensions(getlist(found)) - end - return p - end - - local function rangedimensions(p,f,l,box) - local w, h, d = getrangedimensions(box,p[f],getnext(p[l]),true) - return { width = w, height = h, depth = d } - end - - local getters_one = { - - ["wd"] = function(p,l,found) return dimension_value, p.width end, - ["ht"] = function(p,l,found) return dimension_value, p.height end, - ["dp"] = function(p,l,found) return dimension_value, p.depth end, - ["ls"] = function(p,l,found) return dimension_value, p.leftskip end, - ["rs"] = function(p,l,found) return dimension_value, p.rightskip end, - ["lh"] = function(p,l,found) return dimension_value, p.lefthangskip end, - ["rh"] = function(p,l,found) return dimension_value, p.righthangskip end, - ["lp"] = function(p,l,found) return dimension_value, p.parfillleftskip end, - ["rp"] = function(p,l,found) return dimension_value, p.parfillrightskip end, - ["in"] = function(p,l,found) return dimension_value, p.indent end, - - ["nw"] = function(p,l,found) return dimension_value, naturaldimensions(p,l,found).naturalwidth end, - ["nh"] = function(p,l,found) return dimension_value, naturaldimensions(p,l,found).naturalheigth end, - ["nd"] = function(p,l,found) return dimension_value, naturaldimensions(p,l,found).naturaldepth end, - - ["get"] = function(p,l,found,box) return getline(p,l,found,box,true) end, - } - - local getters_two = { - ["wd"] = function(p,f,l,box) return dimension_value, rangedimensions(p,f,l,box).width end, - ["ht"] = function(p,f,l,box) return dimension_value, rangedimensions(p,f,l,box).height end, - ["dp"] = function(p,f,l,box) return dimension_value, rangedimensions(p,f,l,box).depth end, - } - - local setters_one = { - ["wd"] = function(p,l,found) return setwidth (found,scandimen(false,false,true)) end, - ["ht"] = function(p,l,found) return setheight(found,scandimen(false,false,true)) end, - ["dp"] = function(p,l,found) return setdepth (found,scandimen(false,false,true)) end, - ["set"] = setline, - ["get"] = getline, - ["copy"] = copyline, - } - - local function boxline(name,what) - local props, line, found, box = findline() - if not found then - -- - elseif what == "value" then - local getter = getters_one[name] - if getter then - return getter(props,line,found,box) - end - else - local setter = setters_one[name] - if setter then - return setter(props,line,found,box) - end - end - end - - -- - - local function boxrange(name,what) - local prop, first, last, box = findrange() - if not prop then - -- - elseif what == "value" then - local getter = getters_two[name] - if getter then - return getter(prop,first,last,box) - end - else - local setter = setters_two[name] - if setter then - return setter(prop,first,last,box) - end - end - end - - local function define_one(name,action) - implement { - name = name, - public = true, - usage = "value", - actions = function(what) return boxline(action,what) end, - } - end - - local function define_two(name,action) - implement { - name = name, - public = true, - usage = "value", - actions = function(what) return boxrange(action,what) end, - } - end - - implement { - name = "boxlines", - public = true, - usage = "value", - actions = boxlinecount, - } - - define_one("boxline", "get") - define_one("setboxline", "set") - define_one("copyboxline", "copy") - define_one("boxlineht", "ht") - define_one("boxlinedp", "dp") - define_one("boxlinewd", "wd") - define_one("boxlinels", "ls") - define_one("boxliners", "rs") - define_one("boxlinelh", "lh") - define_one("boxlinerh", "rh") - define_one("boxlinelp", "lp") - define_one("boxlinerp", "rp") - define_one("boxlinein", "in") - define_one("boxlinenw", "nw") - define_one("boxlinenh", "nh") - define_one("boxlinend", "nd") - - define_two("boxrangewd", "wd") - define_two("boxrangeht", "ht") - define_two("boxrangedp", "dp") - -end - -do - - local getbox = tex.getbox - local setfield = nodes.setfield - local getfield = nodes.getfield - local flush = nodes.flush - local copynode = nodes.copy - - local function get(n,field,copy) - local b = getbox(n) - if b then - local p = getfield(b,field) - if copy then - p = copynode(p) - else - setfield(b,field) - end - context(p) - end - end - - local function set(n,l,field) - local b = getbox(n) - if b then - setfield(b,field,l) - else - flush(l) - end - end - - implement { - name = "prelistbox", - public = true, - usage = "value", - arguments = { "integer", '"pre"' }, - actions = get, - } - - implement { - name = "postlistbox", - public = true, - usage = "value", - arguments = { "integer", '"post"' }, - actions = get, - } - - implement { - name = "prelistcopy", - public = true, - usage = "value", - arguments = { "integer", '"pre"', true }, - actions = get, - } - - implement { - name = "postlistcopy", - public = true, - usage = "value", - arguments = { "integer", '"post"', true }, - actions = get, - } - - implement { - name = "setprelistbox", - public = true, - usage = "value", - arguments = { "integer", "box", '"pre"' }, - actions = set, - } - - implement { - name = "setpostlistbox", - public = true, - usage = "value", - arguments = { "integer", "box", '"post"' }, - actions = set, - } - -end |