diff options
Diffstat (limited to 'tex/context/base/tabl-tsp.mkiv')
-rw-r--r-- | tex/context/base/tabl-tsp.mkiv | 470 |
1 files changed, 250 insertions, 220 deletions
diff --git a/tex/context/base/tabl-tsp.mkiv b/tex/context/base/tabl-tsp.mkiv index 21182a988..0138697af 100644 --- a/tex/context/base/tabl-tsp.mkiv +++ b/tex/context/base/tabl-tsp.mkiv @@ -13,8 +13,11 @@ \writestatus{loading}{ConTeXt Table Macros / Splitting} -%D The code in this file is move here from other places and needs -%D a mkiv cleanup. +%D The code in this file is moved here from other places and needs +%D a mkiv cleanup. As it mostly targets at tables the code lives in +%D the tabl and page namespaces. + +% work in progress \unprotect @@ -26,8 +29,6 @@ % \splitfloat [settings] {\placetable[optional args]{test}} {content} -% there is no need for a tracked structure number here - %D When \type {inbetween} is made empty instead of the %D default \type {\page}, we will get delayed flushing %D and text may continue below the graphic. @@ -55,61 +56,81 @@ %D \dorecurse{10}{\input tufte } %D \stoptyping -\newcount\noffloatssplits - -\settrue \onlyonesplitofffloat -\setfalse\somenextsplitofffloat +\installcorenamespace{floatsplitting} -\newconditional\splitfloatdone - -\newif\ifinsidesplitfloat % will become chardef +\installdirectcommandhandler \??floatsplitting {floatsplitting} % \??floatsplitting -\newtoks\everysplitfloatsetup +\setupfloatsplitting + [\c!conversion=\v!character, % \v!romannumerals + \c!lines=3, + \c!before=, + \c!inbetween=\page, + \c!after=] -\def\extrasplitfloatlines{0} +\newconditional\splitfloatfirstdone +\newconditional\somenextsplitofffloat +\newconditional\splitfloatdone +\newconditional\onlyonesplitofffloat \settrue\onlyonesplitofffloat -\let\splitfloatfinalizer\relax +\newif \ifinsidesplitfloat % will become conditional -\ifx\floatcaptionsuffix\undefined \else - \let\floatcaptionsuffix\empty % will become \splitfloatcaptionsuffix -\fi +\newcount \noffloatssplits +\newtoks \everysplitfloatsetup -\unexpanded\def\setupfloatsplitting - {\dodoubleargument\getparameters[\??si]} +\let \extrasplitfloatlines \!!zerocount +\let \splitfloatfinalizer \relax +\let \floatcaptionsuffix \empty \unexpanded\def\splitfloat - {\dosingleempty\dosplitfloat} + {\dosingleempty\page_split_float} -\def\dosplitfloat[#1]#2% nog dubbele refs +\def\page_split_float[#1]#2% nog dubbele refs {\bgroup \global\setfalse\splitfloatdone - \aftergroup\checksplitfloat + \aftergroup\page_split_float_check \insidefloattrue \insidesplitfloattrue - \getparameters[\??si][#1]% + \setupcurrentfloatsplitting[#1]% \global\noffloatssplits\zerocount - \def\floatcaptionsuffix{\convertnumber\@@siconversion\noffloatssplits}% - \let\extrasplitfloatlines\@@silines + \let\floatcaptionsuffix\page_split_float_suffix + \edef\extrasplitfloatlines{\floatsplittingparameter\c!lines}% \the\everysplitfloatsetup \def\splitfloatcommand{#2}% \global\settrue \onlyonesplitofffloat \global\setfalse\somenextsplitofffloat - \dopushsavedfloats - \@@sibefore + \page_floats_push_saved + \floatsplittingparameter\c!before \let\next} % \bgroup -\unexpanded\def\checksplitfloat +\unexpanded\def\page_split_float_suffix + {\begingroup + \usefloatsplittingstyleandcolor\c!style\c!color % only the suffix + \convertnumber{\floatsplittingparameter\c!conversion}\noffloatssplits + \endgroup} + +\unexpanded\def\page_split_float_check {\ifconditional\splitfloatdone \splitfloatfinalizer % a weird place (could interfere with flushing) \else - \blank{\tttf \getmessage\m!floatblocks{13}\empty}\blank + \blank + \begingroup + \tttf \dontleavehmode \getmessage\m!floatblocks{13}\empty + \endgroup + \blank \showmessage\m!floatblocks{13}\empty \fi} -\def\dodowithsplitofffloat - {\dowithnextboxcs\dodowithsplitofffloatfinish\vbox} +\def\page_split_float_process % nextbox + {\ifinsidesplitfloat + \expandafter\page_split_float_process_yes + \else + \expandafter\page_split_float_process_nop + \fi} + +\def\page_split_float_process_yes + {\dowithnextboxcs\page_split_float_process_finish\vbox} -\def\dodowithsplitofffloatfinish +\def\page_split_float_process_finish {\forgetall \dontcomplain \global\settrue\splitfloatdone @@ -127,26 +148,29 @@ \splitfloatcommand{\box\nextbox}% \egroup \ifconditional\somenextsplitofffloat - \doifelsenothing\@@siinbetween - {\ifconditional\splitfloatfirstdone\else\page\fi} - \@@siinbetween + \edef\p_inbetween{\floatsplittingparameter\c!inbetween}% + \ifx\p_inbetween\empty + \ifconditional\splitfloatfirstdone\else\page\fi + \else + \p_inbetween + \fi \else - \@@siafter - \dopopsavedfloats - \doflushsavedfloats + \floatsplittingparameter\c!after + \page_floats_pop_saved + \page_floats_flush_saved \fi \global\settrue\splitfloatfirstdone} -\def\nodowithsplitofffloat - {\dowithnextboxcs\nodowithsplitofffloatfinish\vbox} +\def\page_split_float_process_nop + {\dowithnextboxcs\page_split_float_process_nop_finish\vbox} -\def\nodowithsplitofffloatfinish +\def\page_split_float_process_nop_finish {\forgetall \dontcomplain \box\nextbox % maybe an option to unvbox \global\settrue\splitfloatfirstdone} -\def\dochecksplitofffloat#1% box +\def\page_split_float_check_content#1% box {\ifinsidesplitfloat % \ifdim\ht#1=\zeropoint % funny: \ifcase does not check for overflow \ifcase\ht#1\relax @@ -157,7 +181,7 @@ \fi \fi} -\def\analyzesplitfloatcaption#1% depends on page-flt .. pretty messy +\def\page_split_float_check_caption#1% depends on page-flt .. pretty messy {\edef\extrasplitfloatlines{\extrasplitfloatlines}% \ifx\extrasplitfloatlines\v!auto \bgroup @@ -174,27 +198,15 @@ \doifnumberelse\extrasplitfloatlines\donothing{\def\extrasplitfloatlines{1}}% \fi} -\def\dowithsplitofffloat % nextbox +\unexpanded\def\doifnotinsidesplitfloat {\ifinsidesplitfloat - \expandafter\dodowithsplitofffloat - \else - \expandafter\nodowithsplitofffloat + \expandafter\gobbleoneargument \fi} -\def\doifnotinsidesplitfloat - {\ifinsidesplitfloat\expandafter\gobbleoneargument\fi} - -%D Some defaults: - -\setupfloatsplitting - [\c!conversion=\v!character, % \v!romannumerals - \c!lines=3, - \c!before=, - \c!inbetween=\page, - \c!after=] - %D Table splitter, on top of previous code: +% todo: keep tail to rest, so we need a lookahead + \newbox\tsplitcontent \newbox\tsplitresult \newbox\tsplithead @@ -203,198 +215,216 @@ \newtoks\everyresettsplit -\def\resettsplit{\the\everyresettsplit} - \appendtoks - \def\tsplitminimumfreelines{0}% - \def\tsplitminimumfreespace{0pt}% - \setbox\tsplitcontent\emptyvbox - \setbox\tsplitresult \emptyvbox - \setbox\tsplithead \emptyvbox - \setbox\tsplitnext \emptyvbox - \setbox\tsplittail \emptyvbox - \let\tsplitbeforeresult\donothing - \let\tsplitafterresult \donothing - \let\tsplitinbetween \donothing - \let\tsplitbefore \donothing - \let\tsplitafter \donothing - \let\postprocesstsplit \donothing + \let \tsplitminimumfreelines\!!zerocount + \let \tsplitminimumfreespace\!!zeropoint + \setbox\tsplitcontent \emptyvbox + \setbox\tsplitresult \emptyvbox + \setbox\tsplithead \emptyvbox + \setbox\tsplitnext \emptyvbox + \setbox\tsplittail \emptyvbox + \let \tsplitbeforeresult \donothing + \let \tsplitafterresult \donothing + \let \tsplitinbetween \donothing + \let \tsplitbefore \donothing + \let \tsplitafter \donothing + \let \postprocesstsplit \donothing \to \everyresettsplit +\unexpanded\def\resettsplit + {\the\everyresettsplit} + \resettsplit -% todo: keep tail to rest, so we need a lookahead +\def\tsplitdirectwidth{\hsize} -\newconditional\splitfloatfirstdone +\newconditional\c_tabl_split_done +\newconditional\c_tabl_split_head +\newconditional\c_tabl_split_full -\def\handletsplit - {\analyzesplitfloatcaption{\wd\tsplitcontent}% +\newdimen \d_tabl_split_available + +\unexpanded\def\handletsplit + {\page_split_float_check_caption{\wd\tsplitcontent}% \global\setfalse\splitfloatfirstdone \testpagesync % new, sync, but still tricky [\tsplitminimumfreelines] [\dimexpr\tsplitminimumfreespace+\extrasplitfloatlines\lineheight\relax]% \setbox\scratchbox\vbox{\tsplitinbetween}% \edef\tsplitinbetweenheight{\the\htdp\scratchbox}% etex - \!!doneafalse - \doloop - {\ifinsidecolumns - % brrr, assumes empty columns - \global\setfalse\splitfloatfirstdone - \scratchdimen\textheight - \!!donectrue - \else - \ifconditional\splitfloatfirstdone - \scratchdimen\textheight - \!!donectrue - \else\ifdim\pagegoal<\maxdimen - \scratchdimen\dimexpr\pagegoal-\pagetotal\relax - \!!donecfalse - \else - \scratchdimen\textheight - \!!donectrue - \fi\fi - \fi - \scratchdimen\dimexpr\scratchdimen-\tsplitinbetweenheight-\tsplitminimumfreespace-\extrasplitfloatlines\lineheight\relax - \ifdim\htdp\tsplittail>\zeropoint - \advance\scratchdimen-\htdp\tsplittail - \fi - \setbox\tsplitresult\vbox - {\ifdim\ht\tsplithead>\zeropoint - \unvcopy\tsplithead + \setfalse\c_tabl_split_done + \doloop\tabl_split_loop_body + \global\setfalse\usesamefloatnumber % new, prevent next increment + \global\setfalse\splitfloatfirstdone} % we can use this one for tests + +\def\tabl_split_loop_body + {\ifinsidecolumns + % brrr, assumes empty columns + \global\setfalse\splitfloatfirstdone + \d_tabl_split_available\textheight + \settrue\c_tabl_split_full + \else + \ifconditional\splitfloatfirstdone + \d_tabl_split_available\textheight + \settrue\c_tabl_split_full + \else\ifdim\pagegoal<\maxdimen + \d_tabl_split_available\dimexpr\pagegoal-\pagetotal\relax + \setfalse\c_tabl_split_full + \else + \d_tabl_split_available\textheight + \settrue\c_tabl_split_full + \fi\fi + \fi + \d_tabl_split_available \dimexpr + \d_tabl_split_available + -\tsplitinbetweenheight + -\tsplitminimumfreespace + -\extrasplitfloatlines\lineheight + \relax + \ifdim\htdp\tsplittail>\zeropoint + \advance\d_tabl_split_available-\htdp\tsplittail + \fi + \setbox\tsplitresult\vbox + {\ifdim\ht\tsplithead>\zeropoint + \unvcopy\tsplithead + \tsplitinbetween + \fi}% + \ifconditional\c_tabl_split_done \else + \ifdim\ht\tsplitnext>\zeropoint + \setbox\tsplithead\box\tsplitnext + \fi + \fi + \settrue\c_tabl_split_done + \ifdim\ht\tsplitresult>\zeropoint + \settrue\c_tabl_split_head % table head + \else + \setfalse\c_tabl_split_head % no tablehead + \fi + \splittopskip\zeropoint + \doloop % inner loop + {\setbox\scratchbox\vsplit\tsplitcontent to \onepoint % \lineheight + \setbox\scratchbox\vbox{\unvbox\scratchbox}% + \ifdim\dimexpr\d_tabl_split_available-\htdp\scratchbox-\htdp\tsplitresult\relax>\zeropoint + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult \tsplitinbetween - \fi}% - \if!!donea\else\ifdim\ht\tsplitnext>\zeropoint - \setbox\tsplithead\box\tsplitnext - \fi\fi - \!!doneatrue - \ifdim\ht\tsplitresult>\zeropoint - \!!donedtrue % table head - \else - \!!donedfalse % no tablehead - \fi - \splittopskip\zeropoint - \doloop - {\setbox\scratchbox\vsplit\tsplitcontent to \onepoint % \lineheight - \setbox\scratchbox\vbox{\unvbox\scratchbox}% - \ifdim\dimexpr\scratchdimen-\htdp\scratchbox-\htdp\tsplitresult\relax>\zeropoint - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvbox\scratchbox}% - \ifvoid\tsplitcontent \exitloop \fi - \else\if!!doned - % we only have a tablehead so far - \setbox\tsplitresult\vbox{\unvbox\tsplitresult\unvbox\scratchbox}% - \exitloop - \else\if!!donec - % we have text height available, but the (one) cell is too - % large to fit, so, in order to avoid loops/deadcycles we do: - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvbox\scratchbox}% - \exitloop - \else - \setbox\tsplitcontent\vbox - {\unvbox\scratchbox - \tsplitinbetween - \ifvoid\tsplitcontent\else\unvbox\tsplitcontent\fi}% - \exitloop - \fi\fi\fi - \!!donedfalse - \!!donecfalse}% - \postprocesstsplit - \dochecksplitofffloat\tsplitcontent - \ifvoid\tsplitcontent + \unvbox\scratchbox}% + \ifvoid\tsplitcontent \exitloop \fi + \else\ifconditional\c_tabl_split_head + % we only have a tablehead so far + \setbox\tsplitresult\vbox{\unvbox\tsplitresult\unvbox\scratchbox}% + \exitloop + \else\ifconditional\c_tabl_split_full + % we have text height available, but the (one) cell is too + % large to fit, so, in order to avoid loops/deadcycles we do: \setbox\tsplitresult\vbox {\unvbox\tsplitresult \tsplitinbetween - \unvcopy\tsplittail}% - \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% - \doifnotinsidesplitfloat\tsplitafter - \endgraf + \unvbox\scratchbox}% \exitloop \else - % hack - \ifdim\pagegoal<\maxdimen - \global\pagegoal\dimexpr\pagegoal+\lineheight\relax % etex - \fi - % brrr - \ifdim\ht\tsplitresult>\zeropoint - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvcopy\tsplittail}% - \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% - \doifnotinsidesplitfloat\tsplitafter - \endgraf - \fi - \ifinsidecolumns - \goodbreak % was \doifnotinsidesplitfloat\goodbreak - \else - \page % was \doifnotinsidesplitfloat\page - \fi - \global\settrue\usesamefloatnumber % new, prevent next increment - \fi}% - \global\setfalse\usesamefloatnumber % new, prevent next increment - \global\setfalse\splitfloatfirstdone} % we can use this one for tests + \setbox\tsplitcontent\vbox + {\unvbox\scratchbox + \tsplitinbetween + \ifvoid\tsplitcontent\else\unvbox\tsplitcontent\fi}% + \exitloop + \fi\fi\fi + \setfalse\c_tabl_split_head + \setfalse\c_tabl_split_full}% + \postprocesstsplit + \page_split_float_check_content\tsplitcontent + \ifvoid\tsplitcontent + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvcopy\tsplittail}% + \page_split_float_process{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% + \doifnotinsidesplitfloat\tsplitafter + \endgraf + \exitloop + \else + % hack + \ifdim\pagegoal<\maxdimen + \pagegoal\dimexpr\pagegoal+\lineheight\relax % etex + \fi + % brrr + \ifdim\ht\tsplitresult>\zeropoint + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvcopy\tsplittail}% + \page_split_float_process{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% + \doifnotinsidesplitfloat\tsplitafter + \endgraf + \fi + \ifinsidecolumns + \goodbreak % was \doifnotinsidesplitfloat\goodbreak + \else + \page % was \doifnotinsidesplitfloat\page + \fi + \global\settrue\usesamefloatnumber % new, prevent next increment + \fi} %D The next one assumes that the split takes place elsewhere. This is %D used in xtables. \let\resetdirecttsplit\resettsplit -\def\tsplitdirectwidth{\hsize} - -\def\handledirecttsplit - {\analyzesplitfloatcaption{\tsplitdirectwidth}% +\unexpanded\def\handledirecttsplit + {\page_split_float_check_caption{\tsplitdirectwidth}% \global\setfalse\splitfloatfirstdone \testpagesync % new, sync, but still tricky [\tsplitminimumfreelines] [\dimexpr\tsplitminimumfreespace+\extrasplitfloatlines\lineheight\relax]% - \doloop - {\ifinsidecolumns - \global\setfalse\splitfloatfirstdone - \scratchdimen\textheight - \else\ifconditional\splitfloatfirstdone - \scratchdimen\textheight - \else\ifdim\pagegoal<\maxdimen - \scratchdimen\dimexpr\pagegoal-\pagetotal\relax - \else - \scratchdimen\textheight - \fi\fi\fi - \scratchdimen\dimexpr\scratchdimen-\tsplitminimumfreespace-\extrasplitfloatlines\lineheight\relax - \tsplitdirectsplitter\scratchdimen % also sets state - \ifdim\ht\tsplitresult>\zeropoint - \ifconditional\somenextsplitofffloat - \global\setfalse\onlyonesplitofffloat - \fi - \ifdim\pagegoal<\maxdimen - \global\pagegoal\dimexpr\pagegoal+\lineheight\relax % etex - \fi - \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% - \global\settrue\usesamefloatnumber % new, prevent next increment - \endgraf - \ifconditional\somenextsplitofffloat - \ifinsidecolumns - \goodbreak - \else - \page - \fi - \fi - \global\settrue\splitfloatfirstdone - \else\ifconditional\somenextsplitofffloat - \ifinsidecolumns - \goodbreak - \else - \page % no room - \fi - \else - \exitloop - \fi\fi}% - \global\setfalse\usesamefloatnumber % new, prevent next increment + \doloop\tabl_split_direct_loop_body + \global\setfalse\usesamefloatnumber % new, prevent next increment \global\setfalse\splitfloatfirstdone} % we can use this one for tests +\def\tabl_split_direct_loop_body + {\ifinsidecolumns + \global\setfalse\splitfloatfirstdone + \d_tabl_split_available\textheight + \else\ifconditional\splitfloatfirstdone + \d_tabl_split_available\textheight + \else\ifdim\pagegoal<\maxdimen + \d_tabl_split_available\dimexpr\pagegoal-\pagetotal\relax + \else + \d_tabl_split_available\textheight + \fi\fi\fi + \d_tabl_split_available\dimexpr + \d_tabl_split_available + -\tsplitminimumfreespace + -\extrasplitfloatlines\lineheight + \relax + \tsplitdirectsplitter\d_tabl_split_available % also sets state + \ifdim\ht\tsplitresult>\zeropoint + \ifconditional\somenextsplitofffloat + \global\setfalse\onlyonesplitofffloat + \fi + \ifdim\pagegoal<\maxdimen + \pagegoal\dimexpr\pagegoal+\lineheight\relax % etex + \fi + \page_split_float_process{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% + \global\settrue\usesamefloatnumber % new, prevent next increment + \endgraf + \ifconditional\somenextsplitofffloat + \ifinsidecolumns + \goodbreak + \else + \page + \fi + \fi + \global\settrue\splitfloatfirstdone + \else\ifconditional\somenextsplitofffloat + \ifinsidecolumns + \goodbreak + \else + \page % no room + \fi + \else + \exitloop + \fi\fi} + \protect \endinput % test cases |