diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-01-17 18:05:46 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-01-17 18:05:46 +0100 |
commit | 0cfeab235554eeee0dddd6c3f44d3939ab490ff1 (patch) | |
tree | fed70e9a3332741e5294a01197c716dff8556506 /tex | |
parent | 72d161c0a522fd92f32edd3588fa126c453f4a3d (diff) | |
download | context-0cfeab235554eeee0dddd6c3f44d3939ab490ff1.tar.gz |
2017-01-17 17:43:00
Diffstat (limited to 'tex')
82 files changed, 2709 insertions, 1214 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 353d27e9f..a054df213 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{2016.12.28 17:55} +\newcontextversion{2017.01.17 17:37} %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 5e069a54d..de8003b5a 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{2016.12.28 17:55} +\edef\contextversion{2017.01.17 17:37} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii index 6294d6b29..9a0247e5f 100644 --- a/tex/context/base/mkii/mult-cs.mkii +++ b/tex/context/base/mkii/mult-cs.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{offsetramecku} \setinterfaceconstant{frameradius}{polomerramecku} \setinterfaceconstant{frames}{ramecky} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{z} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 6993afa4d..1e9f742ca 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{rahmenoffset} \setinterfaceconstant{frameradius}{rahmenradius} \setinterfaceconstant{frames}{umrahmen} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{von} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii index 8865cd201..0af55d772 100644 --- a/tex/context/base/mkii/mult-en.mkii +++ b/tex/context/base/mkii/mult-en.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{frameoffset} \setinterfaceconstant{frameradius}{frameradius} \setinterfaceconstant{frames}{frames} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{from} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii index 45f382ec5..382e7e059 100644 --- a/tex/context/base/mkii/mult-fr.mkii +++ b/tex/context/base/mkii/mult-fr.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{decalagecadre} \setinterfaceconstant{frameradius}{rayoncadre} \setinterfaceconstant{frames}{cadres} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{de} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index 05c72b1f1..b59842f89 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{offsetcornice} \setinterfaceconstant{frameradius}{raggiocornice} \setinterfaceconstant{frames}{cornici} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{da} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index 6e87a52fc..a88ec0508 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{kaderoffset} \setinterfaceconstant{frameradius}{kaderstraal} \setinterfaceconstant{frames}{hokjes} +\setinterfaceconstant{freeregion}{vrijgebied} \setinterfaceconstant{from}{van} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1948,7 +1949,7 @@ \setinterfacecommand{useexternalsoundtrack}{gebruikexterngeluidsfragment} \setinterfacecommand{usemodule}{gebruikmodule} \setinterfacecommand{usemodules}{gebruikmodules} -\setinterfacecommand{usepath}{gebruikgebied} +\setinterfacecommand{usepath}{gebruikpad} \setinterfacecommand{usereferences}{gebruikreferenties} \setinterfacecommand{usespecials}{gebruikspecials} \setinterfacecommand{usesymbols}{gebruiksymbolen} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 61b14382a..3203a0ffb 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{آفستقالب} \setinterfaceconstant{frameradius}{شعاعقالب} \setinterfaceconstant{frames}{قالبها} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{از} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index 7edb17d65..41ccfc8ed 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -819,6 +819,7 @@ \setinterfaceconstant{frameoffset}{offsetframe} \setinterfaceconstant{frameradius}{razaframe} \setinterfaceconstant{frames}{frames} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{dela} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} diff --git a/tex/context/base/mkiv/anch-bck.mkvi b/tex/context/base/mkiv/anch-bck.mkvi index 61f32eaa0..3bd8cfb4b 100644 --- a/tex/context/base/mkiv/anch-bck.mkvi +++ b/tex/context/base/mkiv/anch-bck.mkvi @@ -98,12 +98,24 @@ \setuevalue{\currenttextbackground}{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}% \setuevalue{\e!start\currenttextbackground}{\starttextbackground[\currenttextbackground]}% \setuevalue{\e!stop \currenttextbackground}{\stoptextbackground}% -% \doif{\textbackgroundparameter\c!state}\v!start\checkpositionoverlays \to \everydefinetextbackground -% \appendtoks -% \doif{\textbackgroundparameter\c!state}\v!start\checkpositionoverlays -% \to \everysetuptextbackground +\newconstant \c_anch_backgrounds_pos_state +\newconditional\c_anch_backgrounds_pos_no_shape + +\def\anch_backgrounds_bpos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \bposkind\v_anch_backgrounds_text_current\plusthree + \else + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \fi} + +\def\anch_backgrounds_epos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \eposkind\v_anch_backgrounds_text_current\plusthree + \else + \eposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \fi} \unexpanded\def\starttextbackground {\begingroup @@ -122,6 +134,29 @@ \anch_backgrounds_text_preset_nop \anch_backgrounds_text_start_indeed} +% ugly hack to register usage + +\newcount \c_anch_backgrounds_text_count +\newcount \c_anch_backgrounds_text_check +\newconstant\c_anch_backgrounds_text_state + +\unexpanded\def\starttextbackground + {\begingroup + \global\advance\c_anch_backgrounds_text_count\plusone + \advance\c_anch_backgrounds_text_level\plusone + \dodoubleempty\anch_backgrounds_text_start} + +\def\anch_backgrounds_text_level_start + {\c_anch_backgrounds_text_check\c_anch_backgrounds_text_count} + +\def\anch_backgrounds_text_level_stop + {\c_anch_backgrounds_text_state + \ifnum\c_anch_backgrounds_text_count>\c_anch_backgrounds_text_check + \plusone + \else + \zerocount + \fi} + % todo \backgroundvariable\c!variant \let\anch_backgrounds_text_start_indeed\relax @@ -199,42 +234,52 @@ \unexpanded\def\starttextbackgroundmanual {\begingroup + \c_anch_backgrounds_pos_state\plusone \usetextbackgroundstyleandcolor\c!style\c!color - \bpos\v_anch_backgrounds_text_current} + \anch_backgrounds_bpos} \unexpanded\def\stoptextbackgroundmanual - {\epos\v_anch_backgrounds_text_current + {\anch_backgrounds_epos \carryoverpar\endgroup} \def\anch_backgrounds_text_start_txt {\ifvmode \dontleavehmode \fi \begingroup + \c_anch_backgrounds_pos_state\plusone \usetextbackgroundstyleandcolor\c!style\c!color - \bpos\v_anch_backgrounds_text_current} + \anch_backgrounds_bpos} \def\anch_backgrounds_text_stop_txt - {\epos\v_anch_backgrounds_text_current + {\anch_backgrounds_epos \carryoverpar\endgroup} \newskip\textbackgroundskip +% maybe we should have a resetter for such compensation struts + +\def\anch_backgrounds_reset_attributes + {\scratchcounter\attribute\snapmethodattribute + \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \attribute\snapmethodattribute\scratchcounter} + \def\anch_backgrounds_text_start_par % beware .. background shapes {\endgraf % new \textbackgroundparameter\c!before \begingroup + \c_anch_backgrounds_pos_state\plustwo \begingroup - \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \anch_backgrounds_reset_attributes \noindent \ifgridsnapping \spac_helpers_assign_skip\textbackgroundskip{\textbackgroundparameter\c!topoffset}% \ifdim\textbackgroundskip>\zeropoint \struttedbox % not always ok (e.g. setups) - {\hpack{\raise\textbackgroundskip\hpack{\bpos\v_anch_backgrounds_text_current}}}% + {\hpack{\raise\textbackgroundskip\hpack{\anch_backgrounds_bpos}}}% \else - \bpos\v_anch_backgrounds_text_current + \anch_backgrounds_bpos \fi \else - \bpos\v_anch_backgrounds_text_current + \anch_backgrounds_bpos \fi \endgraf % we need a vertical nobreak - 29/06/2004 \endgroup @@ -277,18 +322,19 @@ \endgroup \begingroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM - \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \anch_backgrounds_reset_attributes \nobreak \noindent \strut \hfill \kern\zeropoint + % so far \spac_helpers_assign_skip\textbackgroundskip{\textbackgroundparameter\c!bottomoffset}% \ifgridsnapping % experimental, pascal (todo: topoffset in same way) \ifdim\textbackgroundskip>\zeropoint \struttedbox % not always ok (e.g. setups) - {\hpack{\lower\textbackgroundskip\hpack{\epos\v_anch_backgrounds_text_current}}}% + {\hpack{\lower\textbackgroundskip\hpack{\anch_backgrounds_epos}}}% \else - \epos\v_anch_backgrounds_text_current + \anch_backgrounds_epos \fi \else - \epos\v_anch_backgrounds_text_current + \anch_backgrounds_epos \fi \endgraf \carryoverpar\endgroup @@ -302,9 +348,165 @@ \global\let\checkpositionoverlays\relax \fi} +% shape handling + +\definesystemattribute[textbackground][public] + +\def\page_prepare_backgrounds#1% + {\clf_collectbackgrounds\realpageno#1\relax} + +\def\anch_backgrounds_bpos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \attribute\textbackgroundattribute\attributeunsetvalue + \bposkind\v_anch_backgrounds_text_current\plusthree + \else\ifnum\c_anch_backgrounds_pos_state=\plusone + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \clf_registerbackground{\v_anch_backgrounds_text_current}% + \else + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \attribute\textbackgroundattribute\attributeunsetvalue + \fi\fi} + +% plugs into other code + +\def\strc_floats_wrap_free_region + {\global\setbox\floatbox\hpack % we always need to wrap + {\ifconditional\c_strc_floats_trace_free + \strc_floats_show_free_region + \fi + \box\floatbox}} + +\startuseMPgraphic{floatfree} + draw_free_region( + \the\wd\floatbox, + \the\ht\floatbox, + \the\dp\floatbox, + \the\d_free_offset_left, + \the\d_free_offset_right, + \the\d_free_offset_top, + \the\d_free_offset_bottom + ) ; +\stopuseMPgraphic + +\def\strc_floats_show_free_region + {\lower\dp\floatbox\hpack to \zeropoint {\useMPgraphic{floatfree}}} + +\newconditional\c_strc_floats_mark_as_free +\newconditional\c_strc_floats_trace_free +\newconstant \c_free_offset_kind +\newdimen \d_free_offset_left +\newdimen \d_free_offset_right +\newdimen \d_free_offset_top +\newdimen \d_free_offset_bottom + +\installtextracker{floats.freeregion} + {\settrue \c_strc_floats_trace_free} + {\setfalse\c_strc_floats_trace_free} + +\def\strc_floats_mark_as_free#1#2#3#4#5% + {\c_free_offset_kind #1% + \d_free_offset_left #2% + \d_free_offset_right #3% + \d_free_offset_top #4% + \d_free_offset_bottom#5% + \strc_floats_wrap_free_region + \anch_mark_tagged_box_free + \floatbox + \c_free_offset_kind + \d_free_offset_left + \d_free_offset_right + \d_free_offset_top + \d_free_offset_bottom} + +\ifx\strc_floats_mark_pag_as_free\relax \else + \writestatus{error}{wrong place for pag_as_free}\wait +\fi + +\ifx\strc_floats_mark_par_as_free\relax \else + \writestatus{error}{wrong place for par_as_free}\wait +\fi + +\def\strc_floats_mark_pag_as_free + {\ifpositioning + \ifconditional\c_strc_floats_mark_as_free + \strc_floats_mark_as_free + \plusone + \zeropoint + \zeropoint + \d_strc_floats_top + \d_strc_floats_bottom + \fi + \fi} + +\def\strc_floats_mark_par_as_free + {\ifpositioning + \ifconditional\c_strc_floats_mark_as_free + \ifcase\c_page_sides_float_type + \or % backspace + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftedge + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftmargin + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftside + \strc_floats_mark_as_free + \plustwo + \d_page_sides_leftskip + \d_strc_floats_margin + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightside + \strc_floats_mark_as_free + \plusthree + \d_strc_floats_margin + \d_page_sides_rightskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightmargin + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightedge + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % cutspace + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \fi + \fi + \fi} + +% so far + \setuptextbackground [\c!mp=mpos:region:draw, - \c!method=mpos:region, % mpos:regionshape + \c!method=mpos:region, \c!state=\v!start, \c!location=\v!text, \c!leftoffset=\!!zeropoint, % 1em, @@ -361,9 +563,13 @@ boxlineradius := \MPvar{lineradius} ; boxlineoffset := \MPvar{lineoffset} ; % - def boxgridoptions = withcolor \MPvar{gridcolor} enddef ; - def boxlineoptions = withcolor \MPvar{linecolor} enddef ; - def boxfilloptions = withcolor \MPvar{fillcolor} enddef ; + def boxgridcolor = \MPvar{gridcolor} enddef ; + def boxlinecolor = \MPvar{linecolor} enddef ; + def boxfillcolor = \MPvar{fillcolor} enddef ; + % + def boxgridoptions = withcolor boxgridcolor enddef ; + def boxlineoptions = withcolor boxlinecolor enddef ; + def boxfilloptions = withcolor boxfillcolor enddef ; \stopuseMPgraphic \startuseMPgraphic{mpos:region:extra} @@ -374,17 +580,6 @@ setbounds currentpicture to multibox ; \stopuseMPgraphic -% \startMPpositionmethod{mpos:region} -% \startMPpositiongraphic{mpos:region}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} -% \includeMPgraphic{mpos:region:setup} ; -% \includeMPgraphic{mpos:region:extra} ; -% \MPgetmultipars{\MPvar{self}}{\MPanchorid} ; -% \includeMPgraphic{\MPvar{mp}} ; -% \includeMPgraphic{mpos:region:anchor} ; -% \stopMPpositiongraphic -% \MPpositiongraphic{mpos:region}{}% -% \stopMPpositionmethod - \startMPpositiongraphic{mpos:region}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} \includeMPgraphic{mpos:region:setup} ; \includeMPgraphic{mpos:region:extra} ; @@ -393,14 +588,6 @@ \includeMPgraphic{mpos:region:anchor} ; \stopMPpositiongraphic -\startMPpositiongraphic{mpos:regionshape}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} - \includeMPgraphic{mpos:region:setup} ; - \includeMPgraphic{mpos:region:extra} ; - \MPgetmultishapes{\MPvar{self}}{\MPanchorid} ; - \includeMPgraphic{\MPvar{mp}} ; - \includeMPgraphic{mpos:region:anchor} ; -\stopMPpositiongraphic - \startMPpositionmethod{mpos:region} \MPpositiongraphic{mpos:region}{}% \stopMPpositionmethod diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index fa5d50de8..5c79f70a1 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -7,249 +7,444 @@ if not modules then modules = { } end modules ['anch-pgr'] = { } -- This is a bit messy module but backgrounds are messy anyway. Especially when we want to --- follow shapes. This is work in progress (and always will be). +-- follow shapes. This will always be work in progress as it also depends on new features +-- in context. +-- +-- Alas, shapes and inline didn't work as expected end of 2016 so I had to pick up this +-- thread again. But with regular excursions to listening to Brad Mehldau's Mehliana I +-- could keep myself motivated. Some old stuff has been removed, some suboptimal code has +-- been replaced. Background code is still not perfect, but some day ... the details manual +-- will discuss this issue. -local format = string.format -local abs = math.abs +local abs, div, floor, round = math.abs, math.div, math.floor, math.round local concat, sort, copy = table.concat, table.sort, table.copy local splitter = lpeg.splitat(":") local lpegmatch = lpeg.match -local jobpositions = job.positions -local formatters = string.formatters +local jobpositions = job.positions +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex -local commands = commands -local context = context +local commands = commands +local context = context -local implement = interfaces.implement +local implement = interfaces.implement -local report_graphics = logs.reporter("graphics") +local report_graphics = logs.reporter("backgrounds") +local report_shapes = logs.reporter("backgrounds","shapes") +local report_free = logs.reporter("backgrounds","free") -local f_b_tag = formatters["b:%s"] -local f_e_tag = formatters["e:%s"] -local f_p_tag = formatters["p:%s"] +local trace_shapes = false trackers.register("backgrounds.shapes", function(v) trace_shapes = v end) +local trace_free = false trackers.register("backgrounds.shapes.free",function(v) trace_free = v end) -local f_tag_two = formatters["%s:%s"] +local f_b_tag = formatters["b:%s"] +local f_e_tag = formatters["e:%s"] +local f_p_tag = formatters["p:%s"] -local f_point = formatters["%p"] -local f_pair = formatters["(%p,%p)"] -local f_path = formatters["%--t--cycle"] +local f_tag_two = formatters["%s:%s"] -graphics = graphics or { } -local backgrounds = { } -graphics.backgrounds = backgrounds +local f_point = formatters["%p"] +local f_pair = formatters["(%p,%p)"] +local f_path = formatters["%--t--cycle"] +local f_pair_i = formatters["(%i,%i)"] -local function regionarea(r) - local rx = r.x - local ry = r.y - local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d - return { - f_pair(rx, rh - ry), - f_pair(rw, rh - ry), - f_pair(rw, rd - ry), - f_pair(rx, rd - ry), - } -end +graphics = graphics or { } +local backgrounds = { } +graphics.backgrounds = backgrounds --- we can use a 'local t, n' and reuse the table +-- -- -- -local eps = 2 +local texsetattribute = tex.setattribute +local texgetcount = tex.getcount +local pdfgetpos = pdf.getpos -- why not a generic name ! -local function add(t,x,y,direction,last) - local n = #t - if n == 0 then - t[n+1] = { x, y } +local a_textbackground = attributes.private("textbackground") + +local nuts = nodes.nuts + +local new_latelua = nuts.pool.latelua + +local getbox = nuts.getbox +local getlist = nuts.getlist + +local insert_before = nuts.insert_before +local insert_after = nuts.insert_after + +local processranges = nodes.processranges + +local v_yes = interfaces.variables.yes +local v_always = interfaces.variables.always + +local jobpositions = job.positions + +local data = { } +local realpage = 1 +local recycle = 1000 -- only tables can overflow this +local enabled = false + +-- Freeing the data is somewhat tricky as we can have backgrounds spanning +-- many pages but for an arbitrary background shape that is not so common. + +local function registerbackground(name) + local n = #data + 1 + if n > recycle then + n = 1 + end + local b = jobpositions.tobesaved["b:"..name] + if b then + local s = setmetatableindex("table") + b.s = s + data[n] = { + bpos = b, + name = name, + n = n, + shapes = s, + count = 0, + } + texsetattribute(a_textbackground,n) + enabled = true else - local tn = t[n] - local lx = tn[1] - local ly = tn[2] - if x == lx and y == ly then - -- quick skip - elseif n == 1 then - if abs(lx-x) > eps or abs(ly-y) > eps then - t[n+1] = { x, y } - end - else - local tm = t[n-1] - local px = tm[1] - local py = tm[2] - if (direction == "down" and y > ly) or (direction == "up" and y < ly) then - -- move back from too much hang - tn[1] = x -- hm - elseif abs(lx-px) <= eps and abs(lx-x) <= eps then - if abs(ly-y) > eps then - tn[2] = y - end - t[n+1] = { x, y } - elseif abs(ly-py) <= eps and abs(ly-y) <= eps then - if abs(lx-x) > eps then - tn[1] = x + texsetattribute(a_textbackground,attributes.unsetvalue) + end +end + +local function check(d,where) + -- this is not yet r2l ready + local w = d.shapes[realpage] + local x, y = pdfgetpos() + local n = #w + if n == 0 then + w[n+1] = { x, x, y } + elseif where == "r" then + local w0 = w[n] + if n > 2 then + local w2 = w[n-2] + if w2[2] == x then + local w1 = w[n-1] + if w1[2] == x then + local xx = w1[1] + if w2[1] == xx and xx == w0[1] then + w1[3] = w0[3] + w[n] = nil + return + end end - t[n+1] = { x, y } - elseif not last then - t[n+1] = { x, y } end end + w0[2] = x + elseif w[n][3] == y then + -- we have another one in the same line + -- w[n][2] = x + else + w[n+1] = { x, x, y } end end --- local function add(t,x,y,last) --- t[#t+1] = { x, y } --- end +local function flush(head,f,l,a,parent) + local d = data[a] + if d then + head, f = insert_before(head,f,new_latelua(function() check(d,"l") end)) + head, l = insert_after (head,l,new_latelua(function() check(d,"r") end)) + end + return head, true +end -local function finish(t) -- circulair list - local n = #t - if n > 1 then - local first = t[1] - local last = t[n] - if abs(first[1]-last[1]) <= eps and abs(first[2]-last[2]) <= eps then - t[n] = nil - end +local function collectbackgrounds(r,n) + if enabled then + local parent = getbox(n) + local head = getlist(parent) + realpage = r + processranges(a_textbackground,flush,head) -- ,parent) end end -local function clip(t,ytop,ybot) - local first = 1 - local last = #t - for i=first,last do - local y = t[i][2] - if ytop < y then - first = i - end - if ybot > y then - last = i - break - end +interfaces.implement { + name = "collectbackgrounds", + actions = collectbackgrounds, + arguments = { "integer", "integer" } +} + +interfaces.implement { + name = "registerbackground", + actions = registerbackground, + arguments = { "string" } +} + +-- optimized already but we can assume a cycle i.e. prune the last point and then +-- even less code .. we could merge some loops but his is more robust + +local function topairs(t,n) + local r = { } + for i=1,n do + local ti = t[i] + r[i] = f_pair_i(ti[1]/65556,ti[2]/65536) + end + return concat(r," ") +end + +local eps = 65536 / 4 -- 2 +local pps = eps +local nps = - pps + +local function unitvector(x,y) + if x < pps and x > nps then + x = 0 + elseif x < 0 then + x = -1 + else + x = 1 end - -- or just reuse t - local lp = { { t[first][1], ytop } } - local ln = 2 - for i=first+1,last-1 do - -- lp[ln] = { t[i][1], t[i][2] } - lp[ln] = t[i] - ln = ln + 1 + if y < pps and y > nps then + y = 0 + elseif y < 0 then + y = -1 + else + y = 1 end - lp[ln] = { t[last][1], ybot } - return lp + return x, y end --- todo: mark regions and free paragraphs in collected - --- We assume that we only hang per page and not cross pages which makes sense as hanging --- is only uses in special cases. We can remove data as soon as a page is done so we could --- remember per page and discard areas after each shipout. - -local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot,obeyhang) - local delta = r2l and (rw - rx) or 0 - local xleft = rx + delta - local xright = rw - delta - local paragraphs = r.paragraphs - local leftshape = { { xleft, rh } } -- spikes get removed so we can start at the edge - local rightshape = { { xright, rh } } -- even if we hang next - local extending = false - - if obeyhang and paragraphs and #paragraphs > 0 then - - for i=1,#paragraphs do - local p = paragraphs[i] - local ha = p.ha - if ha and ha ~= 0 then - local py = p.y - local ph = p.h - local pd = p.d - local hi = p.hi - local hang = ha * (ph + pd) - local py_ph = py + ph - if ha < 0 then - if hi < 0 then - -- right top - add(rightshape,xright, py_ph, "down") -- "up" - add(rightshape,xright + hi,py_ph, "down") -- "up" - add(rightshape,xright + hi,py_ph + hang,"down") -- "up" - add(rightshape,xright, py_ph + hang,"down") -- "up" - else - -- left top - add(leftshape,xleft, py_ph, "down") - add(leftshape,xleft + hi,py_ph, "down") - add(leftshape,xleft + hi,py_ph + hang,"down") - add(leftshape,xleft, py_ph + hang,"down") - end +local function finish(t) + local tm = #t + if tm < 2 then + return + end + if trace_shapes then + report_shapes("initial list: %s",topairs(t,tm)) + end + -- remove similar points + local n = 1 + local tn = tm + local tf = t[1] + local tx = tf[1] + local ty = tf[2] + for i=2,#t do + local ti = t[i] + local ix = ti[1] + local iy = ti[2] + local dx = ix - tx + local dy = iy - ty + if dx > eps or dx < - eps or dy > eps or dy < - eps then + n = n + 1 + t[n] = ti + tx = ix + ty = iy + end + end + if trace_shapes then + report_shapes("removing similar points: %s",topairs(t,n)) + end + if n > 2 then + -- remove redundant points + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] + + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= vx2 then + n = n + 1 + t[n] = ti else - -- maybe some day + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= vy2 then + n = n + 1 + t[n] = ti + end end - extending = true -- false - else -- we need to clip to the next par - local ps = p.ps - if ps then - local py = p.y - local ph = p.h - local pd = p.d - local step = ph + pd - local size = #ps * step - local py_ph = py + ph - add(leftshape, rx,py_ph,"up") - add(rightshape,rw,py_ph,"down") - for i=1,#ps do - local p = ps[i] - local l = p[1] - local w = p[2] - add(leftshape, xleft + l, py_ph,"up") - add(rightshape,xright + l + w, py_ph,"down") - py_ph = py_ph - step - add(leftshape, xleft + l, py_ph,"up") - add(rightshape,xright + l + w, py_ph,"down") + + tmx = tix + tmy = tiy + end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing redundant points: %s",topairs(t,n)) + end + -- remove spikes + if n > 2 then + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] + + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= - vx2 then + n = n + 1 + t[n] = ti + else + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= - vy2 then + n = n + 1 + t[n] = ti + end end - extending = true - elseif extending then - local py = p.y - local ph = p.h - local pd = p.d - local py_ph = py + ph - local py_pd = py - pd - add(leftshape, leftshape [#leftshape ][1],py_ph,"up") - add(rightshape,rightshape[#rightshape][1],py_ph,"down") - add(leftshape, xleft ,py_ph,"up") -- shouldn't this be py_pd - add(rightshape,xright,py_ph,"down") -- shouldn't this be py_pd - extending = false + + tmx = tix + tmy = tiy end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing spikes: %s",topairs(t,n)) end end - -- we can have a simple variant when no paragraphs - if extending then - -- not ok - leftshape [#leftshape] [2] = rd - rightshape[#rightshape][2] = rd + end + -- prune trailing points + if tm > n then + for i=tm,n+1,-1 do + t[i] = nil + end + end + if n > 1 then + local tf = t[1] + local tl = t[n] + local dx = tf[1] - tl[1] + local dy = tf[2] - tl[2] + if dx > eps or dx < - eps or dy > eps or dy < - eps then + -- different points else - add(leftshape, xleft ,rd,"up") - add(rightshape,xright,rd,"down") + -- saves a point (as we -- cycle anyway) + t[n] = nil + n = n -1 + end + if trace_shapes then + report_shapes("removing cyclic endpoints: %s",topairs(t,n)) end + end + return t +end - else - leftshape [2] = { xleft, rd } - rightshape[2] = { xright, rd } +local eps = 65536 + +-- The next function can introduce redundant points but these are removed later on +-- in the unspiker. It makes checking easier. + +local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) + local s = b.s + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape",kind) + end + return + end + s = s[realpage] + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape for page %s",kind,realpage) + end + return + end + local ns = #s + if ns == 0 then + if trace_shapes then + report_shapes("calculating %s area, empty shape for page %s",kind,realpage) + end + return + end + -- + if trace_shapes then + report_shapes("calculating %s area, using shape for page %s",kind,realpage) + end + -- it's a bit inefficient to use the par values and later compensate for b and + -- e but this keeps the code (loop) cleaner + local ph = p and p.h or 0 + local pd = p and p.d or 0 + -- + xmax = xmax + eps + xmin = xmin - eps + ymax = ymax + eps + ymin = ymin - eps + local ls = { } -- left shape + local rs = { } -- right shape + local pl = nil -- previous left x + local pr = nil -- previous right x + local n = 0 + for i=1,ns do + local si = s[i] + local xl = si[1] + local xr = si[2] + local y = si[3] + local xm = xl + (xr - xl)/2 -- midpoint should be in region + if xm >= xmin and xm <= xmax and y >= ymin and y <= ymax then + local h = y + ph + local d = y - pd + if pl then + n = n + 1 + ls[n] = { pl, h } + rs[n] = { pr, h } + end + n = n + 1 + ls[n] = { xl, h } + rs[n] = { xr, h } + n = n + 1 + ls[n] = { xl, d } + rs[n] = { xr, d } + end + pl, pr = xl, xr + end + -- + if true and n > 0 then + -- use height of b and depth of e, maybe check for weird border + -- cases here + if fh then + ls[1][2] = fh + rs[1][2] = fh + end + if fd then + ls[n][2] = fd + rs[n][2] = fd + end + end + -- + for i=n,1,-1 do + n = n + 1 rs[n] = ls[i] end - leftshape = clip(leftshape,lytop,lybot) - rightshape = clip(rightshape,rytop,rybot) - return leftshape, rightshape + return rs end -local function singlepart(b,e,r,left,right,obeyhang) +local function singlepart(b,e,p,realpage,r,left,right) local bx, by = b.x, b.y local ex, ey = e.x, e.y local rx, ry = r.x, r.y + local bh, bd = by + b.h, by - b.d + local eh, ed = ey + e.h, ey - e.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local bh = by + b.h - local bd = by - b.d - local eh = ey + e.h - local ed = ey - e.d if ex == rx then -- We probably have a strut at the next line so we force a width -- although of course it is better to move up. But as we have whitespace @@ -258,175 +453,160 @@ local function singlepart(b,e,r,left,right,obeyhang) end local area if by == ey then + if trace_shapes then + report_shapes("calculating single area, partial line") + end + area = { + { bx, bh }, + { ex, eh }, + { ex, ed }, + { bx, bd }, + } + elseif b.k == 2 then area = { - f_pair(bx,bh-ry), - f_pair(ex,eh-ry), - f_pair(ex,ed-ry), - f_pair(bx,bd-ry), + { rx, bh }, + { rw, bh }, + { rw, ed }, + { rx, ed }, } else - area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,ed,bh,eh,obeyhang,b.r2l) - - -- needed for shapes - - bx = leftshapes[1][1] - ex = rightshapes[#rightshapes][1] - - -- - - add(area,bx,bh-ry) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - add(area,ex,eh-ry) - add(area,ex,ed-ry) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - add(area,bx,bd-ry) - add(area,bx,bh-ry,nil,true) -- finish last straight line (but no add as we cycle) - - finish(area) - - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) - end + area = shape("single",b,p,realpage,rx,rw,rd,rh,bh,ed) + end + if not area then + area = { + { bx, bh }, + { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, bd }, + { bx, bd }, + } end return { location = "single", region = r, - area = area, + area = finish(area), } end -local function firstpart(b,r,left,right,obeyhang) +local function firstpart(b,e,p,realpage,r,left,right) local bx, by = b.x, b.y local rx, ry = r.x, r.y + local bh, bd = by + b.h, by - b.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local bh = by + b.h - local bd = by - b.d - local area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,rd,bh,rd,obeyhang,b.r2l) - add(area,bx,bh-ry) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - add(area,bx,bd-ry) - add(area,bx,bh-ry,nil,true) -- finish last straight line (but no add as we cycle) - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("first",b,p,realpage,rx,rw,rd,rh,bh,false) + if not area then + if b.k == 2 then + area = { + { rx, bh }, + { rw, bh }, + { rw, rd }, + { rx, rd }, + } + else + area = { + { bx, bh }, + { rw, bh }, + { rw, rd }, -- { rw, eh }, + { rx, rd }, -- { rx, ed }, + { rx, bd }, + { bx, bd }, + } + end end return { location = "first", region = r, - area = area, + area = finish(area), } end -local function middlepart(r,left,right,obeyhang) - local rx = r.x - local ry = r.y +local function middlepart(b,e,p,realpage,r,left,right) + local rx, ry = r.x, r.y + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,rd,rh,rd,obeyhang) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("middle",b,p,realpage,rx,rw,rd,rh,false,false) + if not area then + area = { + { rw, rh }, + { rw, rd }, + { rx, rd }, + { rx, rh }, + } end return { location = "middle", region = r, - area = area, + area = finish(area), } end -local function lastpart(e,r,left,right,obeyhang) +local function lastpart(b,e,p,realpage,r,left,right) local ex, ey = e.x, e.y local rx, ry = r.x, r.y + local eh, ed = ey + e.h, ey - e.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local eh = ey + e.h - local ed = ey - e.d - local area = { } - -- two cases: till end and halfway e line - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,ed,rh,eh,obeyhang,e.r2l) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - add(area,ex,eh-ry) - add(area,ex,ed-ry) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("last",b,p,realpage,rx,rw,rd,rh,false,ed) + if not area then + if b.k == 2 then + area = { + { rw, rh }, + { rw, ed }, + { rx, ed }, + { rx, rh }, + } + else + area = { + { rw, rh }, -- { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, rh }, -- { rx, bd }, + } + end end return { location = "last", region = r, - area = area, + area = finish(area), } end -local function calculatemultipar(tag,obeyhang) +local function calculatemultipar(tag) local collected = jobpositions.collected local b = collected[f_b_tag(tag)] local e = collected[f_e_tag(tag)] if not b or not e then - report_graphics("invalid tag %a",tag) + report_shapes("invalid tag %a",tag) return { } end local br = b.r local er = e.r if not br or not er then - report_graphics("invalid region for %a",tag) + report_shapes("invalid region for %a",tag) return { } end local btag, bindex = lpegmatch(splitter,br) local etag, eindex = lpegmatch(splitter,er) if not bindex or not eindex or btag ~= etag then - report_graphics("invalid indices for %a",tag) + report_shapes("invalid indices for %a",tag) return { } end local bindex = tonumber(bindex) @@ -435,41 +615,42 @@ local function calculatemultipar(tag,obeyhang) -- entries and these are shared. We compensate left/right based on the columns -- x and w but need to take the region into acount where the specification was -- flushed and not the begin pos's region, because otherwise we get the wrong - -- compensation for assymetrical doublesided layouts. - local left = 0 + -- compensation for asymetrical doublesided layouts. + local left = 0 local right = 0 - local rc = b.c + local bc = b.c + local rc = bc and collected[bc] if rc then - rc = collected[rc] - if rc then - local tb = collected[rc.r] - if tb then - left = -(tb.x - rc.x) - right = (tb.w - rc.w - left) -- tb.x - rc.x - end + local tb = collected[rc.r] + if tb then + left = -(tb.x - rc.x) + right = (tb.w - rc.w - left) end end -- Obeying intermediate changes of left/rightskip makes no sense as it will -- look bad, so we only look at the begin situation. local bn = b.n - if bn then - local bp = collected[f_p_tag(bn)] - if bp then - left = left + bp.ls - right = right + bp.rs - end + local p = bn and collected[f_p_tag(bn)] -- par + if p then + left = left + p.ls + right = right + p.rs + end + -- + local bp = b.p -- page + if trace_shapes then + report_shapes("tag %a, left %p, right %p, par %s, page %s, column %s", + left,right,bn or "-",bp or "-",bc or "-") end -- - local result if bindex == eindex then - result = { - list = { [b.p] = { singlepart(b,e,collected[br],left,right,obeyhang) } }, + return { + list = { [bp] = { singlepart(b,e,p,bp,collected[br],left,right) } }, bpos = b, epos = e, } else local list = { - [b.p] = { firstpart(b,collected[br],left,right,obeyhang) }, + [bp] = { firstpart(b,e,p,bp,collected[br],left,right) }, } for i=bindex+1,eindex-1 do br = f_tag_two(btag,i) @@ -477,68 +658,34 @@ local function calculatemultipar(tag,obeyhang) if not r then report_graphics("invalid middle for %a",br) else - local p = r.p - local pp = list[p] - local mp = middlepart(r,left,right,obeyhang) + local rp = r.p -- page + local pp = list[rp] + local mp = middlepart(b,e,p,rp,r,left,right) if pp then pp[#pp+1] = mp else - list[p] = { mp } + list[rp] = { mp } end end end - local p = e.p - local pp = list[p] - local lp = lastpart(e,collected[er],left,right,obeyhang) + local ep = e.p -- page + local pp = list[ep] + local lp = lastpart(b,e,p,ep,collected[er],left,right) if pp then pp[#pp+1] = lp else - list[p] = { lp } + list[ep] = { lp } end - result = { + return { list = list, bpos = b, epos = e, } end - return result end --- local pending = { } -- needs gc --- --- local function register(data,n,anchor) --- local pa = pending[anchor] --- if not pa then --- pa = { } --- pending[anchor] = pa --- end --- for page, pagedata in next, data do --- local pap = pa[page] --- if pap then --- pap[#pap+1] = n --- else --- pa[page] = { n } --- end --- end --- end --- --- function backgrounds.registered(anchor,page) --- local pa = pending[anchor] --- if pa then --- concat(pa,",") --- else --- return "" --- end --- end - local pbg = { } -- will move to pending -function backgrounds.calculatemultipar(n) - if not pbg[n] then - pbg[n] = calculatemultipar("pbg",n) or { } - end -end - local multilocs = { single = 1, -- maybe 0 first = 1, @@ -563,51 +710,335 @@ par_line_height := %p ; local f_template_b = formatters[ [[ multilocs[%s] := %s ; multikind[%s] := "%s" ; -multipars[%s] := simplified(%--t--cycle) shifted - (%p,%p) ; +multipars[%s] := (%--t--cycle) shifted - (%p,%p) ; ]] ] +-- unspiked(simplified(%--t--cycle)) shifted - (%p,%p) ; + local f_template_c = formatters[ [[ setbounds currentpicture to multibox ; ]] ] -local function fetchmultipar(n,anchor,page,obeyhang) - local data = pbg[n] - if not data then - data = calculatemultipar(n,obeyhang) - pbg[n] = data -- can be replaced by register - -- register(data.list,n,anchor) +local function freemultipar(pagedata,frees) -- ,k + -- if k == 3 then + -- -- tables have local regions + -- return + -- end + if not frees then + return + end + local nfree = #frees + if nfree == 0 then + return + end + for i=1,#pagedata do + local data = pagedata[i] + local area = data.area + + if area then + + local region = data.region + local y = 0 -- region.y + -- local x = region.x + local areas = { } + data.areas = areas + + local f_1, n_1 = { }, 0 + local f_2, n_2 = { }, 0 + for i=1,#frees do + local f = frees[i] + local k = f.k + if k == 1 then -- pag + n_1 = n_1 + 1 + f_1[n_1] = f + elseif k == 2 or k == 3 then -- par + n_2 = n_2 + 1 + f_2[n_2] = f + end + end + + local lineheight = tex.dimen.lineheight + + -- page floats + + local function check_one(free1,free2) + local temp = { } + local some = false + local top = (free2 and (y + free2.y + free2.h + (free2.to or 0))) or false + local bot = (free1 and (y + free1.y - free1.d - (free1.bo or 0))) or false + for i=1,#area do + local a = area[i] + local x = a[1] + local y = a[2] + if free2 and y <= top then + y = top + end + if free1 and y >= bot then + y = bot + end + if not some then + some = y + elseif some == true then + -- done + elseif y ~= some then + some = true + end + temp[i] = { x, y } + end + if some == true then + areas[#areas+1] = temp + end + end + + if n_1 > 0 then + check_one(false,f_1[1]) + for i=2,n_1 do + check_one(f_1[i-1],f_1[i]) + end + check_one(f_1[n_1],false) + end + + -- par floats + + if #areas == 0 then + areas[1] = area + end + + -- we can collect the coordinates first + + local function check_two(area,frees) + local ul = area[1] + local ur = area[2] + local lr = area[3] + local ll = area[4] + local ulx, uly = ul[1], ul[2] + local urx, ury = ur[1], ur[2] + local lrx, lry = lr[1], lr[2] + local llx, lly = ll[1], ll[2] + + local temp = { } + local n = 0 + local done = false + + for i=1,#frees do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 3 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, right") -- ok + end + n = n + 1 temp[n] = { xmin, ury } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, right") -- ok + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, right") + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, lry } + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, right") + end + n = n + 1 temp[n] = { xmin, lly } + n = n + 1 temp[n] = { xmin, uly } + done = true + else + -- case 0 + if trace_free then + report_free("case 0, nothing") + end + end + end + end + + if not done then + if trace_free then + report_free("no right shape") + end + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { lrx, lry } + n = n + 1 temp[n] = { llx, lly } + else + done = false + end + + for i=#frees,1,-1 do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 2 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, left") -- ok + end + n = n + 1 temp[n] = { ulx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, uly } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, left") -- ok + end + n = n + 1 temp[n] = { llx, lly } + n = n + 1 temp[n] = { llx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, uly } + done = true + else + -- case 0 + end + end + end + + if not done then + if trace_free then + report_free("no left shape") + end + n = n + 1 temp[n] = { llx, lly } + end + n = n + 1 temp[n] = { ulx, uly } + + return temp + end + + if n_2 > 0 then + for i=1,#areas do + local area = areas[i] + if #area == 4 then -- and also check type, must be pargaraph + areas[i] = check_two(area,f_2) + else + -- message that not yet supported + end + end + end + + for i=1,#areas do + finish(areas[i]) -- again + end + + end + end - if data then - local list = data.list +end + +local function fetchmultipar(n,anchor,page) + local a = jobpositions.collected[anchor] + if not a then + report_graphics("missing anchor %a",anchor) + else + local data = pbg[n] + if not data then + data = calculatemultipar(n) + pbg[n] = data -- can be replaced by register + -- register(data.list,n,anchor) + end + local list = data and data.list if list then local pagedata = list[page] if pagedata then + local k = data.bpos.k + if k ~= 3 then + -- to be checked: no need in txt mode + freemultipar(pagedata,jobpositions.free[page]) + end local nofmultipars = #pagedata - -- report_graphics("fetching %a at page %s using anchor %a containing %s multipars",n,page,anchor,nofmultipars) - local a = jobpositions.collected[anchor] - if not a then - report_graphics("missing anchor %a",anchor) - else - local x, y, w, h, d = a.x, a.y, a.w, a.h, a.d - local bpos = data.bpos - local bh, bd = bpos.h, bpos.d - local result = { f_template_a(nofmultipars,w,h+d,bh,bd,bh+bd) } - for i=1,nofmultipars do - local region = pagedata[i] - result[#result+1] = f_template_b( - i, multilocs[region.location], - i, region.location, - i, region.area, x, y-region.region.y) + if trace_shapes then + report_graphics("fetching %a at page %s using anchor %a containing %s multipars", + n,page,anchor,nofmultipars) + end + local x, y = a.x, a.y + local w, h, d = a.w, a.h, a.d + local bpos = data.bpos + local bh, bd = bpos.h, bpos.d + local result = { false } -- slot 1 will be set later + local n = 0 + for i=1,nofmultipars do + local data = pagedata[i] + local location = data.location + local region = data.region + local areas = data.areas + if not areas then + areas = { data.area } + end + for i=1,#areas do + local area = areas[i] + for i=1,#area do + local a = area[i] + area[i] = f_pair(a[1],a[2]) + end + n = n + 1 + result[n+1] = f_template_b(n,multilocs[location],n,location,n,area,x,y) end - data[page] = nil - result[#result+1] = f_template_c() - result = concat(result,"\n") - return result end + data[page] = nil + result[1] = f_template_a(n,w,h+d,bh,bd,bh+bd) -- was delayed + result[n+2] = f_template_c() + return concat(result,"\n") end end end - return f_template_a(0,"origin",0,0,0) + return f_template_a(0,0,0,0,0,0); end backgrounds.fetchmultipar = fetchmultipar @@ -624,12 +1055,6 @@ implement { arguments = { "string", "string", "integer" } } -implement { - name = "fetchmultishape", - actions = { fetchmultipar, context }, - arguments = { "string", "string", "integer", true } -} - local f_template_a = formatters[ [[ path posboxes[], posregions[] ; numeric pospages[] ; @@ -663,7 +1088,7 @@ implement { if r then local rx, ry, rw, rh, rd = r.x, r.y, r.w, r.h, r.d local cx = c.x - rx - local cy = c.y - ry + local cy = c.y local cw = cx + c.w local ch = cy + c.h local cd = cy - c.d @@ -689,17 +1114,19 @@ implement { name = "doifelserangeonpage", arguments = { "string", "string", "integer" }, actions = function(first,last,page) - local collected = jobpositions.collected - local f = collected[first] - if not f or f.p == true then - doifelse(false) - return - end - local l = collected[last] - if not l or l.p == true then - doifelse(false) - return + local c = jobpositions.collected + local f = c[first] + if f then + f = f.p + if f and f ~= true and page >= f then + local l = c[last] + if l then + l = l.p + doifelse(l and l ~= true and page <= l) + return + end + end end - doifelse(page >= f.p and page <= l.p) + doifelse(false) end } diff --git a/tex/context/base/mkiv/anch-pgr.mkiv b/tex/context/base/mkiv/anch-pgr.mkiv index a7ad26dff..1a583142e 100644 --- a/tex/context/base/mkiv/anch-pgr.mkiv +++ b/tex/context/base/mkiv/anch-pgr.mkiv @@ -13,18 +13,16 @@ \writestatus{loading}{ConTeXt Anchoring Macros / Grapics} -%D Before we come to graphics support, we have to make sure of -%D the reference point on the page. The next macros do so and -%D are hooked into the page building routine. +%D Before we come to graphics support, we have to make sure of the reference point +%D on the page. The next macros do so and are hooked into the page building routine. \registerctxluafile{anch-pgr}{1.001} \unprotect -%D A few more low level macros take care of defining and recalling -%D actions. Actions are saved globally! The lists can become quite -%D long because there can be lots of parameters passed on so we -%D clean up the list afterwards. +%D A few more low level macros take care of defining and recalling actions. Actions +%D are saved globally! The lists can become quite long because there can be lots of +%D parameters passed on so we clean up the list afterwards. \newtoks\everypositionaction \newtoks\everyinsertpositionaction @@ -91,22 +89,15 @@ \let\anch_positions_trace_action_yes\anch_positions_trace_action_yes_indeed \to \t_anch_positions_tracers -%D Here the complication has to do with collecting actions -%D for later execution. This collection is especially handy -%D when we want to move actions to a specific layer. Such -%D series of actions are stored in a macro that is cleaned up -%D after each invocation. +%D Here the complication has to do with collecting actions for later execution. This +%D collection is especially handy when we want to move actions to a specific layer. +%D Such series of actions are stored in a macro that is cleaned up after each +%D invocation. \def\anch_positions_cleanup_action % not in trialtypesetting {\ifcsname\??positioncleanup\currentpositionaction\endcsname \the\everycleanpositionaction - % \iflocalpositioning - % % erase - % \expandafter\let\csname\??positioncleanup\currentpositionaction\endcsname\empty - % \else - % globalize expansion cleans up - \setxvalue{\??positioncleanup\currentpositionaction}{\csname\??positioncleanup\currentpositionaction\endcsname}% - % \fi + \setxvalue{\??positioncleanup\currentpositionaction}{\csname\??positioncleanup\currentpositionaction\endcsname}% \fi} \def\handlepositionaction#1\with#2\on#3% ugly @@ -124,10 +115,9 @@ \fi \endgroup} -%D The first version of this module implemented head and tail -%D anchors. Currently we stick to just one anchor and derive -%D the head and tail anchors from this one. We set these -%D anchors before and after each page. +%D The first version of this module implemented head and tail anchors. Currently we +%D stick to just one anchor and derive the head and tail anchors from this one. We +%D set these anchors before and after each page. \newdimen\c_anch_page_width \newdimen\c_anch_page_height @@ -160,7 +150,7 @@ {\begingroup \setbox\scratchbox\emptyhbox \ht\scratchbox\textheight - \dp\scratchbox\zeropoint + \dp\scratchbox\zeropoint % redundant \wd\scratchbox\makeupwidth \anch_mark_text_box\scratchbox \box\scratchbox @@ -172,9 +162,8 @@ %D \macros %D {positionoverlay,startpositionoverlay} %D -%D As long as we're dealing with graphics it makes much sense -%D to use the available overlay mechanism. For this purpose, we -%D define some dedicated overlay extensions. +%D As long as we're dealing with graphics it makes much sense to use the available +%D overlay mechanism. For this purpose, we define some dedicated overlay extensions. %D %D \startbuffer[sample] %D \defineoverlay [sample] [\positionoverlay{sample}] @@ -213,27 +202,18 @@ %D %\getbuffer[graphic,sample,text] %D \stoplinecorrection %D -%D The graphic is defined in the following way, using some -%D macros defined in an auxiliary \METAPOST\ module that is -%D preloaded. +%D The graphic is defined in the following way, using some macros defined in an +%D auxiliary \METAPOST\ module that is preloaded. %D %D \typebuffer[graphic] \def\MPanchoridentifier{mpa} % {mp-anchor} -%D The rest of the definitions concerning such overlays may -%D look complicated, +%D The rest of the definitions concerning such overlays may look complicated, \let\currentpositionoverlay\empty -%D Position actions are automatically executed when a position -%D is set. - -% \newcount\localpositionnumber % incremented elsewhere -% \newif\iflocalpositioning -% -% \def\textbackgroundoverlay#1{\iflocalpositioning\v!local\else\v!text\fi#1} -% \def\MPanchornumber {\the\iflocalpositioning\localpositionnumber\else\realpageno\fi} +%D Position actions are automatically executed when a position is set. \def\textbackgroundoverlay#1{\v!text#1} \def\MPanchornumber {\the\realpageno} @@ -327,35 +307,8 @@ \unexpanded\def\stoppositionoverlay {\let\currentpositionoverlay\empty} -% needs checking if still needed -% -% \def\resetpositionoverlay#1% -% {\anch_positions_set_action{#1::\MPanchoridentifier::}{}} -% -% \def\handlepositionboxes#1#2#3% -% {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}} -% -% \def\doinsertpositionboxes#1#2#3% pos tag setups -% {\ifnum\MPp{#1}=\realpageno\relax % can be sped up -% \executeifdefined{\MPoverlayposprefix#1}\gobblethreearguments{#1}{#2}{#3}% not used -% \fi} -% -% \appendtoks -% \let\dohandlepositionboxes\doinsertpositionboxes % was handle ? -% \to \everyinsertpositionaction -% -% \def\docleanpositionboxes#1#2#3% pos tag setups -% {\ifnum\MPp{#1}<\realpageno \else -% \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert -% \fi} -% -% \appendtoks -% \let\dohandlepositionboxes\docleanpositionboxes -% \to \everycleanpositionaction - -%D A position graphic is a normal (non||reused) \METAPOST\ -%D graphic, used immediately, with zero dimensions, so that a -%D sequence of them does not harm. +%D A position graphic is a normal (non||reused) \METAPOST\ graphic, used +%D immediately, with zero dimensions, so that a sequence of them does not harm. \installcorenamespace{positiongraphic} \installcorenamespace{positionmethod} @@ -505,8 +458,7 @@ % Helpers: -\def\MPgetposboxes #1#2{\clf_fetchposboxes {#1}{#2}\realpageno} -\def\MPgetmultipars #1#2{\clf_fetchmultipar {#1}{#2}\realpageno} -\def\MPgetmultishapes#1#2{\clf_fetchmultishape{#1}{#2}\realpageno} +\def\MPgetposboxes #1#2{\clf_fetchposboxes{#1}{#2}\realpageno} +\def\MPgetmultipars#1#2{\clf_fetchmultipar{#1}{#2}\realpageno} \protect \endinput diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index 4360c9386..b415fac3a 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -17,7 +17,10 @@ more efficient.</p> -- maybe replace texsp by our own converter (stay at the lua end) -- eventually mp will have large numbers so we can use sp there too -local tostring, next, rawget, setmetatable = tostring, next, rawget, setmetatable +-- this is one of the first modules using scanners and we need to replace +-- it by implement and friends + +local tostring, next, rawget, setmetatable, tonumber = tostring, next, rawget, setmetatable, tonumber local sort, sortedhash, sortedkeys = table.sort, table.sortedhash, table.sortedkeys local format, gmatch, match, find = string.format, string.gmatch, string.match, string.find local rawget = rawget @@ -25,6 +28,8 @@ local lpegmatch = lpeg.match local insert, remove = table.insert, table.remove local allocate, mark = utilities.storage.allocate, utilities.storage.mark +local report = logs.reporter("positions") + local scanners = tokens.scanners local scanstring = scanners.string local scaninteger = scanners.integer @@ -57,6 +62,10 @@ local getlist = nuts.getlist local setlist = nuts.setlist local getbox = nuts.getbox local getskip = nuts.getskip +local getid = nuts.getid +local getdimensions = nuts.dimensions + +local hlist_code = nodes.listcodes.hlist local find_tail = nuts.tail @@ -124,6 +133,7 @@ local nofregular = 0 jobpositions.used = false -- todo: register subsets and count them indepently +-- todo: categories, like par, page, ... saves find and also ordered tags then -- local function initializer() -- tobesaved = jobpositions.tobesaved @@ -138,92 +148,74 @@ jobpositions.used = false -- if data then -- last = data -- last.p = nil -- no need for a page --- elseif last then +-- elseif last and not collected[region] then -- collected[region] = last -- end -- end -- end --- -- enhance regions with paragraphs --- -- local sorted = sortedkeys(collected) --- -- +-- -- enhance regions with paragraphs -- could be a list of tags instead -- there can be too many +-- local regions = { } +-- -- for tag, data in sortedhash(collected) do --saves a sort later on but can be huge -- for tag, data in next, collected do --- -- for i=1,#sorted do --- -- local tag = sorted[i] --- -- local data = collected[tag] --- local region = data.r --- if region then --- local r = collected[region] --- if r then --- local paragraphs = r.paragraphs --- if not paragraphs then --- r.paragraphs = { data } --- else +-- if find(tag,"^p:") then +-- local region = data.r +-- if region then +-- local paragraphs = regions[region] +-- if paragraphs then +-- local par = match(tag,"%d+") +-- data.par = tonumber(par) -- paragraphs[#paragraphs+1] = data +-- nofusedregions = nofusedregions + 1 +-- elseif r == false then +-- nofmissingregions = nofmissingregions + 1 +-- else +-- local r = collected[region] +-- if r then +-- local par = match(tag,"%d+") +-- data.par = tonumber(par) +-- paragraphs = { data } +-- regions[region] = paragraphs +-- nofusedregions = nofusedregions + 1 +-- r.paragraphs = paragraphs +-- else +-- nofmissingregions = nofmissingregions + 1 +-- regions[region] = false +-- end -- end --- nofusedregions = nofusedregions + 1 -- else --- nofmissingregions = nofmissingregions + 1 +-- nofregular = nofregular + 1 -- end --- else --- nofregular = nofregular + 1 -- end -- setmetatable(data,default) -- end --- -- add metatable --- -- for tag, data in next, collected do --- -- setmetatable(data,default) --- -- end -- -- sort this data --- for tag, data in next, collected do --- -- for i=1,#sorted do --- -- local tag = sorted[i] --- -- local data = collected[tag] --- local region = data.r --- if region then --- local r = collected[region] --- if r then --- local paragraphs = r.paragraphs --- if paragraphs and #paragraphs > 1 then --- sort(paragraphs,sorter) --- end --- end +-- for tag, paragraphs in next, regions do +-- if paragraphs then +-- sort(paragraphs,function(a,b) return a.par < b.par end) -- end --- -- so, we can be sparse and don't need 'or 0' code -- end -- jobpositions.used = next(collected) -- end --- todo: categories, like par, page, ... saves find and also ordered tags then +local splitter = lpeg.splitat(":") local function initializer() tobesaved = jobpositions.tobesaved collected = jobpositions.collected -- add sparse regions - local pages = structures.pages.collected - if pages then - local last = nil - for p=1,#pages do - local region = "page:" .. p - local data = collected[region] - if data then - last = data - last.p = nil -- no need for a page - elseif last then - collected[region] = last - end - end - end -- enhance regions with paragraphs -- could be a list of tags instead -- there can be too many - local regions = { } + local regiondata = { } + local pagedata = { } + local freedata = setmetatableindex("table") -- for tag, data in sortedhash(collected) do --saves a sort later on but can be huge for tag, data in next, collected do - if find(tag,"^p:") then + local prefix, rest = lpegmatch(splitter,tag) + if prefix == "p" then local region = data.r if region then - local paragraphs = regions[region] + local paragraphs = regiondata[region] if paragraphs then - local par = match(tag,"%d+") - data.par = tonumber(par) + data.par = tonumber(rest) or 0 paragraphs[#paragraphs+1] = data nofusedregions = nofusedregions + 1 elseif r == false then @@ -231,33 +223,63 @@ local function initializer() else local r = collected[region] if r then - local par = match(tag,"%d+") - data.par = tonumber(par) + data.par = tonumber(rest) or 0 paragraphs = { data } - regions[region] = paragraphs + regiondata[region] = paragraphs nofusedregions = nofusedregions + 1 r.paragraphs = paragraphs else nofmissingregions = nofmissingregions + 1 - regions[region] = false + regiondata[region] = false end end else nofregular = nofregular + 1 end + elseif prefix == "page" then + pagedata[tonumber(rest) or 0] = data + elseif prefix == "free" then + local t = freedata[data.p or 0] + t[#t+1] = data end setmetatable(data,default) end -- sort this data - for tag, paragraphs in next, regions do + for tag, paragraphs in next, regiondata do if paragraphs then sort(paragraphs,function(a,b) return a.par < b.par end) end end + -- + local pages = structures.pages.collected + if pages then + local last = nil + for p=1,#pages do + local region = "page:" .. p + local data = pagedata[p] + local free = freedata[p] + if free then + sort(free,function(a,b) return b.y < a.y end) -- order matters ! + end + if data then + last = data + last.free = free + elseif last then + local t = setmetatableindex({ free = free, p = p },last) + if not collected[region] then + collected[region] = t + else + -- something is wrong + end + pagedata[p] = t + end + end + end + jobpositions.page = pagedata + jobpositions.free = freedata jobpositions.used = next(collected) end - job.register('job.positions.collected', tobesaved, initializer) local regions = { } @@ -335,9 +357,6 @@ end local function set(name,index,val) -- ,key local data = enhance(val or index) if val then --- if data[key] and not next(next(data)) then --- data = data[key] --- end container = tobesaved[name] if not container then tobesaved[name] = { @@ -469,16 +488,14 @@ end jobpositions.b_region = b_region jobpositions.e_region = e_region -local function setregionbox(n,tag) +local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind if not tag or tag == "" then nofregions = nofregions + 1 tag = f_region(nofregions) end local box = getbox(n) - local w = getfield(box,"width") - local h = getfield(box,"height") - local d = getfield(box,"depth") - local x, y = getpos() -- was only y + local w, h, d = getdimensions(box) + local x, y = getpos() -- hm, makes no sense here tobesaved[tag] = { -- p = texgetcount("realpageno"), -- we copy them x = x ~= 0 and x or nil, -- was true @@ -486,17 +503,27 @@ local function setregionbox(n,tag) w = w ~= 0 and w or nil, h = h ~= 0 and h or nil, d = d ~= 0 and d or nil, + k = k ~= 0 and k or nil, + lo = lo ~= 0 and lo or nil, + ro = ro ~= 0 and ro or nil, + to = to ~= 0 and to or nil, + bo = bo ~= 0 and bo or nil, } return tag, box end -local function markregionbox(n,tag,correct) -- correct needs checking - local tag, box = setregionbox(n,tag) +local function markregionbox(n,tag,correct,...) -- correct needs checking + local tag, box = setregionbox(n,tag,...) -- todo: check if tostring is needed with formatter local push = new_latelua(function() b_region(tag) end) local pop = new_latelua(function() e_region(correct) end) -- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end local head = getlist(box) + -- no : + -- if getid(box) ~= hlist_code then + -- -- report("mark region box assumes a hlist, fix this for %a",tag) + -- head = nuts.hpack(head) + -- end if head then local tail = find_tail(head) setlink(push,head) @@ -528,15 +555,16 @@ local nofparagraphs = 0 scanners.parpos = function() -- todo: relate to localpar (so this is an intermediate variant) nofparagraphs = nofparagraphs + 1 texsetcount("global","c_anch_positions_paragraph",nofparagraphs) - local strutbox = getbox("strutbox") + local box = getbox("strutbox") + local w, h, d = getdimensions(box) local t = { p = true, c = true, r = true, x = true, y = true, - h = getfield(strutbox,"height"), -- never 0 - d = getfield(strutbox,"depth"), -- never 0 + h = h, + d = d, hs = texget("hsize"), -- never 0 } local leftskip = getfield(getskip("leftskip"),"width") @@ -605,9 +633,7 @@ end scanners.dosetpositionbox = function() -- name box local name = scanstring() local box = getbox(scaninteger()) - local w = getfield(box,"width") - local h = getfield(box,"height") - local d = getfield(box,"depth") + local w, h, d = getdimensions(box) tobesaved[name] = { p = true, c = column, @@ -646,10 +672,29 @@ end scanners.dosetpositionstrut = function() -- name local name = scanstring() - local strutbox = getbox("strutbox") - local h = getfield(strutbox,"height") - local d = getfield(strutbox,"depth") + local box = getbox("strutbox") + local w, h, d = getdimensions(box) + tobesaved[name] = { + p = true, + c = column, + r = true, + x = true, + y = true, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, + n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, + } + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) +end + +scanners.dosetpositionstrutkind = function() -- name + local name = scanstring() + local kind = scaninteger() + local box = getbox("strutbox") + local w, h, d = getdimensions(box) tobesaved[name] = { + k = kind, p = true, c = column, r = true, @@ -1279,6 +1324,11 @@ scanners.markregionboxcorrected = function() -- box tag markregionbox(scaninteger(),scanstring(),true) end +scanners.markregionboxtaggedkind = function() -- box tag kind + markregionbox(scaninteger(),scanstring(),nil, + scaninteger(),scandimen(),scandimen(),scandimen(),scandimen()) +end + -- statistics (at least for the moment, when testing) statistics.register("positions", function() diff --git a/tex/context/base/mkiv/anch-pos.mkiv b/tex/context/base/mkiv/anch-pos.mkiv index ecfbb9ce7..8b33dfce8 100644 --- a/tex/context/base/mkiv/anch-pos.mkiv +++ b/tex/context/base/mkiv/anch-pos.mkiv @@ -36,11 +36,12 @@ \def\dosavepositionwhd #1#2#3#4#5#6#7{\clf_dosavepositionwhd {#1}#2 #3 #4 #5 #6 #7\relax} \def\dosavepositionplus#1#2#3#4#5#6#7#8{\clf_dosavepositionplus{#1}#2 #3 #4 #5 #6 #7{#8}} -\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands -\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax} -\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}} -\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax} -\def\dosetpositionstrut #1{\clf_dosetpositionstrut{#1}} +\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands +\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax} +\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}} +\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax} +\def\dosetpositionstrut #1{\clf_dosetpositionstrut {#1}} +\def\dosetpositionstrutkind #1#2{\clf_dosetpositionstrutkind{#1}#2\relax} % #2 = number \newbox\b_anch_position \newif \ifpositioning % sort of public @@ -205,6 +206,26 @@ \strut \hss}} +\unexpanded\def\setpositionstrutkind + {\iftrialtypesetting + \expandafter\anch_positions_set_strut_kind_nop + \else + \expandafter\anch_positions_set_strut_kind_yes + \fi} + +\def\anch_positions_set_strut_kind_yes#1#2% + {\anch_positions_initialize + \hbox to \zeropoint + {\edef\currentposition{#1}% + \dosetpositionstrutkind\currentposition{#2}% + \anch_positions_trace_left + \dopositionaction\currentposition + \strut + \hss}} + +\def\anch_positions_set_strut_kind_nop#1#2% + {\strut} + \unexpanded\def\setpositiondataplus {\iftrialtypesetting \expandafter\gobblefivearguments @@ -294,6 +315,21 @@ \unexpanded\def\anch_mark_text_box#1% {\clf_markregionboxtagged#1{text:\the\realpageno}} % needs an hbox +\newcount\c_anch_free + +\unexpanded\def\anch_mark_tagged_box_free#1#2#3#4#5#6% only needed when positions + {\ifpositioning + \global\advance\c_anch_free\plusone % could be done at the lua end + \clf_markregionboxtaggedkind + #1% + {free:\number\c_anch_free}% + #2\space % kind + #3\space % leftoffset + #4\space % rightoffset + #5\space % topoffset + #6\relax % bottomoffset + \fi} + %D We can copy a position with: %D %D \starttyping @@ -338,10 +374,12 @@ \let\xypos\setpositiononly -\unexpanded\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox} -\unexpanded\def\vpos#1{\setpositionbox{#1}\vbox} -\unexpanded\def\bpos#1{\dontleavehmode \setpositionstrut{b:#1}\ignorespaces} -\unexpanded\def\epos#1{\removeunwantedspaces\setpositionstrut{e:#1}} +\unexpanded\def\hpos #1{\dontleavehmode\setpositionbox{#1}\hbox} +\unexpanded\def\vpos #1{\setpositionbox{#1}\vbox} +\unexpanded\def\bpos #1{\dontleavehmode\setpositionstrut{b:#1}\ignorespaces} +\unexpanded\def\epos #1{\removeunwantedspaces\setpositionstrut{e:#1}} +\unexpanded\def\bposkind#1#2{\dontleavehmode\setpositionstrutkind{b:#1}{#2}\ignorespaces} % not public, used in backgrounds +\unexpanded\def\eposkind#1#2{\removeunwantedspaces\setpositionstrutkind{e:#1}{#2}} % not public, used in backgrounds %D When we want to calculate more complex backgrounds, we need to know what the %D current indentation scheme is. At the cost of many positions and memory, we diff --git a/tex/context/base/mkiv/anch-tab.mkiv b/tex/context/base/mkiv/anch-tab.mkiv index 0c84fd7b5..afa87c7b2 100644 --- a/tex/context/base/mkiv/anch-tab.mkiv +++ b/tex/context/base/mkiv/anch-tab.mkiv @@ -64,6 +64,12 @@ \global\advance\c_anch_tabs\plusone \to \everytabulate +% for text backgrounds + +\appendtoks + \settrue\c_anch_backgrounds_pos_no_shape +\to \everytabulate + %D Beware, the following code is somewhat weird and experimental and might be %D dropped or become a loadable module. diff --git a/tex/context/base/mkiv/colo-ext.mkiv b/tex/context/base/mkiv/colo-ext.mkiv index 74ce2d3e5..98aaaa8aa 100644 --- a/tex/context/base/mkiv/colo-ext.mkiv +++ b/tex/context/base/mkiv/colo-ext.mkiv @@ -46,8 +46,8 @@ \installcorenamespace{colorintent} -\unexpanded\def\registercolorintent#1#2% - {\setevalue{\??colorintent#1}{\attribute\colorintentattribute\clf_registercolorintent{#2}}} +\unexpanded\def\registercolorintent#1#2% \relax is needed ! + {\setevalue{\??colorintent#1}{\attribute\colorintentattribute\clf_registercolorintent{#2}\relax}} \unexpanded\def\colo_intents_set {\clf_enablecolorintents diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 9057defc3..2e1068868 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.12.28 17:55} +\newcontextversion{2017.01.17 17:37} %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 1cab20d40..e4a97f01e 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.12.28 17:55} +\edef\contextversion{2017.01.17 17:37} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/core-uti.lua b/tex/context/base/mkiv/core-uti.lua index 54bcba08d..601e5aa20 100644 --- a/tex/context/base/mkiv/core-uti.lua +++ b/tex/context/base/mkiv/core-uti.lua @@ -22,25 +22,29 @@ local format, match = string.format, string.match local next, type, tostring = next, type, tostring local concat = table.concat -local definetable = utilities.tables.definetable -local accesstable = utilities.tables.accesstable -local migratetable = utilities.tables.migratetable -local serialize = table.serialize -local packers = utilities.packers -local allocate = utilities.storage.allocate -local mark = utilities.storage.mark +local definetable = utilities.tables.definetable +local accesstable = utilities.tables.accesstable +local migratetable = utilities.tables.migratetable +local serialize = table.serialize +local packers = utilities.packers +local allocate = utilities.storage.allocate +local mark = utilities.storage.mark -local implement = interfaces.implement +local getrandom = utilities.randomizer.get +local setrandomseedi = utilities.randomizer.setseedi +local getrandomseed = utilities.randomizer.getseed -local texgetcount = tex.getcount +local implement = interfaces.implement -local report_passes = logs.reporter("job","passes") +local texgetcount = tex.getcount -job = job or { } -local job = job +local report_passes = logs.reporter("job","passes") -job.version = 1.30 -job.packversion = 1.02 +job = job or { } +local job = job + +job.version = 1.30 +job.packversion = 1.02 -- some day we will implement loading of other jobs and then we need -- job.jobs @@ -132,11 +136,11 @@ local function initializer() -- rvalue = collected.randomseed if not rvalue then - rvalue = math.random() - math.setrandomseedi(rvalue,"initialize") + rvalue = getrandom("initialize") + setrandomseedi(rvalue) rmethod = "initialized" else - math.setrandomseedi(rvalue,"previous run") + setrandomseedi(rvalue) rmethod = "resumed" end tobesaved.randomseed = rvalue @@ -169,6 +173,10 @@ function jobvariables.restore(cs) return collectedmacros[cs] or tobesavedmacros[cs] end +function job.getrandomseed() + return tobesaved.randomseed or getrandomseed() +end + -- checksums function jobvariables.getchecksum(tag) diff --git a/tex/context/base/mkiv/example.rng b/tex/context/base/mkiv/example.rng new file mode 100644 index 000000000..09b80d14a --- /dev/null +++ b/tex/context/base/mkiv/example.rng @@ -0,0 +1,304 @@ +<?xml version="1.0" ?> + +<grammar xmlns="http://relaxng.org/ns/structure/1.0"> + + <start> + <choice> + <ref name="script"/> + <ref name="environment"/> + <ref name="sequence"/> + <ref name="request"/> + <ref name="reply"/> + </choice> + </start> + + <define name="script"> + <element name="script"> + <zeroOrMore> + <ref name="script"/> + <ref name="environment"/> + <ref name="sequence"/> + <ref name="request"/> + <ref name="reply"/> + </zeroOrMore> + </element> + </define> + + <define name="environment"> + <element name="environment"> + <zeroOrMore> + <ref name="environment.content"/> + </zeroOrMore> + </element> + </define> + + <define name="environment.content"> + <element name="variable"> + <ref name="content"/> + <attribute name="label"/> + </element> + </define> + + <define name="sequence"> + <element name="sequence"> + <zeroOrMore> + <ref name="sequence.process"/> + </zeroOrMore> + </element> + </define> + + <define name="sequence.process"> + <element name="process"> + <interleave> + <optional> + <ref name="sequence.result"/> + </optional> + <ref name="sequence.command"/> + </interleave> + </element> + </define> + + <define name="sequence.result"> + <element name="result"> + <ref name="content"/> + </element> + </define> + + <define name="sequence.command"> + <element name="command"> + <ref name="content"/> + </element> + </define> + + <define name="reply"> + <element name="reply"> + <interleave> + <optional> + <ref name="reply.result"/> + </optional> + <optional> + <ref name="status"/> + </optional> + <optional> + <ref name="comment"/> + </optional> + <optional> + <ref name="forwarded"/> + </optional> + </interleave> + </element> + </define> + + <define name="reply.result"> + <element name="result"> + <text/> + </element> + </define> + + <define name="request"> + <element name="request"> + <ref name="request.application"/> + <optional> + <ref name="request.client"/> + </optional> + <optional> + <ref name="request.server"/> + </optional> + <optional> + <ref name="request.data"/> + </optional> + <optional> + <zeroOrMore> + <ref name="request.blob"/> + </zeroOrMore> + </optional> + <optional> + <ref name="request.results"/> + </optional> + </element> + </define> + + <define name="request.application"> + <element name="application"> + <choice> + <ref name="request.command"/> + <ref name="request.action"/> + </choice> + <ref name="request.content"/> + </element> + </define> + + <define name="request.client"> + <element name="client"> + <ref name="request.content"/> + </element> + </define> + + <define name="request.server"> + <element name="server"> + <ref name="request.content"/> + </element> + </define> + + <define name="request.content"> + <interleave> + <optional> + <ref name="filename"/> + </optional> + <optional> + <ref name="archive"/> + </optional> + <optional> + <ref name="comment"/> + </optional> + <optional> + <ref name="forwarded"/> + </optional> + <optional> + <ref name="domain"/> + </optional> + <optional> + <ref name="project"/> + </optional> + <optional> + <ref name="usertoken"/> + </optional> + </interleave> + </define> + + <define name="request.command"> + <element name="command"> + <text/> + </element> + <optional> + <element name="option"> + <text/> + </element> + </optional> + </define> + + <define name="request.action"> + <element name="action"> + <text/> + </element> + </define> + + <define name="request.data"> + <element name="data"> + <choice> + <zeroOrMore> + <ref name="data.variable"/> + </zeroOrMore> + <optional> + <ref name="filename"/> + </optional> + </choice> + </element> + </define> + + <define name="request.results"> + <element name="results"> + <zeroOrMore> + <ref name="request.result"/> + </zeroOrMore> + </element> + </define> + + <define name="data.result"> + <element name="result"> + <attribute name="status"/> + <attribute name="name"/> + </element> + </define> + + <define name="request.blob"> + <element name="blob"> + <text/> + <attribute name="label"/> + </element> + </define> + + <define name="data.variable"> + <element name="variable"> + <text/> + <attribute name="label"/> + </element> + </define> + + <define name="content"> + <zeroOrMore> + <mixed> + <ref name="resolve"/> + </mixed> + </zeroOrMore> + </define> + + <define name="resolve"> + <optional> + <element name="resolve"> + <empty/> + <attribute name="label"/> + <optional> + <attribute name="type"> + <choice> + <value>path</value> + <value>name</value> + <value>suffix</value> + <value>nopath</value> + <value>nosuffix</value> + </choice> + </attribute> + </optional> + </element> + </optional> + </define> + + <define name="filename"> + <element name="filename"> + <text/> + </element> + </define> + + <define name="archive"> + <element name="archive"> + <text/> + </element> + </define> + + <define name="comment"> + <element name="comment"> + <text/> + </element> + </define> + + <define name="status"> + <element name="status"> + <text/> + </element> + </define> + + <define name="forwarded"> + <element name="forwarded"> + <text/> + </element> + </define> + + <define name="domain"> + <element name="domain"> + <text/> + </element> + </define> + + <define name="project"> + <element name="project"> + <text/> + </element> + </define> + + <define name="usertoken"> + <element name="usertoken"> + <text/> + </element> + </define> + +</grammar> diff --git a/tex/context/base/mkiv/font-otn.lua b/tex/context/base/mkiv/font-otn.lua index 2ed10f405..ace7bf12b 100644 --- a/tex/context/base/mkiv/font-otn.lua +++ b/tex/context/base/mkiv/font-otn.lua @@ -286,6 +286,8 @@ local registerotffeature = otffeatures.register local onetimemessage = fonts.loggers.onetimemessage or function() end +local getrandom = utilities and utilities.randomizer and utilities.randomizer.get + otf.defaultnodealternate = "none" -- first last -- we share some vars here, after all, we have no nested lookups and less code @@ -682,7 +684,7 @@ end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) local n = #alternatives if value == "random" then - local r = random(1,n) + local r = getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value == "first" then return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 2b18c1e0e..a9d3a8b29 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -645,7 +645,7 @@ local weights = { [300] = "light", [400] = "normal", [500] = "medium", - [600] = "semibold", + [600] = "semibold", -- demi demibold [700] = "bold", [800] = "extrabold", [900] = "black", @@ -1843,8 +1843,8 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo) local fontheader = fontdata.fontheader or { } local cffinfo = fontdata.cffinfo or { } local filename = fontdata.filename - local weight = getname(fontdata,"weight") or cffinfo.weight or metrics.weight - local width = getname(fontdata,"width") or cffinfo.width or metrics.width + local weight = getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width = getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) local fontname = getname(fontdata,"postscriptname") local fullname = getname(fontdata,"fullname") local family = getname(fontdata,"family") diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 17e1a3c30..1f8421481 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -244,6 +244,8 @@ local registerotffeature = otffeatures.register local onetimemessage = fonts.loggers.onetimemessage or function() end +local getrandom = utilities and utilities.randomizer and utilities.randomizer.get + otf.defaultnodealternate = "none" -- first last -- We use a few global variables. The handler can be called nested but this assumes that the @@ -653,7 +655,7 @@ end local function get_alternative_glyph(start,alternatives,value) local n = #alternatives if value == "random" then - local r = random(1,n) + local r = getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value == "first" then return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv index 6dfc6d3d3..881a577fb 100644 --- a/tex/context/base/mkiv/font-pre.mkiv +++ b/tex/context/base/mkiv/font-pre.mkiv @@ -40,6 +40,10 @@ trep=yes] % texligatures=yes,texquotes=yes \definefontfeature + [original] % a clone of default so we can revert + [default] + +\definefontfeature [smallcaps] [always] [smcp=yes, @@ -317,6 +321,10 @@ protrusion=quality] \definefontfeature + [fullprotrusion] + [protrusion=pure] + +\definefontfeature [slanted] [slant=.2] diff --git a/tex/context/base/mkiv/font-sol.lua b/tex/context/base/mkiv/font-sol.lua index 58abf09b4..44c337dd5 100644 --- a/tex/context/base/mkiv/font-sol.lua +++ b/tex/context/base/mkiv/font-sol.lua @@ -23,7 +23,7 @@ if not modules then modules = { } end modules ['font-sol'] = { -- this was: node local gmatch, concat, format, remove = string.gmatch, table.concat, string.format, table.remove local next, tostring, tonumber = next, tostring, tonumber local insert, remove = table.insert, table.remove -local random = math.random +local getrandom = utilities.randomizer.get local utilities, logs, statistics, fonts, trackers = utilities, logs, statistics, fonts, trackers local interfaces, commands, attributes = interfaces, commands, attributes @@ -706,7 +706,7 @@ end variants[v_random] = function(words,list,best,width,badness,line,set,listdir) local changed = 0 while #words > 0 do - local done, c = doit(remove(words,random(1,#words)),list,best,width,badness,line,set,listdir) + local done, c = doit(remove(words,getrandom("solution",1,#words)),list,best,width,badness,line,set,listdir) changed = changed + c if done then break diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index dce668842..a383370f5 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -128,8 +128,8 @@ local weights = Cs ( -- not extra + P("ultralight") + P("extralight") + P("bold") - + P("demi") - + P("semi") + + P("demi") -- / "semibold" + + P("semi") -- / "semibold" + P("light") + P("medium") + P("heavy") @@ -140,15 +140,16 @@ local weights = Cs ( -- not extra + P("regular") / "normal" ) --- numeric_weights = { --- 200 = "extralight", --- 300 = "light", --- 400 = "book", --- 500 = "medium", --- 600 = "demi", --- 700 = "bold", --- 800 = "heavy", --- 900 = "black", +-- local weights = { +-- [100] = "thin", +-- [200] = "extralight", +-- [300] = "light", +-- [400] = "normal", +-- [500] = "medium", +-- [600] = "semibold", -- demi demibold +-- [700] = "bold", +-- [800] = "extrabold", +-- [900] = "black", -- } local normalized_weights = sparse { @@ -569,6 +570,7 @@ local function check_name(data,result,filename,modification,suffix,subfont) -- local compatiblename = result.compatiblename -- local cfffullname = result.cfffullname local weight = result.weight + local width = result.width local italicangle = tonumber(result.italicangle) local subfont = subfont local rawname = fullname or fontname or familyname @@ -584,11 +586,12 @@ local function check_name(data,result,filename,modification,suffix,subfont) -- compatiblename = compatiblename and cleanname(compatiblename) -- cfffullname = cfffullname and cleanname(cfffullname) weight = weight and cleanname(weight) + width = width and cleanname(width) italicangle = italicangle == 0 and nil -- analyze local a_name, a_weight, a_style, a_width, a_variant = analyzespec(fullname or fontname or familyname) -- check - local width = a_width + local width = width or a_width local variant = a_variant local style = subfamilyname or subfamily -- can re really trust subfamilyname? if style then diff --git a/tex/context/base/mkiv/grph-rul.lua b/tex/context/base/mkiv/grph-rul.lua index f3d0bb95c..d5a7577d2 100644 --- a/tex/context/base/mkiv/grph-rul.lua +++ b/tex/context/base/mkiv/grph-rul.lua @@ -15,6 +15,9 @@ local userrule = nodes.rules.userrule local bpfactor = number.dimenfactors.bp local pdfprint = pdf.print +local currentattr = nodes.current_attr +local setfield = nodes.setfield + local getattribute = tex.getattribute local a_color = attributes.private('color') @@ -28,7 +31,7 @@ local trace_mp = false trackers.register("rules.mp", function(v) trace_mp local report_mp = logs.reporter("rules","mp") local floor = math.floor -local random = math.random +local getrandom = utilities.randomizer.get local formatters = string.formatters do @@ -108,7 +111,7 @@ def RuleColor = %color% enddef ; } if not initialized then initialized = true - simplemetapost("rulefun",formatters["randomseed := %s;"](random(0,4095))) + simplemetapost("rulefun",formatters["randomseed := %s;"](getrandom("rulefun",0,4095))) end local pdf = caching and cache[code] or simplemetapost("rulefun",code) -- w, h, d if trace_mp then @@ -172,20 +175,21 @@ interfaces.implement { { "name", "string" }, } } , actions = function(t) - local r = userrule(t) + local rule = userrule(t) local ma = getattribute(a_colormodel) or 1 local ca = getattribute(a_color) local ta = getattribute(a_transparency) + setfield(rule,"attr",currentattr()) if t.type == "mp" then t.ma = ma t.ca = ca t.ta = ta else - r[a_colormodel] = ma - r[a_color] = ca - r[a_transparency] = ta + rule[a_colormodel] = ma + rule[a_color] = ca + rule[a_transparency] = ta end - context(r) + context(rule) end } @@ -200,10 +204,11 @@ interfaces.implement { } } , actions = function(t) local factor = t.factor or 0 + local amount = getrandom("fakeword",t.min,t.max) local rule = userrule { height = 1.25*factor, depth = 0.25*factor, - width = floor(random(t.min,t.max)/10000) * 10000, + width = floor(amount/10000) * 10000, line = 0.10*factor, ma = getattribute(a_colormodel) or 1, ca = getattribute(a_color), @@ -211,6 +216,7 @@ interfaces.implement { type = "mp", name = t.name, } + setfield(rule,"attr",currentattr()) context(rule) end } diff --git a/tex/context/base/mkiv/lpdf-ren.lua b/tex/context/base/mkiv/lpdf-ren.lua index 81b9e9f20..47075ee08 100644 --- a/tex/context/base/mkiv/lpdf-ren.lua +++ b/tex/context/base/mkiv/lpdf-ren.lua @@ -12,6 +12,7 @@ local tostring, tonumber, next = tostring, tonumber, next local format, rep = string.format, string.rep local concat = table.concat local settings_to_array = utilities.parsers.settings_to_array +local getrandom = utilities.randomizer.get local backends, lpdf, nodes, node = backends, lpdf, nodes, node @@ -363,7 +364,7 @@ function codeinjections.setpagetransition(specification) last = 0 return elseif n == v_random then - n = math.random(1,#pagetransitions) + n = getrandom("transition",1,#pagetransitions) else n = tonumber(n) end diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua index 64322e4d0..58b933c44 100644 --- a/tex/context/base/mkiv/lxml-tab.lua +++ b/tex/context/base/mkiv/lxml-tab.lua @@ -502,15 +502,30 @@ do [ [[~]] ] = "&U+7E;", } + local privates_x = { -- for xml + [ [["]] ] = "&U+22;", + [ [[#]] ] = "&U+23;", + [ [[$]] ] = "&U+24;", + [ [[%]] ] = "&U+25;", + [ [[']] ] = "&U+27;", + [ [[\]] ] = "&U+5C;", + [ [[{]] ] = "&U+7B;", + [ [[|]] ] = "&U+7C;", + [ [[}]] ] = "&U+7D;", + [ [[~]] ] = "&U+7E;", + } + local privates_n = { -- keeps track of defined ones } local escaped = utf.remapper(privates_u,"dynamic") local unprivatized = utf.remapper(privates_p,"dynamic") local unspecialized = utf.remapper(privates_s,"dynamic") + local despecialized = utf.remapper(privates_x,"dynamic") xml.unprivatized = unprivatized xml.unspecialized = unspecialized + xml.despecialized = despecialized xml.escaped = escaped local function unescaped(s) diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index c9675d435..fc86b9460 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -45,6 +45,7 @@ local xmltext = xml.text local xmltostring = xml.tostring local xmlapplylpath = xml.applylpath local xmlunspecialized = xml.unspecialized +local xmldespecialized = xml.despecialized -- nicer in expanded xml local xmlprivatetoken = xml.privatetoken local xmlstripelement = xml.stripelement local xmlinclusion = xml.inclusion @@ -53,6 +54,7 @@ local xmlbadinclusions = xml.badinclusions local xmlcontent = xml.content local xmllastmatch = xml.lastmatch + directives.enable("xml.path.keeplastmatch") local variables = interfaces and interfaces.variables or { } @@ -308,14 +310,6 @@ function lxml.stopraw() forceraw = false end -function lxml.startraw() - forceraw = true -end - -function lxml.stopraw() - forceraw = false -end - function lxml.rawroot() return rawroot end @@ -911,7 +905,8 @@ local function sprint(root) -- check rawroot usage if forceraw then rawroot = root -- contextsprint(ctxcatcodes,xmltostring(root)) -- goes wrong with % etc - root = xmlunspecialized(xmltostring(root)) + -- root = xmlunspecialized(xmltostring(root)) -- we loose < > & + root = xmldespecialized(xmltostring(root)) lpegmatch(xmltextcapture,root) -- goes to toc else xmlserialize(root,xmltexhandler) diff --git a/tex/context/base/mkiv/meta-ini.mkiv b/tex/context/base/mkiv/meta-ini.mkiv index 22856ec40..9264185fa 100644 --- a/tex/context/base/mkiv/meta-ini.mkiv +++ b/tex/context/base/mkiv/meta-ini.mkiv @@ -248,8 +248,8 @@ \def\meta_flush_current_initializations {\ifconditional\c_meta_include_initializations \the\t_meta_initializations - \fi - \theMPrandomseed;} + \fi} + % \theMPrandomseed;} \def\meta_flush_current_inclusions {\the\t_meta_inclusions} @@ -262,7 +262,7 @@ \meta_enable_include \the\everyMPgraphic \meta_preset_definitions - \setMPrandomseed % this has to change + %\setMPrandomseed % this has to change \edef\p_initializations{\MPinstanceparameter\s!initializations}% \ifx\p_initializations\v!yes \settrue \c_meta_include_initializations @@ -334,16 +334,16 @@ \meta_process_graphic{input "#1" ;}% \endgroup} -\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default - -\let\theMPrandomseed\empty - -\def\setMPrandomseed - {\ifsetMPrandomseed - \def\theMPrandomseed{randomseed:=\mprandomnumber;}% - \else - \let\theMPrandomseed\empty - \fi} +% \newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default +% +% \let\theMPrandomseed\empty +% +% \def\setMPrandomseed +% {\ifsetMPrandomseed +% \def\theMPrandomseed{randomseed:=\mprandomnumber;}% +% \else +% \let\theMPrandomseed\empty +% \fi} %D Calling up previously defined graphics. diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index 2b5648e16..8f24124b9 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -406,7 +406,7 @@ end -- end function mp.tt_dimensions(n) - local box = textexts[n] + local box = textexts and textexts[n] if box then -- could be made faster with nuts but not critical mptriplet(box.width/factor,box.height/factor,box.depth/factor) @@ -509,3 +509,33 @@ end -- function mp.prefix(str) -- mpprint(hash[str]) -- end + +local getdimen = tex.getdimen +local getcount = tex.getcount +local gettoks = tex.gettoks +local setdimen = tex.setdimen +local setcount = tex.setcount +local settoks = tex.settoks + +local mpprint = mp.print +local mpquoted = mp.quoted + +local factor = number.dimenfactors.bp + +-- more helpers + +function mp.getdimen(k) mpprint (getdimen(k)*factor) end +function mp.getcount(k) mpprint (getcount(k)) end +function mp.gettoks (k) mpquoted(gettoks (k)) end +function mp.setdimen(k,v) setdimen(k,v/factor) end +function mp.setcount(k,v) setcount(k,v) end +function mp.settoks (k,v) settoks (k,v) end + +-- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix + +mp._get_dimen_ = mp.getdimen +mp._get_count_ = mp.getcount +mp._get_toks_ = mp.gettoks +mp._set_dimen_ = mp.setdimen +mp._set_count_ = mp.setcount +mp._set_toks_ = mp.settoks diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index efafb99fd..945830853 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -730,7 +730,9 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib report_metapost("running job %s, asked figure %a",nofruns,askedfig) end processmetapost(mpx, { - preamble, + definitions, + extensions, + inclusions, wrappit and do_begin_fig or "", do_first_run, no_trial_run, diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua index 0ef80892a..bc8cf4dbd 100644 --- a/tex/context/base/mkiv/mlib-run.lua +++ b/tex/context/base/mkiv/mlib-run.lua @@ -187,6 +187,7 @@ local f_preamble = formatters [ [[ boolean mplib ; mplib := true ; let dump = endinput ; input "%s" ; + randomseed:=%s; ]] ] local methods = { @@ -219,8 +220,18 @@ function metapost.maketext(s,mode) end end +local seed = nil + function metapost.load(name,method) starttiming(mplib) + if not seed then + seed = job.getrandomseed() + if seed <= 1 then + seed = seed % 1000 + elseif seed > 4095 then + seed = seed % 4096 + end + end method = method and methods[method] or "scaled" local mpx = new_instance { ini_version = true, @@ -235,7 +246,7 @@ function metapost.load(name,method) if not mpx then result = { status = 99, error = "out of memory"} else - result = mpx:execute(f_preamble(file.addsuffix(name,"mp"))) -- addsuffix is redundant + result = mpx:execute(f_preamble(file.addsuffix(name,"mp"),seed)) -- addsuffix is redundant end stoptiming(mplib) metapost.reporterror(result) diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index e41f7f342..69484a90f 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -6356,7 +6356,7 @@ return { ["en"]="usedirectory", ["fr"]="utilisechemin", ["it"]="usacartella", - ["nl"]="gebruikgebied", + ["nl"]="gebruikpad", ["pe"]="استفادهمسیر", ["ro"]="folosestedirector", }, @@ -8076,6 +8076,10 @@ return { ["pe"]="قالبها", ["ro"]="frames", }, + ["freeregion"]={ + ["en"]="freeregion", + ["nl"]="vrijgebied", + }, ["from"]={ ["cs"]="z", ["de"]="von", diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index 3ecb78941..ea1c169ea 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -205,12 +205,12 @@ return { -- "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", -- - "scratchcounter", "globalscratchcounter", - "scratchdimen", "globalscratchdimen", - "scratchskip", "globalscratchskip", - "scratchmuskip", "globalscratchmuskip", - "scratchtoks", "globalscratchtoks", - "scratchbox", "globalscratchbox", + "scratchcounter", "globalscratchcounter", "privatescratchcounter", + "scratchdimen", "globalscratchdimen", "privatescratchdimen", + "scratchskip", "globalscratchskip", "privatescratchskip", + "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", + "scratchtoks", "globalscratchtoks", "privatescratchtoks", + "scratchbox", "globalscratchbox", "privatescratchbox", -- "normalbaselineskip", "normallineskip", "normallineskiplimit", -- diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index eb4b3a706..369b06ab2 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -35,6 +35,7 @@ \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) \registerctxluafile{node-ppt}{1.001} +\registerctxluafile{node-scn}{1.001} \newcount\c_node_tracers_show_box % box number diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua index 3a60ca502..76be2a5c9 100644 --- a/tex/context/base/mkiv/node-rul.lua +++ b/tex/context/base/mkiv/node-rul.lua @@ -17,8 +17,6 @@ if not modules then modules = { } end modules ['node-rul'] = { -- fill s withcolor .5white ; -- draw boundingbox s withcolor yellow; -local floor = math.floor - local attributes = attributes local nodes = nodes local tasks = nodes.tasks @@ -41,7 +39,6 @@ local setattr = nuts.setattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist -local setlist = nuts.setlist local flushlist = nuts.flush_list local effective_glue = nuts.effective_glue @@ -71,7 +68,6 @@ local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty local kern_code = nodecodes.kern local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist local indent_code = listcodes.indent local line_code = listcodes.line @@ -79,12 +75,6 @@ local line_code = listcodes.line local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip local parfillskip_code = gluecodes.parfillskip -local userskip_code = gluecodes.userskip -local spaceskip_code = gluecodes.spaceskip -local xspaceskip_code = gluecodes.xspaceskip -local leader_code = gluecodes.leaders - -local kerning_code = kerncodes.kern local nodepool = nuts.pool @@ -126,181 +116,11 @@ local dimenfactor = fonts.helpers.dimenfactor local splitdimen = number.splitdimen local setmetatableindex = table.setmetatableindex -local function striprange(first,last) -- todo: dir - if first and last then -- just to be sure - if first == last then - return first, last - end - while first and first ~= last do - local id = getid(first) - if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code - break - else - first = getnext(first) - end - end - if not first then - return nil, nil - elseif first == last then - return first, last - end - while last and last ~= first do - local id = getid(last) - if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code - break - else - local prev = getprev(last) -- luatex < 0.70 has italic correction kern not prev'd - if prev then - last = prev - else - break - end - end - end - if not last then - return nil, nil - end - end - return first, last -end - -nodes.striprange = striprange - --- todo: order and maybe other dimensions - --- we can use this one elsewhere too --- --- todo: functions: word, sentence -- --- glyph rule unset whatsit glue margin_kern kern math disc - --- we assume {glyphruns} and no funny extra kerning, ok, maybe we need --- a dummy character as start and end; anyway we only collect glyphs --- --- this one needs to take layers into account (i.e. we need a list of --- critical attributes) - --- omkeren class en level -> scheelt functie call in analyze - --- todo: switching inside math - --- handlers - -local function processwords(attribute,data,flush,head,parent,skip) -- we have hlistdir and local dir - local n = head - if n then - local f, l, a, d, i, class - local continue, leaders, done, strip, level = false, false, false, true, -1 - while n do - local id = getid(n) - if id == glyph_code or id == rule_code or (id == hlist_code and getattr(n,a_runningtext) == 1) then - local aa = getattr(n,attribute) - if aa and aa ~= skip then - if aa == a then - if not f then -- ? - f = n - end - l = n - else - -- possible extensions: when in same class then keep spanning - local newlevel, newclass = floor(aa/1000), aa%1000 - -- strip = not continue or level == 1 -- 0 - if f then - if class == newclass then -- and newlevel > level then - head, done = flush(head,f,l,d,level,parent,false), true - else - head, done = flush(head,f,l,d,level,parent,strip), true - end - end - f, l, a = n, n, aa - level, class = newlevel, newclass - d = data[class] - local c = d.continue - leaders = c == v_all - continue = leaders or c == v_yes - end - else - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - end - f, l, a = nil, nil, nil - end - if id == hlist_code then - local list = getlist(n) - if list then - setlist(n,(processwords(attribute,data,flush,list,n,aa))) -- watch () - end - end - elseif id == disc_code or id == boundary_code then - if f then - l = n - end - elseif id == kern_code and getsubtype(n) == kerning_code then - if f then - l = n - end - elseif id == math_code then - -- otherwise not consistent: a $b$ c vs a $b+c$ d etc - -- we need a special (optional) go over math variant - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - f, l, a = nil, nil, nil - end - elseif id == hlist_code or id == vlist_code then - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - f, l, a = nil, nil, nil - end - local list = getlist(n) - if list then - setlist(n,(processwords(attribute,data,flush,list,n,skip))) -- watch () - end - elseif id == dir_code then -- only changes in dir, we assume proper boundaries - if f then - l = n - end - elseif f then - if continue then - if id == penalty_code then - l = n - -- elseif id == kern_code then - -- l = n - elseif id == glue_code then - -- catch \underbar{a} \underbar{a} (subtype test is needed) - local subtype = getsubtype(n) - if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) then - l = n - else - head, done = flush(head,f,l,d,level,parent,strip), true - f, l, a = nil, nil, nil - end - end - else - head, done = flush(head,f,l,d,level,parent,strip), true - f, l, a = nil, nil, nil - end - end - n = getnext(n) - end - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - end - return head, true -- todo: done - else - return head, false - end -end - --- nodes.processwords = processwords -nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir - head = tonut(head) - if parent then - parent = tonut(parent) - end - local head, done = processwords(attribute,data,flush,head,parent) - return tonode(head), done -end +local striprange = nodes.striprange +local processwords = nodes.processwords +local processranges = nodes.processranges -- diff --git a/tex/context/base/mkiv/node-scn.lua b/tex/context/base/mkiv/node-scn.lua new file mode 100644 index 000000000..2409750c2 --- /dev/null +++ b/tex/context/base/mkiv/node-scn.lua @@ -0,0 +1,311 @@ +if not modules then modules = { } end modules ['node-scn'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local floor = math.floor + +local attributes = attributes +local nodes = nodes + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local setlist = nuts.setlist + +local end_of_math = nuts.end_of_math + +local nodecodes = nodes.nodecodes +local rulecodes = nodes.rulecodes +local gluecodes = nodes.gluecodes +local listcodes = nodes.listcodes +local kerncodes = nodes.kerncodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local rule_code = nodecodes.rule +local boundary_code = nodecodes.boundary +local dir_code = nodecodes.dir +local math_code = nodecodes.math +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist + +local userskip_code = gluecodes.userskip +local spaceskip_code = gluecodes.spaceskip +local xspaceskip_code = gluecodes.xspaceskip +local leader_code = gluecodes.leaders + +local kerning_code = kerncodes.kern + +local variables = interfaces.variables + +local privateattributes = attributes.private + +local a_runningtext = privateattributes('runningtext') +local a_fontkern = privateattributes('fontkern') + +local v_yes = variables.yes +local v_all = variables.all + +local function striprange(first,last) -- todo: dir + if first and last then -- just to be sure + if first == last then + return first, last + end + while first and first ~= last do + local id = getid(first) + if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code + break + else + first = getnext(first) + end + end + if not first then + return nil, nil + elseif first == last then + return first, last + end + while last and last ~= first do + local id = getid(last) + if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code + break + else + local prev = getprev(last) -- luatex < 0.70 has italic correction kern not prev'd + if prev then + last = prev + else + break + end + end + end + if not last then + return nil, nil + end + end + return first, last +end + +nodes.striprange = striprange + +-- todo: order and maybe other dimensions + +-- we can use this one elsewhere too +-- +-- todo: functions: word, sentence +-- +-- glyph rule unset whatsit glue margin_kern kern math disc + +-- we assume {glyphruns} and no funny extra kerning, ok, maybe we need +-- a dummy character as start and end; anyway we only collect glyphs +-- +-- this one needs to take layers into account (i.e. we need a list of +-- critical attributes) + +-- omkeren class en level -> scheelt functie call in analyze + +-- todo: switching inside math + +-- handlers + +local function processwords(attribute,data,flush,head,parent,skip) -- we have hlistdir and local dir + local n = head + if n then + local f, l, a, d, i, class + local continue, leaders, done, strip, level = false, false, false, true, -1 + while n do + local id = getid(n) + if id == glyph_code or id == rule_code or (id == hlist_code and getattr(n,a_runningtext) == 1) then + local aa = getattr(n,attribute) + if aa and aa ~= skip then + if aa == a then + if not f then -- ? + f = n + end + l = n + else + -- possible extensions: when in same class then keep spanning + local newlevel, newclass = floor(aa/1000), aa%1000 -- will be configurable + -- strip = not continue or level == 1 -- 0 + if f then + if class == newclass then -- and newlevel > level then + head, done = flush(head,f,l,d,level,parent,false), true + else + head, done = flush(head,f,l,d,level,parent,strip), true + end + end + f, l, a = n, n, aa + level, class = newlevel, newclass + d = data[class] + if d then + local c = d.continue + leaders = c == v_all + continue = leaders or c == v_yes + else + continue = true + end + end + else + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + f, l, a = nil, nil, nil + end + if id == hlist_code then + local list = getlist(n) + if list then + setlist(n,(processwords(attribute,data,flush,list,n,aa))) -- watch () + end + end + elseif id == disc_code or id == boundary_code then + if f then + l = n + end + elseif id == kern_code and (getsubtype(n) == kerning_code or getattr(n,a_fontkern)) then + if f then + l = n + end + elseif id == math_code then + -- otherwise not consistent: a $b$ c vs a $b+c$ d etc + -- we need a special (optional) go over math variant + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + elseif id == hlist_code or id == vlist_code then + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + local list = getlist(n) + if list then + setlist(n,(processwords(attribute,data,flush,list,n,skip))) -- watch () + end + elseif id == dir_code then -- only changes in dir, we assume proper boundaries + if f then + l = n + end + elseif f then + if continue then + if id == penalty_code then + l = n + -- elseif id == kern_code then + -- l = n + elseif id == glue_code then + -- catch \underbar{a} \underbar{a} (subtype test is needed) + local subtype = getsubtype(n) + if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) then + l = n + else + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + end + else + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + end + n = getnext(n) + end + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + return head, true -- todo: done + else + return head, false + end +end + +nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir + head = tonut(head) + if parent then + parent = tonut(parent) + end + local head, done = processwords(attribute,data,flush,head,parent) + return tonode(head), done +end + +-- + +local function processranges(attribute,flush,head,parent) + local n = head + if n then + local f, l, a + local done = false + while n do + local id = getid(n) + if id == glyph_code or id == rule_code then + local aa = getattr(n,attribute) + if aa and aa ~= skip then + if aa == a then + if not f then + f = n + end + l = n + else + if f then + head, done = flush(head,f,l,a,parent), true + end + f, l, a = n, n, aa + end + else + if f then + head, done = flush(head,f,l,a,parent), true + end + f, l, a = nil, nil, nil + end + elseif id == disc_code or id == boundary_code then + if f then + l = n + else + -- weird + end + elseif id == kern_code and (getsubtype(n) == kerning_code or getattr(n,a_fontkern)) then + if f then + l = n + end + -- elseif id == penalty_code then + elseif id == glue_code then + -- todo: leaders + elseif id == hlist_code or id == vlist_code then + if f then + l = n + end + local list = getlist(n) + if list then + setlist(n,(processranges(attribute,flush,list,n,aa))) + end + end + n = getnext(n) + end + if f then + head, done = flush(head,f,l,a,parent), true + end + return head, done + else + return head, false + end +end + +nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir + head = tonut(head) + if parent then + parent = tonut(parent) + end + local head, done = processranges(attribute,flush,head,parent) + return tonode(head), done +end + diff --git a/tex/context/base/mkiv/pack-box.mkiv b/tex/context/base/mkiv/pack-box.mkiv index ab9fc465e..8279fcd71 100644 --- a/tex/context/base/mkiv/pack-box.mkiv +++ b/tex/context/base/mkiv/pack-box.mkiv @@ -73,15 +73,11 @@ {\begingroup \edef\currentanchor{#1}% \ifcsname\??anchor\currentanchor\endcsname -% \expandafter\pack_anchor_predefined \expandafter\lastnamedcs \else \expandafter\pack_anchor_notdefined \fi} -% \def\pack_anchor_predefined -% {\csname\??anchor\currentanchor\endcsname} - \def\pack_anchor_notdefined {\dodoubleempty\pack_anchor_notdefined_indeed} @@ -105,67 +101,23 @@ % \definelayer[anchor] -% % old and no longer valid -% -% \def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy -% {\checkpositionoverlays -% % for the moment we ignore the depth -% \setbox\b_pack_anchors\box\nextbox -% \d_pack_anchors_width \wd\b_pack_anchors -% \d_pack_anchors_height\ht\b_pack_anchors -% \d_pack_anchors_depth \dp\b_pack_anchors -% \setbox\scratchbox\emptyhbox -% \wd\scratchbox\d_pack_anchors_width -% \ht\scratchbox\d_pack_anchors_height -% \dp\scratchbox\d_pack_anchors_depth -% \setlayer -% [anchor]% -% [\c!width=\d_pack_anchors_width,% -% \c!height=\d_pack_anchors_height,% -% \c!offset=\zeropoint,% -% #2,#3]% -% {\setlayer[#1]{\box\b_pack_anchors}}% % #1 uses overlaywidth/height -% \framed % could be a predefined framed -% [#2,% -% \c!background=anchor,% -% \c!offset=\v!overlay,% -% \c!frame=\v!off,% -% #3]% -% {\box\scratchbox}% -% \endgroup} - -% % new and ok but not synced -% -% \def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy -% {\checkpositionoverlays -% \setbox\b_pack_anchors\box\nextbox -% \framed % could be a predefined framed -% %[#2,\c!offset=\v!overlay,\c!frame=\v!off,#3] -% [\c!offset=\v!overlay,\c!frame=\v!off,#3] -% {\novrule % hm, not needed as we frame the size (but kind of default) -% \s!width \wd\b_pack_anchors -% \s!height\ht\b_pack_anchors -% \s!depth \dp\b_pack_anchors}% -% \setlayer[#1][#2,\c!position=\v!no]{\box\b_pack_anchors}% no position -% \endgroup} - \newcount\c_pack_anchors_n \newtoks \t_pack_anchors_flush \unexpanded\def\pack_anchors_register#1#2% {\global\advance\c_pack_anchors_n\plusone \pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]% - \putboxincache{\v!anchor}{\number\c_pack_anchors_n}\b_pack_anchors + \putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors \doglobal\appendetoks \pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}% \to \t_pack_anchors_flush \glet\pack_anchors_flush_all\pack_anchors_flush_all_indeed} \unexpanded\def\pack_anchors_flush#1#2#3% - {\doifelseboxincache{\v!anchor}{#1} + {\doifelseboxincache\v!anchor{#1} {\doifelsereferencefound{\v!layer:\v!anchor:#1} {\ifnum\currentreferencerealpage=\realpageno\relax - \setlayer[#2][#3,\c!position=\v!no]{\directboxfromcache{\v!anchor}{#1}}% + \setlayer[#2][#3,\c!position=\v!no]{\directboxfromcache\v!anchor{#1}}% \else \donetrue \fi @@ -189,13 +141,8 @@ \def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy {\checkpositionoverlays \setbox\b_pack_anchors\box\nextbox - \framed % could be a predefined framed - [%#2, - %\c!background=\v!color, - %\c!backgroundcolor=darkblue, - \c!offset=\v!overlay, - \c!frame=\v!off, - #3] + \framed % could be a predefined framed but used seldom + [\c!offset=\v!overlay,\c!frame=\v!off,#3] {\pack_anchors_register{#1}{#2}% \novrule % hm, not needed as we frame the size (but kind of default) \s!width \wd\b_pack_anchors @@ -245,7 +192,6 @@ \unexpanded\def\resetcollector[#1]% {\ifcsname\??collectorbox#1\endcsname - %\global\setbox\csname\??collectorbox#1\endcsname\emptybox \global\setbox\lastnamedcs\emptybox \fi} @@ -257,7 +203,6 @@ {\edef\currentcollector{#1}% \ifcsname\??collectorbox\currentcollector\endcsname \settrue\c_pack_boxes_collector_valid_box - %\expandafter\let\expandafter\b_pack_boxes_collector\csname\??collectorbox\currentcollector\endcsname \expandafter\let\expandafter\b_pack_boxes_collector\lastnamedcs \else \setfalse\c_pack_boxes_collector_valid_box diff --git a/tex/context/base/mkiv/pack-com.mkiv b/tex/context/base/mkiv/pack-com.mkiv index 74230a099..8abee1daf 100644 --- a/tex/context/base/mkiv/pack-com.mkiv +++ b/tex/context/base/mkiv/pack-com.mkiv @@ -487,7 +487,8 @@ \let\stopfloatcombination\relax \def\pack_combinations_start_float[#1][#2]% - {\dontleavehmode\vbox\bgroup + {\ifinsidefloat\else\dontleavehmode\fi % tricky, floatcombinations fail to align well otherwise + \vbox\bgroup %\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature \postcenterfloatmethod\zerocount \forcelocalfloats @@ -499,7 +500,7 @@ {\appendetoks{\getlocalfloat{\recurselevel}}{}\to\scratchtoks}% brrr \expanded{\startcombination[#1]\the\scratchtoks}\stopcombination \resetlocalfloats - \egroup} + \egroup} %D \macros %D {definepairedbox, setuppairedbox, placepairedbox} diff --git a/tex/context/base/mkiv/pack-rul.mkiv b/tex/context/base/mkiv/pack-rul.mkiv index ce97a6bd9..ff39200b8 100644 --- a/tex/context/base/mkiv/pack-rul.mkiv +++ b/tex/context/base/mkiv/pack-rul.mkiv @@ -607,7 +607,11 @@ {\vpack to \framedbackgroundheight{\vss\box\b_framed_normal\vss}} % vertical shift \backgroundheight \def\pack_framed_add_region % experiment - {\anch_mark_region_box\b_framed_normal} + {\ifx\p_framed_region\v!yes + \anch_mark_region_box\b_framed_normal + \else + \anch_mark_tagged_box\b_framed_normal\p_framed_region + \fi} \def\pack_framed_add_background {\setbox\b_framed_normal\hbox % was vbox % see also *1* @@ -1031,7 +1035,7 @@ \unexpanded\def\pack_framed_process_box_indeed#1#2% component box (assumes parameters set and grouped usage) {\setbox\b_framed_normal\box#2% could actually be \let\b_framed_normal#2 \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\v!yes % maybe later named + \ifx\p_framed_region\empty\else \pack_framed_add_region \fi \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds @@ -1598,9 +1602,9 @@ \pack_framed_stop_orientation % moved here at 2014-05-25 \iftrialtypesetting \else \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\v!yes % maybe later named + \ifx\p_framed_region\empty\else \pack_framed_add_region - \fi + \fi \fi \d_framed_applied_offset \ifconditional\c_framed_is_overlaid diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv index 4559ec33f..ed4512561 100644 --- a/tex/context/base/mkiv/page-cst.mkiv +++ b/tex/context/base/mkiv/page-cst.mkiv @@ -293,15 +293,15 @@ % todo line numbers and marks \unexpanded\def\page_grid_command_flush_page_column#1% - {\scratchcounter#1\relax - \clf_flushcolumnsetcolumn{\currentpagegrid}\scratchcounter + {\privatescratchcounter#1\relax + \clf_flushcolumnsetcolumn{\currentpagegrid}\privatescratchcounter \anch_mark_column_box\b_page_grid_column - \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\scratchcounter\b_page_grid_column - \ifnum\scratchcounter>\c_page_grid_n_of_left - \advance\scratchcounter-\c_page_grid_n_of_left - \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_right\plustwo + \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\privatescratchcounter\b_page_grid_column + \ifnum\privatescratchcounter>\c_page_grid_n_of_left + \advance\privatescratchcounter-\c_page_grid_n_of_left + \page_lines_add_numbers_to_box\b_page_grid_column\privatescratchcounter\c_page_grid_n_of_right\plustwo \else - \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_left\plustwo + \page_lines_add_numbers_to_box\b_page_grid_column\privatescratchcounter\c_page_grid_n_of_left\plustwo \fi \begingroup \edef\currentpagegrid{\currentpagegrid:#1}% diff --git a/tex/context/base/mkiv/page-lay.mkiv b/tex/context/base/mkiv/page-lay.mkiv index eff30046f..f2e39c660 100644 --- a/tex/context/base/mkiv/page-lay.mkiv +++ b/tex/context/base/mkiv/page-lay.mkiv @@ -92,9 +92,12 @@ \newdimen\topdistance \newdimen\headerdistance +\newdimen\textdistance \newdimen\footerdistance \newdimen\bottomdistance +\newdimen\textovershoot % available in pagebuilder + %D We need to calculate the extra distances: \newdimen\naturalmarginwidth @@ -107,6 +110,7 @@ \newdimen\naturalrightmargindistance \newdimen\naturaltopdistance \newdimen\naturalheaderdistance +\newdimen\naturaltextdistance \newdimen\naturalfooterdistance \newdimen\naturalbottomdistance @@ -178,6 +182,7 @@ \global\naturalrightmargindistance\layoutparameter\c!rightmargindistance \global\naturaltopdistance \layoutparameter\c!topdistance \global\naturalheaderdistance \layoutparameter\c!headerdistance + \global\naturaltextdistance \layoutparameter\c!textdistance \global\naturalfooterdistance \layoutparameter\c!footerdistance \global\naturalbottomdistance \layoutparameter\c!bottomdistance % @@ -192,6 +197,7 @@ \global\rightmargindistance \layoutdistance\rightmarginwidth\naturalrightmargindistance \global\topdistance \layoutdistance\topheight \naturaltopdistance \global\headerdistance \layoutdistance\headerheight \naturalheaderdistance + \global\textdistance \naturaltextdistance \global\footerdistance \layoutdistance\footerheight \naturalfooterdistance \global\bottomdistance \layoutdistance\bottomheight \naturalbottomdistance } diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv index 501f24e88..f32a443be 100644 --- a/tex/context/base/mkiv/page-sid.mkiv +++ b/tex/context/base/mkiv/page-sid.mkiv @@ -55,8 +55,8 @@ \newdimen \d_page_sides_shift \newdimen \d_page_sides_extrashift -\newdimen \d_page_sided_leftshift -\newdimen \d_page_sided_rightshift +\newdimen \d_page_sides_leftshift +\newdimen \d_page_sides_rightshift \newdimen \d_page_sides_leftskip \newdimen \d_page_sides_rightskip \newdimen \d_page_sides_maximum @@ -77,7 +77,7 @@ \def\page_sides_process_float_cutspace {\global\c_page_sides_float_type\pluseight\page_sides_handle_float} \def\page_sides_process_float_margin {\global\c_page_sides_float_type\pluseight\page_sides_handle_float} -\let\logsidefloat \relax +\let\logsidefloat\relax \newif\iftracesidefloats % public (might change) @@ -287,13 +287,13 @@ % alternative method (unsnapped) % % \def\page_sides_flush_floats_indeed -% {\scratchdimen\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax +% {\privatescratchdimen\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax % \ifdim\parskip>\zeropoint % why this test ? -% \ifdim\scratchdimen>\parskip -% \blank[\v!nowhite,\the\scratchdimen] % better in stages +% \ifdim\privatescratchdimen>\parskip +% \blank[\v!nowhite,\the\privatescratchdimen] % better in stages % \fi % \else -% \blank[\the\scratchdimen] +% \blank[\the\privatescratchdimen] % \fi} \def\page_sides_check_floats_after_par @@ -363,6 +363,7 @@ \def\page_sides_output_routine_yes % we need to rework this ... add pagediscards and such {\unvbox\normalpagebox % bah, and the discards? +% \pagediscards \setbox\b_page_sides_bottom\lastbox \ifdim\wd\b_page_sides_bottom>\d_page_sides_hsize \penalty-201 % hm, i really need to write this from scatch @@ -415,7 +416,7 @@ % {\ifcase\c_page_sides_float_type % \vbox{#1}% % \or % 1 -% \kern\d_page_sided_leftshift +% \kern\d_page_sides_leftshift % \kern\d_page_sides_shift % \vbox{#1}% % \kern-\d_page_sides_extrashift @@ -428,7 +429,7 @@ % \vbox{#1}% % \kern-\d_page_sides_extrashift % \or % 4 -% \kern\d_page_sided_leftshift +% \kern\d_page_sides_leftshift % \kern\d_page_sides_shift % \vbox{#1\removedepth}% % \kern-\d_page_sides_extrashift @@ -436,7 +437,7 @@ % \kern-\d_page_sides_extrashift % \vbox{#1}% % \kern\d_page_sides_shift -% \kern\d_page_sided_rightshift +% \kern\d_page_sides_rightshift % \or % 6 % \kern-\d_page_sides_extrashift % \vbox{#1}% @@ -449,7 +450,7 @@ % \kern-\d_page_sides_extrashift % \vbox{#1}% % \kern\d_page_sides_shift -% \kern\d_page_sided_rightshift +% \kern\d_page_sides_rightshift % \fi} % % The compact way: @@ -457,9 +458,9 @@ \def\page_sides_relocate_float#1% {\global\setbox\floatbox\hpack {\ifnum\c_page_sides_float_type=\plusfour - \kern\d_page_sided_leftshift + \kern\d_page_sides_leftshift \else\ifnum\c_page_sides_float_type=\plusone - \kern\d_page_sided_leftshift + \kern\d_page_sides_leftshift \fi\fi \ifnum\c_page_sides_float_type>\plusfour \kern-\d_page_sides_extrashift @@ -473,27 +474,27 @@ \kern-\d_page_sides_extrashift \fi \ifnum\c_page_sides_float_type=\pluseight - \kern\d_page_sided_rightshift + \kern\d_page_sides_rightshift \else\ifnum\c_page_sides_float_type=\plusfive - \kern\d_page_sided_rightshift + \kern\d_page_sides_rightshift \fi\fi}} \def\page_sides_apply_vertical_shift {\ifnum\c_page_sides_align=\plusfour \getnoflines{\ht\floatbox}% - \scratchdimen\dimexpr\noflines\lineheight-\strutdepth\relax + \privatescratchdimen\dimexpr\noflines\lineheight-\strutdepth\relax \getrawnoflines\d_page_sides_topskip - \advance\scratchdimen\noflines\lineheight + \advance\privatescratchdimen\noflines\lineheight % todo: maybe rounding problem here % \global\setbox\floatbox\hbox{\lower\lineheight\box\floatbox}% \global\setbox\floatbox\hpack{\lower\strutdepth\box\floatbox}% - \ht\floatbox\scratchdimen + \ht\floatbox\privatescratchdimen \dp\floatbox\zeropoint \fi \ifcase\c_page_sides_align \else \global\d_page_sides_topskip\zeropoint \fi - \scratchdimen + \privatescratchdimen \ifnum\c_page_sides_float_type<\plusfour \d_page_sides_topskip \else\ifnum\c_page_sides_float_type>\plusfive @@ -504,26 +505,26 @@ % the top of the box is at the previous baseline \ifcase\c_page_sides_align % 0 normal - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 1 height - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 2 line \or % 3 depth - \advance\scratchdimen\lineheight % or \openlineheight - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\lineheight % or \openlineheight + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 4 grid - \scratchdimen\zeropoint + \privatescratchdimen\zeropoint \or - \advance\scratchdimen\strutheight % or \openstrutheight + \advance\privatescratchdimen\strutheight % or \openstrutheight \fi % new \global\c_page_sides_lines_done\zerocount \ifnum\c_page_sides_n_of_lines>\zerocount - \advance\scratchdimen\c_page_sides_n_of_lines\lineheight + \advance\privatescratchdimen\c_page_sides_n_of_lines\lineheight \fi \global\setbox\floatbox\hpack % why extra box {\vbox - {\vskip\scratchdimen + {\vskip\privatescratchdimen \nointerlineskip \box\floatbox \ifnum\c_page_sides_align=\plusfive \vskip-\lineheight \fi}}% @@ -568,6 +569,8 @@ \d_page_sides_height\noflines\lineheight \page_sides_push_float_inline\page_sides_place_snap_to_grid} +\let\strc_floats_mark_par_as_free\relax + \def\page_sides_push_float_inline#1% {\begingroup \reseteverypar % needed ! @@ -576,6 +579,7 @@ \page_sides_insert_info \relax \lefttoright % \textdir TLT\relax % or \ifconditional\displaylefttoright below (more work) + \strc_floats_mark_par_as_free \ifcase\c_page_sides_float_type % invalid \or % backspace @@ -639,7 +643,7 @@ \global\setfalse\c_page_floats_room \else \ifdim\dimexpr\pagegoal-\d_page_sides_vsize\relax<\d_page_sides_bottomskip - \global\advance\d_page_sides_vsize \dimen0 + % just weird: \global\advance\d_page_sides_vsize \dimen0 \global\settrue\c_page_sides_short \page_otr_sides_push_penalties % why was this \global\holdinginserts\plusone @@ -660,30 +664,34 @@ % \vskip-\struttotal % \endgroup} -\installtextracker - {sidefloats.anchor} - {\let\page_sides_anchor\page_sides_anchor_yes} - {\let\page_sides_anchor\page_sides_anchor_nop} - -\def\page_sides_anchor_yes - {\darkred - \hskip-5\emwidth - \vrule\s!height.05\exheight\s!depth.05\exheight\s!width10\emwidth} - -\def\page_sides_anchor_nop - {\strut} - -\let\page_sides_anchor\page_sides_anchor_nop +% \installtextracker +% {sidefloats.anchor} +% {\let\page_sides_anchor\page_sides_anchor_yes} +% {\let\page_sides_anchor\page_sides_anchor_nop} +% +% \def\page_sides_anchor_yes +% {\darkred +% \hskip-5\emwidth +% \vrule\s!height.05\exheight\s!depth.05\exheight\s!width10\emwidth} +% +% \def\page_sides_anchor_nop +% {\strut} +% +% \let\page_sides_anchor\page_sides_anchor_nop +% +% \def\page_sides_prepare_space +% {\par +% \begingroup +% \reseteverypar +% \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% +% \vskip-\parskip +% \vskip-\struttotal +% \inhibitblank +% \endgroup} \def\page_sides_prepare_space - {\par - \begingroup - \reseteverypar - \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% - \vskip-\parskip - \vskip-\struttotal - \inhibitblank - \endgroup} + {\fakenextstrutline + \inhibitblank} \def\page_sides_handle_float#1% grid (4) is rather experimental {\page_sides_prepare_space @@ -714,8 +722,8 @@ \let\page_sides_check_floats\page_sides_check_floats_indeed \unexpanded\def\page_sides_check_floats_set - {\scratchdimen\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax - \c_page_sides_n_of_hang\scratchdimen + {\privatescratchdimen\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax + \c_page_sides_n_of_hang\privatescratchdimen \divide\c_page_sides_n_of_hang \baselineskip\relax \ifnum\c_page_sides_n_of_hang>\zerocount % new from here (needs test case, old code) @@ -724,31 +732,31 @@ \ifcase\c_page_sides_lines_done \global\c_page_sides_lines_done\c_page_sides_n_of_hang \else - \scratchcounter\c_page_sides_lines_done - \advance\scratchcounter-\c_page_sides_n_of_hang - \global\advance\c_page_sides_n_of_lines-\scratchcounter + \privatescratchcounter\c_page_sides_lines_done + \advance\privatescratchcounter-\c_page_sides_n_of_hang + \global\advance\c_page_sides_n_of_lines-\privatescratchcounter \fi \fi % hm, when do we get the parshape branch? needs testing \ifnum\c_page_sides_n_of_lines>\zerocount - \scratchtoks\emptytoks - \scratchcounter\c_page_sides_n_of_lines - \scratchdimen\dimexpr\hsize-\d_page_sides_width\relax + \privatescratchtoks\emptytoks + \privatescratchcounter\c_page_sides_n_of_lines + \privatescratchdimen\dimexpr\hsize-\d_page_sides_width\relax \dorecurse\c_page_sides_n_of_lines - {\appendtoks \zeropoint \hsize \to \scratchtoks}% + {\appendtoks \zeropoint \hsize \to \privatescratchtoks}% \ifnum\c_page_sides_n_of_hang>\c_page_sides_n_of_lines \advance\c_page_sides_n_of_hang -\c_page_sides_n_of_lines\relax - \advance\scratchcounter\c_page_sides_n_of_hang + \advance\privatescratchcounter\c_page_sides_n_of_hang \dorecurse\c_page_sides_n_of_hang % weird, shouldn't that be scratchcounter {\ifnum\c_page_sides_float_type>\plusfour - \appendtoks \zeropoint \scratchdimen \to \scratchtoks + \appendtoks \zeropoint \privatescratchdimen \to \privatescratchtoks \else - \appendtoks \d_page_sides_width\scratchdimen \to \scratchtoks + \appendtoks \d_page_sides_width\privatescratchdimen \to \privatescratchtoks \fi}% \fi \parshape - \numexpr\scratchcounter+\plusone\relax - \the\scratchtoks % \scratchcounter + \numexpr\privatescratchcounter+\plusone\relax + \the\privatescratchtoks % \privatescratchcounter \zeropoint \hsize % \plusone \relax \else @@ -786,12 +794,12 @@ \def\page_sides_inject_dummy_lines {\begingroup - \scratchcounter\pageshrink - \divide\scratchcounter \baselineskip - \advance\scratchcounter \plusone + \privatescratchcounter\pageshrink + \divide\privatescratchcounter \baselineskip + \advance\privatescratchcounter \plusone \parskip\zeropoint - \dorecurse\scratchcounter{\hpack to \hsize{}}% - \kern-\scratchcounter\baselineskip + \dorecurse\privatescratchcounter{\hpack to \hsize{}}% + \kern-\privatescratchcounter\baselineskip \penalty\zerocount \endgroup} diff --git a/tex/context/base/mkiv/page-txt.mkvi b/tex/context/base/mkiv/page-txt.mkvi index 3f0f95420..7d0883a3c 100644 --- a/tex/context/base/mkiv/page-txt.mkvi +++ b/tex/context/base/mkiv/page-txt.mkvi @@ -831,9 +831,9 @@ \the\toptextcontent \vskip\dimexpr\topheight+\topdistance\relax \the\headertextcontent - \vskip\dimexpr\headerheight+\headerdistance\relax + \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax \anch_positions_place_anchors - \vskip-\textheight + \vskip\dimexpr-\textdistance-\textheight\relax \the\texttextcontent \vskip\textheight \the\everyendoftextbody @@ -846,14 +846,19 @@ \smashbox\b_page_layouts_element \box\b_page_layouts_element} +\ifdefined\page_prepare_backgrounds\else + \let\page_prepare_backgrounds\gobbleoneargument +\fi + \def\page_insert_body#1#2% {\setbox\b_page_layouts_element\vpack {\offinterlineskip \calculatereducedvsizes \calculatehsizes \swapmargins - \vskip\dimexpr\headerheight+\headerdistance+\layoutparameter\c!textdistance\relax + \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax \dontleavehmode + \page_prepare_backgrounds{#2}% \hbox to \makeupwidth {\begingroup \swapmargins diff --git a/tex/context/base/mkiv/spac-grd.mkiv b/tex/context/base/mkiv/spac-grd.mkiv index 7b3ee6d6c..be3c947eb 100644 --- a/tex/context/base/mkiv/spac-grd.mkiv +++ b/tex/context/base/mkiv/spac-grd.mkiv @@ -300,4 +300,30 @@ \normalstartbaselinecorrection \fi} +% This is new (and experimental) and might replace some of the above. beware it doesn't always work +% out well, e.g. when used grouped and such (e.g. before display math doesn't work out well). + +\unexpanded\def\spac_fake_next_line_new + {\par + \begingroup + \reseteverypar + \dontleavehmode\hpack{\strut}\par + \clf_fakenextstrutline + \ifdim\pagetotal>\lineheight + \pagetotal\dimexpr\pagetotal-\lineheight\relax + \fi + \endgroup} + +\unexpanded\def\spac_fake_next_line_old + {\par + \begingroup + \reseteverypar + \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% just a tracer + \vskip-\parskip + \vskip-\struttotal + \endgroup} + +%let\fakenextstrutline\spac_fake_next_line_old +\let\fakenextstrutline\spac_fake_next_line_new + \protect \endinput diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index 166bd0aa2..29eabb64f 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -2077,3 +2077,16 @@ implement { arguments = { "string", "string" } } +local remove_node = nodes.remove +local find_node_tail = nodes.tail + +interfaces.implement { + name = "fakenextstrutline", + actions = function() + local head = texlists.page_head + if head then + local head = remove_node(head,find_node_tail(head),true) + texlists.page_head = head + end + end +} diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index 58486c177..5bc73abb8 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -527,6 +527,7 @@ \unexpanded\def\spac_lines_start_correction[#1]% {\edef\m_spac_lines_around{#1}% + % todo: play with \fakenextstrutline \spac_lines_action_around \d_spac_prevdepth\prevdepth \spac_lines_initialize_corrections @@ -556,7 +557,10 @@ \unexpanded\def\spac_lines_stop_correction_ongrid {\directcheckedvspacing\v!white % \blank[\v!white]% - \snaptogrid\hpack{\box\scratchbox}} + \spac_lines_action_around + \snaptogrid\hpack{\box\scratchbox}% + \directcheckedvspacing\v!white + \spac_lines_action_around} \unexpanded\def\spac_lines_stop_correction_normal {\directcheckedvspacing\v!nowhite % \blank[\v!nowhite]% @@ -1444,7 +1448,7 @@ \newdimen \bodyfontstrutheight \newdimen \bodyfontstrutdepth -\newskip \globalbodyfontlineheight +\newskip \globalbodyfontlineheight % why a skip \newdimen \globalbodyfontstrutheight \newdimen \globalbodyfontstrutdepth @@ -1649,6 +1653,28 @@ \spac_grids_check_yes \fi\fi\fi} +\unexpanded\gdef\page_layouts_calculate_overshoot + {\ifgridsnapping\ifcase\layoutlines + \getnoflines\textheight + \textovershoot\dimexpr\noflines\globalbodyfontlineheight-\textheight\relax + \fi\fi} + +\unexpanded\def\page_layouts_report_overshoot + {\page_layouts_calculate_overshoot + \ifdim\textovershoot>\zeropoint + \writestatus\m!layouts{gridmode,\space + noflines: \the\noflines,\space + textheight: \the\textheight,\space + textovershoot: \the\textovershoot\space + (maybe set number of lines instead)% + }% + \fi + \glet\page_layouts_report_overshoot\page_layouts_calculate_overshoot} + +\appendtoks + \page_layouts_report_overshoot +\to \everybeforepagebody + %D Visualization: \definepalet diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex d5f616baf..f535d39b3 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 419d34320..d3fb5d973 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/status-mkiv.lua b/tex/context/base/mkiv/status-mkiv.lua index 2afd47709..ab1419c98 100644 --- a/tex/context/base/mkiv/status-mkiv.lua +++ b/tex/context/base/mkiv/status-mkiv.lua @@ -3092,6 +3092,12 @@ return { }, { ["category"]="lua", + ["filename"]="node-scn", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", ["filename"]="node-met", ["loading"]="always", ["status"]="okay", diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi index b63d678ab..bf6681283 100644 --- a/tex/context/base/mkiv/strc-flt.mkvi +++ b/tex/context/base/mkiv/strc-flt.mkvi @@ -154,12 +154,13 @@ \c!outermargin=\zeropoint, % idem \c!leftmargindistance=\zeropoint, \c!rightmargindistance=\floatparameter\c!leftmargindistance, - \c!step=\v!big, % the flish side float step (big=line, medium=halfline, small=quarterline, depth=halfline with normaldepth) + \c!step=\v!big, % the flush side float step (big=line, medium=halfline, small=quarterline, depth=halfline with normaldepth) \c!ntop=2, \c!nbottom=0, \c!nlines=4, % used? \c!topoffset=\zeropoint, \c!bottomoffset=\zeropoint, + \c!freeregion=\v!yes, %\c!local=, %\c!bottombefore=, % e.g. \vfill %\c!bottomafter=, @@ -585,9 +586,11 @@ \edef\savedfloatlocation{\floatcaptionparameter\c!location}% \setexpandedfloatcaptionparameter\c!topoffset {\floatparameter\c!topoffset}% \setexpandedfloatcaptionparameter\c!bottomoffset{\floatparameter\c!bottomoffset}% + \setexpandedfloatcaptionparameter\c!freeregion {\floatparameter\c!freeregion}% \setupcurrentfloatcaption[\c!location=,\c!reference=,\c!title=,\c!marking=,\c!list=,\c!bookmark=,#settings]% \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}% \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}% + \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}% \def\m_strc_floats_saved_userdata{#2}% \edef\floatlocation{\floatcaptionparameter\c!location}% \setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded @@ -813,6 +816,8 @@ \else \doifelseinset\v!local\floatlocation\settrue\setfalse\c_page_floats_center_box_local \fi + \doifelse{\floatparameter\c!freeregion}\v!yes + \settrue\setfalse\c_strc_floats_mark_as_free \doifnotcommon{\v!always,\v!here,\v!force}\floatlocation % ! ! ! ! ! ! {\setfalse\c_page_floats_center_box_global \setfalse\c_page_floats_center_box_local}} @@ -1179,8 +1184,8 @@ \strc_floats_calculate_skip\d_page_sides_topskip {\rootfloatparameter\c!sidespacebefore}% \strc_floats_calculate_skip\d_page_sides_bottomskip{\rootfloatparameter\c!sidespaceafter }% \global\d_strc_floats_margin \rootfloatparameter\c!margin - \global\d_page_sided_leftshift \floatparameter \c!leftmargindistance - \global\d_page_sided_rightshift \floatparameter \c!rightmargindistance + \global\d_page_sides_leftshift \floatparameter \c!leftmargindistance + \global\d_page_sides_rightshift \floatparameter \c!rightmargindistance \global\c_page_floats_n_of_top \rootfloatparameter\c!ntop \global\c_page_floats_n_of_bottom\rootfloatparameter\c!nbottom \endgroup} @@ -1383,6 +1388,8 @@ \def\captionminwidth {15\bodyfontsize} \def\captionovershoot{2\emwidth} +\let\strc_floats_mark_pag_as_free\relax + \def\strc_floats_set_page_variant {\bgroup \strc_floats_set_local_hsize @@ -1426,6 +1433,7 @@ \global\setbox\floatbox\vpack {\rotate[\c!rotation=\number\c_strc_floats_rotation]{\box\floatbox}}% \fi + \strc_floats_mark_pag_as_free \egroup} \def\strc_floats_prepare_no_caption @@ -1670,7 +1678,7 @@ {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance} \def\strc_floats_build_box_next_left_margin - {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance } + {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance} \def\strc_floats_build_box_next_outer_margin {\doifelserightpagefloat @@ -1887,6 +1895,8 @@ \unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}} +\let\strc_floats_mark_box_as_free\relax + \def\strc_floats_build_box {\global\setbox\floatbox\vbox % pack ? probably not {\strc_floats_set_local_hsize diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 52ab811b0..643f6d22d 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -638,7 +638,7 @@ \ifdim\lastskip>\zeropoint % bah \else - \strc_math_obey_depth + \strc_math_obey_depth % somehow \fakenextstrutline doesn't work here \nointerlineskip \fi \ifx\p_spacebefore\v!none @@ -731,7 +731,10 @@ \d_strc_formulas_display_skip_right\zeropoint} \unexpanded\def\strc_formulas_start_formula_indeed[#1][#2]% setting leftskip adaption is slow ! - {\bgroup % HERE + {\ifhmode + \par + \fi + \bgroup % HERE \def\currentformula{#1}% \dostarttaggedchained\t!formula\currentformula\??formula \the\everybeforedisplayformula @@ -818,7 +821,10 @@ %D \stoptyping \unexpanded\def\startdisplaymath - {\bgroup + {\ifhmode + \par + \fi + \bgroup \informulatrue \beforedisplayspace \setdisplaydimensions diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index e0a49115c..51f87a66c 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['strc-reg'] = { local next, type = next, type local format, gmatch = string.format, string.gmatch local equal, concat, remove = table.are_equal, table.concat, table.remove -local lpegmatch = lpeg.match +local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct local allocate = utilities.storage.allocate local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) @@ -436,7 +436,13 @@ implement { arguments = { "string", "string" } } -local entrysplitter = lpeg.tsplitat('+') -- & obsolete in mkiv + +local p_s = P("+") +local p_e = P("&") * (1-P(";"))^0 * P(";") +local p_r = C((p_e + (1-p_s))^0) + +local entrysplitter_xml = Ct(p_r * (p_s * p_r)^0) -- bah +local entrysplitter_tex = lpeg.tsplitat('+') -- & obsolete in mkiv local tagged = { } @@ -467,6 +473,7 @@ local function preprocessentries(rawdata) local kt = entries.keys local entryproc = processors and processors.entry local pageproc = processors and processors.page + local coding = rawdata.metadata.coding if entryproc == "" then entryproc = nil end @@ -478,14 +485,14 @@ local function preprocessentries(rawdata) if p then entryproc = p end - et = lpegmatch(entrysplitter,e) + et = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,e) end if not kt then local p, k = splitprocessor(entries.key or "") if p then pageproc = p end - kt = lpegmatch(entrysplitter,k) + kt = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,k) end -- entries = { } diff --git a/tex/context/base/mkiv/supp-ran.lua b/tex/context/base/mkiv/supp-ran.lua index 4968e8cfc..8bfc09e58 100644 --- a/tex/context/base/mkiv/supp-ran.lua +++ b/tex/context/base/mkiv/supp-ran.lua @@ -10,8 +10,8 @@ if not modules then modules = { } end modules ['supp-ran'] = { local report_system = logs.reporter("system","randomizer") -local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) -local trace_random_mp = false trackers.register("system.randomizer.mp",function(v) trace_random_mp = v end) +local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) +local trace_detail = false trackers.register("system.randomizer.detail",function(v) trace_detail = v end) local insert, remove = table.insert, table.remove @@ -26,6 +26,14 @@ local stack = { } local last = 1 local maxcount = 2^30-1 -- 1073741823 +math.random = function(...) + local n = random(...) + if trace_detail then + report_system("math %s",n) + end + return n +end + local function setrandomseedi(n) if n <= 1 then n = n * maxcount @@ -33,17 +41,22 @@ local function setrandomseedi(n) n = n * 1000 end n = round(n) - if trace_random then - report_system("setting seed to %s",n) - end randomseed(n) last = random(0,maxcount) -- we need an initial value + if trace_detail then + report_system("seed %s from %s",last,n) + elseif trace_random then + report_system("setting seed %s",n) + end end math.setrandomseedi = setrandomseedi local function getrandomnumber(min,max) last = random(min,max) + if trace_detail then + report_system("number %s",last) + end return last end @@ -56,19 +69,19 @@ local function getrandomseed() return last end -local function getmprandomnumber() - last = random(0,4095) - if trace_random_mp then - report_system("using mp seed %s",last) - end - return last -end +-- local function getmprandomnumber() +-- last = random(0,4095) +-- if trace_detail then +-- report_system("mp number %s",last) +-- end +-- return last +-- end -- maybe stack local function pushrandomseed() insert(stack,last) - if trace_random then + if trace_random or trace_detail then report_system("pushing seed %s",last) end end @@ -76,7 +89,7 @@ end local function reuserandomseed(n) local seed = stack[#stack] if seed then - if trace_random then + if trace_random or trace_detail then report_system("reusing seed %s",last) end randomseed(seed) @@ -86,19 +99,47 @@ end local function poprandomseed() local seed = remove(stack) if seed then - if trace_random then + if trace_random or trace_detail then report_system("popping seed %s",seed) end randomseed(seed) end end +local function getrandom(where,...) + if type(where) == "string" then + local n = random(...) + if trace_detail then + report_system("%s %s",where,n) + end + return n + else + local n = random(where,...) + if trace_detail then + report_system("utilities %s",n) + end + return n + end +end + +utilities.randomizer = { + setseedi = setrandomseedi, + getnumber = getrandomnumber, + setseed = setrandomseed, + getseed = getrandomseed, + -- getmpnumber = getmprandomnumber, + pushseed = pushrandomseed, + reuseseed = reuserandomseed, + popseed = poprandomseed, + get = getrandom, +} + -- todo: also open up in utilities.randomizer.* implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } } implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } } implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } } -implement { name = "getmprandomnumber", actions = { getmprandomnumber, context } } +--------- { name = "getmprandomnumber", actions = { getmprandomnumber, context } } implement { name = "setrandomseed", actions = { setrandomseed }, arguments = { "integer" } } implement { name = "getrandomseed", actions = { getrandomseed, context } } implement { name = "pushrandomseed", actions = { pushrandomseed } } diff --git a/tex/context/base/mkiv/supp-ran.mkiv b/tex/context/base/mkiv/supp-ran.mkiv index f7cfd6e73..5b70a075f 100644 --- a/tex/context/base/mkiv/supp-ran.mkiv +++ b/tex/context/base/mkiv/supp-ran.mkiv @@ -20,11 +20,11 @@ \unprotect -\unexpanded\def\getrandomcount #1#2#3{#1=\clf_getrandomnumber#2 #3\relax} -\unexpanded\def\getrandomdimen #1#2#3{#1=\clf_getrandomdimen#2 #3 \scaledpoint\relax} -\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\clf_getrandomnumber#2 #3}} -\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat#2 #3}} -\unexpanded\def\setrandomseed #1{\clf_setrandomseed#1\relax} +\unexpanded\def\getrandomcount #1#2#3{#1=\clf_getrandomnumber\numexpr#2\relax\numexpr#3\relax\relax} +\unexpanded\def\getrandomdimen #1#2#3{#1=\clf_getrandomdimen\dimexpr#2\relax\dimexpr#3\relax\scaledpoint\relax} +\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\clf_getrandomnumber\numexpr#2\relax\numexpr#3\relax}} +\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat\dimexpr#2\relax\dimexpr#3\relax}} +\unexpanded\def\setrandomseed #1{\clf_setrandomseed\numexpr#1\relax} \unexpanded\def\getrandomseed #1{\edef#1{\clf_getrandomseed}} \unexpanded\def\pushrandomseed {\clf_pushrandomseed} \unexpanded\def\poprandomseed {\clf_poprandomseed} diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua index 98b92cef3..7cdda273d 100644 --- a/tex/context/base/mkiv/syst-aux.lua +++ b/tex/context/base/mkiv/syst-aux.lua @@ -121,6 +121,7 @@ implement { -- \gdef\setpercentdimen#1#2% -- {#1=\ctxcommand{percentageof("#2",\number#1)}\relax} +local space = P(" ") / "" local spaces = P(" ")^0 / "" local nohash = 1 - P("#") local digit = R("09") @@ -130,27 +131,147 @@ local sentinel = spaces * (nohash^1 / "\\%0") local sargument = (single * digit)^1 local dargument = (double * digit)^1 -local usespaces = nil -local texpreamble = nil - -local pattern = Cs( -- ^-1 - ( P("spaces") / function() usespaces = true return "" end )^0 - * spaces - * ( P("nospaces") / function() usespaces = false return "" end )^0 - * spaces - * ( P("global") / "\\global" )^0 - * spaces - * ( P("unexpanded") / "\\unexpanded" )^0 - * spaces - * Cc("\\expandafter\\") - * spaces - * ( P("expanded") / "e" )^0 - * spaces - * ( P((1-S(" #"))^1) / "def\\csname %0\\endcsname" ) - * spaces - * ( - -- (double * digit)^1 * sentinel^-1 * double^-1 - -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- first variant: +-- +-- local texpreamble = nil +-- local usespaces = nil +-- +-- local pattern = Cs( -- ^-1 +-- ( P("spaces") / function() usespaces = true return "" end )^0 +-- * spaces +-- * ( P("nospaces") / function() usespaces = false return "" end )^0 +-- * spaces +-- * ( P("global") / "\\global" )^0 +-- * spaces +-- * ( P("unexpanded") / "\\unexpanded" )^0 +-- * spaces +-- * Cc("\\expandafter\\") +-- * spaces +-- * ( P("expanded") / "e" )^0 +-- * spaces +-- * ( P((1-S(" #"))^1) / "def\\csname %0\\endcsname" ) +-- * spaces +-- * ( +-- -- (double * digit)^1 * sentinel^-1 * double^-1 +-- -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 +-- + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 +-- + sentinel^-1 * (double+single)^-1 +-- ) +-- ) +-- +-- local ctx_dostarttexdefinition = context.dostarttexdefinition +-- +-- local function texdefinition_one(str) +-- usespaces = nil +-- texpreamble = lpegmatch(pattern,str) +-- if usespaces == true then +-- setcatcode(32,10) -- space +-- setcatcode(13, 5) -- endofline +-- elseif usespaces == false then +-- setcatcode(32, 9) -- ignore +-- setcatcode(13, 9) -- ignore +-- else +-- -- this is default +-- -- setcatcode(32,10) -- space +-- -- setcatcode(13, 9) -- ignore +-- end +-- ctx_dostarttexdefinition() +-- end +-- +-- local function texdefinition_two() +-- context(texpreamble) +-- end + +-- second variant: +-- +-- -- default: +-- -- +-- -- setcatcode(32,10) -- space +-- -- setcatcode(13, 9) -- ignore +-- +-- local function catcodes_s() +-- setcatcode(32,10) -- space +-- setcatcode(13, 5) -- endofline +-- return "" +-- end +-- +-- local function catcodes_n() +-- setcatcode(32, 9) -- ignore +-- setcatcode(13, 9) -- ignore +-- return "" +-- end +-- +-- local pattern = Cs( -- ^-1 +-- ( P("spaces") * space / catcodes_s )^0 +-- * spaces * ( P("nospaces") * space / catcodes_n )^0 +-- * spaces * ( P("global") * space / "\\global" )^0 +-- * spaces * ( P("unexpanded") * space / "\\unexpanded" )^0 +-- * spaces * Cc("\\expandafter\\") +-- * spaces * ( P("expanded") / "e" )^0 +-- * spaces * ( P((1-S(" #["))^1) / "def\\csname %0\\endcsname" ) +-- * spaces * ( +-- -- (double * digit)^1 * sentinel^-1 * double^-1 +-- -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 +-- + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 +-- + sentinel^-1 * (double+single)^-1 +-- ) +-- ) +-- +-- local texpreamble = nil +-- +-- local ctx_dostarttexdefinition = context.dostarttexdefinition +-- +-- local function texdefinition_one(str) +-- texpreamble = lpegmatch(pattern,str) +-- ctx_dostarttexdefinition() +-- end +-- +-- local function texdefinition_two() +-- context(texpreamble) +-- end + +-- third variant: + +local global = nil +local unexpanded = nil +local expanded = nil +local optional = nil +local csname = nil +local rest = nil + +local function catcodes_s() + setcatcode(32,10) -- space + setcatcode(13, 5) -- endofline +end + +local function catcodes_n() + setcatcode(32, 9) -- ignore + setcatcode(13, 9) -- ignore +end + +local space = P(" ") +local spaces = space^0 + +local option = ( + P("single") + + P("double") + + P("tripple") + + P("quadruple") + + P("quintuple") + + P("sixtuple") + ) * (P("empty") + P("argument")) + +local pattern = ( + ( P("spaces") * space / catcodes_s )^0 + * spaces * ( P("nospaces") * space / catcodes_n )^0 + * spaces * ( P("global") * space * Cc(true) + Cc(false) ) + * spaces * ( P("unexpanded") * space * Cc(true) + Cc(false) ) + * spaces * ( P("expanded") * space * Cc(true) + Cc(false) ) + * spaces * ( C(option) * space + Cc(false) ) + * spaces * ( C((1-S(" #["))^1) ) + * spaces * Cs( ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 + sentinel^-1 * (double+single)^-1 @@ -160,24 +281,42 @@ local pattern = Cs( -- ^-1 local ctx_dostarttexdefinition = context.dostarttexdefinition local function texdefinition_one(str) - usespaces = nil - texpreamble = lpegmatch(pattern,str) - if usespaces == true then - setcatcode(32,10) -- space - setcatcode(13, 5) -- endofline - elseif usespaces == false then - setcatcode(32, 9) -- ignore - setcatcode(13, 9) -- ignore - else - -- this is default - -- setcatcode(32,10) -- space - -- setcatcode(13, 9) -- ignore - end + global, unexpanded, expanded, optional, csname, rest = lpegmatch(pattern,str) ctx_dostarttexdefinition() end local function texdefinition_two() - context(texpreamble) + if optional then + context ( + [[\unexpanded\expandafter]] .. + (global and [[\xdef]] or [[\edef]]) .. + [[\csname ]] .. + csname .. + [[\endcsname{\expandafter\noexpand\expandafter\do]] .. + optional .. + [[\csname _do_]] .. + csname .. + [[_\endcsname}\unexpanded\expandafter]] .. + (global and [[\gdef]] or [[\edef]]) .. + [[\csname _do_]] .. + csname .. + [[_\endcsname ]] .. + rest + ) + else + context ( + [[\unexpanded\expandafter]] .. + ( global and ( + expanded and [[\xdef]] or [[\gdef]] + ) or ( + expanded and [[\edef]] or [[\def]] + ) ) .. + [[\csname ]] .. + csname .. + [[\endcsname ]] .. + rest + ) + end end implement { name = "texdefinition_one", actions = texdefinition_one, scope = "private", arguments = "string" } diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv index e81f61807..6c2fb2014 100644 --- a/tex/context/base/mkiv/syst-aux.mkiv +++ b/tex/context/base/mkiv/syst-aux.mkiv @@ -3186,7 +3186,7 @@ %D are needed: \unexpanded\def\newif#1% - {\scratchcounter\escapechar + {\privatescratchcounter\escapechar \escapechar\minusone \expandafter\expandafter\expandafter \redoglobal\expandafter\expandafter\expandafter @@ -3195,7 +3195,7 @@ \redoglobal\expandafter\expandafter\expandafter \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}% \dodoglobal\@if#1{false}% - \escapechar\scratchcounter} + \escapechar\privatescratchcounter} %D Also new: @@ -6234,23 +6234,23 @@ {\def\m_syst_string_three{#1}% \ifx\m_syst_string_two\m_syst_string_three \else \ifx\m_syst_string_one\m_syst_string_three - \advance\scratchcounter\plusone + \advance\privatescratchcounter\plusone \fi \expandafter\syst_helpers_count_token \fi} \unexpanded\def\counttoken#1\in#2\to#3% - {\scratchcounter\zerocount + {\privatescratchcounter\zerocount \def\m_syst_string_one{#1}% \def\m_syst_string_two{\end}% \syst_helpers_count_token#2\end - \dodoglobal#3\scratchcounter} + \dodoglobal#3\privatescratchcounter} \unexpanded\def\counttokens#1\to#2% - {\scratchcounter\zerocount - \def\syst_helpers_count_token##1{\advance\scratchcounter\plusone}% + {\privatescratchcounter\zerocount + \def\syst_helpers_count_token##1{\advance\privatescratchcounter\plusone}% \handletokens#1\with\syst_helpers_count_token - \dodoglobal#2\scratchcounter} + \dodoglobal#2\privatescratchcounter} %D \macros %D {splitofftokens} @@ -6261,10 +6261,10 @@ \unexpanded\def\splitofftokens#1\from#2\to#3% slow but hardly used {\ifnum#1>\zerocount - \scratchcounter#1\relax + \privatescratchcounter#1\relax \def\syst_helpers_split_off_tokens##1% - {\ifnum\scratchcounter>\zerocount - \advance\scratchcounter \minusone + {\ifnum\privatescratchcounter>\zerocount + \advance\privatescratchcounter \minusone \edef#3{#3##1}% \fi}% % \let#3\empty % #3 can be #2, so: @@ -6460,7 +6460,7 @@ {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty} \unexpanded\def\freezedimensionwithunit#1#2% - {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}} + {\setdimensionwithunit\privatescratchdimen#1{#2}\edef#1{\the\privatescratchdimen}} %D \macros %D {doifsometokselse, doifsometoks} @@ -6715,7 +6715,7 @@ %D This is a dirty one: we simply append a unit and discard it when needed. \def\doifelsedimension#1% - {\afterassignment\syst_helpers_if_dimension_else\scratchdimen#1pt\relax} + {\afterassignment\syst_helpers_if_dimension_else\privatescratchdimen#1pt\relax} \let\doifdimensionelse\doifelsedimension @@ -6861,10 +6861,10 @@ \syst_helpers_unspaced} \unexpanded\def\unspaceargument#1\to#2% - {\scratchcounter\catcode\spaceasciicode + {\privatescratchcounter\catcode\spaceasciicode \catcode\spaceasciicode\ignorecatcode \scantextokens{\edef#2{#1}}% - \catcode\spaceasciicode\scratchcounter} + \catcode\spaceasciicode\privatescratchcounter} \unexpanded\def\unspaceafter#1#2% {\unspaceargument#2\to\ascii @@ -6921,7 +6921,7 @@ \def\syst_helpers_if_non_zero_positive_else#1#2\end % #3#4% {\ifx#1\relax - \ifcase\scratchcounter + \ifcase\privatescratchcounter \endgroup \doubleexpandafter\secondoftwoarguments \else @@ -6934,7 +6934,7 @@ \fi} \def\doifelsenonzeropositive#1% - {\begingroup\afterassignment\syst_helpers_if_non_zero_positive_else\scratchcounter=0#1\relax\empty\end} + {\begingroup\afterassignment\syst_helpers_if_non_zero_positive_else\privatescratchcounter=0#1\relax\empty\end} \let\doifnonzeropositiveelse\doifelsenonzeropositive diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index 808aa820c..97c612db7 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -320,14 +320,15 @@ %D scratchtoks} %D %D We now define a few scratch registers, so that successive loads at least have -%D some available. - -\newcount \scratchcounter \newcount \globalscratchcounter -\newdimen \scratchdimen \newdimen \globalscratchdimen -\newskip \scratchskip \newskip \globalscratchskip -\newmuskip\scratchmuskip \newmuskip\globalscratchmuskip -\newtoks \scratchtoks \newtoks \globalscratchtoks -\newbox \scratchbox \newbox \globalscratchbox +%D some available. The private ones are used in cases where we don't want to +%D intrude on normal scratch ones. + +\newcount \scratchcounter \newcount \globalscratchcounter \newcount \privatescratchcounter +\newdimen \scratchdimen \newdimen \globalscratchdimen \newdimen \privatescratchdimen +\newskip \scratchskip \newskip \globalscratchskip \newskip \privatescratchskip +\newmuskip\scratchmuskip \newmuskip\globalscratchmuskip \newmuskip\privatescratchmuskip +\newtoks \scratchtoks \newtoks \globalscratchtoks \newtoks \privatescratchtoks +\newbox \scratchbox \newbox \globalscratchbox \newbox \privatescratchbox \newcount\scratchcounterone \newcount\scratchcountertwo \newcount\scratchcounterthree \newdimen \scratchdimenone \newdimen \scratchdimentwo \newdimen \scratchdimenthree diff --git a/tex/context/base/mkiv/tabl-ntb.mkiv b/tex/context/base/mkiv/tabl-ntb.mkiv index 0d1c97f88..c1805ada9 100644 --- a/tex/context/base/mkiv/tabl-ntb.mkiv +++ b/tex/context/base/mkiv/tabl-ntb.mkiv @@ -255,6 +255,7 @@ \installcorenamespace{naturaltablehei} \installcorenamespace{naturaltabledis} \installcorenamespace{naturaltableaut} +\installcorenamespace{naturaltablebck} %installcorenamespace{naturaltablefwd} % forcedwidth \installcorenamespace{naturaltabletxt} \installcorenamespace{naturaltablespn} @@ -279,7 +280,7 @@ \def\tabl_ntb_set_nob#1{\expandafter\let\csname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone} \def\tabl_ntb_get_nob#1{\ifcsname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone\else\zerocount\fi} -\def\tabl_ntb_set_tag#1#2{\expandafter\edef\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} +%def\tabl_ntb_set_tag#1#2{\expandafter\edef\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_col#1#2{\expandafter\edef\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_row#1#2{\expandafter\edef\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} @@ -287,17 +288,17 @@ \def\tabl_ntb_let_col#1#2{\expandafter\let\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_let_row#1#2{\expandafter\let\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +%def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_set_ht#1#2{\expandafter\xdef\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! -\def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +%def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_let_ht#1#2{\global\expandafter\let\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_get_tag#1#2{\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_col#1#2{\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_row#1#2{\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_get_wd#1#2{\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} +%def\tabl_ntb_get_wd#1#2{\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_ht#1#2{\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_wid#1{\expandafter\xdef\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! @@ -315,6 +316,10 @@ \def\tabl_ntb_get_dis#1{\ifcsname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi} \def\tabl_ntb_get_aut#1{\csname \??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} +\def\tabl_ntb_let_bck#1#2{\global\expandafter\chardef\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname} + +\def\tabl_ntb_get_bck#1#2{\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname} + \def\tabl_ntb_tag_pattern#1#2{\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2} \def\tabl_ntb_row_pattern#1#2{\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2} \def\tabl_ntb_col_pattern#1#2{\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2} @@ -1109,7 +1114,7 @@ \fi \fi \tabl_ntb_let_ht\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint - \tabl_ntb_let_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint + %tabl_ntb_let_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint \ifcsname\tabl_ntb_col_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname \else \tabl_ntb_let_col\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zerocount \fi @@ -1387,7 +1392,7 @@ \fi \setbox\scratchbox\hbox{\tabl_ntb_get_txt{#1}{#2}}% \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}% - \tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% + %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% \ifdim\ht\scratchbox>\tabl_ntb_get_hei{#1}\relax \tabl_ntb_set_hei{#1}{\the\ht\scratchbox}% \fi}% @@ -1506,7 +1511,7 @@ % new \c_tabl_ntb_current_col_one\recurselevel\relax \dorecurse\c_tabl_ntb_maximum_row - {\tabl_ntb_let_wd\recurselevel\c_tabl_ntb_current_col_one\zeropoint + {%tabl_ntb_let_wd\recurselevel\c_tabl_ntb_current_col_one\zeropoint \tabl_ntb_let_ht\recurselevel\c_tabl_ntb_current_col_one\zeropoint}% % till here \tabl_ntb_let_tal\recurselevel\zerocount @@ -1940,7 +1945,13 @@ \ifdim\scratchdimen>\tabl_ntb_get_dis{#2}\relax \tabl_ntb_set_dis{#2}{\the\scratchdimen}% \fi - \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop\tabl_ntb_cell_finalize}}% + \anch_backgrounds_text_level_start + \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop\tabl_ntb_cell_finalize}% + \anch_backgrounds_text_level_stop +\ifcase\c_anch_backgrounds_text_count\else + \tabl_ntb_let_bck{#1}{#2}\c_anch_backgrounds_text_state +\fi + }% \scratchdimen\tabl_ntb_get_wid\c_tabl_ntb_col\relax \ifdim\wd\scratchbox>\scratchdimen \ifsqueezeTBLspan @@ -1956,7 +1967,7 @@ \tabl_ntb_set_hei\scratchcounter{\the\ht\scratchbox}% auto set \fi \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}% - \tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% + %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% \ifautoTBLcheckwidth \ifdim\wd\scratchbox<.75\hsize % fuzzy guess \ifdim\ht\scratchbox>2\openlineheight % honor width since this @@ -1974,11 +1985,11 @@ \fi \fi \fi - \setbox2\emptyhbox - \wd2\wd\scratchbox - \ht2\ht\scratchbox - \dp2\dp\scratchbox - \box2 + \setbox\scratchboxone\emptyhbox + \wd\scratchboxone\wd\scratchbox + \ht\scratchboxone\ht\scratchbox + \dp\scratchboxone\dp\scratchbox + \box\scratchboxone \egroup} \unexpanded\def\tabl_ntb_cell_process_b_c#1#2#3[#4]#5% @@ -2043,6 +2054,12 @@ \else \setnaturaltablelocalparameter\c!height{\d_tabl_ntb_height}% \fi +\ifcase\c_anch_backgrounds_text_count\else + \edef\p_region{\naturaltablelocalparameter\c!region}% + \ifx\p_region\empty\ifnum\tabl_ntb_get_bck{#1}{#2}>\zerocount + \letnaturaltablelocalparameter\c!region\v!yes + \fi\fi +\fi \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop}}% \hskip\tabl_ntb_get_dis{#2}} diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv index 81d2b3c4e..4493db4f8 100644 --- a/tex/context/base/mkiv/tabl-tbl.mkiv +++ b/tex/context/base/mkiv/tabl-tbl.mkiv @@ -2264,7 +2264,12 @@ {\notesenabledfalse \d_tabl_tabulate_indent\zeropoint \settrialtypesetting % very important +\anch_backgrounds_text_level_start \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}}% +\anch_backgrounds_text_level_stop +\ifcase\c_anch_backgrounds_text_state\else + \global\settrue\tablehaspositions +\fi \ifnum\c_tabl_tabulate_nofauto>\zerocount % so, even if the natural size is larger, in the final run, we force the calculated width \d_tabl_tabulate_width\dimexpr\hsize-\wd\scratchbox-\d_tabl_tabulate_width_p-\d_tabl_tabulate_width_w\relax diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua index afcdc5855..c3e022b24 100644 --- a/tex/context/base/mkiv/tabl-xtb.lua +++ b/tex/context/base/mkiv/tabl-xtb.lua @@ -67,6 +67,7 @@ local getprev = nuts.getprev local getlist = nuts.getlist local getfield = nuts.getfield local getbox = nuts.getbox +local getdimensions = nuts.dimensions local setfield = nuts.setfield local setlink = nuts.setlink @@ -256,9 +257,7 @@ function xtables.set_reflow_width() -- drc.list = true -- we don't need to keep the content around as we're in trial mode (no: copy_node_list(tb)) -- - local width = getfield(tb,"width") - local height = getfield(tb,"height") - local depth = getfield(tb,"depth") + local width, height, depth = getdimensions(tb) -- local widths = data.widths local heights = data.heights @@ -428,9 +427,7 @@ function xtables.set_reflow_height() local tb = getbox("b_tabl_x") local drc = row[c] -- - local width = getfield(tb,"width") - local height = getfield(tb,"height") - local depth = getfield(tb,"depth") + local width, height, depth = getdimensions(tb) -- if drc.ny < 2 then if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2 @@ -821,7 +818,8 @@ function xtables.construct() end local list = drc.list if list then - setfield(list,"shift",getfield(list,"height") + getfield(list,"depth")) + local w, h, d = getdimensions(list) + setfield(list,"shift",h+d) -- list = hpack_node_list(list) -- is somehow needed -- setfield(list,"width",0) -- setfield(list,"height",0) @@ -1168,10 +1166,8 @@ function xtables.cleanup() -- local cell = row[i] -- local list = cell.list -- if list then - -- cell.width = getfield(list,"width") - -- cell.height = getfield(list,"height") - -- cell.depth = getfield(list,"depth") - -- cell.list = true + -- cell.width, cell.height, cell.depth = getdimensions(list) + -- cell.list = true -- end -- end -- end diff --git a/tex/context/base/mkiv/trac-tex.lua b/tex/context/base/mkiv/trac-tex.lua index 6b0c31c1f..66cdc2c91 100644 --- a/tex/context/base/mkiv/trac-tex.lua +++ b/tex/context/base/mkiv/trac-tex.lua @@ -6,29 +6,36 @@ if not modules then modules = { } end modules ['trac-tex'] = { license = "see context related readme files" } --- moved from trac-deb.lua - -local next = next - local texhashtokens = tex.hashtokens -local trackers = trackers -local token = token -local saved = { } +local trackers = trackers +local token = token +local saved = { } +local create = token.create +local undefined = create("undefined").command function trackers.savehash() saved = texhashtokens() + if type(saved[1]) == "table" then + -- LUATEXVERSION < 1.002 + saved = table.tohash(saved) + end + return saved end function trackers.dumphashtofile(filename,delta) local list = { } - local hash = tex.hashtokens() + local hash = texhashtokens() local create = token.create - for name, token in next, hash do + if type(hash[1]) == "table" then + -- LUATEXVERSION < 1.002 + hash = table.sortedkeys(hash) + end + for i=1,#hash do + local name = hash[i] if not delta or not saved[name] then - if token[2] ~= 0 then -- still old interface - local token = create(name) - -- inspect(token) + local token = create(name) + if token.command ~= undefined then local category = token.cmdname local dk = list[category] if not dk then @@ -59,34 +66,11 @@ function trackers.dumphashtofile(filename,delta) table.save(filename or tex.jobname .. "-hash.log",list) end --- -- old token code --- --- function trackers.dumphashtofile(filename,delta) --- local list = { } --- local hash = texhashtokens() --- local getname = token.command_name --- for name, token in next, hash do --- if not delta or not saved[name] then --- -- token: cmd, chr, csid -- combination cmd,chr determines name --- local category = getname(token) --- local dk = list[category] --- if not dk then --- -- a bit funny names but this sorts better (easier to study) --- dk = { names = { }, found = 0, code = token[1] } --- list[category] = dk --- end --- dk.names[name] = { token[2], token[3] } --- dk.found = dk.found + 1 --- end --- end --- table.save(filename or tex.jobname .. "-hash.log",list) --- end - local delta = nil local function dump_hash(wanteddelta) if delta == nil then - saved = saved or texhashtokens() -- no need for trackers.dump_hash + saved = saved or trackers.savehash() luatex.registerstopactions(1,function() dump_hash(nil,wanteddelta) end) -- at front end delta = wanteddelta diff --git a/tex/context/base/mkiv/typo-cap.lua b/tex/context/base/mkiv/typo-cap.lua index a4e221ea1..972c5ea20 100644 --- a/tex/context/base/mkiv/typo-cap.lua +++ b/tex/context/base/mkiv/typo-cap.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['typo-cap'] = { local next, type = next, type local format, insert = string.format, table.insert -local div, randomnumber = math.div, math.random +local div, getrandom = math.div, utilities.randomizer.get local trace_casing = false trackers .register("typesetters.casing", function(v) trace_casing = v end) local check_kerns = true directives.register("typesetters.casing.checkkerns", function(v) check_kerns = v end) @@ -293,7 +293,7 @@ local function none(start,attr,lastfont,n,count,where,first) return start, false, true end -local function random(start,attr,lastfont,n,count,where,first) +local function randomized(start,attr,lastfont,n,count,where,first) local used = first or start local char = getchar(used) local font = getfont(used) @@ -302,7 +302,7 @@ local function random(start,attr,lastfont,n,count,where,first) local kind = categories[char] if kind == "lu" then while true do - local n = randomnumber(0x41,0x5A) + local n = getrandom("capital lu",0x41,0x5A) if tfm[n] then -- this also intercepts tables setchar(used,n) return start, true @@ -310,7 +310,7 @@ local function random(start,attr,lastfont,n,count,where,first) end elseif kind == "ll" then while true do - local n = randomnumber(0x61,0x7A) + local n = getrandom("capital ll",0x61,0x7A) if tfm[n] then -- this also intercepts tables setchar(used,n) return start, true @@ -327,7 +327,7 @@ register(variables.Words, Words) -- 4 register(variables.capital,capital) -- 5 register(variables.Capital,Capital) -- 6 register(variables.none, none) -- 7 (dummy) -register(variables.random, random) -- 8 +register(variables.random, randomized) -- 8 register(variables.mixed, mixed) -- 9 register(variables.camel, camel) -- 10 diff --git a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv index 0ff75a977..63f74027b 100644 --- a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv +++ b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv @@ -28,7 +28,7 @@ \starttypescriptcollection[latinmodern] - \starttypescript [\s!serif] [simple] [\s!name]% for old times sake (manuals) + \starttypescript [\s!serif] [simple] [\s!name] \definefontsynonym [\s!Simple] [\s!file:lmmonoproplt10-regular] [\s!features=\s!default] \stoptypescript @@ -82,9 +82,9 @@ \starttypescript [\s!serif] [modern-variable,latin-modern-variable-designsize,latin-modern-variable] [\s!name] \loadfontgoodies[lm] \definefontsynonym [\s!Serif] [LMTypewriterVarWd-Regular] [\s!features=\s!default] - \definefontsynonym [\s!SerifBold] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [LMTypewriterVarWd-Dark] [\s!features=\s!default] \definefontsynonym [\s!SerifItalic] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] - \definefontsynonym [\s!SerifSlanted] [LMTypewriterVarWd-Dark] [\s!features=\s!default] + \definefontsynonym [\s!SerifSlanted] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] \definefontsynonym [\s!SerifBoldItalic] [LMTypewriterVarWd-DarkOblique] [\s!features=\s!default] \definefontsynonym [\s!SerifBoldSlanted] [LMTypewriterVarWd-DarkOblique] [\s!features=\s!default] \definefontsynonym [\s!SerifCaps] [LMTypewriterVarWd-Regular] [\s!features=\s!default] diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml index ad166f2f9..65def6288 100644 --- a/tex/context/interface/mkii/keys-cs.xml +++ b/tex/context/interface/mkii/keys-cs.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='offsetramecku'/> <cd:constant name='frameradius' value='polomerramecku'/> <cd:constant name='frames' value='ramecky'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='z'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index 19ffc98e7..a607b6358 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='rahmenoffset'/> <cd:constant name='frameradius' value='rahmenradius'/> <cd:constant name='frames' value='umrahmen'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='von'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml index 80f348b9e..c84454f54 100644 --- a/tex/context/interface/mkii/keys-en.xml +++ b/tex/context/interface/mkii/keys-en.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='frameoffset'/> <cd:constant name='frameradius' value='frameradius'/> <cd:constant name='frames' value='frames'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='from'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml index ae600f5f9..725272f3c 100644 --- a/tex/context/interface/mkii/keys-fr.xml +++ b/tex/context/interface/mkii/keys-fr.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='decalagecadre'/> <cd:constant name='frameradius' value='rayoncadre'/> <cd:constant name='frames' value='cadres'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='de'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index 49902eee5..d9642bf3a 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='offsetcornice'/> <cd:constant name='frameradius' value='raggiocornice'/> <cd:constant name='frames' value='cornici'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='da'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index a8f65b552..add0efe38 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='kaderoffset'/> <cd:constant name='frameradius' value='kaderstraal'/> <cd:constant name='frames' value='hokjes'/> + <cd:constant name='freeregion' value='vrijgebied'/> <cd:constant name='from' value='van'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1960,7 +1961,7 @@ <cd:command name='useexternalsoundtrack' value='gebruikexterngeluidsfragment'/> <cd:command name='usemodule' value='gebruikmodule'/> <cd:command name='usemodules' value='gebruikmodules'/> - <cd:command name='usepath' value='gebruikgebied'/> + <cd:command name='usepath' value='gebruikpad'/> <cd:command name='usereferences' value='gebruikreferenties'/> <cd:command name='usespecials' value='gebruikspecials'/> <cd:command name='usesymbols' value='gebruiksymbolen'/> diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index b31c3ee97..6cb1bf833 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='آفستقالب'/> <cd:constant name='frameradius' value='شعاعقالب'/> <cd:constant name='frames' value='قالبها'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='از'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 707082d64..f1d644a29 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -825,6 +825,7 @@ <cd:constant name='frameoffset' value='offsetframe'/> <cd:constant name='frameradius' value='razaframe'/> <cd:constant name='frames' value='frames'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='dela'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 4fac278b4..db1aca861 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 b284c4966..49433f88f 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/modules/mkiv/m-steps.lua b/tex/context/modules/mkiv/m-steps.lua index c02e8f1c1..7fbb58370 100644 --- a/tex/context/modules/mkiv/m-steps.lua +++ b/tex/context/modules/mkiv/m-steps.lua @@ -62,7 +62,7 @@ local chart = nil local steps = { } local count = 0 -local function step_start_chart(name) +local function step_start_chart(name,alternative) name = name or "" steps = table.setmetatableindex(function(t,k) local v = { -- could be metatable @@ -81,8 +81,9 @@ local function step_start_chart(name) end) count = 0 chart = { - steps = steps, - count = count, + steps = steps, + count = count, + alternative = alternative, } charts[name] = chart end @@ -176,7 +177,15 @@ local function step_make_chart(settings) start() flush("step_begin_chart ;") -- - local alternative = utilities.parsers.settings_to_hash(chartsettings.alternative) + print(chartsettings.alternative) + local alternative = chartsettings.alternative + if not alternative or alternative == "" then + alternative = chart.alternative + end + if not alternative or alternative == "" then + alternative = variables.horizontal + end + local alternative = utilities.parsers.settings_to_hash(alternative) local vertical = alternative[variables.vertical] local align = alternative[variables.three] local category = chartsettings.category @@ -391,7 +400,7 @@ end interfaces.implement { name = "step_start_chart", - arguments = "string", + arguments = { "string", "string" }, actions = step_start_chart, } diff --git a/tex/context/modules/mkiv/m-steps.mkvi b/tex/context/modules/mkiv/m-steps.mkvi index e03ffa5ef..ce018a0d1 100644 --- a/tex/context/modules/mkiv/m-steps.mkvi +++ b/tex/context/modules/mkiv/m-steps.mkvi @@ -29,25 +29,22 @@ \stopMPdefinitions \installcorenamespace {stepcharts} -\installcorenamespace {steptables} \installcorenamespace {stepcells} \installcorenamespace {steptexts} \installcorenamespace {steplines} \installstylisticautosetuphandler \??stepcharts {STEPchart} \??stepcharts -\installstylisticautosetuphandler \??steptables {STEPtable} \??steptables \installstylisticautosetuphandler \??stepcells {STEPcell} \??stepcells \installstylisticautosetuphandler \??steptexts {STEPtext} \??steptexts \installstylisticautosetuphandler \??steplines {STEPline} \??steplines \let\setupSTEPcharts\setupSTEPchart -\let\setupSTEPtables\setupSTEPtable +\let\setupSTEPtables\setupSTEPchart % one can define categories so no need \let\setupSTEPcells \setupSTEPcell \let\setupSTEPtexts \setupSTEPtext \let\setupSTEPlines \setupSTEPline \let\setSTEPchartsparameter\setSTEPchartparameter -\let\setSTEPtablesparameter\setSTEPtableparameter \let\setSTEPcellsparameter \setSTEPcellparameter \let\setSTEPtextsparameter \setSTEPtextparameter \let\setSTEPlinesparameter \setSTEPlineparameter @@ -56,21 +53,12 @@ % numeric step_distance ; step_distance := 20pt ; \setupSTEPcharts - [\c!alternative=\v!horizontal, + [%c!alternative=\v!horizontal, % travels with stored so dealt with in lua %\c!offset=.15\bodyfontsize %\c!height=2ex \c!before=\blank, \c!after=\blank] -% \setupSTEPtables -% [\c!before=\blank, -% \c!after=\blank, -% \c!distance=.25em, -% \c!voffset=1ex, -% \c!method=1, -% \c!width=4em, -% \c!offset=.15\bodyfontsize] - \setupSTEPcells [\c!alternative=24, \c!style=, @@ -150,10 +138,12 @@ \setupcurrentSTEPchart[#name]% \def\module_steps_flush_chart{\module_steps_chart[][#name]}} {\edef\currentSTEPchart{#name}% + \setupcurrentSTEPchart[#settings]% \let\m_module_steps_category\currentSTEPchart \resetboxesincache{\??stepcharts\m_module_steps_category}% - \setupcurrentSTEPchart[#settings]% - \let\module_steps_flush_chart\relax}% settings are not stored + \doifelse{\STEPchartparameter\c!buffer}\v!no + {\def\module_steps_flush_chart{\STEPchart[#name]}} + {\let\module_steps_flush_chart\relax}}% \else \let\currentSTEPchart\empty \def\module_steps_flush_chart{\module_steps_chart[][]}% @@ -167,7 +157,7 @@ \checkSTEPlineparent \the\everySTEPchart \startnointerference - \clf_step_start_chart{\currentSTEPchart}} + \clf_step_start_chart{\currentSTEPchart}{\STEPchartparameter\c!alternative}} \unexpanded\def\stopSTEPchart {\clf_step_stop_chart @@ -615,4 +605,53 @@ \page +\setupSTEPchart + [mytable] + [before={\blank[2*big]}, + after={\blank[2*big]}] + +\starttext + +\startSTEPaligntable[mytable] + \cells {$2c$} {$=$} {$2a+3b$} + \text {with $a=5$} + \cells {$2c$}{$=$} {$10+3b$} + \text {and $b=6$} + \cells {$2c$} {$=$} {$10+18$} + \text {we get} + \cells {$2c$} {$=$} {$28$} + \text {and therefore} + \cells {$c$} {$=$} {$28/2$} + \text {which reduces to} + \cells {$c$} {$=$} {$14$} +\stopSTEPaligntable + +\input tufte + +\STEPchart[mytable] + +\input tufte + +\setupSTEPchart + [mytable] + [buffer=no] + +\startSTEPaligntable[mytable] + \cells {$2c$} {$=$} {$2a+3b$} + \text {with $a=5$} + \cells {$2c$}{$=$} {$10+3b$} + \text {and $b=6$} + \cells {$2c$} {$=$} {$10+18$} + \text {we get} + \cells {$2c$} {$=$} {$28$} + \text {and therefore} + \cells {$c$} {$=$} {$28/2$} + \text {which reduces to} + \cells {$c$} {$=$} {$14$} +\stopSTEPaligntable + +\input tufte + +\STEPchart[mytable] + \stoptext diff --git a/tex/context/modules/mkiv/m-visual.mkiv b/tex/context/modules/mkiv/m-visual.mkiv index 17d679452..6ec0a52b0 100644 --- a/tex/context/modules/mkiv/m-visual.mkiv +++ b/tex/context/modules/mkiv/m-visual.mkiv @@ -81,7 +81,8 @@ fr8c=darkorange] \unexpanded\def\onlyfakewords#1#2% min max / 10 40 - {\ifvmode\noindentation\fi + {\dontleavehmode + \ifvmode\noindentation\fi \getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}% \dofakewords\scratchcounter } % no \par diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index f5339a3b7..cc7ed88ad 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 : 12/28/16 17:55:48 +-- merge date : 01/17/17 17:37:54 do -- begin closure to overcome local limits and interference @@ -9092,8 +9092,8 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo) local fontheader=fontdata.fontheader or {} local cffinfo=fontdata.cffinfo or {} local filename=fontdata.filename - local weight=getname(fontdata,"weight") or cffinfo.weight or metrics.weight - local width=getname(fontdata,"width") or cffinfo.width or metrics.width + local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) local fontname=getname(fontdata,"postscriptname") local fullname=getname(fontdata,"fullname") local family=getname(fontdata,"family") @@ -18462,6 +18462,7 @@ local fontfeatures=fonthashes.features local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local onetimemessage=fonts.loggers.onetimemessage or function() end +local getrandom=utilities and utilities.randomizer and utilities.randomizer.get otf.defaultnodealternate="none" local tfmdata=false local characters=false @@ -18807,7 +18808,7 @@ end local function get_alternative_glyph(start,alternatives,value) local n=#alternatives if value=="random" then - local r=random(1,n) + local r=getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value=="first" then return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) diff --git a/tex/generic/context/luatex/luatex-pdf.tex b/tex/generic/context/luatex/luatex-pdf.tex index 81eb872ab..57004c6f8 100644 --- a/tex/generic/context/luatex/luatex-pdf.tex +++ b/tex/generic/context/luatex/luatex-pdf.tex @@ -168,7 +168,7 @@ \global\pdfobjcompresslevel 1 \global\pdfdecimaldigits 4 \global\pdfgamma 1000 - \global\pdfimageresolution 71 + \global\pdfimageresolution 72 \global\pdfimageapplygamma 0 \global\pdfimagegamma 2200 \global\pdfimagehicolor 1 |