%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Module: ZzTeX New Tabular Facilities % % Synopsis: This module contains all the facilities for producing % tabular material. This is the second major version. % % Author: Paul C. Anagnostopoulos % Created: 30 April 2001 % % 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 % \belowpenalty = integer % \belowskip = glue % \bodyfont = {...} % \columngutter = glue % \colheadaboveskip = glue % \colheadbelowskip = glue % \colheadfont = {...} % \cutinheadfont = {...} % \setflag \hastoprule = \false % \interrowskip = glue % \leftindent = glue % \parhang = dimen % \parrag = dimen % \rightindent = glue % \rulecolwidth = dimen % \sectionheadaboveskip = glue % \sectionheadbelowskip = glue % \sideheadfont = {...} % \spannerheadfont = {...} % \spannerruleaboveskip = dimen % \spannerrulebelowskip = dimen % \spannerrulecolor = {color} % \spannerruleheight = dimen % \style = {...} % \tabbottomruleaboveskip = dimen % \tabheadrulebelowskip = dimen % \def \tabnoteformat ##1{...} % \tabrulecolor = {color} % \tabruleheight = dimen % \width = dimen %~end \defineskip{\colheadaboveskip}{0pt} %%%\defineskip{\colheadbelowskip}{0pt} %%%\definetoks{\colheadfont} \definetoks{\cutinheadfont} %%%\definedimen{\rulecolwidth}{0pt} \defineskip{\sectionheadaboveskip}{0pt} \defineskip{\sectionheadbelowskip}{0pt} %%%\definetoks{\sideheadfont} %%%\definetoks{\spannerheadfont} %%%\defineskip{\spannerruleaboveskip}{0pt} %%%\defineskip{\spannerrulebelowskip}{0pt} %%%\definetoks{\spannerrulecolor} %%%\definedimen{\spannerruleheight}{0pt} %%%\definedimen{\tabbottomruleaboveskip}{0pt} %%%\definedimen{\tabheadrulebelowskip}{0pt} %%%\definetoks{\tabrulecolor} %%%\definedimen{\tabruleheight}{0pt} %%%\definecount{\tabcolcount}{0} % Number of columns in table. \definetoks{\ztabspacetoks} % Special row for vertical spacing. %%%\definebox{\zrowstrut} % Strut for table rows. %%%\definebox{\zparcelltopstrut} % Strut for first line of par cell. %%%\definebox{\zparcellbotstrut} % Strut for last line of par cell. \def \tabular #1#2{% {type}{template} \endgraf \beginblockscope{tabular}% \global\increment \tabulardepth \abovepenalty = \breakgood %~default hard \belowpenalty = \breakbetter %~default hard \setflag \hastoprule = \false %~default soft \parhang = 0pt %~default soft \spannerrulecolor = {black}% %~default soft \style = {top/head/bottom rules}% %~default soft \tabrulecolor = {black}% %~default soft \processdesign{\tabular}{#1}% \global\increment \tabularnumber \iffalse{\fi % Analyze the template with \tabcolcount = 0 % master counter > 0 to hide \ztabspacetoks = {}% % \set and &. \zchecktabcols #2&\zmark \let \set = \span \iffalse}\fi \tabularformat \offinterlineskip \everycr = {}% \defineatsigncommand @A{\adjustcolrule}% \defineatsigncommand @C{\nointerrowskip}% \defineatsigncommand @N{\nocolrule}% \defineatsigncommand @S{\skipabovespannerrule}% \defineatsigncommand @T{\skipbelowspannerrule}% \tabskip = \leftskip \halign \if \dimneqlp{\width}{\naturalwidth}to \width \fi \bgroup #2\tabskip = \rightskip\cr} \def \endtabular {% \egroup % \halign \if \posp{\prevdepth}% % Does the last line have a strut? \kern -.5\interrowskip % To eliminate row strut depth. \prevdepth = \dp\strutbox \else \prevdepth = \tabruleheight \fi \futurelet\nexttoken \zendtabular} \def \zendtabular {% \endtabularformat \global\decrement \tabulardepth \endblockscope{tabular}% \parnext} \def \tabularformat {% \the\bodyfont \calculate \tdimena = {\interrowskip,/,2,+,\ht\strutbox}% \calculate \tdimenb = {\interrowskip,/,2,+,\dp\strutbox}% \setbox \zrowstrut = \hbox{\vrule width 0pt height \tdimena depth \tdimenb}% \setbox \zparcelltopstrut = \hbox{\vrule width 0pt height \tdimena depth 0pt}% \setbox \zparcellbotstrut = \hbox{\vrule width 0pt height 0pt depth \tdimenb}% \bbskipabove{\abovepenalty}{\aboveskip}% \fakepar % This fakes an empty paragraph \hbox{}% % so the \bbskipabove works. \nobreak \vskip \if \hastoprule -\tabruleheight \else -\ht\zrowstrut \fi \alterindentation{\leftindent}{\rightindent}} \def \endtabularformat{% \bbskipbelowblockpar{\nexttoken}{\belowpenalty}{\belowskip}} \def \zchecktabcols #1#2#3\zmark{% \if \notp{\tokeqlp{#1}{\set}}% \error{misset}{A tabular column template must begin with \string\set}% \fi \if \posp{\tabcolcount}% \ztabspacetoks = \expandafter{\the\ztabspacetoks &}% \fi \if \notp{\tokeqlp{#2}{\rulecol}}% \ztabspacetoks = \expandafter{\the\ztabspacetoks \omit \ztabspacestrut}% \fi \increment \tabcolcount \if \notp{\emptyargp{#4}}\zchecktabcols #4\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 \gutter = \tabskip \def \customcol #1{% {template} #1\rowstrut \tabskip=\columngutter} \def \customrulecol #1#2{% {color}{width} \color{#1}% \vrule width #2 ##% \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}% \unhcopy \zparcelltopstrut ##% \if \hmodep \unhcopy \zparcellbotstrut \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 \cutinhead #1{% {heading} \skipabovetabsection \multispan{\tabcolcount}% \leftcell{\the\cutinheadfont #1}\cr \skipbelowtabsection} \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 \multispan #1{% {columns} \omit \tcounta = #1% \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 \parcell #1#2{% {width}{text} \omit \vtop{\zpushvcontext \zinitparcell{#1}{\parhang}% \unhcopy \zparcelltopstrut #2% \if \hmodep \unhcopy \zparcellbotstrut \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 \rowstrut {% \unhcopy \zrowstrut} \def \sidehead #1{% {heading} \leftcell{\the\sideheadfont #1}} \def \spannerhead #1#2{% {columns}{heading} \multispan{#1}% \centercell{\the\spannerheadfont #2}} \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} % Rule Facilities % ---- ---------- \def \adjustcolrule #1,#2,#3;{% width,height,depth; \if \notp{\emptyargp{#1}}width #1pt\fi \if \notp{\emptyargp{#2}}height #2pt\fi \if \notp{\emptyargp{#3}}depth #3pt\fi\relax} \def \custompartialtabrule #1#2#3{% {color}{thickness}{columns} \multispan{#3}% \color{#1}% \ruleleaders{\hrule height #2 depth 0pt}% \endcolor} \def \customspannerrule #1#2#3{% {color}{thickness}{columns} \multispan{#3}% \rowstrut \color{#1}% \ruleleaders{\hrule height #2 depth 0pt}% \endcolor} \def \customtabrule #1#2{% {color}{thickness} \multispan{\tabcolcount}% \color{#1}% \ruleleaders{\hrule height #2 depth 0pt}% \endcolor\cr} \def \nocolrule {% width 0pt } \def \partialtabrule #1{% {columns} \custompartialtabrule{\the\tabrulecolor}{\tabruleheight}{#1}} \def \spannerrule #1{% {columns} \customspannerrule{\the\spannerrulecolor}{\spannerruleheight}{#1}} \def \tabbottomrule {% \tabbbskipaboverule{\tabbottomruleaboveskip}% \tabrule} \def \tabheadrule {% \tabbbskipaboverule{\colheadbelowskip}% \tabrule \tabbbskipbelowrule{\tabheadrulebelowskip}} \def \tabrule {% \customtabrule{\the\tabrulecolor}{\tabruleheight}} \def \tabtoprule {% \tabrule \tabbbskipbelowrule{\colheadaboveskip}} % Spacing Facilities % ------- ---------- \definedimen{\zskipamount}{0pt} \def \nointerrowskip {% \tabvspace{-\interrowskip}} \def \skipabovecolhead {% \tabbbskip{\colheadaboveskip}} \def \skipbelowcolhead {% \tabbbskip{\colheadbelowskip}} \def \skipabovespannerrule {% \tabbbskip{\spannerruleaboveskip}} \def \skipbelowspannerrule {% \tabbbskip{\spannerrulebelowskip}} \def \skipabovetabsection {% \tabbbskip{\sectionheadaboveskip}} \def \skipbelowtabsection {% \tabbbskip{\sectionheadbelowskip}} \def \tabbbskip #1{% \noalign{% \calculate \zskipamount = {#1,-,\dp\zrowstrut,-,\ht\zrowstrut}% \ztabvspace{\zskipamount}}% \the\ztabspacetoks\cr} \def \tabbbskipaboverule #1{% \noalign{% \calculate \zskipamount = {#1,-,\dp\zrowstrut,-,\tabruleheight}% \ztabvspace{\zskipamount}}% \the\ztabspacetoks\cr} \def \tabbbskipbelowrule #1{% \noalign{% \calculate \zskipamount = {#1,-,\ht\zrowstrut,-,\tabruleheight}% \ztabvspace{\zskipamount}}% \the\ztabspacetoks\cr} \def \tabvspace #1{% \noalign{\ztabvspace{#1}}% \the\ztabspacetoks\cr} \def \ztabvspace #1{% \if \dimnegp{#1}% \vskip #1\relax \global\zskipamount = 0pt \else \global\zskipamount = #1% \fi} \def \ztabspacestrut {% \vrule width 0pt height 0pt depth \zskipamount\relax} % Inter-Row Facilities % --------- ---------- \def \adjusttab #1{% \if \notp{\vmodep}% \error{badrowcmd}{The \string\adjusttab command cannot be used in a table row}% \fi \noalign{#1}} % 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}