summaryrefslogtreecommitdiff
path: root/tex/context/base/tabl-tsp.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/tabl-tsp.mkiv')
-rw-r--r--tex/context/base/tabl-tsp.mkiv470
1 files changed, 220 insertions, 250 deletions
diff --git a/tex/context/base/tabl-tsp.mkiv b/tex/context/base/tabl-tsp.mkiv
index 0138697af..21182a988 100644
--- a/tex/context/base/tabl-tsp.mkiv
+++ b/tex/context/base/tabl-tsp.mkiv
@@ -13,11 +13,8 @@
\writestatus{loading}{ConTeXt Table Macros / Splitting}
-%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
+%D The code in this file is move here from other places and needs
+%D a mkiv cleanup.
\unprotect
@@ -29,6 +26,8 @@
% \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.
@@ -56,81 +55,61 @@
%D \dorecurse{10}{\input tufte }
%D \stoptyping
-\installcorenamespace{floatsplitting}
+\newcount\noffloatssplits
-\installdirectcommandhandler \??floatsplitting {floatsplitting} % \??floatsplitting
+\settrue \onlyonesplitofffloat
+\setfalse\somenextsplitofffloat
-\setupfloatsplitting
- [\c!conversion=\v!character, % \v!romannumerals
- \c!lines=3,
- \c!before=,
- \c!inbetween=\page,
- \c!after=]
-
-\newconditional\splitfloatfirstdone
-\newconditional\somenextsplitofffloat
\newconditional\splitfloatdone
-\newconditional\onlyonesplitofffloat \settrue\onlyonesplitofffloat
-\newif \ifinsidesplitfloat % will become conditional
+\newif\ifinsidesplitfloat % will become chardef
+
+\newtoks\everysplitfloatsetup
-\newcount \noffloatssplits
-\newtoks \everysplitfloatsetup
+\def\extrasplitfloatlines{0}
-\let \extrasplitfloatlines \!!zerocount
-\let \splitfloatfinalizer \relax
-\let \floatcaptionsuffix \empty
+\let\splitfloatfinalizer\relax
+
+\ifx\floatcaptionsuffix\undefined \else
+ \let\floatcaptionsuffix\empty % will become \splitfloatcaptionsuffix
+\fi
+
+\unexpanded\def\setupfloatsplitting
+ {\dodoubleargument\getparameters[\??si]}
\unexpanded\def\splitfloat
- {\dosingleempty\page_split_float}
+ {\dosingleempty\dosplitfloat}
-\def\page_split_float[#1]#2% nog dubbele refs
+\def\dosplitfloat[#1]#2% nog dubbele refs
{\bgroup
\global\setfalse\splitfloatdone
- \aftergroup\page_split_float_check
+ \aftergroup\checksplitfloat
\insidefloattrue
\insidesplitfloattrue
- \setupcurrentfloatsplitting[#1]%
+ \getparameters[\??si][#1]%
\global\noffloatssplits\zerocount
- \let\floatcaptionsuffix\page_split_float_suffix
- \edef\extrasplitfloatlines{\floatsplittingparameter\c!lines}%
+ \def\floatcaptionsuffix{\convertnumber\@@siconversion\noffloatssplits}%
+ \let\extrasplitfloatlines\@@silines
\the\everysplitfloatsetup
\def\splitfloatcommand{#2}%
\global\settrue \onlyonesplitofffloat
\global\setfalse\somenextsplitofffloat
- \page_floats_push_saved
- \floatsplittingparameter\c!before
+ \dopushsavedfloats
+ \@@sibefore
\let\next} % \bgroup
-\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
+\unexpanded\def\checksplitfloat
{\ifconditional\splitfloatdone
\splitfloatfinalizer % a weird place (could interfere with flushing)
\else
- \blank
- \begingroup
- \tttf \dontleavehmode \getmessage\m!floatblocks{13}\empty
- \endgroup
- \blank
+ \blank{\tttf \getmessage\m!floatblocks{13}\empty}\blank
\showmessage\m!floatblocks{13}\empty
\fi}
-\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\dodowithsplitofffloat
+ {\dowithnextboxcs\dodowithsplitofffloatfinish\vbox}
-\def\page_split_float_process_finish
+\def\dodowithsplitofffloatfinish
{\forgetall
\dontcomplain
\global\settrue\splitfloatdone
@@ -148,29 +127,26 @@
\splitfloatcommand{\box\nextbox}%
\egroup
\ifconditional\somenextsplitofffloat
- \edef\p_inbetween{\floatsplittingparameter\c!inbetween}%
- \ifx\p_inbetween\empty
- \ifconditional\splitfloatfirstdone\else\page\fi
- \else
- \p_inbetween
- \fi
+ \doifelsenothing\@@siinbetween
+ {\ifconditional\splitfloatfirstdone\else\page\fi}
+ \@@siinbetween
\else
- \floatsplittingparameter\c!after
- \page_floats_pop_saved
- \page_floats_flush_saved
+ \@@siafter
+ \dopopsavedfloats
+ \doflushsavedfloats
\fi
\global\settrue\splitfloatfirstdone}
-\def\page_split_float_process_nop
- {\dowithnextboxcs\page_split_float_process_nop_finish\vbox}
+\def\nodowithsplitofffloat
+ {\dowithnextboxcs\nodowithsplitofffloatfinish\vbox}
-\def\page_split_float_process_nop_finish
+\def\nodowithsplitofffloatfinish
{\forgetall
\dontcomplain
\box\nextbox % maybe an option to unvbox
\global\settrue\splitfloatfirstdone}
-\def\page_split_float_check_content#1% box
+\def\dochecksplitofffloat#1% box
{\ifinsidesplitfloat
% \ifdim\ht#1=\zeropoint % funny: \ifcase does not check for overflow
\ifcase\ht#1\relax
@@ -181,7 +157,7 @@
\fi
\fi}
-\def\page_split_float_check_caption#1% depends on page-flt .. pretty messy
+\def\analyzesplitfloatcaption#1% depends on page-flt .. pretty messy
{\edef\extrasplitfloatlines{\extrasplitfloatlines}%
\ifx\extrasplitfloatlines\v!auto
\bgroup
@@ -198,14 +174,26 @@
\doifnumberelse\extrasplitfloatlines\donothing{\def\extrasplitfloatlines{1}}%
\fi}
-\unexpanded\def\doifnotinsidesplitfloat
+\def\dowithsplitofffloat % nextbox
{\ifinsidesplitfloat
- \expandafter\gobbleoneargument
+ \expandafter\dodowithsplitofffloat
+ \else
+ \expandafter\nodowithsplitofffloat
\fi}
-%D Table splitter, on top of previous code:
+\def\doifnotinsidesplitfloat
+ {\ifinsidesplitfloat\expandafter\gobbleoneargument\fi}
-% todo: keep tail to rest, so we need a lookahead
+%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:
\newbox\tsplitcontent
\newbox\tsplitresult
@@ -215,216 +203,198 @@
\newtoks\everyresettsplit
+\def\resettsplit{\the\everyresettsplit}
+
\appendtoks
- \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
+ \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
\to \everyresettsplit
-\unexpanded\def\resettsplit
- {\the\everyresettsplit}
-
\resettsplit
-\def\tsplitdirectwidth{\hsize}
-
-\newconditional\c_tabl_split_done
-\newconditional\c_tabl_split_head
-\newconditional\c_tabl_split_full
+% todo: keep tail to rest, so we need a lookahead
-\newdimen \d_tabl_split_available
+\newconditional\splitfloatfirstdone
-\unexpanded\def\handletsplit
- {\page_split_float_check_caption{\wd\tsplitcontent}%
+\def\handletsplit
+ {\analyzesplitfloatcaption{\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
- \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
+ \!!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
\tsplitinbetween
- \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:
+ \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
\setbox\tsplitresult\vbox
{\unvbox\tsplitresult
\tsplitinbetween
- \unvbox\scratchbox}%
+ \unvcopy\tsplittail}%
+ \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}%
+ \doifnotinsidesplitfloat\tsplitafter
+ \endgraf
\exitloop
\else
- \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}
+ % 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
%D The next one assumes that the split takes place elsewhere. This is
%D used in xtables.
\let\resetdirecttsplit\resettsplit
-\unexpanded\def\handledirecttsplit
- {\page_split_float_check_caption{\tsplitdirectwidth}%
+\def\tsplitdirectwidth{\hsize}
+
+\def\handledirecttsplit
+ {\analyzesplitfloatcaption{\tsplitdirectwidth}%
\global\setfalse\splitfloatfirstdone
\testpagesync % new, sync, but still tricky
[\tsplitminimumfreelines]
[\dimexpr\tsplitminimumfreespace+\extrasplitfloatlines\lineheight\relax]%
- \doloop\tabl_split_direct_loop_body
- \global\setfalse\usesamefloatnumber % new, prevent next increment
+ \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
\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