summaryrefslogtreecommitdiff
path: root/tex/context/base/tabl-tsp.tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/tabl-tsp.tex')
-rw-r--r--tex/context/base/tabl-tsp.tex427
1 files changed, 427 insertions, 0 deletions
diff --git a/tex/context/base/tabl-tsp.tex b/tex/context/base/tabl-tsp.tex
new file mode 100644
index 000000000..49bb7ad90
--- /dev/null
+++ b/tex/context/base/tabl-tsp.tex
@@ -0,0 +1,427 @@
+%D \module
+%D [ file=tabl-tsp,
+%D version=2000.10.20,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Splitting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Table Macros / Splitting}
+
+%D The code in this file is move here from other places.
+
+\unprotect
+
+% only to be used with single tokens (will be prim)
+
+\ifx\htdp\undefined \def\htdp#1{\dimexpr\ht#1+\dp#1\relax} \fi
+
+%D Although the name resembles floats, and therefore this should be
+%D a page module, we decided to make it core functionality because the
+%D table code depends on it. Othrwise there would be too much
+%D overloading afterwards involved. Actually, the float part is rather
+%D generic and not that related to floats.
+
+% \splitfloat [settings] {\placetable[optional args]{test}} {content}
+
+\definenumber
+ [\??si]
+ [\c!way=\v!by\v!text,
+ \c!conversion=\@@siconversion]
+
+\def\setupfloatsplitting
+ {\dodoubleargument\getparameters[\??si]}
+
+\newif\ifinsidesplitfloat % will become chardef
+
+\newtoks \everysplitfloatsetup
+
+\def\splitfloat
+ {\dosingleempty\dosplitfloat}
+
+\ifx\floatcaptionsuffix\undefined \else
+ \let\floatcaptionsuffix\empty % will become \splitfloatcaptionsuffix
+\fi
+
+\def\extrasplitfloatlines{0}
+
+\def\dosplitfloat[#1]#2% nog dubbele refs
+ {\bgroup
+ \global\setfalse\splitfloatdone
+ \aftergroup\checksplitfloat
+ \insidefloattrue
+ \insidesplitfloattrue
+ \getparameters[\??si][#1]%
+ \resetnumber[\??si]%
+ \def\floatcaptionsuffix{\convertednumber[\??si]}%
+ \let\extrasplitfloatlines\@@silines
+ \the\everysplitfloatsetup
+ \def\splitfloatcommand{#2}%
+ \global\settrue \onlyonesplitofffloat
+ \global\setfalse\somenextplitofffloat
+ \dopushsavedfloats
+ \@@sibefore
+ \let\next} % \bgroup
+
+\def\checksplitfloat
+ {\ifconditional\splitfloatdone\else
+ \blank{\tttf \getmessage\m!floatblocks{13}\empty}\blank
+ \showmessage\m!floatblocks{13}\empty
+ \fi}
+
+\settrue \onlyonesplitofffloat
+\setfalse\somenextplitofffloat
+
+%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.
+%D
+%D \starttyping
+%D \dorecurse{2}{\input tufte }
+%D
+%D \splitfloat[lines=auto,inbetween=]
+%D {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}}
+%D {\bTABLE[split=yes]
+%D \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 14 \eTD \bTD test \eTD \eTR
+%D \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 24 \eTD \bTD test \eTD \eTR
+%D \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR
+%D \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR
+%D \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR
+%D \bTR \bTD 34 \eTD \bTD test \eTD \eTR
+%D \eTABLE}
+%D
+%D \dorecurse{10}{\input tufte }
+%D \stoptyping
+
+\newconditional\splitfloatdone
+
+\def\dodowithsplitofffloat
+ {\dowithnextbox
+ {\forgetall
+ \dontcomplain
+ \global\settrue\splitfloatdone
+ \chardef\nodelocationmode\zerocount % bypass auto-renumbering
+ \incrementnumber[\??si]%
+ \ifcase\rawnumber[\??si]\or \ifconditional\onlyonesplitofffloat
+ \let\floatcaptionsuffix\empty
+ \fi \fi
+ \bgroup
+ \ifconditional\somenextplitofffloat
+ \settrue\retainfloatnumber
+\notesenabledfalse % best here, experimental, brrr; test with note in caption
+ \else
+ \setfalse\retainfloatnumber
+ \fi
+ \splitfloatcommand{\box\nextbox}%
+ \egroup
+ \ifconditional\somenextplitofffloat
+ \doifelsenothing\@@siinbetween
+ {\ifconditional\splitfloatfirstdone\else\page\fi}
+ \@@siinbetween
+ \else
+ \@@siafter
+ \dopopsavedfloats
+ \doflushsavedfloats
+ \fi
+ \global\settrue\splitfloatfirstdone}%
+ \vbox}
+
+\def\nodowithsplitofffloat
+ {\dowithnextbox
+ {\forgetall
+ \dontcomplain
+ \box\nextbox % maybe an option to unvbox
+ \global\settrue\splitfloatfirstdone}%
+ \vbox}
+
+\def\dochecksplitofffloat#1% box
+ {\ifinsidesplitfloat
+ \ifdim\ht#1=\zeropoint
+ \global\setfalse\somenextplitofffloat
+ \else
+ \global\settrue \somenextplitofffloat
+ \global\setfalse\onlyonesplitofffloat
+ \fi
+ \fi}
+
+\def\analyzesplitfloatcaption#1% depends on page-flt
+ {\doif\extrasplitfloatlines\v!auto
+ {\bgroup
+ \settrue\retainfloatnumber
+ \chardef\nodelocationmode\zerocount
+ \forcelocalfloats
+ \setuplocalfloats[\c!before=,\c!after=,\c!inbetween=]%
+ \splitfloatcommand{\hbox to \wd#1{\strut}}% dummy line
+ \setbox\scratchbox\vbox{\flushlocalfloats}%
+ \getnoflines{\ht\scratchbox}%
+ \resetlocalfloats
+ \advance\noflines\minusone % compensate dummy line
+ \expanded{\egroup\noexpand\edef\noexpand\extrasplitfloatlines{\the\noflines}}}}
+
+% \def\analyzesplitfloatcaption#1%
+% {\edef\extrasplitfloatlines{11}}
+
+\def\dowithsplitofffloat % nextbox
+ {\ifinsidesplitfloat
+ \expandafter\dodowithsplitofffloat
+ \else
+ \expandafter\nodowithsplitofffloat
+ \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:
+
+\newbox\tsplitcontent
+\newbox\tsplitresult
+\newbox\tsplithead
+\newbox\tsplitnext
+\newbox\tsplittail
+
+\def\resettsplit{% only \def's starting a a new line are seen by the dep checker
+ \def\tsplitminimumfreelines{0}%
+ \def\tsplitminimumfreespace{0pt}%
+ \setbox\tsplitcontent \vbox{}%
+ \setbox\tsplitresult \vbox{}%
+ \setbox\tsplithead \vbox{}%
+ \setbox\tsplitnext \vbox{}%
+ \setbox\tsplittail \vbox{}%
+ \let\tsplitbeforeresult\donothing
+ \let\tsplitafterresult \donothing
+ \let\tsplitinbetween \donothing
+ \let\tsplitbefore \donothing
+ \let\tsplitafter \donothing
+ \let\postprocesstsplit \donothing
+}
+
+\resettsplit
+
+% todo: keep tail to rest, so we need a lookahead
+
+\newconditional\splitfloatfirstdone
+
+\def\handletsplit
+ {\analyzesplitfloatcaption\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
+ \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
+ \setbox\tsplitresult\vbox
+ {\unvbox\tsplitresult
+ \tsplitinbetween
+ \unvcopy\tsplittail}%
+ \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}%
+ \doifnotinsidesplitfloat\tsplitafter
+ \endgraf
+ \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
+ \doifnotinsidesplitfloat\goodbreak
+ \else
+ \doifnotinsidesplitfloat\page
+ \fi
+ \fi}%
+ \global\setfalse\splitfloatfirstdone} % we can use this one for tests
+
+\protect \endinput
+
+% test cases
+
+% \setupTABLE[split=repeat]
+%
+% \input tufte \endgraf
+% \splitfloat[lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE}
+% \input tufte \endgraf \page
+%
+% \input tufte \endgraf
+% \bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE
+% \input tufte \page
+
+% \setuptabulate[split=yes]
+%
+% \input tufte \endgraf
+% \splitfloat[lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate
+% \input tufte \page
+
+% \setuptables[split=yes]
+%
+% \newtoks\TestToks
+%
+% \TestToks\emptytoks
+% \appendtoks\starttablehead\to\TestToks
+% \dorecurse{3}{\appendtoks\VL head \VL head \VL \SR\to\TestToks}
+% \appendtoks\stoptablehead\to\TestToks
+% \appendtoks\starttabletail\to\TestToks
+% \dorecurse{3}{\appendtoks\VL tail \VL tail \VL \SR\to\TestToks}
+% \appendtoks\stoptabletail\to\TestToks
+% \appendtoks\starttables[|c|c|]\to\TestToks
+% \dorecurse{100}{\appendtoks\VL test \VL test \VL \SR\to\TestToks}
+% \appendtoks\stoptables\to\TestToks
+%
+% \input tufte \endgraf
+% \splitfloat[lines=auto] % [lines=11]
+% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}}
+% {\the\TestToks}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \splitfloat[lines=0]
+% {}
+% {\the\TestToks}
+% \input tufte \page
+%
+% \input tufte \endgraf
+% \the\TestToks
+% \input tufte \page
+%
+% multiple floats
+%
+% \starttext
+% \dorecurse{3}{\input tufte } \endgraf
+% \dorecurse{5}{\placefigure{}{\framed[height=.5\textheight]{}}}
+% \splitfloat[lines=auto,inbetween=]
+% {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}}
+% {\bTABLE[split=yes]
+% \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 14 \eTD \bTD test \eTD \eTR
+% \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 24 \eTD \bTD test \eTD \eTR
+% \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR
+% \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR
+% \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR
+% \bTR \bTD 34 \eTD \bTD test \eTD \eTR
+% \eTABLE}
+% \dorecurse{10}{\input tufte }
+% \stoptext