From 22570ae5671af164143a1831310fe3d4b73f4983 Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Mon, 3 Aug 2015 16:15:04 +0200 Subject: 2015-08-03 15:35:00 --- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4210 -> 4199 bytes tex/context/base/context.mkiv | 8 +- tex/context/base/math-noa.lua | 2 + tex/context/base/mult-low.lua | 3 +- tex/context/base/pack-com.mkiv | 60 +- tex/context/base/pack-rul.lua | 17 +- tex/context/base/page-lin.lua | 83 +- tex/context/base/scrn-ini.mkvi | 2 +- tex/context/base/spac-ali.mkiv | 4 + tex/context/base/spac-prf.lua | 958 +++++++++++++++++++++ tex/context/base/spac-prf.mkiv | 31 - tex/context/base/spac-prf.mkvi | 117 +++ tex/context/base/status-files.pdf | Bin 24403 -> 24460 bytes tex/context/base/status-lua.pdf | Bin 255423 -> 255415 bytes tex/context/base/strc-con.mkvi | 28 +- tex/context/base/strc-not.mkvi | 7 +- tex/context/base/task-ini.lua | 52 +- tex/context/base/trac-vis.lua | 2 +- tex/context/base/typo-dha.lua | 410 +++++---- tex/context/base/typo-dir.mkiv | 2 +- tex/context/base/typo-mar.lua | 19 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- tex/generic/context/luatex/luatex-test.tex | 2 +- 24 files changed, 1434 insertions(+), 377 deletions(-) create mode 100644 tex/context/base/spac-prf.lua delete mode 100644 tex/context/base/spac-prf.mkiv create mode 100644 tex/context/base/spac-prf.mkvi (limited to 'tex') diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index dc278f6cd..c19f3f4a2 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2015.07.28 19:12} +\newcontextversion{2015.08.03 15:33} %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/context-version.pdf b/tex/context/base/context-version.pdf index 95d044ee5..febc7fa42 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 1f811fe07..baef083fc 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2015.07.28 19:12} +\edef\contextversion{2015.08.03 15:33} \edef\contextkind {beta} %D For those who want to use this: @@ -271,11 +271,7 @@ \loadmarkfile{spac-par} %loadmarkfile{spac-adj} % no longer needed \loadmarkfile{spac-def} - -\doiffileelse{spac-prf.mkvi} - {\loadmkvifile{spac-prf}} - {\loadmkivfile{spac-prf}} - +\loadmkvifile{spac-prf} \loadmarkfile{spac-grd} %loadmarkfile{anch-pos} diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index b11105cd0..6d3662b8f 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -19,6 +19,8 @@ if not modules then modules = { } end modules ['math-noa'] = { -- 20D6 -> 2190 -- 20D7 -> 2192 +-- todo: most is math_char so we can have simple dedicated loops + local utfchar, utfbyte = utf.char, utf.byte local formatters = string.formatters local sortedhash = table.sortedhash diff --git a/tex/context/base/mult-low.lua b/tex/context/base/mult-low.lua index 6d299ec08..90c45b493 100644 --- a/tex/context/base/mult-low.lua +++ b/tex/context/base/mult-low.lua @@ -211,7 +211,7 @@ return { -- "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", -- - "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", + "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", -- "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", @@ -400,6 +400,7 @@ return { "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", + "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft","synchronizelayoutdirection","synchronizedisplaydirection","synchronizeinlinedirection", -- "lesshyphens", "morehyphens", "nohyphens", "dohyphens", diff --git a/tex/context/base/pack-com.mkiv b/tex/context/base/pack-com.mkiv index b734d6028..2508c6041 100644 --- a/tex/context/base/pack-com.mkiv +++ b/tex/context/base/pack-com.mkiv @@ -76,20 +76,60 @@ \global\resetsystemmode{combination}% \to \everyinsidefloat -\newcount\c_pack_combinations_x -\newcount\c_pack_combinations_n -\newcount\c_pack_combinations_max -\newbox \b_pack_combinations_captions -\newbox \b_pack_combinations_content -\newbox \b_pack_combinations_caption -\newbox \b_pack_combinations_temp % global +\newcount\c_pack_combinations_nesting % local +\newcount\c_pack_combinations_x % global +\newcount\c_pack_combinations_n % global +\newcount\c_pack_combinations_max % global +\newbox \b_pack_combinations_captions % global +\newbox \b_pack_combinations_temp % global +\newbox \b_pack_combinations_content % local +\newbox \b_pack_combinations_caption % local \installcorenamespace{combination} \installcommandhandler \??combination {combination} \??combination +\initializeboxstack{\??combination captions} +\initializeboxstack{\??combination temp} + +\newcount\c_pack_combinations_x_saved +\newcount\c_pack_combinations_n_saved +\newcount\c_pack_combinations_max_saved +\newbox \b_pack_combinations_captions_saved +\newbox \b_pack_combinations_temp_saved +\newbox \b_pack_combinations_content_saved +\newbox \b_pack_combinations_caption_saved + \setfalse\c_strc_constructions_define_commands +\def\pack_combinations_push + {\advance\c_pack_combinations_nesting\plusone + \ifnum\c_pack_combinations_nesting>\plusone + \c_pack_combinations_x_saved \c_pack_combinations_x + \c_pack_combinations_n_saved \c_pack_combinations_n + \c_pack_combinations_max_saved\c_pack_combinations_max + \setbox\b_pack_combinations_captions_saved\box\b_pack_combinations_captions + \setbox\b_pack_combinations_temp_saved \box\b_pack_combinations_temp + \setbox\b_pack_combinations_content_saved \box\b_pack_combinations_content + \setbox\b_pack_combinations_caption_saved \box\b_pack_combinations_caption + \else + \global\setsystemmode{combination}% why global + \fi} + +\def\pack_combinations_pop + {\ifnum\c_pack_combinations_nesting>\plusone + \global\c_pack_combinations_x \c_pack_combinations_x_saved + \global\c_pack_combinations_n \c_pack_combinations_n_saved + \global\c_pack_combinations_max\c_pack_combinations_max_saved + \global\setbox\b_pack_combinations_captions\box\b_pack_combinations_captions_saved + \global\setbox\b_pack_combinations_temp \box\b_pack_combinations_temp_saved + \setbox\b_pack_combinations_content \box\b_pack_combinations_content_saved + \setbox\b_pack_combinations_caption \box\b_pack_combinations_caption_saved + \else + \global\resetsystemmode{combination}% why global + \fi + \advance\c_pack_combinations_nesting\minusone} + \definelabel [\v!combination] % handy for configuring [\c!numberconversion=\v!character, @@ -143,6 +183,7 @@ \unexpanded\def\startcombination {\bgroup % so we can grab a group + \pack_combinations_push \dodoubleempty\pack_combinations_start} % formally ok: @@ -181,14 +222,13 @@ {\bgroup\normalexpanded{\egroup{}\ntimes{{}{}}\c_pack_combinations_n}% brr \dostoptagged \egroup + \pack_combinations_pop \egroup} \newtoks\everycombination \def\pack_combinations_start[#1][#2]% needs a cleanup, also nx ny (pretty old, this one) - {\global\setsystemmode{combination}% - % - \edef\currentcombination{#1}% + {\edef\currentcombination{#1}% \edef\currentcombinationspec{#2}% \ifx\currentcombinationspec\empty \doifelseassignment{#1}% diff --git a/tex/context/base/pack-rul.lua b/tex/context/base/pack-rul.lua index dc4e48655..a8c5de321 100644 --- a/tex/context/base/pack-rul.lua +++ b/tex/context/base/pack-rul.lua @@ -46,6 +46,7 @@ local getbox = nuts.getbox local hpack = nuts.hpack local traverse_id = nuts.traverse_id local node_dimensions = nuts.dimensions +local free_node = nuts.free local function doreshapeframedbox(n) local box = getbox(n) @@ -107,10 +108,18 @@ local function doreshapeframedbox(n) if l then local subtype = getsubtype(h) if subtype == box_code or subtype == line_code then - l = hpack(l,maxwidth,'exactly',getfield(h,"dir")) -- multiple return values --- setfield(l,"attr",getfield(h,"attr")) - setfield(h,"list",l) - setfield(h,"shift",0) -- needed for display math, so no width check possible + local p = hpack(l,maxwidth,'exactly',getfield(h,"dir")) -- multiple return value + if false then + setfield(h,"list",p) + setfield(h,"shift",0) -- needed for display math, so no width check possible + -- setfield(p,"attr",getfield(h,"attr")) + else + setfield(h,"glue_set",getfield(p,"glue_set")) + setfield(h,"glue_order",getfield(p,"glue_order")) + setfield(h,"glue_sign",getfield(p,"glue_sign")) + setfield(p,"list",nil) + free_node(p) + end end setfield(h,"width",maxwidth) end diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua index 5a447c458..8cbc350f9 100644 --- a/tex/context/base/page-lin.lua +++ b/tex/context/base/page-lin.lua @@ -76,14 +76,17 @@ local setfield = nuts.setfield local traverse_id = nuts.traverse_id local traverse = nuts.traverse local copy_node = nuts.copy -local hpack_node = nuts.hpack +local hpack_nodes = nuts.hpack +local linked_nodes = nuts.linked local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local is_display_math = nuts.is_display_math local leftmarginwidth = nuts.leftmarginwidth -local negated_glue = nuts.pool.negatedglue -local new_hlist = nuts.pool.hlist +local nodepool = nuts.pool +local negated_glue = nodepool.negatedglue +local new_hlist = nodepool.hlist +local new_kern = nodepool.kern local ctx_convertnumber = context.convertnumber local ctx_makelinenumber = context.makelinenumber @@ -296,13 +299,11 @@ function boxed.stage_one(n,nested) n = getnext(n) elseif id == glue_code and getsubtype(n) == leftskip_code then n = getnext(n) - else -if id == glyph_code then + elseif id == glyph_code then break -else - -- can be hlist or skip (e.g. footnote line) - n = getnext(n) -end + else + -- can be hlist or skip (e.g. footnote line) + n = getnext(n) end end a = n and getattr(n,a_linenumber) @@ -342,54 +343,14 @@ end end end --- [dir][leftskip][content] +-- todo: a general model for attaching stuff l/r -function boxed.stage_two(n,m) - if #current_list > 0 then - m = m or lines.scratchbox - local t, tn = { }, 0 - for l in traverse_id(hlist_code,getlist(getbox(m))) do - tn = tn + 1 - t[tn] = copy_node(l) -- use take_box instead - end - for i=1,#current_list do - local li = current_list[i] - local n, m, ti = li[1], li[2], t[i] - if ti then - local l = getlist(n) - -- we want to keep leftskip at the start --- local id = getid(l) --- if id == whatsit_code and getsubtype(l) == textdir_code then --- l = getnext(l) --- id = getid(l) --- end --- if getid(l) == glue_code and getsubtype(l) == leftskip_code then --- -- [leftskip] [number] [rest] --- local forward = copy_node(l) --- local backward = negated_glue(l) --- local next = getnext(l) --- setfield(l,"next",backward) --- setfield(backward,"prev",l) --- setfield(backward,"next",ti) --- setfield(ti,"prev",backward) --- setfield(ti,"next",forward) --- setfield(forward,"prev",ti) --- setfield(forward,"next",next) --- setfield(next,"prev",forward) --- else - -- [number] [rest] - setfield(ti,"next",l) - setfield(l,"prev",ti) - setfield(n,"list",ti) --- end - resolve(n,m) - else - report_lines("error in linenumbering (1)") - return - end - end - end -end +-- setfield(ti,"next",l) +-- setfield(l,"prev",ti) +-- local h = copy_node(n) +-- -- setfield(h,"dir","TLT") +-- setfield(h,"list",ti) -- the number +-- setfield(n,"list",h) function boxed.stage_two(n,m) if #current_list > 0 then @@ -403,13 +364,15 @@ function boxed.stage_two(n,m) local li = current_list[i] local n, m, ti = li[1], li[2], t[i] if ti then + local d = getfield(n,"dir") local l = getlist(n) + if d == "TRT" then + local w = getfield(n,"width") + ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w))) + end setfield(ti,"next",l) setfield(l,"prev",ti) - local h = copy_node(n) - setfield(h,"dir","TLT") - setfield(h,"list",ti) - setfield(n,"list",h) + setfield(n,"list",ti) resolve(n,m) else report_lines("error in linenumbering (1)") diff --git a/tex/context/base/scrn-ini.mkvi b/tex/context/base/scrn-ini.mkvi index 2ed822c6e..0e00fb456 100644 --- a/tex/context/base/scrn-ini.mkvi +++ b/tex/context/base/scrn-ini.mkvi @@ -182,7 +182,7 @@ title {\interactionparameter\c!title}% subtitle {\interactionparameter\c!subtitle}% author {\interactionparameter\c!author}% - creator { ConTeXt - \contextversion}% + creator {ConTeXt - \contextversion}% date {\interactionparameter\c!date}% keywords {\interactionparameter\c!keyword}% \relax} diff --git a/tex/context/base/spac-ali.mkiv b/tex/context/base/spac-ali.mkiv index 07d588ba7..f90ab4fa9 100644 --- a/tex/context/base/spac-ali.mkiv +++ b/tex/context/base/spac-ali.mkiv @@ -167,6 +167,10 @@ \unexpanded\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox \unexpanded\def\autodirvtop#1#{\vtop#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vtop +\unexpanded\def\leftorrighthbox{\ifconditional\displaylefttoright\expandafter\lefttorighthbox\else\expandafter\righttolefthbox\fi} +\unexpanded\def\leftorrightvbox{\ifconditional\displaylefttoright\expandafter\lefttorightvbox\else\expandafter\righttoleftvbox\fi} +\unexpanded\def\leftorrightvtop{\ifconditional\displaylefttoright\expandafter\lefttorightvtop\else\expandafter\righttoleftvtop\fi} + % Tolerance and hyphenation \ifdefined\lesshyphens \else \let\lesshyphens\relax \fi diff --git a/tex/context/base/spac-prf.lua b/tex/context/base/spac-prf.lua new file mode 100644 index 000000000..503a31e29 --- /dev/null +++ b/tex/context/base/spac-prf.lua @@ -0,0 +1,958 @@ + if not modules then modules = { } end modules ['spac-prf'] = { + version = 1.001, + comment = "companion to spac-prf.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is a playground, a byproduct of some experiments in a project where +-- we needed something like this where it works ok, but nevertheless it's +-- still experimental code. It is very likely to change (or extended). + +local unpack, rawget = unpack, rawget + +local formatters = string.formatters + +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes +local listcodes = nodes.listcodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local penalty_code = nodecodes.penalty +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local unset_code = nodecodes.unset +local math_code = nodecodes.math +local whatsit_code = nodecodes.whatsit +local rule_code = nodecodes.rule +local marginkern_code = nodecodes.marginkern + +local leaders_code = gluecodes.leaders +local lineskip_code = gluecodes.lineskip +local baselineskip_code = gluecodes.baselineskip +local line_code = listcodes.line +local parskip_code = listcodes.parskip + +local texlists = tex.lists +local gettexdimen = tex.getdimen +local settexattribute = tex.setattribute +local settexbox = tex.setbox +local taketexbox = tex.takebox + +local nuts = nodes.nuts +local tonut = nodes.tonut +local tonode = nuts.tonode +local setfield = nuts.setfield +local setattr = nuts.setattr +local getfield = nuts.getfield +local getattr = nuts.getattr +local getid = nuts.getid +local getnext = nuts.getnext +local getprev = nuts.getprev +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local gettexbox = nuts.getbox + +local theprop = nuts.theprop + +local floor = math.floor +local ceiling = math.ceil + +local new_rule = nuts.pool.rule +local new_glue = nuts.pool.glue +local new_kern = nuts.pool.kern +local hpack_nodes = nuts.hpack +local link_nodes = nuts.link +local find_node_tail = nuts.tail + +local properties = nodes.properties.data + +local get_dimensions = nodes.whatsitters.getters.dimensions + +local a_visual = attributes.private("visual") +local a_snapmethod = attributes.private("snapmethod") +local a_profilemethod = attributes.private("profilemethod") +local a_specialcontent = attributes.private("specialcontent") + +local variables = interfaces.variables +local v_none = variables.none +local v_fixed = variables.fixed +local v_strict = variables.strict + +local setcolor = nodes.tracers.colors.set +local settransparency = nodes.tracers.transparencies.set + +local profiling = { } +builders.profiling = profiling + +local report = logs.reporter("profiling") + +local show_profile = false trackers.register("profiling.show", function(v) show_profile = v end) +local trace_profile = false trackers.register("profiling.trace",function(v) trace_profile = v end) + +local function getprofile(line,step) + + -- only l2r + -- no hz yet + + local line = tonut(line) + local current = getlist(line) + + if not current then + return + end + + local glue_sign = getfield(line,"glue_sign") + local glue_order = getfield(line,"glue_order") + local glue_set = getfield(line,"glue_set") + + local heights = { } + local depths = { } + local width = 0 + local position = 0 + local step = step or 65536 -- * 2 -- 2pt + local margin = step / 4 + local min = 0 + local max = ceiling(getfield(line,"width")/step) + 1 + + for i=min,max do + heights[i] = 0 + depths [i] = 0 + end + + -- remember p + + local wd, ht, dp = 0, 0, 0 + + local function progress() + position = width + width = position + wd + p = floor((position - margin)/step + 0.5) + w = floor((width + margin)/step - 0.5) + if p < 0 then + p = 0 + end + if w < 0 then + w = 0 + end + if p > w then + w, p = p, w + end + if w > max then + for i=max+1,w+1 do + heights[i] = 0 + depths [i] = 0 + end + max = w + end + for i=p,w do + if ht > heights[i] then + heights[i] = ht + end + if dp > depths[i] then + depths[i] = dp + end + end + end + + local function process(current) -- called nested in disc replace + while current do + local id = getid(current) + if id == glyph_code then + wd = getfield(current,"width") + ht = getfield(current,"height") + dp = getfield(current,"depth") + progress() + elseif id == kern_code then + wd = getfield(current,"kern") + ht = 0 + dp = 0 + progress() + elseif id == disc_code then + local replace = getfield(current,"replace") + if replace then + process(replace) + end + elseif id == glue_code then + local spec = getfield(current,"spec") + wd = getfield(spec,"width") + if glue_sign == 1 then + if getfield(spec,"stretch_order") == glue_order then + -- wd = (wd + getfield(spec,"stretch")) * glue_set + wd = wd + getfield(spec,"stretch") * glue_set + end + elseif glue_sign == 2 then + if getfield(spec,"shrink_order") == glue_order then + -- wd = (wd - getfield(spec,"shrink")) * glue_set + wd = wd - getfield(spec,"shrink") * glue_set + end + end + if getsubtype(current) >= leaders_code then + local leader = getleader(current) + ht = getfield(leader,"height") + dp = getfield(leader,"depth") + else + ht = 0 + dp = 0 + end + progress() + elseif id == hlist_code then + -- we could do a nested check .. but then we need to push / pop glue + local shift = getfield(current,"shift") + wd = getfield(current,"width") + if getattr(current,a_specialcontent) then + -- like a margin note, maybe check for wd + ht = 0 + dp = 0 + else + ht = getfield(current,"height") - shift + dp = getfield(current,"depth") + shift + end + progress() + elseif id == vlist_code or id == unset_code then + local shift = getfield(current,"shift") -- todo + wd = getfield(current,"width") + ht = getfield(current,"height") -- - shift + dp = getfield(current,"depth") -- + shift + progress() + elseif id == rule_code then + wd = getfield(current,"width") + ht = getfield(current,"height") + dp = getfield(current,"depth") + progress() + elseif id == math_code then + wd = getfield(current,"surround") + ht = 0 + dp = 0 + progress() + elseif id == whatsit_code then + local subtype = getsubtype(current) + local getdimen = get_dimensions[subtype] + if getdimen then + -- unlikely to happen as we always wrap images etc in a box + wd, ht, dp = get_dimensions(current) + progress() + end + elseif id == marginkern_code then + wd = getfield(current,"width") + ht = 0 + dp = 0 + progress() + end + current = getnext(current) + end + end + + process(current) + + return { + heights = heights, + depths = depths, + min = min, -- not needed + max = max, + step = step, + } + +end + +profiling.get = getprofile + +local function getpagelist() + local pagehead = texlists.page_head + if pagehead then + pagehead = tonut(texlists.page_head) + pagetail = find_node_tail(pagehead) + else + pagetail = nil + end + return pagehead, pagetail +end + +local function setprofile(n,step) + local p = rawget(properties,n) + if p then + local pp = p.profile + if not pp then + pp = getprofile(n,step) + p.profile = pp + end + return pp + else + local pp = getprofile(n,step) + properties[n] = { profile = pp } + return pp + end +end + +local function hasprofile(n) + local p = rawget(properties,n) + if p then + return p.profile + end +end + +local function addstring(height,depth) + local typesetters = nuts.typesetters + local hashes = fonts.hashes + local infofont = fonts.infofont() + local emwidth = hashes.emwidths [infofont] + local exheight = hashes.exheights[infofont] + local httext = height + local dptext = depth + local httext = typesetters.fast_hpack(height,infofont) + local dptext = typesetters.fast_hpack(depth,infofont) + setfield(httext,"shift",- 1.2 * exheight) + setfield(dptext,"shift", 0.6 * exheight) + local text = nuts.fasthpack( + nuts.linked( + new_kern(-getfield(httext,"width")-emwidth), + httext, + new_kern(-getfield(dptext,"width")), + dptext + ) + ) + setfield(text,"height",0) + setfield(text,"depth",0) + setfield(text,"width",0) + return text +end + +local function addprofile(node,profile,step) + + local line = tonut(node) + + if not profile then + profile = setprofile(line,step) + end + + if not profile then + report("some error") + return node + end + + if profile.shown then + return node + end + + local list = getlist(line) + profile.shown = true + + local heights = profile.heights + local depths = profile.depths + local step = profile.step + + local head = nil + local tail = nil + + local lastht = 0 + local lastdp = 0 + local lastwd = 0 + + local visual = "f:s:t" -- this can change ! + + local function progress() + if lastwd == 0 then + return + end + local what = nil + if lastht == 0 and lastdp == 0 then + what = new_kern(lastwd) + else + what = new_rule(lastwd,lastht,lastdp) + setcolor(what,visual) + settransparency(what,visual) + end + if tail then + setfield(tail,"next",what) + setfield(what,"prev",tail) + else + head = what + end + tail = what + end + +-- inspect(profile) + + for i=profile.min,profile.max do + local ht = heights[i] + local dp = depths[i] + if ht ~= lastht or dp ~= lastdp and lastwd > 0 then + progress() + lastht = ht + lastdp = dp + lastwd = step + else + lastwd = lastwd + step + end + end + if lastwd > 0 then + progress() + end + + local rule = hpack_nodes(head) + + setfield(rule,"width", 0) + setfield(rule,"height",0) + setfield(rule,"depth", 0) + + -- if texttoo then + -- + -- local text = addstring( + -- formatters["%0.4f"](getfield(rule,"height")/65536), + -- formatters["%0.4f"](getfield(rule,"depth") /65536) + -- ) + -- + -- setfield(text,"next",rule) + -- setfield(rule,"prev",text) + -- + -- rule = text + -- + -- end + + setfield(rule,"next",list) + setfield(list,"prev",rule) + setfield(line,"list",rule) + +end + +profiling.add = addprofile + +local methods = { } + +local function getdelta(t_profile,b_profile) + local t_heights = t_profile.heights + local t_depths = t_profile.depths + local t_max = t_profile.max + local b_heights = b_profile.heights + local b_depths = b_profile.depths + local b_max = b_profile.max + + local max = t_max + local delta = 0 + + if t_max > b_max then + for i=b_max+1,t_max do + b_depths [i] = 0 + b_heights[i] = 0 + end + max = t_max + elseif b_max > t_max then + for i=t_max+1,b_max do + t_depths [i] = 0 + t_heights[i] = 0 + end + max = b_max + end + + for i=0,max do + local ht = b_heights[i] + local dp = t_depths[i] + local hd = ht + dp + if hd > delta then + delta = hd + end + end + + return delta +end + +-- local properties = theprop(bot) +-- local unprofiled = properties.unprofiled +-- if not unprofiled then -- experiment +-- properties.unprofiled = { +-- height = height, +-- strutht = strutht, +-- } +-- end + +-- lineskip | lineskiplimit + +local function inject(top,bot,amount) + local glue = new_glue(amount) + -- + setattr(glue,a_profilemethod,0) + setattr(glue,a_visual,getattr(top,a_visual)) + -- + setfield(glue,"next",bot) + setfield(glue,"prev",top) + setfield(top,"next",glue) + setfield(bot,"prev",glue) +end + +methods[v_none] = function() + return false +end + +methods[v_strict] = function(top,bot,t_profile,b_profile,specification) + + local top = tonut(top) + local bot = tonut(bot) + + local strutht = specification.height or texdimen.strutht + local strutdp = specification.depth or texdimen.strutdp + local lineheight = strutht + strutdp + + local depth = getfield(top,"depth") + local height = getfield(bot,"height") + local total = depth + height + local distance = specification.distance or 0 + local delta = lineheight - total + + -- there is enough room between the lines so we don't need + -- to add extra distance + + if delta >= distance then + inject(top,bot,delta) + return true + end + + local delta = getdelta(t_profile,b_profile) + local skip = delta - total + distance + + -- we don't want to be too tight so we limit the skip and + -- make sure we have at least lineheight + + inject(top,bot,skip) + return true + +end + +-- todo: also set ht/dp of first / last (but what is that) + +methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) + + local top = tonut(top) + local bot = tonut(bot) + + local strutht = specification.height or texdimen.strutht + local strutdp = specification.depth or texdimen.strutdp + local lineheight = strutht + strutdp + + local depth = getfield(top,"depth") + local height = getfield(bot,"height") + local total = depth + height + local distance = specification.distance or 0 + local delta = lineheight - total + + local snapmethod = getattr(top,a_snapmethod) + + if snapmethod then + distance = 0 -- if needed take it from the snapper + end + + if delta >= distance then + setfield(top,"depth",strutdp) + setfield(bot,"height",strutht) + return true + end + + local delta = getdelta(t_profile,b_profile) + + if delta < lineheight + distance then + setfield(top,"depth",strutdp) + setfield(bot,"height",strutht) + return true + end + + if snapmethod then + local dp = strutdp + while depth > lineheight - strutdp do + depth = depth - lineheight + dp = dp + lineheight + end + setfield(top,"depth",dp) + local ht = strutht + while height > lineheight - strutht do + height = height - lineheight + ht = ht + lineheight + end + setfield(bot,"height",ht) + local lines = floor(delta/lineheight) + if lines > 0 then + inject(top,bot,-lines * lineheight) + end + return true + end + + local room = total - delta + local factor = specification.factor or 1 + local lines = specification.lines or 0 -- todo + local step = lineheight / factor + local correction = 0 + local initial = room - distance + local nofsteps = 0 + while initial > step do -- a loop is more accurate, for now + correction = correction + step + initial = initial - step + nofsteps = nofsteps + 1 + end + + if correction + total <= lineheight then + setfield(top,"depth",strutdp) + setfield(bot,"height",strutht) + end + + if trace_profile then + report("top line : %s %05i > %s",t_profile.shown and "+" or "-",top,nodes.toutf(getlist(top))) + report("bottom line : %s %05i > %s",b_profile.shown and "+" or "-",bot,nodes.toutf(getlist(bot))) + report(" depth : %p",depth) + report(" height : %p",height) + report(" total : %p",total) + report(" lineheight : %p",lineheight) + report(" delta : %p",delta) + report(" room : %p",room) + report(" factor : %i",factor) + report(" distance : %p",distance) + report(" step : %p",step) + report(" nofsteps : %i",nofsteps) + report(" max lines : %s",lines == 0 and "unset" or lines) + report(" correction : %p",correction) + end + + correction = correction - distance + + if correction ~= 0 then + inject(top,bot,-correction) -- we could mess with the present glue (if present) + end + + return true -- remove interlineglue + +end + +function profiling.distance(top,bot,specification) + local step = specification.step + local method = specification.method + local ptop = getprofile(top,step) + local pbot = getprofile(bot,step) + local action = methods[method or v_strict] or methods[v_strict] + return action(top,bot,ptop,pbot,specification) +end + +local specifications = { } -- todo: save these ! + +function profiling.fixedprofile(current) + local a = getattr(current,a_profilemethod) + if a then + local s = specifications[a] + if s then + return s.method == v_fixed + end + end + return false +end + +local function profilelist(line,mvl) + + local current = tonut(line) + + local top = nil + local bot = nil + + local t_profile = nil + local b_profile = nil + + local specification = nil + local lastattr = nil + local method = nil + local action = nil + + local distance = 0 + local lastglue = nil + + local pagehead = nil + local pagetail = nil + + if mvl then + + pagehead, pagetail = getpagelist() + + if pagetail then + local current = pagetail + while current do + local id = getid(current) + if id == hlist_code then + local subtype = getsubtype(current) + if subtype == line_code then + t_profile = hasprofile(current) + if t_profile then + top = current + end + end + break + elseif id == glue_code then + local spec = getfield(current,"spec") + local wd = getfield(spec,"width") + if not wd or wd == 0 then + -- go on + else + break + end + elseif id == penalty_code then + -- ok + else + break + end + current = getnext(current) + end + end + + end + + while current do + + local attr = getattr(current,a_profilemethod) + + if attr then + + if attr ~= lastattr then + specification = specifications[attr] + method = specification and specification.method + action = method and methods[method] or methods[v_strict] + lastattr = attr + end + + local id = getid(current) + + if id == hlist_code then -- check subtype + local subtype = getsubtype(current) + if subtype == line_code then + if top == current then + -- skip + bot = nil -- to be sure + elseif top then + bot = current + b_profile = setprofile(bot) + if show_profile then + addprofile(bot,b_profile) + end + if not t_profile.done then + if action then + local ok = action(top,bot,t_profile,b_profile,specification) + if ok and lastglue and distance ~= 0 then + setfield(lastglue,"spec",nil) + end + end + t_profile.done = true + end + top = bot + bot = nil + t_profile = b_profile + b_profile = nil + distance = 0 + else + top = current + t_profile = setprofile(top) + bot = nil + if show_profile then + addprofile(top,t_profile) + end + end + else + top = nil + bot = nil + end + elseif id == glue_code then + if top then + local subtype = getsubtype(current) + -- if subtype == lineskip_code or subtype == baselineskip_code then + local spec = getfield(current,"spec") + local wd = getfield(spec,"width") + if wd > 0 then + distance = wd + lastglue = current + elseif wd < 0 then + top = nil + bot = nil + else + -- ok + end + -- else + -- top = nil + -- bot = nil + -- end + else + top = nil + bot = nil + end + elseif id == penalty_code then + -- okay + else + top = nil + bot = nil + end + else + top = nil + bot = nil + end + current = getnext(current) + end + if top then + t_profile = setprofile(top) + if show_profile then + addprofile(top,t_profile) + end + end +end + +profiling.list = profilelist + +local enabled = false + +function profiling.set(specification) + if not enabled then + nodes.tasks.enableaction("mvlbuilders", "builders.profiling.pagehandler") + -- too expensive so we expect that this happens explicitly, we keep for reference: + -- nodes.tasks.enableaction("vboxbuilders","builders.profiling.vboxhandler") + enabled = true + end + local n = #specifications + 1 + specifications[n] = specification + settexattribute(a_profilemethod,n) +end + +function profiling.profilebox(specification) + local boxnumber = specification.box + local current = getlist(gettexbox(boxnumber)) + local top = nil + local bot = nil + local t_profile = nil + local b_profile = nil + local method = specification and specification.method + local action = method and methods[method] or methods[v_strict] + local lastglue = nil + local distance = 0 + while current do + local id = getid(current) + if id == hlist_code then + local subtype = getsubtype(current) + if subtype == line_code then + if top then + bot = current + b_profile = setprofile(bot) + if show_profile then + addprofile(bot,b_profile) + end + if not t_profile.done then + if action then + local ok = action(top,bot,t_profile,b_profile,specification) + if ok and lastglue and distance ~= 0 then + setfield(lastglue,"spec",nil) + end + end + t_profile.done = true + end + top = bot + t_profile = b_profile + b_profile = nil + distance = 0 + else + top = current + t_profile = setprofile(top) + if show_profile then + addprofile(top,t_profile) + end + bot = nil + end + else + top = nil + bot = nil + end + elseif id == glue_code then +local subtype = getsubtype(current) +if subtype == lineskip_code or subtype == baselineskip_code then + if top then + local spec = getfield(current,"spec") + local wd = getfield(spec,"width") + if wd > 0 then + distance = wd + lastglue = current + elseif wd < 0 then + top = nil + bot = nil + else + -- ok + end + else + top = nil + bot = nil + end +else + top = nil + bot = nil +end + elseif id == penalty_code then + -- okay + else + top = nil + bot = nil + end + current = getnext(current) + end + + if top then + t_profile = setprofile(top) -- not needed + if show_profile then + addprofile(top,t_profile) + end + end + +end + +local ignore = table.tohash { + "split_keep", + "split_off", + -- "vbox", +} + +-- function profiling.vboxhandler(head,where) +-- if head and not ignore[where] then +-- local h = tonut(head) +-- if getnext(h) then +-- profilelist(h) +-- end +-- end +-- return head +-- end + +function profiling.pagehandler(head) + if head then + profilelist(head,true) + end + return head, true +end + +interfaces.implement { + name = "setprofile", + actions = profiling.set, + arguments = { + { + { "name" }, + { "height", "dimen" }, + { "depth", "dimen" }, + { "distance", "dimen" }, + { "factor", "integer" }, + { "lines", "integer" }, + { "method" } + } + } +} + +interfaces.implement { + name = "profilebox", + actions = profiling.profilebox, + arguments = { + { + { "box", "integer" }, + { "height", "dimen" }, + { "depth", "dimen" }, + { "distance", "dimen" }, + { "factor", "integer" }, + { "lines", "integer" }, + { "method" } + } + } +} diff --git a/tex/context/base/spac-prf.mkiv b/tex/context/base/spac-prf.mkiv deleted file mode 100644 index 5f1553ede..000000000 --- a/tex/context/base/spac-prf.mkiv +++ /dev/null @@ -1,31 +0,0 @@ -%D \module -%D [ file=spac-prf, -%D version=2015.11.16, % moved from test module mathplus -%D title=\CONTEXT\ Spacing Macros, -%D subtitle=Profiling, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Spacing Macros / Profiling} - -%D This is a placeholder for something to come. But as I don't want to -%D be harrassed by 'why does it work different than a week before' this -%D cool new feature will only end up here when stable enough. Alas. - -\unprotect - -\definesystemattribute[profilemethod][public] - -\unexpanded\def\setprofile [#1]{} -\unexpanded\def\resetprofile {} -\unexpanded\def\useprofileparameter#1{} -\unexpanded\def\addprofiletobox #1{} -\unexpanded\def\profilegivenbox #1#2{} -\unexpanded\def\profiledbox {\vbox} - -\protect \endinput diff --git a/tex/context/base/spac-prf.mkvi b/tex/context/base/spac-prf.mkvi new file mode 100644 index 000000000..8d150f58d --- /dev/null +++ b/tex/context/base/spac-prf.mkvi @@ -0,0 +1,117 @@ +%D \module +%D [ file=spac-prf, +%D version=2015.11.16, % moved from test module mathplus +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Profiling, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Spacing Macros / Profiling} + +%D This is experimental code that we need for a project. The interface and +%D details can change. I moved it into the core because that way we can use +%D it on servers. + +% framed: first reflow then profile + +\unprotect + +\registerctxluafile{spac-prf}{1.001} + +\definesystemattribute[profilemethod][public] + +\installcorenamespace {profile} % beware, profiles are not like in mkii at all +\installcorenamespace {profiles} + +\installcommandhandler \??profile {profile} \??profile + +\setupprofile + [\c!height=\strutht, + \c!depth=\strutdp, + \c!distance=\normallineskip, + \c!lines=\zerocount, + \c!factor=\plusone] + +\defineprofile + [\v!strict] + [\c!method=\v!strict] + +\defineprofile + [\v!fixed] + [\c!method=\v!fixed] + +\defineprofile + [\v!none] + [\c!method=\v!none, + \c!height=\zeropoint, + \c!depth=\zeropoint, + \c!distance=\zeropoint, + \c!factor=\plusone] + +\defineprofile[halffixed] [\v!fixed][\c!factor=\plustwo] +\defineprofile[quarterfixed][\v!fixed][\c!factor=\plusfour] +\defineprofile[eightsfixed] [\v!fixed][\c!factor=\pluseight] + +\unexpanded\def\setprofile[#profile]% + {\edef\currentprofile{#profile}% + \clf_setprofile + name {\currentprofile}% + height \dimexpr\profileparameter\c!height\relax + depth \dimexpr\profileparameter\c!depth\relax + distance \dimexpr\profileparameter\c!distance\relax + factor \numexpr\profileparameter\c!factor\relax + lines \numexpr\profileparameter\c!lines\relax + method {\profileparameter\c!method}% + \relax} + +\unexpanded\def\resetprofile + {\attribute\profilemethodattribute\attributeunsetvalue} + +\unexpanded\def\useprofileparameter#getparameter% + {\edef\m_spac_profile_asked{#getparameter\c!profile}% + \ifx\m_spac_profile_asked\empty + \resetprofile + \else + \setprofile[\m_spac_profile_asked]% + \fi} + +\unexpanded\def\profiledbox + {\vbox\bgroup + \dodoubleempty\spac_profiling_box} + +\def\spac_profiling_box[#profile][#settings]% + {\ifsecondargument + \edef\currentprofile{#profile}% + \setupcurrentprofile[#settings]% + \else + \doifassignmentelse{#profile} + {\let\currentprofile\v!none + \setupcurrentprofile[#profile]}% + {\edef\currentprofile{#profile}}% + \fi + \dowithnextbox + {\profilegivenbox\currentprofile\nextbox + \unvbox\nextbox + \egroup}% + \vbox} + +\unexpanded\def\profilegivenbox#profile#box% + {\begingroup + \edef\currentprofile{#profile}% + \clf_profilebox + box \numexpr#box\relax + height \dimexpr\profileparameter\c!height\relax + depth \dimexpr\profileparameter\c!depth\relax + distance \dimexpr\profileparameter\c!distance\relax + factor \numexpr\profileparameter\c!factor\relax + lines \numexpr\profileparameter\c!lines\relax + method {\profileparameter\c!method}% + \relax + \endgroup} + +\protect \endinput diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index efbebe057..8d209396f 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 75260f543..baf4424a1 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi index 11f6f758e..36ca5314f 100644 --- a/tex/context/base/strc-con.mkvi +++ b/tex/context/base/strc-con.mkvi @@ -492,7 +492,7 @@ \ifconditional\c_strc_constructions_distance_none \else \advance\ifx#1\v!flushleft\rightskip\else\leftskip\fi\constructionsheaddistance % only difference and wrong anyway \fi - \ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \flushconstructionheadbox}% \setbox\constructionheadbox\hbox{\box\constructionheadbox}% needed in case of e.g. a real big head font, see descriptions-006.tex \ht\constructionheadbox\strutht \dp\constructionheadbox\strutdp} @@ -507,7 +507,7 @@ \else \setupalign[\p_strc_constructions_headalign]% use fast one \fi - \ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \flushconstructionheadbox}% \setbox\constructionheadbox\hbox{\box\constructionheadbox}% needed in case of e.g. a real big head font, see descriptions-006.tex \ht\constructionheadbox\strutht \dp\constructionheadbox\strutdp} @@ -529,6 +529,12 @@ \relax \hangindent\ifx#1\v!right-\fi\constructionsheadwidth} +% \unexpanded\def\flushconstructionheadbox +% {\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox} + +\unexpanded\def\flushconstructionheadbox + {\ifhbox\constructionheadbox\unhbox\else\box\fi\constructionheadbox} + % The setups. These only deal with placement of the descriptor and initializing the % environment. The wrapping happens elsewhere. @@ -694,7 +700,7 @@ \startsetups[\??constructionrenderings:\v!margin] \let\\=\crlf \noindent - \inmargin[\c!scope=\v!local]{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \inmargin[\c!scope=\v!local]{\flushconstructionheadbox}% \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups @@ -702,7 +708,7 @@ \startsetups[\??constructionrenderings:\v!leftmargin] \let\\=\crlf \noindent - \inleft[\c!scope=\v!local]{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \inleft[\c!scope=\v!local]{\flushconstructionheadbox}% \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups @@ -710,7 +716,7 @@ \startsetups[\??constructionrenderings:\v!rightmargin] \let\\=\crlf \noindent - \inright[\c!scope=\v!local]{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \inright[\c!scope=\v!local]{\flushconstructionheadbox}% \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups @@ -718,7 +724,7 @@ \startsetups[\??constructionrenderings:\v!innermargin] \let\\=\crlf \noindent - \ininner[\c!scope=\v!local]{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \ininner[\c!scope=\v!local]{\flushconstructionheadbox}% \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups @@ -726,7 +732,7 @@ \startsetups[\??constructionrenderings:\v!outermargin] \let\\=\crlf \noindent - \inouter[\c!scope=\v!local]{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox}% + \inouter[\c!scope=\v!local]{\flushconstructionheadbox}% \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups @@ -755,7 +761,7 @@ \startsetups[\??constructionrenderings:\v!serried:\v!fit] \let\\=\crlf \noindent - \ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox % why copy? leftover? + \flushconstructionheadbox \nobreak \hskip\constructionsheaddistance\relax \useconstructionstyleandcolor\c!style\c!color @@ -765,7 +771,7 @@ \startsetups[\??constructionrenderings:\v!serried:\v!broad] \let\\=\crlf \noindent - \ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox % why copy? leftover? + \flushconstructionheadbox \ifconditional\c_strc_constructions_distance_none \else \nobreak \hskip\constructionsheaddistance \!!plus .5\constructionsheaddistance \!!minus .25\constructionsheaddistance\relax @@ -782,7 +788,7 @@ \let\\=\crlf \noindent \hbox to \constructionsheadwidth { - \ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox + \flushconstructionheadbox \hss } \nobreak @@ -827,7 +833,7 @@ \startsetups[\??constructionrenderings:\v!command] \noindent - \constructionparameter\c!headcommand{\ifhbox\constructionheadbox\unhcopy\else\copy\fi\constructionheadbox} + \constructionparameter\c!headcommand{\flushconstructionheadbox} \useconstructionstyleandcolor\c!style\c!color \ignorespaces \stopsetups diff --git a/tex/context/base/strc-not.mkvi b/tex/context/base/strc-not.mkvi index 25a1072a3..57ca672d0 100644 --- a/tex/context/base/strc-not.mkvi +++ b/tex/context/base/strc-not.mkvi @@ -1358,9 +1358,10 @@ {\begingroup \useinterlinespaceparameter\noteparameter \doifelse{\noteparameter\c!paragraph}\v!yes - {\vbox\starthboxestohbox - \iftrialtypesetting\unvcopy\else\unvbox\fi\currentnoteinsertionnumber - \stophboxestohbox} + {\leftorrightvbox % cf mail from ws to list + {\starthboxestohbox + \iftrialtypesetting\unvcopy\else\unvbox\fi\currentnoteinsertionnumber + \stophboxestohbox}} {\iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteinsertionnumber}% \endgroup} diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index fde2f39ad..958867e94 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -65,6 +65,7 @@ appendaction("processors", "lists", "languages.visualizediscretionaries" -- appendaction("processors", "lists", "typesetters.initials.handler") -- disabled +appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled appendaction("shipouts", "normalizers", "typesetters.alignments.handler") @@ -90,26 +91,27 @@ appendaction("shipouts", "finishers", "attributes.viewerlayers.handler") appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nohead") -appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nohead") -- always on (maybe disabled) -appendaction("math", "normalizers", "noads.handlers.variants", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.families", nil, "nohead") -- always on - -appendaction("math", "normalizers", "noads.handlers.render", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nohead") -- * first -- always on -appendaction("math", "normalizers", "noads.handlers.domains", nil, "nohead") -- * last -- disabled -appendaction("math", "normalizers", "noads.handlers.autofences",nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on -------------("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled +appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nohead") -- always on (maybe disabled) +appendaction("math", "normalizers", "noads.handlers.variants", nil, "nohead") -- always on +appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on +appendaction("math", "normalizers", "noads.handlers.families", nil, "nohead") -- always on + +appendaction("math", "normalizers", "noads.handlers.render", nil, "nohead") -- always on +appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nohead") -- * first-- always on +appendaction("math", "normalizers", "noads.handlers.domains", nil, "nohead") -- * last -- disabled +appendaction("math", "normalizers", "noads.handlers.autofences",nil, "nohead") -- disabled +appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on +------------("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on +appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on +appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled +appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled +appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on ------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late) +appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled appendaction("finalizers", "lists", "builders.paragraphs.keeptogether") ------------("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental @@ -117,13 +119,15 @@ appendaction("finalizers", "lists", "builders.paragraphs.tag") -- still experimental +appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -- disabled appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate") appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler") -- last ! -appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here ! +appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here ! +------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler") appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler") -appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here ! +appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here ! -- experimental too @@ -159,7 +163,9 @@ disableaction("processors", "typesetters.kerns.handler") disableaction("processors", "typesetters.italics.handler") disableaction("processors", "languages.visualizediscretionaries") disableaction("processors", "nodes.handlers.stripping") +disableaction("processors", "builders.paragraphs.solutions.splitters.split") +disableaction("shipouts", "typesetters.margins.finalhandler") disableaction("shipouts", "builders.paragraphs.expansion.trace") disableaction("shipouts", "typesetters.alignments.handler") disableaction("shipouts", "nodes.rules.handler") @@ -175,16 +181,11 @@ disableaction("shipouts", "nodes.visualizers.handler") disableaction("shipouts", "nodes.handlers.accessibility") disableaction("shipouts", "nodes.handlers.backgrounds") disableaction("shipouts", "nodes.handlers.alignbackgrounds") - disableaction("shipouts", "nodes.references.handler") disableaction("shipouts", "nodes.destinations.handler") +-------------("shipouts", "nodes.handlers.export") ---~ disableaction("shipouts", "nodes.handlers.export") - -disableaction("mvlbuilders", "nodes.handlers.migrate") - -disableaction("processors", "builders.paragraphs.solutions.splitters.split") - +disableaction("finalizers", "typesetters.margins.localhandler") disableaction("finalizers", "builders.paragraphs.keeptogether") disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") -------------("finalizers", "nodes.handlers.graphicvadjust") -- sort of obsolete @@ -198,9 +199,12 @@ disableaction("math", "noads.handlers.classes") disableaction("math", "noads.handlers.autofences") disableaction("math", "typesetters.directions.processmath") +disableaction("mvlbuilders", "typesetters.margins.globalhandler") +disableaction("mvlbuilders", "nodes.handlers.migrate") disableaction("mvlbuilders", "typesetters.checkers.handler") disableaction("mvlbuilders", "builders.profiling.pagehandler") +-------------("vboxbuilders","typesetters.margins.localhandler") disableaction("vboxbuilders","typesetters.checkers.handler") disableaction("vboxbuilders","builders.profiling.vboxhandler") diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index 40ba1e8c3..a29913fce 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -301,7 +301,7 @@ trackers .register("visualizers.reset", function(v) set("reset", v) end) trackers .register("visualizers.all", function(v) set("all", v) end) trackers .register("visualizers.makeup", function(v) set("makeup",v) end) trackers .register("visualizers.boxes", function(v) set("boxes", v) end) -directives.register("visualizers.fraction", function(v) fraction = tonumber(v) or fraction end) +directives.register("visualizers.fraction", function(v) fraction = v and tonumber(v) or 10 end) local c_positive = "trace:b" local c_negative = "trace:r" diff --git a/tex/context/base/typo-dha.lua b/tex/context/base/typo-dha.lua index 904b774ec..5ea18f001 100644 --- a/tex/context/base/typo-dha.lua +++ b/tex/context/base/typo-dha.lua @@ -123,234 +123,184 @@ local function startdir(finish) return new_textdir(finish == "TRT" and "+TRT" or "+TLT") end +local function nextisright(current) + current = getnext(current) + local id = getid(current) + if id == glyph_code then + local character = getchar(current) + local direction = chardirections[character] + return direction == "r" or direction == "al" or direction == "an" + end +end + +local function previsright(current) + current = getprev(current) + local id = getid(current) + if id == glyph_code then + local character = getchar(current) + local direction = chardirections[character] + return direction == "r" or direction == "al" or direction == "an" + end +end + local function process(start) local head = tonut(start) -- we have a global head - local current = head - local inserted = nil - local finish = nil local autodir = 0 local embedded = 0 local override = 0 local pardir = 0 local textdir = 0 local done = false - local finished = nil - local finidir = nil local stack = { } local top = 0 local obsolete = { } - local lro = false + local rlo = false local lro = false local prevattr = false local fences = { } - local function finish_auto_before() - head, inserted = insert_node_before(head,current,stopdir(finish)) - finished, finidir, autodir = inserted, finish, 0 - finish, done = nil, true - end - - local function finish_auto_after() - head, current = insert_node_after(head,current,stopdir(finish)) - finished, finidir, autodir = current, finish, 0 - finish, done = nil, true - end - - local function force_auto_left_before(direction) - if finish then - head, inserted = insert_node_before(head,current,stopdir(finish)) - finished = inserted - finidir = finish - end - if embedded >= 0 then - finish, autodir = "TLT", 1 - else - finish, autodir = "TRT", -1 - end - done = true - if finidir == finish then - head = remove_node(head,finished,true) - else - head, inserted = insert_node_before(head,current,startdir(finish)) - end - end - - local function force_auto_right_before(direction) - if finish then - head, inserted = insert_node_before(head,current,stopdir(finish)) - finished = inserted - finidir = finish - end - if embedded <= 0 then - finish, autodir = "TRT", -1 - else - finish, autodir = "TLT", 1 - end - done = true - if finidir == finish then - head = remove_node(head,finished,true) - else - head, inserted = insert_node_before(head,current,startdir(finish)) - end - end - - local function nextisright(current) - current = getnext(current) - local id = getid(current) - if id == glyph_code then - local character = getchar(current) - local direction = chardirections[character] - return direction == "r" or direction == "al" or direction == "an" - end - end - - local function previsright(current) - current = getprev(current) - local id = getid(current) - if id == glyph_code then - local character = getchar(current) - local direction = chardirections[character] - return direction == "r" or direction == "al" or direction == "an" - end - end - while current do - local id = getid(current) + local id = getid(current) + local next = getnext(current) if id == math_code then - current = getnext(end_of_math(getnext(current))) + current = getnext(end_of_math(next)) + elseif getprop(current,"direction") then + -- this handles unhbox etc + current = next else local attr = getattr(current,a_directions) - if attr and attr > 0 and attr ~= prevattr then - if not getglobal(a) then - lro, rlo = false, false + if attr and attr > 0 then + if attr ~= prevattr then + if not getglobal(a) then + lro = false + rlo = false + end + prevattr = attr end - prevattr = attr end if id == glyph_code then if attr and attr > 0 then local character = getchar(current) - local direction = chardirections[character] - local reversed = false - if rlo or override > 0 then - if direction == "l" then - direction = "r" - reversed = true - end - elseif lro or override < 0 then - if direction == "r" or direction == "al" then - setprop(current,a_state,s_isol) - direction = "l" - reversed = true + if character == 0 then + -- skip signals + setprop(current,"direction",true) + else + local direction = chardirections[character] + local reversed = false + if rlo or override > 0 then + if direction == "l" then + direction = "r" + reversed = true + end + elseif lro or override < 0 then + if direction == "r" or direction == "al" then + setprop(current,a_state,s_isol) -- hm + direction = "l" + reversed = true + end end - end - if direction == "on" then - local mirror = charmirrors[character] - if mirror and fontchar[getfont(current)][mirror] then - local class = charclasses[character] - if class == "open" then - if nextisright(current) then - if autodir >= 0 then - force_auto_right_before(direction) + if direction == "on" then + local mirror = charmirrors[character] + if mirror and fontchar[getfont(current)][mirror] then + local class = charclasses[character] + if class == "open" then + if nextisright(current) then + setfield(current,"char",mirror) + setprop(current,"direction","r") + elseif autodir < 0 then + setfield(current,"char",mirror) + setprop(current,"direction","r") + else + mirror = false + setprop(current,"direction","l") + end + local fencedir = autodir == 0 and textdir or autodir + fences[#fences+1] = fencedir + elseif class == "close" and #fences > 0 then + local fencedir = fences[#fences] + fences[#fences] = nil + if fencedir < 0 then + setfield(current,"char",mirror) + setprop(current,"direction","r") + else + setprop(current,"direction","l") + mirror = false end - setfield(current,"char",mirror) - done = true elseif autodir < 0 then setfield(current,"char",mirror) - done = true + setprop(current,"direction","r") else + setprop(current,"direction","l") mirror = false end - local fencedir = autodir == 0 and textdir or autodir - fences[#fences+1] = fencedir - elseif class == "close" and #fences > 0 then - local fencedir = fences[#fences] - fences[#fences] = nil - if fencedir < 0 then - setfield(current,"char",mirror) - done = true - force_auto_right_before(direction) - else - mirror = false - end - elseif autodir < 0 then - setfield(current,"char",mirror) - done = true + end + if trace_directions then + setcolor(current,direction,false,mirror) + end + elseif direction == "l" then + if trace_directions then + setcolor(current,"l",reversed) + end + setprop(current,"direction","l") + elseif direction == "r" then + if trace_directions then + setcolor(current,"r",reversed) + end + setprop(current,"direction","r") + elseif direction == "en" then -- european number + if trace_directions then + setcolor(current,"l") + end + setprop(current,"direction","l") + elseif direction == "al" then -- arabic number + if trace_directions then + setcolor(current,"r") + end + setprop(current,"direction","r") + elseif direction == "an" then -- arabic number + if trace_directions then + setcolor(current,"r") + end + setprop(current,"direction","r") + elseif direction == "lro" then -- Left-to-Right Override -> right becomes left + top = top + 1 + stack[top] = { override, embedded } + override = -1 + obsolete[#obsolete+1] = current + elseif direction == "rlo" then -- Right-to-Left Override -> left becomes right + top = top + 1 + stack[top] = { override, embedded } + override = 1 + obsolete[#obsolete+1] = current + elseif direction == "lre" then -- Left-to-Right Embedding -> TLT + top = top + 1 + stack[top] = { override, embedded } + embedded = 1 + obsolete[#obsolete+1] = current + elseif direction == "rle" then -- Right-to-Left Embedding -> TRT + top = top + 1 + stack[top] = { override, embedded } + embedded = -1 + obsolete[#obsolete+1] = current + elseif direction == "pdf" then -- Pop Directional Format + if top > 0 then + local s = stack[top] + override = s[1] + embedded = s[2] + top = top - 1 else - mirror = false + override = 0 + embedded = 0 end + obsolete[#obsolete+1] = current + elseif trace_directions then + setcolor(current) end - if trace_directions then - setcolor(current,direction,false,mirror) - end - elseif direction == "l" then - if trace_directions then - setcolor(current,"l",reversed) - end - if autodir <= 0 then -- could be option - force_auto_left_before(direction) - end - elseif direction == "r" then - if trace_directions then - setcolor(current,"r",reversed) - end - if autodir >= 0 then - force_auto_right_before(direction) - end - elseif direction == "en" then -- european number - if trace_directions then - setcolor(current,"l") - end - if autodir <= 0 then -- could be option - force_auto_left_before(direction) - end - elseif direction == "al" then -- arabic number - if trace_directions then - setcolor(current,"r") - end - if autodir >= 0 then - force_auto_right_before(direction) - end - elseif direction == "an" then -- arabic number - if trace_directions then - setcolor(current,"r") - end - if autodir >= 0 then - force_auto_right_before(direction) - end - elseif direction == "lro" then -- Left-to-Right Override -> right becomes left - top = top + 1 - stack[top] = { override, embedded } - override = -1 - obsolete[#obsolete+1] = current - elseif direction == "rlo" then -- Right-to-Left Override -> left becomes right - top = top + 1 - stack[top] = { override, embedded } - override = 1 - obsolete[#obsolete+1] = current - elseif direction == "lre" then -- Left-to-Right Embedding -> TLT - top = top + 1 - stack[top] = { override, embedded } - embedded = 1 - obsolete[#obsolete+1] = current - elseif direction == "rle" then -- Right-to-Left Embedding -> TRT - top = top + 1 - stack[top] = { override, embedded } - embedded = -1 - obsolete[#obsolete+1] = current - elseif direction == "pdf" then -- Pop Directional Format - if top > 0 then - local s = stack[top] - override, embedded = s[1], s[2] - top = top - 1 - end - obsolete[#obsolete+1] = current - elseif trace_directions then - setcolor(current) end else - -- we do nothing + setprop(current,"direction",true) end elseif id == whatsit_code then local subtype = getsubtype(current) @@ -361,40 +311,69 @@ local function process(start) elseif dir == 'TLT' then autodir = 1 end - pardir = autodir + pardir = autodir textdir = pardir elseif subtype == dir_code then - -- todo: also treat as lro|rlo and stack - if finish then - finish_auto_before() - end local dir = getfield(current,"dir") if dir == "+TRT" then - finish, autodir = "TRT", -1 - elseif dir == "-TRT" then - finish, autodir = nil, 0 + autodir = -1 elseif dir == "+TLT" then - finish, autodir = "TLT", 1 - elseif dir == "-TLT" then - finish, autodir = nil, 0 + autodir = 1 + elseif dir == "-TRT" or dir == "-TLT" then + if embedded and embedded~= 0 then + autodir = embedded + else + autodir = 0 + end + else + -- message end textdir = autodir - else - if finish then - finish_auto_before() - end end - elseif finish then - finish_auto_before() + setprop(current,"direction",true) + else + setprop(current,"direction",true) end - local cn = getnext(current) - if cn then - -- we're okay - elseif finish then - finish_auto_after() + current = next + end + end + + -- todo: track if really needed + + local pp = nil + + while current do + local id = getid(current) + if id == math_code then + current = getnext(end_of_math(getnext(current))) + else + local cp = getprop(current,"direction") + if cp == pp then + elseif cp == true then + if pp == "r" then + head = insert_node_before(head,current,stopdir("TRT")) + elseif pp == "l" then + head = insert_node_before(head,current,stopdir("TLT")) + end + pp = cp + done = true + elseif cp == "l" then + if pp == "r" then + head = insert_node_before(head,current,stopdir("TRT")) + end + head = insert_node_before(head,current,startdir("TLT")) + pp = cp + done = true + elseif cp == "r" then + if pp == "l" then + head = insert_node_before(head,current,stopdir("TLT")) + end + head = insert_node_before(head,current,startdir("TRT")) + pp = cp + done = true end - current = cn end + current = getnext(current) end if done and strip then @@ -403,7 +382,9 @@ local function process(start) for i=1,n do remove_node(head,obsolete[i],true) end - report_directions("%s character nodes removed",n) + if trace_directions then + report_directions("%s character nodes removed",n) + end end end @@ -412,4 +393,3 @@ local function process(start) end directions.installhandler(interfaces.variables.default,process) - diff --git a/tex/context/base/typo-dir.mkiv b/tex/context/base/typo-dir.mkiv index f9b4ecb97..7290c8313 100644 --- a/tex/context/base/typo-dir.mkiv +++ b/tex/context/base/typo-dir.mkiv @@ -53,7 +53,7 @@ % \setupdirections[bidi=global,method=two] % \setupdirections[bidi=global,method=two,fences=no] -% maybee use chardefs +% maybe use chardefs \def\typo_dir_get_mode {\def\currentbidimode{\clf_getbidimode diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index fed9e0745..dcd37b72c 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -180,6 +180,7 @@ local isleftpage = layouts.status.isleftpage local registertogether = builders.paragraphs.registertogether -- tonode local a_margindata = attributes.private("margindata") +local a_specialcontent = attributes.private("specialcontent") local inline_mark = nodepool.userids["margins.inline"] @@ -261,6 +262,7 @@ end function margins.save(t) setmetatable(t,defaults) local content = getbox(t.number) +setattr(content,a_specialcontent,1) local location = t.location local category = t.category local inline = t.inline @@ -786,12 +788,17 @@ local function flushed(scope,parent) -- current is hlist done = done or don end if done then - local a = getattr(head,a_linenumber) -- hack .. we need a more decent critical attribute inheritance mechanism - local l = hpack_nodes(head,getfield(parent,"width"),"exactly") - setfield(parent,"list",l) - if a then - setattr(l,a_linenumber,a) - end +-- local a = getattr(head,a_linenumber) -- hack .. we need a more decent critical attribute inheritance mechanism +-- local l = hpack_nodes(head,getfield(parent,"width"),"exactly") +-- setfield(parent,"list",l) +-- if a then +-- setattr(l,a_linenumber,a) +-- end +-- packing messes up profiling +local a = getattr(head,a_linenumber) +if a then + setattr(parent,a_linenumber,a) +end -- resetstacked() end return done, continue diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 9f598b524..67366bfed 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 07/28/15 19:12:55 +-- merge date : 08/03/15 15:33:36 do -- begin closure to overcome local limits and interference diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex index a1398ef48..9f03027bc 100644 --- a/tex/generic/context/luatex/luatex-test.tex +++ b/tex/generic/context/luatex/luatex-test.tex @@ -35,7 +35,7 @@ \font\mathtest=cambria(math) {\mathtest 123} -\font\gothic=msgothic(ms-gothic) {\gothic whatever} +% \font\gothic=msgothic(ms-gothic) {\gothic whatever} % no longer in windows 10 \bgroup -- cgit v1.2.3