%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Module: ZzTeX Tabular Facilities % % Synopsis: This module contains all the facilities for producing % tabular material. % % Author: Paul C. Anagnostopoulos % Created: 1990 % % Copyright 1989--2020 by Paul C. Anagnostopoulos % under The MIT License (opensource.org/licenses/MIT) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tabular Block % ------- ----- \let \tabularcomptext = \relax \let \tabulardepth = \relax \let \tabularnumber = \relax \defineblock{\tabular}{\endtabular}{\false}{} %~obsolete-block tabular Type % \abovepenalty = integer % \aboveskip = glue % \setflag \allowbreaks = boolean % \belowpenalty = integer % \belowskip = glue % \bodyfont = {...} % \colheadaboveskip = glue % \colheadbelowskip = glue % \colheadfont = {...} % \colsubheadfont = {...} % \columngutter = glue % \cutinheadaboveskip = glue % \cutinheadbelowskip = glue % \cutinheadfont = {...} % \interrowskip = glue % \leftindent = glue % \parhang = dimen % \parrag = dimen % \rightindent = glue % \rulecolwidth = dimen % \spannerheadfont = {...} % \spannerruleaboveskip = dimen % \spannerrulebelowskip = dimen % \spannerruleheight = dimen % \def \tabnoteformat ##1{...} % \tabrulecolor = {color}% % \tabruleheight = dimen % \width = dimen %~end \defineskip{\colheadaboveskip}{0pt} \let \headaboveskip = \colheadaboveskip \let \headbelowskip = \colheadbelowskip \definetoks{\colsubheadfont} \defineskip{\cutinheadaboveskip}{0pt} \defineskip{\cutinheadbelowskip}{0pt} \definetoks{\cutinheadfont} \definecount{\tabularcolcount}{0} % Number of columns in table. \definebox{\rowstrutbox} % Strut for table rows. \def \tabular #1#2{% {type}{template} \endgraf \beginblockscope{tabular}% \global\increment \tabulardepth \abovepenalty = \breakgood %~default hard \belowpenalty = \breakbetter %~default hard \tabrulecolor = {black}% %~default soft \processdesign{\tabular}{#1}% \global\increment \tabularnumber \iffalse{\fi % Must be done with master \tabularcolcount = 0 % counter > 0, to hide inner \ztabcols #2&\zmark % \set and &. \let \set = \span \iffalse}\fi \tabularformat \fakepar \nointerlineskip % We assume this below. \if \notp{\allowbreaks}\vtop \fi \bgroup \offinterlineskip \everycr = {}% \tabskip = \leftskip \halign \if \dimneqlp{\width}{\naturalwidth}to \width \fi \bgroup #2\tabskip = \rightskip \cr} \def \endtabular {% \crcr \egroup % \halign \if \posp{\prevdepth}\kern -\interrowskip \fi % If last line has strut. \egroup % \vtop \prevdepth = \dp\strutbox % So row strut depth won't shine thru. \futurelet\nexttoken \zendtabular} \def \zendtabular {% \endtabularformat \global\decrement \tabulardepth \endblockscope{tabular}% \parnext} \def \tabularformat {% \endgraf \the\bodyfont \tdimena = \dp\strutbox \advance \tdimena by \interrowskip \setbox \rowstrutbox = \hbox{\vrule height \ht\strutbox depth \tdimena width 0pt}% \advance \aboveskip by \baselineskip % Compensate for absence \advance \aboveskip by -\prevdepth % of interlineskip above \advance \aboveskip by -\ht\rowstrutbox % first row of tabular. \bbskipabove{\abovepenalty}{\aboveskip}% \alterindentation{\leftindent}{\rightindent}} \def \endtabularformat{% \bbskipbelowblockpar{\nexttoken}{\belowpenalty}{\belowskip}} \def \ztabcols #1\zmark{% \increment \tabularcolcount \if \notp{\emptyargp{#2}}\ztabcols #2\zmark \fi} % Template Facilities % -------- ---------- % The following macros are used to construct the tabular template. % They are all used with the \set macro. \def \centercol {% \hfil ##\rowstrut \hfil \tabskip=\columngutter} \def \centernumbercol #1{% {template} \hfil \znumcell{#1}{##}\rowstrut \hfil \tabskip=\columngutter} \let \colgutter = \tabskip \def \customcol #1#2{% {left}{right} #1\relax##\rowstrut #2\relax \tabskip=\columngutter} \def \customrulecol #1{% {width} \color{\the\tabrulecolor}% \vrule width #1 ##% \endcolor \tabskip=\columngutter} \def \emptycol #1{% {width} ##\rowstrut \hspace{#1}\tabskip=\columngutter} \def \leftcol {% ##\rowstrut \hfil \tabskip=\columngutter} \def \leftnumbercol #1{% {template} \znumcell{#1}{##}\rowstrut \hfil \tabskip=\columngutter} \def \parcol #1{% {width} \vtop{\zpushvcontext \zinitparcell{#1}{\parhang}% \strut ##% \if \hmodep \rowstrut \par \fi \zpopvcontext}% \tabskip=\columngutter} \def \rightcol {% \hfil ##\rowstrut \tabskip=\columngutter} \def \rightnumbercol #1{% {template} \hfil \znumcell{#1}{##}\rowstrut \tabskip=\columngutter} \def \rulecol {% \color{\the\tabrulecolor}% \vrule width \rulecolwidth ##% \endcolor \tabskip=\columngutter} % Cell Facilities % ---- ---------- % The following macros help with tabular entries (cells). \def \0{\phantom{0}} \def \centercell #1{% {text} \omit \hfil #1\rowstrut \hfil} \def \centerhead #1{% {heading} \centercell{\the\colheadfont #1}} \def \centernumbercell #1#2{% {template}{text} \omit \hfil \znumcell{#1}{#2}\rowstrut \hfil} \def \centersubhead #1{% {heading} \centercell{\the\colsubheadfont #1}} \def \customspannerrule #1#2{% {columns}{height} \multispan{#1}% \rowstrut \ruleleaders{\hrule height #2 depth 0pt}} \def \customspannerruleabut #1#2{% {columns}{height} \multispan{#1}% \ruleleaders{\hrule height #2 depth 0pt}} \def \cutinhead #1{% {heading} \multispan{\tabularcolcount}% \leftcell{\the\cutinheadfont #1}} \def \cutinpar #1#2{% {width}{text} \multispan{\tabularcolcount}% \parhang = 0pt \parcell{#1}{#2}} \zremovePlaindef \hideskip \defineskip{\hideskip}{-1000pt plus 1fill} \def \hidewidth {\hskip \hideskip} \def \leftcell #1{% {text} \omit #1\rowstrut \hfil} \def \lefthead #1{% {heading} \leftcell{\the\colheadfont #1}} \def \leftnumbercell #1#2{% {template}{text} \omit \znumcell{#1}{#2}\rowstrut \hfil} \def \leftsubhead #1{% {heading} \leftcell{\the\colsubheadfont #1}} \def \multispan #1{% {columns} \omit \tcounta =#1\relax \loop \ifnum \tcounta > 1 \zspan \repeat \let \omit = \relax % In case the next thing is a \leftcell or whatever. \ignorespaces} \def \zspan{\span\omit \decrement \tcounta} \def \nocolrule {% width 0pt } \def \parcell #1#2{% {width}{text} \omit \vtop{\zpushvcontext \zinitparcell{#1}{\parhang}% \strut #2% \if \hmodep \rowstrut \par \fi \zpopvcontext}} \def \rightcell #1{% {text} \omit \hfil #1\rowstrut} \def \righthead #1{% {heading} \rightcell{\the\colheadfont #1}} \def \rightnumbercell #1#2{% {template}{text} \omit \hfil \znumcell{#1}{#2}\rowstrut} \def \rightsubhead #1{% {heading} \rightcell{\the\colsubheadfont #1}} \def \rowstrut {\unhcopy \rowstrutbox} \def \spannerhead #1#2{% {columns}{heading} \multispan{#1}% \centercell{\the\spannerheadfont #2}} \def \spannerrule #1{% {columns} \multispan{#1}% \rowstrut \ruleleaders{\hrule height \spannerruleheight depth 0pt}} \def \spannerruleabut #1{% {columns} \multispan{#1}% \ruleleaders{\hrule height \spannerruleheight depth 0pt}} \def \spannerruleabutbelow #1{% {columns} \multispan{#1}% \vrule height \ht\rowstrutbox depth 0pt width 0pt\relax \ruleleaders{\hrule height \spannerruleheight depth 0pt}} \def \tabnote #1{% {note-mark} {\tabnoteformat{#1}}} \def \znumcell #1#2{% {template}{text} \if \emptyargp{#2}% \relax \else \znumcella{#1}{#2}% \fi} \def \znumcella #1#2{% {template}{text} {\ztoksa = {}\ztoksb = {}% \setflag \znumpt = \false \znumcellb #1\zmark \setbox\zboxa = \hbox{\the\ztoksa}% \tdimena = \wd\zboxa \setbox\zboxa = \hbox{\the\ztoksb}% \tdimenb = \wd\zboxa \setflag \ztempt = \znumpt \ztoksa = {}\ztoksb = {}% \setflag \znumpt = \false \znumcellb #2\zmark \if \ztempt % Template had a decimal point. \if \znumpt \hbox to \tdimena{\hss \the\ztoksa}% \the\decimalpoint \hbox to \tdimenb{\the\ztoksb \hss}% \else \setbox\zboxa = \hbox{\the\decimalpoint}% \hbox to \tdimena{\hss \the\ztoksa}% \kern \wd\zboxa \kern \tdimenb \fi \else % Template had no decimal point. \if \znumpt \error{celldecpt}{Tabular template did not specify a decimal point}% \else \hbox to \tdimena{\hss \the\ztoksa}% \fi \fi}} \def \znumcellb #1#2\zmark{% t1 trest \zmark \if \codeeqlp{\noexpand#1}{\the\decimalpoint}% \setflag \znumpt = \true \else \if \znumpt \ztoksb = \expandafter{\the\ztoksb #1}% \else \ztoksa = \expandafter{\the\ztoksa #1}% \fi \fi \if \emptyargp{#2}% \let \znext = \relax \else \def \znext {\znumcellb #2\zmark}% \fi \znext} % Inter-Row Facilities % --------- ---------- % The following macros perform various actions in between rows. \def \adjusttab #1{% \if \notp{\vmodep}% \error{badrowcmd}{The \string\adjusttab command cannot be used in a table row}% \fi \noalign{#1}} \def \customtabrule #1{% {height} \multispan{\tabularcolcount}% \rowstrut \color{\the\tabrulecolor}% \ruleleaders{\hrule height #1 depth 0pt}% \endcolor \cr} \def \customtabruleabut #1{% \multispan{\tabularcolcount}% \color{\the\tabrulecolor}% \ruleleaders{\hrule height #1 depth 0pt}% \endcolor \cr} \def \customtabruleabutbelow #1{% \multispan{\tabularcolcount}% \vrule height \ht\rowstrutbox depth 0pt width 0pt\relax \color{\the\tabrulecolor}% \ruleleaders{\hrule height #1 depth 0pt}% \endcolor \cr} \def \nointerrowskip {\tabvspace{-\interrowskip}} \def \skipabovecolhead {% \tabbbskip{\colheadaboveskip}} \def \skipbelowcolhead {% \tabbbskip{\colheadbelowskip}} \def \skipabovespannerrule {% \tabbbskip{\spannerruleaboveskip}} \def \skipbelowspannerrule {% \tabbbskip{\spannerrulebelowskip}} \def \skipabovecutinhead {% \tabbbskip{\cutinheadaboveskip}} \def \skipbelowcutinhead {% \tabbbskip{\cutinheadbelowskip}} \def \tabbbskip #1{% {glue} \adjusttab{\zskipa = #1\relax \advance \zskipa by -\ht\rowstrutbox \advance \zskipa by -\dp\rowstrutbox \vskip \zskipa}} \def \tabrule {% \multispan{\tabularcolcount}% \rowstrut \color{\the\tabrulecolor}% \ruleleaders{\hrule height \tabruleheight depth 0pt}% \endcolor \cr} \def \tabruleabut {% \multispan{\tabularcolcount}% \color{\the\tabrulecolor}% \ruleleaders{\hrule height \tabruleheight depth 0pt}% \endcolor \cr} \def \tabruleabutbelow {% \multispan{\tabularcolcount}% \vrule height \ht\rowstrutbox depth 0pt width 0pt\relax \color{\the\tabrulecolor}% \ruleleaders{\hrule height \tabruleheight depth 0pt}% \endcolor \cr} \def \tabvspace #1{\adjusttab{\vskip #1}}% {glue} % Alignment Utilities % --------- --------- \let \completerow = \cr \def \ialign {\everycr = {}\tabskip = 0pt \halign} \def \oalign #1{% {row...} \ensurepar \vtop{\baselineskip = 0pt \lineskip = .25ex \ialign{##\cr #1\crcr}}} \def \ooalign {% \lineskiplimit = -\maxdimen \oalign} \def \ozalign {% \lineskiplimit = 0pt\relax \oalign} \def \zinitparcell #1#2{% {width}{hang} \baselineskip = \normalbaselineskip \lineskiplimit = 0pt \lineskip = 0pt \setindentation{0pt}{0pt}% \settextwidth{#1}% \setparrag{\parrag}% \leftskip = #2 \parindent = -#2 \parfillskip = \normalparfillskip}