%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Module: ZzTeX Blocks % % Synopsis: This module provides facilities for defining and creating % element blocks. % % Author: Paul C. Anagnostopoulos % Created: 23 August 1989 % % Copyright 1989--2020 by Paul C. Anagnostopoulos % under The MIT License (opensource.org/licenses/MIT) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Block Definition % ----- ---------- \setlist \zblocklist = {} \def \defineblock #1#2#3#4{% {\name}{\endname}{snap?}{redefine} \if \emptyargp{#4}% \withname\definecount{#1depth}{0}% \withname\definecount{#1number}{0}% \withname\definetoks{#1comptext}% \withname\gdef{#1varinit}{}% \if #3\withname\declaresnapitem{#1number}\fi \append{#1}{\zblocklist}% \fi} \def \resetinvcontext #1{% {\name} \zdeclareeveryvcontext{\zblockvcontext{#1}}} \def \zblockvcontext #1{% {\name} \zsavevcontext{\name{#1depth}=\the\name{#1depth}% \name{#1number}=\the\name{#1number}% \name{#1comptext}={\the\name{#1comptext}}}% \global\name{#1depth}= 0\relax \global\name{#1number}= 0\relax} % Block Utilities % ----- --------- \defineskip{\enclosingbaselineskip}{0pt} \defineskip{\enclosingleftss}{0pt} \definedimen{\enclosingparindent}{0pt} \definedimen{\enclosingparrag}{0pt} \defineskip{\enclosingparskip}{0pt} \defineskip{\enclosingrightss}{0pt} \def \beginblockscope #1{% \begingroup \zpushblock{#1}% \enclosingbaselineskip = \baselineskip \enclosingleftss = \leftskip \tdimena = \leftskip \advance \enclosingleftss by -\tdimena \enclosingparindent = \parindent \enclosingparrag = \parrag \enclosingparskip = \parskip \enclosingrightss = \rightskip \tdimena = \rightskip \advance \enclosingrightss by -\tdimena} \def \endblockscope #1{% \zpopblock{#1}% \endgroup} \def \processdesign #1#2{% {\block}{type etc.} \zprocessvariant{#1}% \resetnumber = {}% \if \definedp{#1#2design}% \name{#1#2design}\relax % \relax terminates numbers and such. \else \error{nodesign}{No design has been defined for the `\string#1#2' block}% \fi \zprocesswith {\globaldefs = 1 \the\resetnumber}} \def \inblockp #1{% {\block-name} \if \posp{\name{#1depth}}\true \else \false \fi} \def \setcomptext #1{% {\xxxcomptext} \edef \znext {\comptextformat}% #1= \expandafter{\znext}}% \def \blockmustbein #1#2{% {\inner}{\outer} \if \zerop{\name{#2depth}}% \error{blkmustnest}{A `\string#1' must be nested in a `\string#2'}% \fi} \def \blockcantbein #1#2{% {\inner}{\outer} \if \posp{\name{#2depth}}% \error{blkcantnest} {A `\string#1' cannot be nested inside a `\string#2'}% \fi} \def \closeifinblock #1#2{% {\block}{\endblock} \if \inblockp{#1}#2\fi} % Block Stack % ----- ----- \setlist \zblockstack = {} \setlist \zlinestack = {} \def \zpushblock #1{% \push{#1}{\zblockstack}% \edef \znext {\noexpand\push{\the\inputlineno}}% \znext{\zlinestack}} \def \zpopblock #1{% \pop{\zblk}{\zblockstack}% \pop{\zline}{\zlinestack}% \stringeql{\znext}{\zblk}{#1}% \if \notp{\znext}% \error{blkinvnest}{The `\string\end#1' command does not match the `\zblk' block that was started on line \zline}% \fi} \def \zemptyblockstackp {\emptylistp{\zblockstack}} % Block Variants % ----- -------- \def \definevariant #1#2#3{% {\block}{\style}{\modifier0,\modifier1,...} \if \emptyargp{#3}% \error{varmod}{Between 1 and 8 modifier commands must be specified}% \fi \withname\definecount{#2variant}{0}% \withname\xdef{#1varinit}{\name{#1varinit}\name{#2variant}=0}% {\tcounta = 0 \zdefvarpre #2#3,\zmark \if \gtrp{\tcounta}{8}% \error{varmod}{Between 1 and 8 modifier commands must be specified}% \fi \ztoksa = \expandaftertwice{\name{\zvarcase\lcromannumeral\tcounta}}% \edef \znext {\global\let \name{#2varcase}=\the\ztoksa}% \znext}} \def \zdefvarpre #1#2,#3\zmark{% \style\modifier,\modifier,...,\zmark \xdef #2{\noexpand\variant{\name{#1variant}=\the\tcounta}}% \increment \tcounta \if \notp{\emptyargp{#3}}\zdefvarpre #1#3\zmark \fi} \gdef \zvariant {} % Holds \stylevariant assignments. \def \variant #1{% {\stylevariant assignment} {\ztoksa = \expandafter{\zvariant}% \ztoksb = {#1}% \xdef \zvariant {\the\ztoksa \the\ztoksb}}% \ignorespaces} \def \zprocessvariant #1{% {\block} \name{#1varinit}% \zvariant \relax % \relax terminates numbers and such. \gdef \zvariant {}} \def \varcase #1{% \style \name{#1varcase}#1} \long\def \zvarcasei #1#2{% \style {var1 code} \ifcase \name{#1variant}#2\else\zbadvar\fi\relax} \long\def \zvarcaseii #1#2#3{% \style {var1 code}{var2 code} \ifcase \name{#1variant}#2\or#3\else\zbadvar\fi\relax} \long\def \zvarcaseiii #1#2#3#4{% \ifcase \name{#1variant}#2\or#3\or#4\else\zbadvar\fi\relax} \long\def \zvarcaseiv #1#2#3#4#5{% \ifcase \name{#1variant}#2\or#3\or#4\or#5\else\zbadvar\fi\relax} \long\def \zvarcasev #1#2#3#4#5#6{% \ifcase \name{#1variant}#2\or#3\or#4\or#5\or#6\else\zbadvar\fi\relax} \long\def \zvarcasevi #1#2#3#4#5#6#7{% \ifcase \name{#1variant}#2\or#3\or#4\or#5\or#6\or#7\else\zbadvar\fi\relax} \long\def \zvarcasevii #1#2#3#4#5#6#7#8{% \ifcase \name{#1variant}#2\or#3\or#4\or#5\or#6\or#7\or#8\else\zbadvar\fi\relax} \long\def \zvarcaseviii #1#2#3#4#5#6#7#8#9{% \ifcase\name{#1variant}#2\or#3\or#4\or#5\or#6\or#7\or#8\or#9\else\zbadvar\fi\relax} \def \setvariant #1{% \modifier #1% \zvariant \relax \gdef \zvariant {}} \def \zbadvar {% \zzerror{Invalid value for variant}} % Block Options % ----- ------- \gdef \zwith {} % Holds \with parameters. %~ The |\with| modifier can be used to modify specific design %~ parameters for the following block. It only makes sense %~ preceding block commands. Sometimes it is used with parameters %~ that are specifically intended for |\with|: %~ \with{\itemnumber=4} \list{number} %~ Other times it is used with a parameter that needs to be %~ changed for one particular block. %~ \with{\advance\belowskip by -8pt} \float{figure} %~ Again, be careful to use |\with| only on block commands. \long\def \with #1{% {parameter-assignments} %^modifier {\ztoksa = \expandafter{\zwith}% \ztoksb = {#1}% \xdef \zwith {\the\ztoksa \the\ztoksb}}% \ignorespaces} \def \zprocesswith {% \zwith \relax % \relax terminates numbers and such. \gdef \zwith {}} %~ This block modifier forces a page break above the block. \def \breakabove {% %^modifier \with{\abovepenalty=\breakalways}} %~ This block modifier forces a page break below the block. \def \breakbelow {% %^modifier \with{\belowpenalty=\breakalways}} % Common Design Parameters % ------ ------ ---------- % These design parameters are used by a variety of ZZTeX's blocks, so % they are defined here. % Integer parameters: \definecount{\abovepenalty}{0} % Penalty above block. \definecount{\authorlevel}{0} % Author ToC entry level. \definecount{\belowpenalty}{0} % Penalty below block. \definecount{\continue}{0} % Block is continued (bit 0) and/or continuation (bit 1). \definecount{\difficulty}{0} % Level of difficulty of the block. % Flag parameters: \setflag \allowbreaks = \false % Allow page breaks in block? \setflag \allowintoc = \false % Allow section in ToC? % Dimension parameters: \definedimen{\height}{0pt} % Height of text. \definedimen{\ruleshift}{0pt} % Horizontal shift for rule. \definedimen{\ruleheight}{0pt} % Height (thickness) of rule. \definedimen{\rulewidth}{0pt} % Width of rule. \definedimen{\topadjust}{\mindimen} % Adjustment for head at top of page. \definedimen{\vshift}{0pt} % Vertical shift. \definedimen{\width}{0pt} % Width of text. % Skip (glue) parameters: \defineskip{\aboveskip}{0pt} % Base/base skip above block. \defineskip{\belowskip}{0pt} % Base/base skip below block. \defineskip{\columngutter}{0pt} % Width of gutter between columns. \defineskip{\interrowskip}{0pt} % Extra space between rows. \defineskip{\leftindent}{0pt} % Left indentation glue. \defineskip{\numbersink}{0pt} % Sinkage to section number, or \defineskip{\numberskip}{0pt} % Space b/b to section number. \defineskip{\parhang}{0pt} % Hanging indent for paragraph. \defineskip{\rightindent}{0pt} % Right indentation glue. \defineskip{\ruleskip}{0pt} % Vskip for rule. \defineskip{\textsink}{0pt} % Vsink for text. \defineskip{\textskip}{0pt} % Base/base skip for text. \defineskip{\titlesink}{0pt} % Sinkage to section title, or \defineskip{\titleskip}{0pt} % Space b/b to section title. % Token list parameters: \definetoks{\authortext} % Part/chapter author text. \definetoks{\bodyfont} % Font for body of block. \definetoks{\divisions} % List of division names. \definetoks{\numberfont} % Font for block number. \definetoks{\numberwordfont} % Font for block word like "chapter". \definetoks{\openertext} % Part/chapter opener text. \definetoks{\position} % Position of the block. \definetoks{\resetnumber} % List of sequence numbers to reset. \definetoks{\rulecolor} % Color of a rule. \definetoks{\runners} % Running head/foot macros. \definetoks{\style} % Heading style. \definetoks{\textcolor} % Color of text. \definetoks{\titlefont} % Font for title. % Macro parameters: \def \numberformat #1{} % {code} %~ Formatter for block number. \def \paging {} % {code} %~ Page control commands. \def \providemark #1{} % {code} %~ Provide marks for the block. \def \titleformat {} % {code} %~ Formatter for title. % The \continue Parameter % --- --------- --------- % The \continue parameter is set as follows: % 0: neither continued nor continuation % 1: continued % 2: continuation % 3: both continuation and continued \def \continuedp {\oddp{\continue}} \def \continuationp {\gtrp{\continue}{1}} \def \zsetcontinue {% \if \andp{\zerop{\continue}}{\continuation}% \continue = 2\relax \fi} % Break Element % ----- ------- \long\def \breakelement #1{% \global\setflag \zinpar = {\hmodep}% \if \zinpar \flushendpar \fi #1% \if \zinpar \noindent \ignorespaces \fi}