diff options
Diffstat (limited to 'tex')
21 files changed, 984 insertions, 879 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 55741083b..51b6ba7e2 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.03.07 12:18} +\newcontextversion{2018.03.10 14:52} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index f2fce340e..4d00fa41e 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2018.03.07 12:18} +\edef\contextversion{2018.03.10 14:52} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index de3a8c84a..46b61c882 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -1077,6 +1077,7 @@ \setinterfaceconstant{preview}{previzualizare} \setinterfaceconstant{previous}{precendent} \setinterfaceconstant{previousnumber}{numarprecedent} +\setinterfaceconstant{print}{print} \setinterfaceconstant{printable}{tiparibil} \setinterfaceconstant{process}{process} \setinterfaceconstant{profile}{profile} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index ae8748f0f..79be46772 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{2018.03.07 12:18} +\newcontextversion{2018.03.10 14:52} %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 8cf5eff00..482a24192 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,7 +42,7 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.03.07 12:18} +\edef\contextversion{2018.03.10 14:52} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/grph-epd.lua b/tex/context/base/mkiv/grph-epd.lua index a189a8706..7855ce891 100644 --- a/tex/context/base/mkiv/grph-epd.lua +++ b/tex/context/base/mkiv/grph-epd.lua @@ -11,6 +11,10 @@ local settings_to_hash = utilities.parsers.settings_to_hash -- todo: page, name, file, url +-- I have some experimental code for including comments and fields but it's +-- unfinished and not included as it was just a proof of concept to get some idea +-- about what is needed and possible. But the placeholders are here already. + local codeinjections = backends.codeinjections local function mergegoodies(optionlist) diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index 71ee2f7ea..47eb7bbbb 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -1923,6 +1923,15 @@ function figures.getinfo(name,page) end end +function figures.getpdfinfo(name,page,metadata) + -- not that useful but as we have it for detailed inclusion we can as + -- we expose it + if type(name) ~= "table" then + name = { name = name, page = page, metadata = metadata } + end + return codeinjections.getinfo(name) +end + -- interfacing implement { diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua index d17ae5065..89b2c6e0e 100644 --- a/tex/context/base/mkiv/lpdf-epa.lua +++ b/tex/context/base/mkiv/lpdf-epa.lua @@ -14,6 +14,7 @@ local formatters = string.formatters local abs = math.abs local expandname = file.expandname local allocate = utilities.storage.allocate +local isfile = lfs.isfile ----- lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns @@ -21,6 +22,8 @@ local trace_links = false trackers.register("figures.links", function(v) local trace_outlines = false trackers.register("figures.outliness", function(v) trace_outlines = v end) local report_link = logs.reporter("backend","link") +local report_comment = logs.reporter("backend","comment") +local report_field = logs.reporter("backend","field") local report_outline = logs.reporter("backend","outline") local epdf = epdf @@ -324,7 +327,7 @@ function codeinjections.getbookmarks(filename) local document = nil - if lfs.isfile(filename) then + if isfile(filename) then document = loadpdffile(filename) else report_outline("unknown file %a",filename) @@ -467,3 +470,82 @@ function codeinjections.mergebookmarks(specification) end end end + +-- placeholders: + +function codeinjections.mergecomments(specification) + report_comment("unfinished experimental code, not used yet") +end + +function codeinjections.mergefields(specification) + report_field("unfinished experimental code, not used yet") +end + +-- A bit more than a placeholder but in the same perspective as +-- inclusion of comments and fields: +-- +-- getinfo{ filename = "tt.pdf", metadata = true } +-- getinfo{ filename = "tt.pdf", page = 1, metadata = "xml" } +-- getinfo("tt.pdf") + +function codeinjections.getinfo(specification) + if type(specification) == "string" then + specification = { filename = specification } + end + local filename = specification.filename + if type(filename) == "string" and isfile(filename) then + local pdffile = loadpdffile(filename) + if pdffile then + local pagenumber = specification.page or 1 + local metadata = specification.metadata + local catalog = pdffile.Catalog + local info = pdffile.Info + local pages = pdffile.pages + local nofpages = pages.n + if metadata then + local m = catalog.Metadata + if m then + m = m() + if metadata == "xml" then + metadata = xml.convert(m) + else + metadata = m + end + else + metadata = nil + end + else + metadata = nil + end + if pagenumber > nofpages then + pagenumber = nofpages + end + local nobox = { 0, 0, 0, 0 } + local crop = nobox + local media = nobox + local page = pages[pagenumber] + if page then + crop = page.CropBox or nobox + media = page.MediaBox or crop or nobox + crop.n = nil -- nicer + media.n = nil -- nicer + end + local bbox = crop or media or nobox + return { + filename = filename, + pdfversion = tonumber(catalog.Version), + nofpages = nofpages, + title = info.Title, + creator = info.Creator, + producer = info.Producer, + creationdate = info.CreationDate, + modification = info.ModDate, + metadata = metadata, + width = bbox[4] - bbox[2], + height = bbox[3] - bbox[1], + cropbox = { crop[1], crop[2], crop[3], crop[4] }, -- we need access + mediabox = { media[1], media[2], media[3], media[4] } , -- we need access + } + end + end +end diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index 3d263dafd..288630a5d 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -195,6 +195,8 @@ local belowdisplayskip_code = skipcodes.belowdisplayskip local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip +local properties = nodes.properties.data + local vspacing = builders.vspacing or { } builders.vspacing = vspacing @@ -699,45 +701,43 @@ local function snap_topskip(current,method) return w, 0 end -do - - local categories = allocate { - [0] = 'discard', - [1] = 'largest', - [2] = 'force' , - [3] = 'penalty', - [4] = 'add' , - [5] = 'disable', - [6] = 'nowhite', - [7] = 'goback', - [8] = 'together', -- not used (?) - [9] = 'overlay', - [10] = 'notopskip', - } +local categories = { + [0] = "discard", + [1] = "largest", + [2] = "force", + [3] = "penalty", + [4] = "add", + [5] = "disable", + [6] = "nowhite", + [7] = "goback", + [8] = "packed", + [9] = "overlay", + [10] = "enable", + [11] = "notopskip", +} - vspacing.categories = categories +categories = allocate(table.swapped(categories,categories)) +vspacing.categories = categories - function vspacing.tocategories(str) - local t = { } - for s in gmatch(str,"[^, ]") do -- use lpeg instead - local n = tonumber(s) - if n then - t[categories[n]] = true - else - t[b] = true - end - end - return t - end - - function vspacing.tocategory(str) -- can be optimized - if type(str) == "string" then - return set.tonumber(vspacing.tocategories(str)) +function vspacing.tocategories(str) + local t = { } + for s in gmatch(str,"[^, ]") do -- use lpeg instead + local n = tonumber(s) + if n then + t[categories[n]] = true else - return set.tonumber({ [categories[str]] = true }) + t[b] = true end end + return t +end +function vspacing.tocategory(str) -- can be optimized + if type(str) == "string" then + return set.tonumber(vspacing.tocategories(str)) + else + return set.tonumber({ [categories[str]] = true }) + end end vspacingdata.map = vspacingdata.map or { } -- allocate ? @@ -783,6 +783,7 @@ do -- todo: interface.variables and properties local ctx_flushblankhandling = context.flushblankhandling local ctx_addpredefinedblankskip = context.addpredefinedblankskip local ctx_addaskedblankskip = context.addaskedblankskip + local ctx_setblankpacked = context.setblankpacked local ctx_pushlogger = context.pushlogger local ctx_startblankhandling = context.startblankhandling @@ -791,6 +792,8 @@ do -- todo: interface.variables and properties local pattern = nil + local packed = categories.packed + local function handler(amount, keyword, detail) if not keyword then report_vspacing("unknown directive %a",s) @@ -804,7 +807,9 @@ do -- todo: interface.variables and properties ctx_flexibleblankskip() elseif keyword == k_category then local category = tonumber(detail) - if category then + if category == packed then + ctx_setblankpacked() + elseif category then ctx_setblankcategory(category) ctx_flushblankhandling() end @@ -961,14 +966,14 @@ function vspacing.snapbox(n,how) end else local h, d, ch, cd, lines, extra = snap_hlist("box",box,sv,ht,dp) -setprop(box,"snapper",{ - ht = h, - dp = d, - ch = ch, - cd = cd, - extra = extra, - current = current, -}) + setprop(box,"snapper",{ + ht = h, + dp = d, + ch = ch, + cd = cd, + extra = extra, + current = current, + }) setwhd(box,wd,ch,cd) if trace_vsnapping then report_snapper("box list snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", @@ -993,702 +998,702 @@ end -- We can register and copy the rule instead. -local w, h, d = 0, 0, 0 ------ w, h, d = 100*65536, 65536, 65536 +do -local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now - if head == current then - if getsubtype(head) == baselineskip_code then - width = width - getwidth(head) + local w, h, d = 0, 0, 0 + ----- w, h, d = 100*65536, 65536, 65536 + + local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now + if head == current then + if getsubtype(head) == baselineskip_code then + width = width - getwidth(head) + end end + if width == 0 then + -- do nothing + elseif where == "after" then + head, current = insert_node_after(head,current,new_rule(w,h,d)) + head, current = insert_node_after(head,current,new_kern(width)) + head, current = insert_node_after(head,current,new_rule(w,h,d)) + else + local c = current + head, current = insert_node_before(head,current,new_rule(w,h,d)) + head, current = insert_node_before(head,current,new_kern(width)) + head, current = insert_node_before(head,current,new_rule(w,h,d)) + current = c + end + if trace then + report_vspacing("inserting forced skip of %p",width) + end + return head, current end - if width == 0 then - -- do nothing - elseif where == "after" then - head, current = insert_node_after(head,current,new_rule(w,h,d)) - head, current = insert_node_after(head,current,new_kern(width)) - head, current = insert_node_after(head,current,new_rule(w,h,d)) - else - local c = current - head, current = insert_node_before(head,current,new_rule(w,h,d)) - head, current = insert_node_before(head,current,new_kern(width)) - head, current = insert_node_before(head,current,new_rule(w,h,d)) - current = c - end - if trace then - report_vspacing("inserting forced skip of %p",width) - end - return head, current -end - --- penalty only works well when before skip -local discard = 0 -local largest = 1 -local force = 2 -local penalty = 3 -local add = 4 -local disable = 5 -local nowhite = 6 -local goback = 7 -local together = 8 -- not used (?) -local overlay = 9 -local enable = 10 + -- penalty only works well when before skip --- [whatsits][hlist][glue][glue][penalty] + local discard = categories.discard + local largest = categories.largest + local force = categories.force + local penalty = categories.penalty + local add = categories.add + local disable = categories.disable + local nowhite = categories.nowhite + local goback = categories.goback + local packed = categories.packed + local overlay = categories.overlay + local enable = categories.enable + local notopskip = categories.notopskip -local special_penalty_min = 32250 -local special_penalty_max = 35000 -local special_penalty_xxx = 0 + -- [whatsits][hlist][glue][glue][penalty] --- this is rather messy and complex: we want to make sure that successive --- header don't break but also make sure that we have at least a decent --- break when we have succesive ones (often when testing) + local special_penalty_min = 32250 + local special_penalty_max = 35000 + local special_penalty_xxx = 0 --- todo: mark headers as such so that we can recognize them + -- this is rather messy and complex: we want to make sure that successive + -- header don't break but also make sure that we have at least a decent + -- break when we have succesive ones (often when testing) -local specialmethods = { } -local specialmethod = 1 + -- todo: mark headers as such so that we can recognize them -local properties = nodes.properties.data + local specialmethods = { } + local specialmethod = 1 -specialmethods[1] = function(pagehead,pagetail,start,penalty) - -- - if not pagehead or penalty < special_penalty_min or penalty > special_penalty_max then - return - end - local current = pagetail - -- - -- nodes.showsimplelist(pagehead,0) - -- - if trace_specials then - report_specials("checking penalty %a",penalty) - end - while current do - local id = getid(current) - if id == penalty_code then - local p = properties[current] - if p then - local p = p.special_penalty - if not p then - if trace_specials then - report_specials(" regular penalty, continue") - end - elseif p == penalty then - if trace_specials then - report_specials(" context penalty %a, same level, overloading",p) - end - return special_penalty_xxx - elseif p > special_penalty_min and p < special_penalty_max then - if penalty < p then + specialmethods[1] = function(pagehead,pagetail,start,penalty) + -- + if not pagehead or penalty < special_penalty_min or penalty > special_penalty_max then + return + end + local current = pagetail + -- + -- nodes.showsimplelist(pagehead,0) + -- + if trace_specials then + report_specials("checking penalty %a",penalty) + end + while current do + local id = getid(current) + if id == penalty_code then + local p = properties[current] + if p then + local p = p.special_penalty + if not p then if trace_specials then - report_specials(" context penalty %a, lower level, overloading",p) + report_specials(" regular penalty, continue") end - return special_penalty_xxx - else + elseif p == penalty then if trace_specials then - report_specials(" context penalty %a, higher level, quitting",p) + report_specials(" context penalty %a, same level, overloading",p) end - return - end - elseif trace_specials then - report_specials(" context penalty %a, higher level, continue",p) - end - else - local p = getpenalty(current) - if p < 10000 then - -- assume some other mechanism kicks in so we seem to have content - if trace_specials then - report_specials(" regular penalty %a, quitting",p) + return special_penalty_xxx + elseif p > special_penalty_min and p < special_penalty_max then + if penalty < p then + if trace_specials then + report_specials(" context penalty %a, lower level, overloading",p) + end + return special_penalty_xxx + else + if trace_specials then + report_specials(" context penalty %a, higher level, quitting",p) + end + return + end + elseif trace_specials then + report_specials(" context penalty %a, higher level, continue",p) end - break else - if trace_specials then - report_specials(" regular penalty %a, continue",p) + local p = getpenalty(current) + if p < 10000 then + -- assume some other mechanism kicks in so we seem to have content + if trace_specials then + report_specials(" regular penalty %a, quitting",p) + end + break + else + if trace_specials then + report_specials(" regular penalty %a, continue",p) + end end end end + current = getprev(current) end - current = getprev(current) - end - -- none found, so no reson to be special - if trace_specials then - if pagetail then - report_specials(" context penalty, discarding, nothing special") - else - report_specials(" context penalty, discarding, nothing preceding") + -- none found, so no reson to be special + if trace_specials then + if pagetail then + report_specials(" context penalty, discarding, nothing special") + else + report_specials(" context penalty, discarding, nothing preceding") + end end + return special_penalty_xxx end - return special_penalty_xxx -end --- specialmethods[2] : always put something before and use that as to-be-changed --- --- we could inject a vadjust to force a recalculation .. a mess --- --- So, the next is far from robust and okay but for the moment this overlaying --- has to do. Always test this with the examples in spac-ver.mkvi! - -local function check_experimental_overlay(head,current) - local p = nil - local c = current - local n = nil - local function overlay(p,n,mvl) - local p_wd, p_ht, p_dp = getwhd(p) - local n_wd, n_ht, n_dp = getwhd(n) - local skips = 0 - -- - -- We deal with this at the tex end .. we don't see spacing .. enabling this code - -- is probably harmless but then we need to test it. - -- - -- we could calculate this before we call - -- - -- problem: prev list and next list can be unconnected - -- - local c = getnext(p) - local l = c - while c and c ~= n do - local id = getid(c) - if id == glue_code then - skips = skips + getwidth(c) - elseif id == kern_code then - skips = skips + getkern(c) + -- This will be replaced after 0.80+ when we have a more robust look-back and + -- can look at the bigger picture. + + -- todo: look back and when a special is there before a list is seen penalty keep ut + + -- we now look back a lot, way too often + + -- userskip + -- lineskip + -- baselineskip + -- parskip + -- abovedisplayskip + -- belowdisplayskip + -- abovedisplayshortskip + -- belowdisplayshortskip + -- topskip + -- splittopskip + + -- we could inject a vadjust to force a recalculation .. a mess + -- + -- So, the next is far from robust and okay but for the moment this overlaying + -- has to do. Always test this with the examples in spac-ver.mkvi! + + local function check_experimental_overlay(head,current) + local p = nil + local c = current + local n = nil + local function overlay(p,n,mvl) + local p_wd, p_ht, p_dp = getwhd(p) + local n_wd, n_ht, n_dp = getwhd(n) + local skips = 0 + -- + -- We deal with this at the tex end .. we don't see spacing .. enabling this code + -- is probably harmless but then we need to test it. + -- + -- we could calculate this before we call + -- + -- problem: prev list and next list can be unconnected + -- + local c = getnext(p) + local l = c + while c and c ~= n do + local id = getid(c) + if id == glue_code then + skips = skips + getwidth(c) + elseif id == kern_code then + skips = skips + getkern(c) + end + l = c + c = getnext(c) end - l = c - c = getnext(c) - end - local c = getprev(n) - while c and c ~= n and c ~= l do - local id = getid(c) - if id == glue_code then - skips = skips + getwidth(c) - elseif id == kern_code then - skips = skips + getkern(c) + local c = getprev(n) + while c and c ~= n and c ~= l do + local id = getid(c) + if id == glue_code then + skips = skips + getwidth(c) + elseif id == kern_code then + skips = skips + getkern(c) + end + c = getprev(c) end - c = getprev(c) - end - -- - local delta = n_ht + skips + p_dp - texsetdimen("global","d_spac_overlay",-delta) -- for tracing - -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak - local k = new_kern(-delta) - head = insert_node_before(head,n,k) - if n_ht > p_ht then - local k = new_kern(n_ht-p_ht) - head = insert_node_before(head,p,k) - end - if trace_vspacing then - report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,skips,delta) + -- + local delta = n_ht + skips + p_dp + texsetdimen("global","d_spac_overlay",-delta) -- for tracing + -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak + local k = new_kern(-delta) + head = insert_node_before(head,n,k) + if n_ht > p_ht then + local k = new_kern(n_ht-p_ht) + head = insert_node_before(head,p,k) + end + if trace_vspacing then + report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,skips,delta) + end + return remove_node(head,current,true) end - return remove_node(head,current,true) - end - -- goto next line - while c do - local id = getid(c) - if id == glue_code or id == penalty_code or id == kern_code then - -- skip (actually, remove) - c = getnext(c) - elseif id == hlist_code then - n = c - break - else - break - end - end - if n then - -- we have a next line, goto prev line - c = current + -- goto next line while c do local id = getid(c) - if id == glue_code or id == penalty_code then -- kern ? - c = getprev(c) + if id == glue_code or id == penalty_code or id == kern_code then + -- skip (actually, remove) + c = getnext(c) elseif id == hlist_code then - p = c + n = c break else break end end - if not p then - if a_snapmethod == a_snapvbox then - -- quit, we're not on the mvl - else - -- inefficient when we're at the end of a page - local c = tonut(texlists.page_head) - while c and c ~= n do - local id = getid(c) - if id == hlist_code then - p = c - end - c = getnext(c) + if n then + -- we have a next line, goto prev line + c = current + while c do + local id = getid(c) + if id == glue_code or id == penalty_code then -- kern ? + c = getprev(c) + elseif id == hlist_code then + p = c + break + else + break end - if p and p ~= n then - return overlay(p,n,true) + end + if not p then + if a_snapmethod == a_snapvbox then + -- quit, we're not on the mvl + else + -- inefficient when we're at the end of a page + local c = tonut(texlists.page_head) + while c and c ~= n do + local id = getid(c) + if id == hlist_code then + p = c + end + c = getnext(c) + end + if p and p ~= n then + return overlay(p,n,true) + end end + elseif p ~= n then + return overlay(p,n,false) end - elseif p ~= n then - return overlay(p,n,false) end + -- in fact, we could try again later ... so then no remove (a few tries) + return remove_node(head, current, true) end - -- in fact, we could try again later ... so then no remove (a few tries) - return remove_node(head, current, true) -end - --- This will be replaced after 0.80+ when we have a more robust look-back and --- can look at the bigger picture. - --- todo: look back and when a special is there before a list is seen penalty keep ut --- we now look back a lot, way too often - --- userskip --- lineskip --- baselineskip --- parskip --- abovedisplayskip --- belowdisplayskip --- abovedisplayshortskip --- belowdisplayshortskip --- topskip --- splittopskip - -local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail - if trace then - reset_tracing(head) - end - local current, oldhead = head, head - local glue_order, glue_data, force_glue = 0, nil, false - local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil - local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false - local lastsnap = nil - -- - -- todo: keep_together: between headers - -- - local pagehead = nil - local pagetail = nil - - local function getpagelist() - if not pagehead then - pagehead = texlists.page_head - if pagehead then - pagehead = tonut(pagehead) - pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet - end - end - end - -- - local function compensate(n) - local g = 0 - while n and getid(n) == glue_code do - g = g + getwidth(n) - n = getnext(n) + local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail + if trace then + reset_tracing(head) end - if n then - local p = getprop(n,"snapper") - if p then - local extra = p.extra - if extra and extra < 0 then -- hm, extra can be unset ... needs checking - local h = p.ch -- getheight(n) - -- maybe an extra check - -- if h - extra < g then - setheight(n,h-2*extra) - p.extra = 0 - if trace_vsnapping then - report_snapper("removed extra space at top: %p",extra) - end - -- end + local current, oldhead = head, head + local glue_order, glue_data, force_glue = 0, nil, false + local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil + local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false + local lastsnap = nil + -- + -- todo: keep_together: between headers + -- + local pagehead = nil + local pagetail = nil + + local function getpagelist() + if not pagehead then + pagehead = texlists.page_head + if pagehead then + pagehead = tonut(pagehead) + pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet end end - return n end - end - -- - local function removetopsnap() - getpagelist() - if pagehead then - local n = pagehead and compensate(pagehead) - if n and n ~= pagetail then - local p = getprop(pagetail,"snapper") + -- + local function compensate(n) + local g = 0 + while n and getid(n) == glue_code do + g = g + getwidth(n) + n = getnext(n) + end + if n then + local p = getprop(n,"snapper") if p then - local e = p.extra - if e and e < 0 then - local t = texget("pagetotal") - if t > 0 then - local g = texget("pagegoal") -- 1073741823 is signal - local d = g - t - if d < -e then - local penalty = new_penalty(1000000) - setlink(penalty,head) - head = penalty - report_snapper("force pagebreak due to extra space at bottom: %p",e) + local extra = p.extra + if extra and extra < 0 then -- hm, extra can be unset ... needs checking + local h = p.ch -- getheight(n) + -- maybe an extra check + -- if h - extra < g then + setheight(n,h-2*extra) + p.extra = 0 + if trace_vsnapping then + report_snapper("removed extra space at top: %p",extra) end - end + -- end end end + return n end - elseif head then - compensate(head) end - end - -- - local function getavailable() - getpagelist() - if pagehead then - local t = texget("pagetotal") - if t > 0 then - local g = texget("pagegoal") - return g - t + -- + local function removetopsnap() + getpagelist() + if pagehead then + local n = pagehead and compensate(pagehead) + if n and n ~= pagetail then + local p = getprop(pagetail,"snapper") + if p then + local e = p.extra + if e and e < 0 then + local t = texget("pagetotal") + if t > 0 then + local g = texget("pagegoal") -- 1073741823 is signal + local d = g - t + if d < -e then + local penalty = new_penalty(1000000) + setlink(penalty,head) + head = penalty + report_snapper("force pagebreak due to extra space at bottom: %p",e) + end + end + end + end + end + elseif head then + compensate(head) end end - return false - end - -- - local function flush(why) - if penalty_data then - local p = new_penalty(penalty_data) - if trace then - trace_done("flushed due to " .. why,p) - end - if penalty_data >= 10000 then -- or whatever threshold? - local prev = getprev(current) - if getid(prev) == glue_code then -- maybe go back more, or maybe even push back before any glue - -- tricky case: spacing/grid-007.tex: glue penalty glue - head = insert_node_before(head,prev,p) - else - head = insert_node_before(head,current,p) + -- + local function getavailable() + getpagelist() + if pagehead then + local t = texget("pagetotal") + if t > 0 then + local g = texget("pagegoal") + return g - t end - else - head = insert_node_before(head,current,p) - end - -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then - local props = properties[p] - if props then - props.special_penalty = special_penalty or penalty_data - else - properties[p] = { - special_penalty = special_penalty or penalty_data - } end - -- end + return false end - if glue_data then - if force_glue then + -- + local function flush(why) + if penalty_data then + local p = new_penalty(penalty_data) if trace then - trace_done("flushed due to forced " .. why,glue_data) + trace_done("flushed due to " .. why,p) end - head = forced_skip(head,current,getwidth(glue_data,width),"before",trace) - flush_node(glue_data) - else - local width, stretch, shrink = getglue(glue_data) - if width ~= 0 then - if trace then - trace_done("flushed due to non zero " .. why,glue_data) + if penalty_data >= 10000 then -- or whatever threshold? + local prev = getprev(current) + if getid(prev) == glue_code then -- maybe go back more, or maybe even push back before any glue + -- tricky case: spacing/grid-007.tex: glue penalty glue + head = insert_node_before(head,prev,p) + else + head = insert_node_before(head,current,p) end - head = insert_node_before(head,current,glue_data) - elseif stretch ~= 0 or shrink ~= 0 then + else + head = insert_node_before(head,current,p) + end + -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then + local props = properties[p] + if props then + props.special_penalty = special_penalty or penalty_data + else + properties[p] = { + special_penalty = special_penalty or penalty_data + } + end + -- end + end + if glue_data then + if force_glue then if trace then - trace_done("flushed due to stretch/shrink in" .. why,glue_data) + trace_done("flushed due to forced " .. why,glue_data) end - head = insert_node_before(head,current,glue_data) - else - -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w) + head = forced_skip(head,current,getwidth(glue_data,width),"before",trace) flush_node(glue_data) + else + local width, stretch, shrink = getglue(glue_data) + if width ~= 0 then + if trace then + trace_done("flushed due to non zero " .. why,glue_data) + end + head = insert_node_before(head,current,glue_data) + elseif stretch ~= 0 or shrink ~= 0 then + if trace then + trace_done("flushed due to stretch/shrink in" .. why,glue_data) + end + head = insert_node_before(head,current,glue_data) + else + -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w) + flush_node(glue_data) + end end end - end + if trace then + trace_node(current) + end + glue_order, glue_data, force_glue = 0, nil, false + penalty_order, penalty_data, natural_penalty = 0, nil, nil + parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false + end + -- + if trace_vsnapping then + report_snapper("global ht/dp = %p/%p, local ht/dp = %p/%p", + texgetdimen("globalbodyfontstrutheight"), + texgetdimen("globalbodyfontstrutdepth"), + texgetdimen("bodyfontstrutheight"), + texgetdimen("bodyfontstrutdepth") + ) + end if trace then - trace_node(current) + trace_info("start analyzing",where,what) end - glue_order, glue_data, force_glue = 0, nil, false - penalty_order, penalty_data, natural_penalty = 0, nil, nil - parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false - end - -- - if trace_vsnapping then - report_snapper("global ht/dp = %p/%p, local ht/dp = %p/%p", - texgetdimen("globalbodyfontstrutheight"), - texgetdimen("globalbodyfontstrutdepth"), - texgetdimen("bodyfontstrutheight"), - texgetdimen("bodyfontstrutdepth") - ) - end - if trace then - trace_info("start analyzing",where,what) - end - if snap and where == "page" then - removetopsnap() - end - while current do - local id = getid(current) - if id == hlist_code or id == vlist_code then - -- needs checking, why so many calls - if snap then - lastsnap = nil - local list = getlist(current) - local s = getattr(current,a_snapmethod) - if not s then - -- if trace_vsnapping then - -- report_snapper("mvl list not snapped") - -- end - elseif s == 0 then - if trace_vsnapping then - report_snapper("mvl %a not snapped, already done: %s",nodecodes[id],listtoutf(list)) - end - else - local sv = snapmethods[s] - if sv then - -- check if already snapped - local done = list and already_done(id,list,a_snapmethod) - if done then - -- assume that the box is already snapped - if trace_vsnapping then - local w, h, d = getwhd(current) - report_snapper("mvl list already snapped at (%p,%p): %s",h,d,listtoutf(list)) - end - else - local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false) - lastsnap = { - ht = h, - dp = d, - ch = ch, - cd = cd, - extra = extra, - current = current, - } - setprop(current,"snapper",lastsnap) - if trace_vsnapping then - report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", - nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list)) + if snap and where == "page" then + removetopsnap() + end + while current do + local id = getid(current) + if id == hlist_code or id == vlist_code then + -- needs checking, why so many calls + if snap then + lastsnap = nil + local list = getlist(current) + local s = getattr(current,a_snapmethod) + if not s then + -- if trace_vsnapping then + -- report_snapper("mvl list not snapped") + -- end + elseif s == 0 then + if trace_vsnapping then + report_snapper("mvl %a not snapped, already done: %s",nodecodes[id],listtoutf(list)) + end + else + local sv = snapmethods[s] + if sv then + -- check if already snapped + local done = list and already_done(id,list,a_snapmethod) + if done then + -- assume that the box is already snapped + if trace_vsnapping then + local w, h, d = getwhd(current) + report_snapper("mvl list already snapped at (%p,%p): %s",h,d,listtoutf(list)) + end + else + local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false) + lastsnap = { + ht = h, + dp = d, + ch = ch, + cd = cd, + extra = extra, + current = current, + } + setprop(current,"snapper",lastsnap) + if trace_vsnapping then + report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", + nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list)) + end end + elseif trace_vsnapping then + report_snapper("mvl %a not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list)) end - elseif trace_vsnapping then - report_snapper("mvl %a not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list)) + setattr(current,a_snapmethod,0) end - setattr(current,a_snapmethod,0) + else + -- end - else - -- - end - -- tex.prevdepth = 0 - flush("list") - current = getnext(current) - elseif id == penalty_code then - -- natural_penalty = getpenalty(current) - -- if trace then - -- trace_done("removed penalty",current) - -- end - -- head, current = remove_node(head, current, true) - current = getnext(current) - elseif id == kern_code then - if snap and trace_vsnapping and getkern(current) ~= 0 then - report_snapper("kern of %p kept",getkern(current)) - end - flush("kern") - current = getnext(current) - elseif id == glue_code then - local subtype = getsubtype(current) - if subtype == userskip_code then - local sc = getattr(current,a_skipcategory) -- has no default, no unset (yet) - local so = getattr(current,a_skiporder) or 1 -- has 1 default, no unset (yet) - local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet) - if sp and sc == penalty then - if where == "page" then - getpagelist() - local p = specialmethods[specialmethod](pagehead,pagetail,current,sp) - if p then - -- todo: other tracer - -- - -- if trace then - -- trace_skip("previous special penalty %a is changed to %a using method %a",sp,p,specialmethod) - -- end - special_penalty = sp - sp = p + -- tex.prevdepth = 0 + flush("list") + current = getnext(current) + elseif id == penalty_code then + -- natural_penalty = getpenalty(current) + -- if trace then + -- trace_done("removed penalty",current) + -- end + -- head, current = remove_node(head, current, true) + current = getnext(current) + elseif id == kern_code then + if snap and trace_vsnapping and getkern(current) ~= 0 then + report_snapper("kern of %p kept",getkern(current)) + end + flush("kern") + current = getnext(current) + elseif id == glue_code then + local subtype = getsubtype(current) + if subtype == userskip_code then + local sc = getattr(current,a_skipcategory) -- has no default, no unset (yet) + local so = getattr(current,a_skiporder) or 1 -- has 1 default, no unset (yet) + local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet) + if sp and sc == penalty then + if where == "page" then + getpagelist() + local p = specialmethods[specialmethod](pagehead,pagetail,current,sp) + if p then + -- todo: other tracer + -- + -- if trace then + -- trace_skip("previous special penalty %a is changed to %a using method %a",sp,p,specialmethod) + -- end + special_penalty = sp + sp = p + end end - end - if not penalty_data then - penalty_data = sp - elseif penalty_order < so then - penalty_order, penalty_data = so, sp - elseif penalty_order == so and sp > penalty_data then - penalty_data = sp - end - if trace then - trace_skip("penalty in skip",sc,so,sp,current) - end - head, current = remove_node(head, current, true) - elseif not sc then -- if not sc then - if glue_data then - if trace then - trace_done("flush",glue_data) + if not penalty_data then + penalty_data = sp + elseif penalty_order < so then + penalty_order, penalty_data = so, sp + elseif penalty_order == so and sp > penalty_data then + penalty_data = sp end - head = insert_node_before(head,current,glue_data) if trace then - trace_natural("natural",current) + trace_skip("penalty in skip",sc,so,sp,current) end - current = getnext(current) - else - -- not look back across head - -- todo: prev can be whatsit (latelua) - local previous = getprev(current) - if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then - local pwidth, pstretch, pshrink, pstretch_order, pshrink_order = getglue(previous) - local cwidth, cstretch, cshrink, cstretch_order, cshrink_order = getglue(current) - if pstretch_order == 0 and pshrink_order == 0 and cstretch_order == 0 and cshrink_order == 0 then - setglue(previous,pwidth + cwidth, pstretch + cstretch, pshrink + cshrink) - if trace then - trace_natural("removed",current) - end - head, current = remove_node(head, current, true) - if trace then - trace_natural("collapsed",previous) + head, current = remove_node(head, current, true) + elseif not sc then -- if not sc then + if glue_data then + if trace then + trace_done("flush",glue_data) + end + head = insert_node_before(head,current,glue_data) + if trace then + trace_natural("natural",current) + end + current = getnext(current) + else + -- not look back across head + -- todo: prev can be whatsit (latelua) + local previous = getprev(current) + if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then + local pwidth, pstretch, pshrink, pstretch_order, pshrink_order = getglue(previous) + local cwidth, cstretch, cshrink, cstretch_order, cshrink_order = getglue(current) + if pstretch_order == 0 and pshrink_order == 0 and cstretch_order == 0 and cshrink_order == 0 then + setglue(previous,pwidth + cwidth, pstretch + cstretch, pshrink + cshrink) + if trace then + trace_natural("removed",current) + end + head, current = remove_node(head, current, true) + if trace then + trace_natural("collapsed",previous) + end + else + if trace then + trace_natural("filler",current) + end + current = getnext(current) end else if trace then - trace_natural("filler",current) + trace_natural("natural (no prev)",current) end current = getnext(current) end - else + end + glue_order, glue_data = 0, nil + elseif sc == disable or sc == enable then + local next = getnext(current) + if next then + ignore_following = sc == disable if trace then - trace_natural("natural (no prev)",current) + trace_skip(sc == disable and "disable" or "enable",sc,so,sp,current) end - current = getnext(current) + head, current = remove_node(head, current, true) + else + current = next end - end - glue_order, glue_data = 0, nil - elseif sc == disable or sc == enable then - local next = getnext(current) - if next then - ignore_following = sc == disable + elseif sc == packed then if trace then - trace_skip(sc == disable and "disable" or "enable",sc,so,sp,current) + trace_skip("packed",sc,so,sp,current) end + -- can't happen ! head, current = remove_node(head, current, true) - else - current = next - end - elseif sc == together then - local next = getnext(current) - if next then - keep_together = true + elseif sc == nowhite then + local next = getnext(current) + if next then + ignore_whitespace = true + head, current = remove_node(head, current, true) + else + current = next + end + elseif sc == discard then if trace then - trace_skip("together",sc,so,sp,current) + trace_skip("discard",sc,so,sp,current) end head, current = remove_node(head, current, true) - else - current = next - end - elseif sc == nowhite then - local next = getnext(current) - if next then - ignore_whitespace = true - head, current = remove_node(head, current, true) - else - current = next - end - elseif sc == discard then - if trace then - trace_skip("discard",sc,so,sp,current) - end - head, current = remove_node(head, current, true) - elseif sc == overlay then - -- todo (overlay following line over previous - if trace then - trace_skip("overlay",sc,so,sp,current) - end - -- beware: head can actually be after the affected nodes as - -- we look back ... some day head will the real head - head, current = check_experimental_overlay(head,current,a_snapmethod) - elseif ignore_following then - if trace then - trace_skip("disabled",sc,so,sp,current) - end - head, current = remove_node(head, current, true) - elseif not glue_data then - if trace then - trace_skip("assign",sc,so,sp,current) - end - glue_order = so - head, current, glue_data = remove_node(head, current) - elseif glue_order < so then - if trace then - trace_skip("force",sc,so,sp,current) - end - glue_order = so - flush_node(glue_data) - head, current, glue_data = remove_node(head, current) - elseif glue_order == so then - -- is now exclusive, maybe support goback as combi, else why a set - if sc == largest then - local cw = getwidth(current) - local gw = getwidth(glue_data) - if cw > gw then - if trace then - trace_skip("largest",sc,so,sp,current) - end - flush_node(glue_data) - head, current, glue_data = remove_node(head,current) - else - if trace then - trace_skip("remove smallest",sc,so,sp,current) - end - head, current = remove_node(head, current, true) + elseif sc == overlay then + -- todo (overlay following line over previous + if trace then + trace_skip("overlay",sc,so,sp,current) end - elseif sc == goback then + -- beware: head can actually be after the affected nodes as + -- we look back ... some day head will the real head + head, current = check_experimental_overlay(head,current,a_snapmethod) + elseif ignore_following then if trace then - trace_skip("goback",sc,so,sp,current) + trace_skip("disabled",sc,so,sp,current) end - flush_node(glue_data) - head, current, glue_data = remove_node(head,current) - elseif sc == force then - -- last one counts, some day we can provide an accumulator and largest etc - -- but not now + head, current = remove_node(head, current, true) + elseif not glue_data then if trace then - trace_skip("force",sc,so,sp,current) + trace_skip("assign",sc,so,sp,current) end - flush_node(glue_data) + glue_order = so head, current, glue_data = remove_node(head, current) - elseif sc == penalty then + elseif glue_order < so then if trace then - trace_skip("penalty",sc,so,sp,current) + trace_skip("force",sc,so,sp,current) end + glue_order = so flush_node(glue_data) - glue_data = nil - head, current = remove_node(head, current, true) - elseif sc == add then - if trace then - trace_skip("add",sc,so,sp,current) + head, current, glue_data = remove_node(head, current) + elseif glue_order == so then + -- is now exclusive, maybe support goback as combi, else why a set + if sc == largest then + local cw = getwidth(current) + local gw = getwidth(glue_data) + if cw > gw then + if trace then + trace_skip("largest",sc,so,sp,current) + end + flush_node(glue_data) + head, current, glue_data = remove_node(head,current) + else + if trace then + trace_skip("remove smallest",sc,so,sp,current) + end + head, current = remove_node(head, current, true) + end + elseif sc == goback then + if trace then + trace_skip("goback",sc,so,sp,current) + end + flush_node(glue_data) + head, current, glue_data = remove_node(head,current) + elseif sc == force then + -- last one counts, some day we can provide an accumulator and largest etc + -- but not now + if trace then + trace_skip("force",sc,so,sp,current) + end + flush_node(glue_data) + head, current, glue_data = remove_node(head, current) + elseif sc == penalty then + if trace then + trace_skip("penalty",sc,so,sp,current) + end + flush_node(glue_data) + glue_data = nil + head, current = remove_node(head, current, true) + elseif sc == add then + if trace then + trace_skip("add",sc,so,sp,current) + end + local cwidth, cstretch, cshrink = getglue(current) + local gwidth, gstretch, gshrink = getglue(glue_data) + setglue(old,gwidth + cwidth, gstretch + cstretch, gshrink + cshrink) + -- toto: order + head, current = remove_node(head, current, true) + else + if trace then + trace_skip("unknown",sc,so,sp,current) + end + head, current = remove_node(head, current, true) end - local cwidth, cstretch, cshrink = getglue(current) - local gwidth, gstretch, gshrink = getglue(glue_data) - setglue(old,gwidth + cwidth, gstretch + cstretch, gshrink + cshrink) - -- toto: order - head, current = remove_node(head, current, true) else if trace then trace_skip("unknown",sc,so,sp,current) end head, current = remove_node(head, current, true) end - else - if trace then - trace_skip("unknown",sc,so,sp,current) + if sc == force then + force_glue = true end - head, current = remove_node(head, current, true) - end - if sc == force then - force_glue = true - end - elseif subtype == lineskip_code then - if snap then - local s = getattr(current,a_snapmethod) - if s and s ~= 0 then - setattr(current,a_snapmethod,0) - setwidth(current,0) - if trace_vsnapping then - report_snapper("lineskip set to zero") + elseif subtype == lineskip_code then + if snap then + local s = getattr(current,a_snapmethod) + if s and s ~= 0 then + setattr(current,a_snapmethod,0) + setwidth(current,0) + if trace_vsnapping then + report_snapper("lineskip set to zero") + end + else + if trace then + trace_skip("lineskip",sc,so,sp,current) + end + flush("lineskip") end else if trace then @@ -1696,21 +1701,21 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end flush("lineskip") end - else - if trace then - trace_skip("lineskip",sc,so,sp,current) - end - flush("lineskip") - end - current = getnext(current) - elseif subtype == baselineskip_code then - if snap then - local s = getattr(current,a_snapmethod) - if s and s ~= 0 then - setattr(current,a_snapmethod,0) - setwidth(current,0) - if trace_vsnapping then - report_snapper("baselineskip set to zero") + current = getnext(current) + elseif subtype == baselineskip_code then + if snap then + local s = getattr(current,a_snapmethod) + if s and s ~= 0 then + setattr(current,a_snapmethod,0) + setwidth(current,0) + if trace_vsnapping then + report_snapper("baselineskip set to zero") + end + else + if trace then + trace_skip("baselineskip",sc,so,sp,current) + end + flush("baselineskip") end else if trace then @@ -1718,53 +1723,53 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end flush("baselineskip") end - else - if trace then - trace_skip("baselineskip",sc,so,sp,current) - end - flush("baselineskip") - end - current = getnext(current) - elseif subtype == parskip_code then - -- parskip always comes later - if ignore_whitespace then - if trace then - trace_natural("ignored parskip",current) - end - head, current = remove_node(head, current, true) - elseif glue_data then - local w = getwidth(current) - if (w ~= 0) and (w > getwidth(glue_data)) then - glue_data = current + current = getnext(current) + elseif subtype == parskip_code then + -- parskip always comes later + if ignore_whitespace then if trace then - trace_natural("taking parskip",current) + trace_natural("ignored parskip",current) + end + head, current = remove_node(head, current, true) + elseif glue_data then + local w = getwidth(current) + if (w ~= 0) and (w > getwidth(glue_data)) then + glue_data = current + if trace then + trace_natural("taking parskip",current) + end + head, current = remove_node(head, current) + else + if trace then + trace_natural("removed parskip",current) + end + head, current = remove_node(head, current, true) end - head, current = remove_node(head, current) else if trace then - trace_natural("removed parskip",current) + trace_natural("honored parskip",current) end - head, current = remove_node(head, current, true) + head, current, glue_data = remove_node(head, current) end - else - if trace then - trace_natural("honored parskip",current) + elseif subtype == topskip_code or subtype == splittopskip_code then + local next = getnext(current) + if next and getattr(next,a_skipcategory) == notopskip then + nuts.setglue(current) -- zero end - head, current, glue_data = remove_node(head, current) - end - elseif subtype == topskip_code or subtype == splittopskip_code then - local next = getnext(current) - if next and getattr(next,a_skipcategory) == 10 then -- no top skip - nuts.setglue(current) -- zero - end - if snap then - local s = getattr(current,a_snapmethod) - if s and s ~= 0 then - setattr(current,a_snapmethod,0) - local sv = snapmethods[s] - local w, cw = snap_topskip(current,sv) - if trace_vsnapping then - report_snapper("topskip snapped from %p to %p for %a",w,cw,where) + if snap then + local s = getattr(current,a_snapmethod) + if s and s ~= 0 then + setattr(current,a_snapmethod,0) + local sv = snapmethods[s] + local w, cw = snap_topskip(current,sv) + if trace_vsnapping then + report_snapper("topskip snapped from %p to %p for %a",w,cw,where) + end + else + if trace then + trace_skip("topskip",sc,so,sp,current) + end + flush("topskip") end else if trace then @@ -1772,130 +1777,124 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end flush("topskip") end - else + current = getnext(current) + elseif subtype == abovedisplayskip_code and remove_math_skips then + -- if trace then - trace_skip("topskip",sc,so,sp,current) + trace_skip("above display skip (normal)",sc,so,sp,current) end - flush("topskip") - end - current = getnext(current) - elseif subtype == abovedisplayskip_code and remove_math_skips then - -- - if trace then - trace_skip("above display skip (normal)",sc,so,sp,current) - end - flush("above display skip (normal)") - current = getnext(current) - -- - elseif subtype == belowdisplayskip_code and remove_math_skips then - -- - if trace then - trace_skip("below display skip (normal)",sc,so,sp,current) - end - flush("below display skip (normal)") - current = getnext(current) - -- - elseif subtype == abovedisplayshortskip_code and remove_math_skips then - -- - if trace then - trace_skip("above display skip (short)",sc,so,sp,current) - end - flush("above display skip (short)") - current = getnext(current) - -- - elseif subtype == belowdisplayshortskip_code and remove_math_skips then - -- - if trace then - trace_skip("below display skip (short)",sc,so,sp,current) - end - flush("below display skip (short)") - current = getnext(current) - -- - else -- other glue - if snap and trace_vsnapping then - local w = getwidth(current) - if w ~= 0 then - report_snapper("glue %p of type %a kept",w,skipcodes[subtype]) + flush("above display skip (normal)") + current = getnext(current) + -- + elseif subtype == belowdisplayskip_code and remove_math_skips then + -- + if trace then + trace_skip("below display skip (normal)",sc,so,sp,current) end + flush("below display skip (normal)") + current = getnext(current) + -- + elseif subtype == abovedisplayshortskip_code and remove_math_skips then + -- + if trace then + trace_skip("above display skip (short)",sc,so,sp,current) + end + flush("above display skip (short)") + current = getnext(current) + -- + elseif subtype == belowdisplayshortskip_code and remove_math_skips then + -- + if trace then + trace_skip("below display skip (short)",sc,so,sp,current) + end + flush("below display skip (short)") + current = getnext(current) + -- + else -- other glue + if snap and trace_vsnapping then + local w = getwidth(current) + if w ~= 0 then + report_snapper("glue %p of type %a kept",w,skipcodes[subtype]) + end + end + if trace then + trace_skip(formatters["glue of type %a"](subtype),sc,so,sp,current) + end + flush("some glue") + current = getnext(current) end - if trace then - trace_skip(formatters["glue of type %a"](subtype),sc,so,sp,current) - end - flush("some glue") + else + flush(formatters["node with id %a"](id)) current = getnext(current) end - else - flush(formatters["node with id %a"](id)) - current = getnext(current) end - end - if trace then - trace_info("stop analyzing",where,what) - end - -- if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then - -- penalty_data = natural_penalty - -- end - if trace and (glue_data or penalty_data) then - trace_info("start flushing",where,what) - end - local tail - if penalty_data then - tail = find_node_tail(head) - local p = new_penalty(penalty_data) if trace then - trace_done("result",p) + trace_info("stop analyzing",where,what) end - setlink(tail,p) - -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then - local props = properties[p] - if props then - props.special_penalty = special_penalty or penalty_data - else - properties[p] = { - special_penalty = special_penalty or penalty_data - } - end + -- if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then + -- penalty_data = natural_penalty -- end - end - if glue_data then - if not tail then tail = find_node_tail(head) end - if trace then - trace_done("result",glue_data) - end - if force_glue then - head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace) - flush_node(glue_data) - glue_data = nil - elseif tail then - setlink(tail,glue_data) - else - head = glue_data + if trace and (glue_data or penalty_data) then + trace_info("start flushing",where,what) end - texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler - end - if trace then - if glue_data or penalty_data then - trace_info("stop flushing",where,what) + local tail + if penalty_data then + tail = find_node_tail(head) + local p = new_penalty(penalty_data) + if trace then + trace_done("result",p) + end + setlink(tail,p) + -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then + local props = properties[p] + if props then + props.special_penalty = special_penalty or penalty_data + else + properties[p] = { + special_penalty = special_penalty or penalty_data + } + end + -- end + end + if glue_data then + if not tail then tail = find_node_tail(head) end + if trace then + trace_done("result",glue_data) + end + if force_glue then + head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace) + flush_node(glue_data) + glue_data = nil + elseif tail then + setlink(tail,glue_data) + else + head = glue_data + end + texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler end - show_tracing(head) - if oldhead ~= head then - trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)]) + if trace then + if glue_data or penalty_data then + trace_info("stop flushing",where,what) + end + show_tracing(head) + if oldhead ~= head then + trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)]) + end end + return head, true end - return head, true -end --- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display --- \par -> vmode_par --- --- status.best_page_break --- tex.lists.best_page_break --- tex.lists.best_size (natural size to best_page_break) --- tex.lists.least_page_cost (badness of best_page_break) --- tex.lists.page_head --- tex.lists.contrib_head + -- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display + -- \par -> vmode_par + -- + -- status.best_page_break + -- tex.lists.best_page_break + -- tex.lists.best_size (natural size to best_page_break) + -- tex.lists.least_page_cost (badness of best_page_break) + -- tex.lists.page_head + -- tex.lists.contrib_head -do + -- do local stackhead, stacktail, stackhack = nil, nil, false @@ -1933,13 +1932,14 @@ do elseif subtype == parskip_code then -- if where == new_graf then ... end if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then - texsetcount("c_spac_vspacing_ignore_parskip",0) +-- texsetcount("c_spac_vspacing_ignore_parskip",0) setglue(n) -- maybe removenode end end end end + texsetcount("c_spac_vspacing_ignore_parskip",0) if flush then if stackhead then if trace_collect_vspacing then report("%s > appending %s nodes to stack (final): %s",where,newhead) end @@ -1973,10 +1973,6 @@ do return nil end -end - -do - local ignore = table.tohash { "split_keep", "split_off", diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index 98e46fa39..a1bc0559f 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -1956,6 +1956,7 @@ \newconditional\c_space_vspacing_done \newconditional\c_space_vspacing_fixed +\newconditional\c_space_ignore_parskip \appendtoks \s_spac_vspacing_temp\zeropoint @@ -1978,6 +1979,9 @@ \relax \to \everyafterblankhandling +\unexpanded\def\setblankpacked + {\settrue\c_space_ignore_parskip} + \unexpanded\def\setblankcategory#1% {\settrue\c_space_vspacing_done \attribute\skipcategoryattribute#1\relax} @@ -2016,6 +2020,7 @@ \def\dostartblankhandling {\begingroup \setfalse\c_space_vspacing_done + \setfalse\c_space_ignore_parskip \the\everybeforeblankhandling} \unexpanded\def\stopblankhandling @@ -2023,7 +2028,11 @@ \ifconditional\c_space_vspacing_done \vskip\s_spac_vspacing_temp \fi - \endgroup} + \ifconditional\c_space_ignore_parskip + \endgroup\ignoreparskip + \else + \endgroup + \fi} \unexpanded\def\flushblankhandling {\the\everyafterblankhandling @@ -2210,10 +2219,13 @@ \definevspacing[\v!disable] [category:5] \definevspacing[\v!nowhite] [category:6] \definevspacing[\v!back] [category:7] -% together [category:8] +\definevspacing[\v!packed] [category:8] % noparskip (kind of special) \definevspacing[\v!overlay] [category:9] \definevspacing[\v!enable] [category:10] +%definevspacing[\v!noparskip] [category:8] +%definevspacing[\v!notopskip] [category:11] + \definevspacing[\v!weak] [order:0] \definevspacing[\v!strong] [order:100] diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex b5094c116..319680a90 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 5ee29c774..767fa89ad 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/util-sql-loggers.lua b/tex/context/base/mkiv/util-sql-loggers.lua index 7e64a435a..7cf4f6175 100644 --- a/tex/context/base/mkiv/util-sql-loggers.lua +++ b/tex/context/base/mkiv/util-sql-loggers.lua @@ -78,6 +78,7 @@ local sqlite_template = [[ function loggers.createdb(presets,datatable) local db = checkeddb(presets,datatable) + db.execute { template = (db.usedmethod == "sqlite" or db.usedmethod == "sqlffi") and sqlite_template or template, variables = { diff --git a/tex/context/base/mkiv/util-sql-logins.lua b/tex/context/base/mkiv/util-sql-logins.lua index e4329ecc2..9717a8175 100644 --- a/tex/context/base/mkiv/util-sql-logins.lua +++ b/tex/context/base/mkiv/util-sql-logins.lua @@ -27,7 +27,13 @@ logins.cooldowntime = logins.cooldowntime or 10 * 60 logins.purgetime = logins.purgetime or 1 * 60 * 60 logins.autopurge = true -local template_create = [[ +local function checkeddb(presets,datatable) + return sql.usedatabase(presets,datatable or presets.datatable or "logins") +end + +logins.usedb = checkeddb + +local template = [[ CREATE TABLE `logins` ( @@ -46,6 +52,42 @@ CREATE TABLE COMMENT='state: 0=unset 1=known 2=unknown' ]] +function logins.createdb(presets,datatable) + + local db = checkeddb(presets,datatable) + + local data, keys = db.execute { + template = template, + variables = { + basename = db.basename, + }, + } + + report_logins("datatable %a created in %a",db.name,db.base) + + return db + +end + +local template =[[ + DROP TABLE IF EXISTS %basename% ; +]] + +function logins.deletedb(presets,datatable) + + local db = checkeddb(presets,datatable) + + local data, keys = db.execute { + template = template, + variables = { + basename = db.basename, + }, + } + + report_logins("datatable %a removed in %a",db.name,db.base) + +end + local states = { [0] = "unset", [1] = "known", @@ -105,58 +147,54 @@ local template_purge = [[ local cache = { } setmetatable(cache, { __mode = 'v' }) -local function usercreate(presets) - sqlexecute { - template = template_create, - presets = presets, - } -end +-- local function usercreate(presets) +-- sqlexecute { +-- template = template_create, +-- presets = presets, +-- } +-- end -local function userunknown(presets,name) +function logins.userunknown(db,name) local d = { name = name, state = 2, time = ostime(), n = 0, } - sqlexecute { + db.execute { template = template_update, - presets = presets, variables = d, } cache[name] = d report_logins("user %a is registered as unknown",name) end -local function userknown(presets,name) +function logins.userknown(db,name) local d = { name = name, state = 1, time = ostime(), n = 0, } - sqlexecute { + db.execute { template = template_update, - presets = presets, variables = d, } cache[name] = d report_logins("user %a is registered as known",name) end -local function userreset(presets,name) - sqlexecute { +function logins.userreset(db,name) + db.execute { template = template_delete, - presets = presets, } cache[name] = nil report_logins("user %a is reset",name) end -local function userpurge(presets,delay) - sqlexecute { +local function userpurge(db,delay) + db.execute { template = template_purge, - presets = presets, variables = { time = ostime() - (delay or logins.purgetime), } @@ -165,6 +203,8 @@ local function userpurge(presets,delay) report_logins("users are purged") end +logins.userpurge = userpurge + local function verdict(okay,...) if not trace_logins then -- no tracing @@ -178,11 +218,11 @@ end local lasttime = 0 -local function userpermitted(presets,name) +function logins.userpermitted(db,name) local currenttime = ostime() if logins.autopurge and (lasttime == 0 or (currenttime - lasttime > logins.purgetime)) then report_logins("automatic purge triggered") - userpurge(presets) + userpurge(db) lasttime = currenttime end local data = cache[name] @@ -190,9 +230,8 @@ local function userpermitted(presets,name) report_logins("user %a is cached",name) else report_logins("user %a is fetched",name) - data = sqlexecute { + data = db.execute { template = template_fetch, - presets = presets, converter = converter_fetch, variables = { name = name, @@ -206,9 +245,8 @@ local function userpermitted(presets,name) time = currenttime, n = 1, } - sqlexecute { + db.execute { template = template_insert, - presets = presets, variables = d, } cache[name] = d @@ -237,9 +275,8 @@ local function userpermitted(presets,name) time = currenttime, n = 1, } - sqlexecute { + db.execute { template = template_update, - presets = presets, variables = d, } cache[name] = d @@ -251,9 +288,8 @@ local function userpermitted(presets,name) time = currenttime, n = n + 1, } - sqlexecute { + db.execute { template = template_update, - presets = presets, variables = d, } cache[name] = d @@ -261,46 +297,4 @@ local function userpermitted(presets,name) end end -logins.create = usercreate -logins.known = userknown -logins.unknown = userunknown -logins.reset = userreset -logins.purge = userpurge -logins.permitted = userpermitted - return logins - --- -- - --- sql.setmethod("client") - --- local presets = { --- database = "test", --- username = "root", --- password = "something", --- } - --- logins.cooldowntime = 2*60 --- logins.maxnoflogins = 3 - --- sql.logins.purge(presets,0) - --- for i=1,6 do --- print("") --- sql.logins.permitted(presets,"hans") --- sql.logins.permitted(presets,"kees") --- sql.logins.permitted(presets,"ton") --- if i == 1 then --- -- sql.logins.unknown(presets,"hans") --- -- sql.logins.known(presets,"kees") --- end --- end - --- if loginpermitted(presets,username) then --- if validlogin(username,...) then --- -- sql.logins.known(presets,username) --- elseif unknownuser(username) then --- sql.logins.unknown(presets,username) --- end --- end - diff --git a/tex/context/base/mkiv/util-sql-tickets.lua b/tex/context/base/mkiv/util-sql-tickets.lua index f392c0b91..68e54a015 100644 --- a/tex/context/base/mkiv/util-sql-tickets.lua +++ b/tex/context/base/mkiv/util-sql-tickets.lua @@ -18,6 +18,8 @@ local ostime, uuid, osfulltime = os.time, os.uuid, os.fulltime local random = math.random local concat = table.concat +if not utilities.sql then require("util-sql") end + local sql = utilities.sql local tickets = { } sql.tickets = tickets @@ -27,7 +29,6 @@ local report = logs.reporter("sql","tickets") local serialize = sql.serialize local deserialize = sql.deserialize -local execute = sql.execute tickets.newtoken = sql.tokens.new @@ -87,7 +88,9 @@ local template =[[ ]] function tickets.createdb(presets,datatable) + local db = checkeddb(presets,datatable) + local data, keys = db.execute { template = template, variables = { diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 89f2650f2..c0308086c 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -1083,6 +1083,7 @@ <cd:constant name='preview' value='previzualizare'/> <cd:constant name='previous' value='precendent'/> <cd:constant name='previousnumber' value='numarprecedent'/> + <cd:constant name='print' value='print'/> <cd:constant name='printable' value='tiparibil'/> <cd:constant name='process' value='process'/> <cd:constant name='profile' value='profile'/> diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml index 83ef9fb62..bc8e96fbf 100644 --- a/tex/context/interface/mkiv/context-en.xml +++ b/tex/context/interface/mkiv/context-en.xml @@ -44488,6 +44488,7 @@ <cd:constant type="enable"/> <cd:constant type="disable"/> <cd:constant type="nowhite"/> + <cd:constant type="packed"/> <cd:constant type="back"/> <cd:constant type="overlay"/> <cd:constant type="always"/> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex ac301f450..c53f0ae43 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex d7c363731..39d5fb89d 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/interface/mkiv/i-vspace.xml b/tex/context/interface/mkiv/i-vspace.xml index 9e1836dbc..ce6d5ac08 100644 --- a/tex/context/interface/mkiv/i-vspace.xml +++ b/tex/context/interface/mkiv/i-vspace.xml @@ -31,6 +31,7 @@ <cd:constant type="enable"/> <cd:constant type="disable"/> <cd:constant type="nowhite"/> + <cd:constant type="packed"/> <cd:constant type="back"/> <cd:constant type="overlay"/> <cd:constant type="always"/> @@ -212,4 +213,4 @@ <cd:command name="bigskip" level="system" category="whitespace" file="spac-ver.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 1670e68e3..b8aa715ed 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 : 03/07/18 12:18:24 +-- merge date : 03/10/18 14:52:21 do -- begin closure to overcome local limits and interference |