%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Module: ZzTeX Tabbing Facilities % % Synopsis: This module contains the definition of the block that is % used to format text with tab stops. % % Authors: Paul C. Anagnostopoulos % Created: 27 May 2016 % % Copyright 1989--2020 by Paul C. Anagnostopoulos % under The MIT License (opensource.org/licenses/MIT) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tabbing Block % ------- ----- \defineblock{\tabbing}{\endtabbing}{\false}{} \resetinvcontext{\tabbing} %~block tabbing Type % \abovepenalty = integer % Penalty above text. % \aboveskip = glue % Space b/b above text. % \setflag \autocallout = boolean % Automatically number lines? % \def \beginformat {...} % Beginning of text formatter. % \belowpenalty = integer % Penalty below text. % \belowskip = glue % Space b/b below text. % \bodyfont = {font} % Body font. % \def \calloutformat ##1{...} % Callout formatter. % \calloutnumber = integer % Number of first callout. % \def \callouttext {...} % Callout text or \arg. % \defaulttabwidth = dimen % Default repeating tab width. % \def \endformat {...} % End of text formatter. % \leftindent = glue % Left indentation. % \rightindent = glue % Right indentation. % \tabbinggapskip = glue % Standard tabbing gap. % \textcolor = {...} % Color of text. % \width = dimen % Line width. %~end \defineskip{\tabbinggapskip}{0pt} \def \tabbing #1{% {type} \blockcantbein{\tabbing}{\tabbing}% \beginblockscope{tabbing}% \global\increment \tabbingdepth \abovepenalty = \breakgood %~default hard \setflag \autocallout = \false %~default soft \def \beginformat {}% %~default soft \belowpenalty = \breakgood %~default hard \calloutnumber = 1 %~default with \def \callouttext {\number\calloutnumber}% %~default soft \defaulttabwidth = \mindimen %~default soft \def \endformat {}% %~default soft \tabbinggapskip = \enclosingbaselineskip %~default soft \textcolor = {}% %~default soft \parindent = 0pt \parrag = 0pt \parskip = 0pt \processdesign{\tabbing}{#1}% \global\increment \tabbingnumber \tabbingformat \def \zarg {\arg}% \if \tokeqlp{\callouttext}{\zarg}% \defineatsigncommand @##{\ztbngatcallout}% \else \defineatsigncommand @##{\ztbngatcallout{\callouttext}}% \fi \if \emptytoksp{\textcolor}% % Must have a group around \ztbnginit. \bgroup \else \color{\the\textcolor}% \fi \ztbnginit \ztbngstartline} \def \endtabbing {% \ztbngfinal \if \emptytoksp{\textcolor}% \egroup % \tabbing group \else \endcolor \fi \futurelet\nexttoken \zendtabbing} \def \zendtabbing {% \endtabbingformat \global\decrement \tabbingdepth \endblockscope{tabbing}% \parnext} \def \tabbingformat {% \endgraf \the\bodyfont \bbskipabove{\abovepenalty}{\aboveskip}% \alterindentation{\leftindent}{\rightindent}% \settextwidth{\width}% \beginformat} \def \endtabbingformat {% \endformat \bbskipbelowblockpar{\nexttoken}{\belowpenalty}{\belowskip}} %~ Use this command in between lines in a |\tabbing| block to %~ perform a vertical adjustment between those two lines. For example, %~ %~ \adjusttabbing{\fullpagebreak} \long\def \adjusttabbing #1{% {commands} \ztbngadjust{#1}} % Initialize and Finalize % ---------- --- -------- \definecount{\ztbngstopcount}{0} \definecount{\ztbngstopindex}{0} \definebox{\ztbngline} \definebox{\ztbngfragment} \def \ztbnginit {% \let \par = \ztbngshouldntbepar \def \nl {\ztbngfinishline{\false}}% \defineatsigncommand @.{\ztbngatsetstop}% \defineatsigncommand @>{\ztbngattab}% \defineatsigncommand @C{\ztbngatclear}% \defineatsigncommand @D{\ztbngatdiscard}% \ztbngsetdefaultstops{\defaulttabwidth}} \def \ztbngsetdefaultstops #1{% {width} \global\ztbngstopcount = 0 \def \ztbngstop {0pt}% \if \dimgtrp{#1}{0pt}% \tdimena = 0pt \loop \global\increment \ztbngstopcount \advance \tdimena by #1\relax \withname\edef {\ztbngstop\romannumeral\ztbngstopcount}{\the\tdimena}% \if \dimlssp{\tdimena}{\hsize}% \repeat \fi} \def \ztbngfinal {% \ztbngfinishline{\true}} % Build Lines % ----- ----- \def \ztbngstartline {% \ztbngstopindex = 0 \setbox\ztbngline = \hbox{}% \global\setflag \ztbngdiscardp = \false \settaginfo{\number\calloutnumber}{???title???}% \ztbngstartfragment} \def \ztbngstartfragment {% \setbox \ztbngfragment = \hbox\bgroup \ignorespaces} \def \ztbngfinishfragment {% \egroup % \ztbngfragment box \setbox\ztbngline = \hbox{% \unhbox\ztbngline \tdimena = \name{\ztbngstop\romannumeral\ztbngstopindex}% \hskip \tdimena \tdimenb = \hsize \advance \tdimenb by -\tdimena \hbox to \tdimenb{\copy\ztbngfragment \hfil}% \hskip -\tdimenb \hskip -\tdimena}} \def \ztbngfinishline #1{% {end-of-block?} \ztbngfinishfragment \if \notp{\ztbngdiscardp}% \if \orp{\posp{\ztbngstopindex}}{\dimposp{\wd\ztbngfragment}}% \noindent \if \autocallout \llap{\calloutformat{\the\calloutnumber}}% \increment \calloutnumber \fi \box\ztbngline \endgraf \else\if \notp{#1}% \vspace{\tabbinggapskip}% \fi\fi \fi \if #1\let \znext = \relax \else \let \znext = \ztbngstartline \fi \znext} % At-sign Commands % ------- -------- % @#{callout}text... \def \ztbngatcallout #1{% {callout} \ztbngfinishfragment \if \andp{\zerop{\ztbngstopindex}}{\dimzerop{\wd\ztbngfragment}} \setbox\ztbngfragment = \hbox\bgroup \llap{\calloutformat{#1}}% \ztbngfinishfragment \else \error{badtabcallout}{Callout command (\noexpand@##) must appear at the beginning of the line}% \fi \increment \calloutnumber \ztbngstartfragment} % text@.more text... \def \ztbngatsetstop {% \ztbngfinishfragment \tdimena = \name{\ztbngstop\romannumeral\ztbngstopindex}% \advance \tdimena by \wd\ztbngfragment \increment \ztbngstopindex \if \gtrp{\ztbngstopindex}{\ztbngstopcount}% \withname\edef {\ztbngstop\romannumeral\ztbngstopindex}{\the\tdimena}% \increment \ztbngstopcount \else \error{badtabstop}{There is already a tab stop}% \fi \ztbngstartfragment} % text@>more text... \def \ztbngattab {% \ztbngfinishfragment \if \lssp{\ztbngstopindex}{\ztbngstopcount}% \increment \ztbngstopindex \else \warning{toomanytabs}{Too many tabs on line; extra tabs ignored}% \fi \ztbngstartfragment} % @Ctext...\nl \def \ztbngatclear {% \if \zerop{\ztbngstopindex}% \global\ztbngstopcount = 0\relax \else \error{badtabclear}{Tabs must be cleared at the beginning of the line}% \fi} % text@D\nl \def \ztbngatdiscard {% \global\setflag \ztbngdiscardp = \true \relax} % Adjustment % ---------- \long\def \ztbngadjust #1{% {commands} \ztbngfinishfragment \if \andp{\zerop{\ztbngstopindex}}{\dimzerop{\wd\ztbngfragment}} #1% \else \error{badtabadjust}{The \noexpand\adjusttabbing command must appear in between lines}% \fi \ztbngstartfragment}