diff options
Diffstat (limited to 'tex/context/base/typo-pag.lua')
-rw-r--r-- | tex/context/base/typo-pag.lua | 358 |
1 files changed, 179 insertions, 179 deletions
diff --git a/tex/context/base/typo-pag.lua b/tex/context/base/typo-pag.lua index 0dd75ddf9..d39748d26 100644 --- a/tex/context/base/typo-pag.lua +++ b/tex/context/base/typo-pag.lua @@ -1,179 +1,179 @@ -if not modules then modules = { } end modules ['typo-pag'] = { - version = 1.001, - comment = "companion to typo-pag.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - -local nodecodes = nodes.nodecodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local penalty_code = nodecodes.penalty - -local insert_node_after = node.insert_after -local new_penalty = nodes.pool.penalty - -local unsetvalue = attributes.unsetvalue - -local a_keeptogether = attributes.private("keeptogether") - -local trace_keeptogether = false -local report_keeptogether = logs.reporter("parbuilders","keeptogether") - -local cache = { } -local last = 0 -local enabled = false - -trackers.register("parbuilders.keeptogether", function(v) trace_keeptogether = v end) - --- todo: also support lines = 3 etc (e.g. dropped caps) but how to set that --- when no hlists are there ? ... maybe the local_par - -function builders.paragraphs.registertogether(line,specification) -- might change - if not enabled then - nodes.tasks.enableaction("finalizers","builders.paragraphs.keeptogether") - end - local a = line[a_keeptogether] - local c = a and cache[a] - if c then - local height = specification.height - local depth = specification.depth - local slack = specification.slack - if height and height > c.height then - c.height = height - end - if depth and depth > c.depth then - c.depth = depth - end - if slack and slack > c.slack then - c.slack = slack - end - else - last = last + 1 - cache[last] = specification - if not specification.height then - specification.height = 0 - end - if not specification.depth then - specification.depth = 0 - end - if not specification.slack then - specification.slack = 0 - end - line[a_keeptogether] = last - end - if trace_keeptogether then - local a = a or last - local c = cache[a] - if trace_keeptogether then - local noflines = specification.lineheight - local height = c.height - local depth = c.depth - local slack = c.slack - if not noflines or noflines == 0 then - noflines = "unknown" - else - noflines = math.round((height + depth - slack) / noflines) - end - report_keeptogether("registered, index %s, height %p, depth %p, slack %p, noflines %a",a,height,depth,slack,noflines) - end - end -end - -local function keeptogether(start,a) - if start then - local specification = cache[a] - if a then - local current = start.next - local previous = start - local total = previous.depth - local slack = specification.slack - local threshold = specification.depth - slack - if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p, slack %p","list",a,total,threshold,slack) - end - while current do - local id = current.id - if id == vlist_code or id == hlist_code then - total = total + current.height + current.depth - if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p","list",a,total,threshold) - end - if total <= threshold then - if previous.id == penalty_code then - previous.penalty = 10000 - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == glue_code then - -- hm, breakpoint, maybe turn this into kern - total = total + current.spec.width - if trace_keeptogether then - report_keeptogether("%s, index %s, total %p, threshold %p","glue",a,total,threshold) - end - if total <= threshold then - if previous.id == penalty_code then - previous.penalty = 10000 - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == kern_code then - total = total + current.kern - if trace_keeptogether then - report_keeptogether("%s, index %s, total %s, threshold %s","kern",a,total,threshold) - end - if total <= threshold then - if previous.id == penalty_code then - previous.penalty = 10000 - else - insert_node_after(head,previous,new_penalty(10000)) - end - else - break - end - elseif id == penalty_code then - if total <= threshold then - if previous.id == penalty_code then - previous.penalty = 10000 - end - current.penalty = 10000 - else - break - end - end - previous = current - current = current.next - end - end - end -end - --- also look at first non glue/kern node e.g for a dropped caps - -function builders.paragraphs.keeptogether(head) - local done = false - local current = head - while current do - if current.id == hlist_code then - local a = current[a_keeptogether] - if a and a > 0 then - keeptogether(current,a) - current[a_keeptogether] = unsetvalue - cache[a] = nil - done = true - end - end - current = current.next - end - return head, done -end +if not modules then modules = { } end modules ['typo-pag'] = {
+ version = 1.001,
+ comment = "companion to typo-pag.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local nodecodes = nodes.nodecodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+local penalty_code = nodecodes.penalty
+
+local insert_node_after = node.insert_after
+local new_penalty = nodes.pool.penalty
+
+local unsetvalue = attributes.unsetvalue
+
+local a_keeptogether = attributes.private("keeptogether")
+
+local trace_keeptogether = false
+local report_keeptogether = logs.reporter("parbuilders","keeptogether")
+
+local cache = { }
+local last = 0
+local enabled = false
+
+trackers.register("parbuilders.keeptogether", function(v) trace_keeptogether = v end)
+
+-- todo: also support lines = 3 etc (e.g. dropped caps) but how to set that
+-- when no hlists are there ? ... maybe the local_par
+
+function builders.paragraphs.registertogether(line,specification) -- might change
+ if not enabled then
+ nodes.tasks.enableaction("finalizers","builders.paragraphs.keeptogether")
+ end
+ local a = line[a_keeptogether]
+ local c = a and cache[a]
+ if c then
+ local height = specification.height
+ local depth = specification.depth
+ local slack = specification.slack
+ if height and height > c.height then
+ c.height = height
+ end
+ if depth and depth > c.depth then
+ c.depth = depth
+ end
+ if slack and slack > c.slack then
+ c.slack = slack
+ end
+ else
+ last = last + 1
+ cache[last] = specification
+ if not specification.height then
+ specification.height = 0
+ end
+ if not specification.depth then
+ specification.depth = 0
+ end
+ if not specification.slack then
+ specification.slack = 0
+ end
+ line[a_keeptogether] = last
+ end
+ if trace_keeptogether then
+ local a = a or last
+ local c = cache[a]
+ if trace_keeptogether then
+ local noflines = specification.lineheight
+ local height = c.height
+ local depth = c.depth
+ local slack = c.slack
+ if not noflines or noflines == 0 then
+ noflines = "unknown"
+ else
+ noflines = math.round((height + depth - slack) / noflines)
+ end
+ report_keeptogether("registered, index %s, height %p, depth %p, slack %p, noflines %a",a,height,depth,slack,noflines)
+ end
+ end
+end
+
+local function keeptogether(start,a)
+ if start then
+ local specification = cache[a]
+ if a then
+ local current = start.next
+ local previous = start
+ local total = previous.depth
+ local slack = specification.slack
+ local threshold = specification.depth - slack
+ if trace_keeptogether then
+ report_keeptogether("%s, index %s, total %p, threshold %p, slack %p","list",a,total,threshold,slack)
+ end
+ while current do
+ local id = current.id
+ if id == vlist_code or id == hlist_code then
+ total = total + current.height + current.depth
+ if trace_keeptogether then
+ report_keeptogether("%s, index %s, total %p, threshold %p","list",a,total,threshold)
+ end
+ if total <= threshold then
+ if previous.id == penalty_code then
+ previous.penalty = 10000
+ else
+ insert_node_after(head,previous,new_penalty(10000))
+ end
+ else
+ break
+ end
+ elseif id == glue_code then
+ -- hm, breakpoint, maybe turn this into kern
+ total = total + current.spec.width
+ if trace_keeptogether then
+ report_keeptogether("%s, index %s, total %p, threshold %p","glue",a,total,threshold)
+ end
+ if total <= threshold then
+ if previous.id == penalty_code then
+ previous.penalty = 10000
+ else
+ insert_node_after(head,previous,new_penalty(10000))
+ end
+ else
+ break
+ end
+ elseif id == kern_code then
+ total = total + current.kern
+ if trace_keeptogether then
+ report_keeptogether("%s, index %s, total %s, threshold %s","kern",a,total,threshold)
+ end
+ if total <= threshold then
+ if previous.id == penalty_code then
+ previous.penalty = 10000
+ else
+ insert_node_after(head,previous,new_penalty(10000))
+ end
+ else
+ break
+ end
+ elseif id == penalty_code then
+ if total <= threshold then
+ if previous.id == penalty_code then
+ previous.penalty = 10000
+ end
+ current.penalty = 10000
+ else
+ break
+ end
+ end
+ previous = current
+ current = current.next
+ end
+ end
+ end
+end
+
+-- also look at first non glue/kern node e.g for a dropped caps
+
+function builders.paragraphs.keeptogether(head)
+ local done = false
+ local current = head
+ while current do
+ if current.id == hlist_code then
+ local a = current[a_keeptogether]
+ if a and a > 0 then
+ keeptogether(current,a)
+ current[a_keeptogether] = unsetvalue
+ cache[a] = nil
+ done = true
+ end
+ end
+ current = current.next
+ end
+ return head, done
+end
|