summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/plain/zztex/zzreg.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/plain/zztex/zzreg.tex')
-rw-r--r--Master/texmf-dist/tex/plain/zztex/zzreg.tex437
1 files changed, 437 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/plain/zztex/zzreg.tex b/Master/texmf-dist/tex/plain/zztex/zzreg.tex
new file mode 100644
index 00000000000..c50f9e74d8f
--- /dev/null
+++ b/Master/texmf-dist/tex/plain/zztex/zzreg.tex
@@ -0,0 +1,437 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Module: ZzTeX Register Facilities
+%
+% Synopsis: This module provides facilities for defining and manipulating
+% TeX registers.
+%
+% Author: Paul C. Anagnostopoulos
+% Created: 13 August 1989
+%
+% Copyright 1989--2020 by Paul C. Anagnostopoulos
+% under The MIT License (opensource.org/licenses/MIT)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Register Definition
+% -------- ----------
+
+
+% The following constant specifies the number of the first insert register
+% set. Such a set is composed of a count, dimen, skip, and box.
+
+\chardef \zfirstinsert = 245
+
+% Establish counters to keep track of the most recently allocated
+% registers. The registers are initialized to the first available
+% register.
+
+\count10 = 20 % Count registers.
+\count11 = 0 % Dimen registers.
+\count12 = 0 % Skip registers.
+\count13 = 0 % Muskip registers.
+\count14 = 1 % Box registers (Plain TeX uses box 0).
+\count15 = 0 % Toks registers.
+\count16 = 0 % Read streams.
+\count17 = 0 % Write streams.
+\count18 = 0 % Math families.
+\count19 = \zfirstinsert % Insertion register sets.
+
+
+% There is one macro for each type of register, used to allocate one.
+
+\def \definecount #1#2{% {\name}{initial}
+ \zalloc{\count}{10}{\zfirstinsert}{\countdef}{#1}%
+ #1 = #2}
+
+\def \definedimen #1#2{% {\name}{initial}
+ \zalloc{\dimen}{11}{\zfirstinsert}{\dimendef}{#1}%
+ #1 = #2}
+
+\def \defineskip #1#2{% {\name}{initial}
+ \zalloc{\skip}{12}{\zfirstinsert}{\skipdef}{#1}%
+ #1 = #2}
+
+\def \definemuskip #1#2{% {\name}{initial}
+ \zalloc{\muskip}{13}{255}{\muskipdef}{#1}% Muskip 255 is scratch.
+ #1 = #2}
+
+\def \definebox #1{% {\name}
+ \zalloc{\box}{14}{\zfirstinsert}{\chardef}{#1}}
+
+\def \definetoks #1{% {\name}
+ \zalloc{\toks}{15}{256}{\toksdef}{#1}%
+ #1 = {}}
+
+\def \defineread #1{% {\name}
+ \zalloc{\read}{16}{16}{\chardef}{#1}}
+
+\def \definewrite #1{% {\name}
+ \zalloc{\write}{17}{16}{\chardef}{#1}}
+
+% Families are not defined directly by the user, but via \definetypestyle.
+
+\def \zdeffam #1{% {\name}
+ \if \lssp{\count18}{15}%
+ \zalloc{\fam}{18}{16}{\chardef}{#1}%
+ \else
+ \global\chardef #1=\count18
+ \fi}
+
+\def \defineinsert #1{% {\name}
+ \zalloc{\insert}{19}{255}{\chardef}{#1}} % Registers 255 are scratch.
+
+
+\def \zalloc #1#2#3#4#5{% {type}{counter}{limit}{\def-er}{\name}
+ \if \eqlp{\count#2}{#3}%
+ \error{noregsleft}{All `\string#1' registers have been allocated}%
+ \fi
+ \if \definedp{#5}%
+ \error{dupreg}{The register `\string#5' is already defined}%
+ \fi
+ \global#4 #5=\count#2
+ \global\increment {\count#2}}
+
+% Register Statistics
+% -------- ----------
+
+
+{\catcode`\_ = \catactive
+
+\gdef \zregstats {%
+ {\def _{\space}%
+ \writelog{}%
+ \writelog{Register Statistics:}%
+ \writelog{}%
+ \writelog{Type_____Used / Total}%
+ \writelog{----_____------------}%
+ \zrsone{Count_}{10}{\zfirstinsert}{}%
+ \zrsone{Dimen_}{11}{\zfirstinsert}{}%
+ \zrsone{Skip__}{12}{\zfirstinsert}{}%
+ \zrsone{Muskip}{13}{255}{}%
+ \zrsone{Box___}{14}{\zfirstinsert}{}%
+ \zrsone{Toks__}{15}{256}{}%
+ \zrsone{Read__}{16}{16}{}%
+ \zrsone{Write_}{17}{16}{}%
+ \zrsone{Family}{18}{256}{(15 for math)}%
+ \zrsone{Insert}{19}{255}{(starts at \the\zfirstinsert)}%
+ \writelog{}}}
+
+\gdef \zrsone #1#2#3#4{% {name}{counter}{ex-limit}{comment}
+ \tcounta = #3
+ \advance \tcounta by -1
+ \writelog{#1___\the\count#2 _/_\the\tcounta_#4}}
+
+} % \catcode
+
+% Constant Registers
+% -------- ---------
+
+
+\definecount{\maxcount}{2147483647}
+\definecount{\mincount}{-\maxcount}
+\zremovePlaindef \maxdimen
+\definedimen{\maxdimen}{16383.99999pt}
+\definedimen{\mindimen}{-\maxdimen}
+\definedimen{\naturalwidth}{\mindimen}
+
+\defineskip{\centerindent}{0pt plus 10000pt}
+\let \centering = \centerindent
+
+\defineskip{\normalparfillskip}{0pt plus 1fil}
+
+\definebox{\voidbox} % Permanently void box register.
+
+% Temporary Internal Registers
+% --------- -------- ---------
+
+
+\definecount{\tcounta}{0}
+\definecount{\tcountb}{0}
+\definecount{\tcountc}{0}
+
+\definedimen{\tdimena}{0pt}
+\definedimen{\tdimenb}{0pt}
+\definedimen{\tdimenc}{0pt}
+\definedimen{\tdimend}{0pt}
+
+\defineskip{\zskipa}{0pt}
+\defineskip{\zskipb}{0pt}
+\defineskip{\zskipc}{0pt}
+
+\definemuskip{\zmuskipa}{0mu}
+\definemuskip{\zmuskipb}{0mu}
+\definemuskip{\zmuskipc}{0mu}
+
+\definebox{\zboxa}
+\definebox{\zboxb}
+\definebox{\zboxc}
+
+\definetoks{\ztoksa}
+\definetoks{\ztoksb}
+\definetoks{\ztoksc}
+
+\defineread{\zreada}
+
+\definewrite{\zwritea}
+
+% Manipulating Boxes
+% ------------ -----
+
+
+\def \shiftboxbaseline #1#2{% {\box}{amount}
+ {\tdimena = #2%
+ \tdimenb = \ht#1%
+ \advance \tdimenb by \tdimena
+ \ht#1= \tdimenb
+ \tdimenb = \dp#1%
+ \advance \tdimenb by -\tdimena
+ \dp#1= \tdimenb}}
+
+% Lists
+% -----
+
+
+% These macros support the manipulation of lists in the following format:
+%
+% \:{<element-0>}\:{<element-1>}\: ...
+%
+% All lists are global!
+
+% We need two toks registers, which will be used just for lists.
+
+\definetoks{\zlta}
+\definetoks{\zltb}
+
+
+\def \setlist #1=#2{% \listname = {value}
+ \zlta = \expandafter{#2}%
+ \xdef #1{\the\zlta}}
+
+\long\def \append #1#2{% {item}{\list-name}
+ {\zlta = {\:{#1}}%
+ \zltb = \expandafter{#2}%
+ \xdef #2{\the\zltb\the\zlta}}}
+
+\long\def \appendlf #1#2{% {\list-name}{item}
+ {\zlta = {\:{#2}}%
+ \zltb = \expandafter{#1}%
+ \xdef #1{\the\zltb\the\zlta}}}
+
+\long\def \prepend #1#2{% {item}{\list-name}
+ {\zlta = {\:{#1}}%
+ \zltb = \expandafter{#2}%
+ \xdef #2{\the\zlta\the\zltb}}}
+
+\let \push = \prepend
+
+\def \pop #1#2{% {\return-macro}{\list-name}
+ \expandafter\zpop #2\zmark#1#2}
+
+\long\def \zpop \:#1#2\zmark#3#4{%
+ \def #3{#1}%
+ \gdef #4{#2}}
+
+\def \listtop #1#2{% {\return-macro}{\list-name}
+ \expandafter\zlisttop #2\zmark#1}
+
+\long\def \zlisttop \:#1#2\zmark#3{%
+ \def #3{#1}}
+
+\definecount{\zmapldepth}{0}
+
+\def \maplist #1#2{% {body}{\listname}
+ \increment \zmapldepth
+ \withname\let{\zmapl\romannumeral\zmapldepth}=\:%
+ \long\def \:##1{#1}%
+ #2%
+ \expandafter\let
+ \expandafter\:\csname zmapl\romannumeral\zmapldepth\endcsname
+ \decrement \zmapldepth}
+
+\def \maplistlf #1#2{% {\listname}{body}
+ \increment \zmapldepth
+ \withname\let{\zmapl\romannumeral\zmapldepth}=\:%
+ \long\def \:##1{#2}%
+ #1%
+ \expandafter\let
+ \expandafter\:\csname zmapl\romannumeral\zmapldepth\endcsname
+ \decrement \zmapldepth}
+
+\def \exitmaplist {\def \:##1{}}
+
+\def \listlength #1#2{% {\result-count}{\list}
+ #1= 0
+ \maplist{\increment #1}{#2}}
+
+\def \member #1#2#3{% {\result-flag}{item}{\list}
+ \setflag #1= \false
+ \maplist{\stringeql{#1}{##1}{#2}\if #1\exitmaplist \fi}
+ {#3}}
+
+\def \commalist #1#2{% {\result-name}{comma-list}
+ \setlist #1={}%
+ \expandafter\zcomma #2,\zmark#1}
+
+\def \zcomma #1,#2\zmark#3{%
+ \if \notp{\emptyargp{#1}}\append{#1}{#3}\fi
+ \if \notp{\emptyargp{#2}}%
+ \def \znext {\zcomma #2\zmark#3}%
+ \else
+ \let \znext = \relax
+ \fi
+ \znext}
+
+\def \inclusionlist #1#2#3{% {\result}{item}{inclusion-list}
+ \zincla {#1}{#2}#3\zmark}
+
+\let \all = \relax
+\let \allbut = \relax
+\def \zallname {\all}
+\def \zallbutname {\allbut}
+
+\def \zincla #1#2#3#4\zmark{% {\result}{item}{token1}{tokens...}
+ \def \znext {#3}%
+ \if \tokeqlp{\znext}{\zallname}%
+ \setflag #1= \true
+ \else \if \tokeqlp{\znext}{\zallbutname}%
+ \commalist{\zincllist}{#4}%
+ \member{#1}{#2}{\zincllist}%
+ \setflag #1= {\notp{#1}}%
+ \else
+ \commalist{\zincllist}{#3#4}%
+ \member{#1}{#2}{\zincllist}%
+ \fi\fi}
+
+% New Expression Evaluation
+% --- ---------- ----------
+
+
+% These macros provide a rudimentary expression evaluation facility.
+% The accumulator can be a count, dimen, or skip register. The expression
+% is in the form {operand0,op1,operand1,op2,operand2,...}.
+%
+% WARNING: The \register cannot be used in the expression except possibly
+% as the first operand.
+
+
+\definedimen{\zcalct}{0pt}
+
+
+\def \calculate #1=#2{% \register = {expression}
+ \let \zaccum = #1%
+ \zcalca =,#2,;,,\zmark}
+
+\def \gcalculate #1=#2{% \register = {expression}
+ \let \zaccum = #1%
+ \zcalca =,#2,;,,\zmark
+ \global \zaccum = \zaccum}
+
+\def \zcalca #1,#2,#3\zmark{%
+ \def \znext{\zcalca #3\zmark}%
+ \if #1=\zaccum = #2% % Assignment
+ \else\if #1+\advance \zaccum #2% % Addition
+ \else\if #1-\advance \zaccum -#2% % Subtraction
+ \else\if #1*\multiply \zaccum #2% % Multiplication
+ \else\if #1/\divide \zaccum #2% % Division
+ \else\if #1N\if \dimlssp{#2}{\zaccum}\zaccum = #2\fi % Minimum
+ \else\if #1P\divide \zaccum 100 % Percentage
+ \expandafter\zaccum #2\zaccum
+ \else\if #1R\zcalct = #2% % Ratio
+ \divide \zcalct by 4096
+ \divide \zaccum by \zcalct
+ \multiply \zaccum by 16\relax
+ \else\if #1S\zaccum = \thefactor#2\zaccum % Scale
+ \else\if #1X\if \dimgtrp{#2}{\zaccum}\zaccum = #2\fi % Maximum
+ \else\if #1;\let \znext = \relax % Done
+ \else
+ \error{invoper}{Invalid operator `#1' in expression}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \znext}
+
+% Calculating Values
+% ----------- ------
+
+%%%\defineskip{\zcaccum}{0pt}
+%%%\setflag \zexprpos = \true
+%%%
+%%%\def \calculate #1=#2{% {\reg} = {expression}
+%%% \commalist{\zexprlist}{#2}%
+%%% \zcaccum = 0pt
+%%% \def \zoper {+}%
+%%% \setflag \zexprpos = \true
+%%% \maplist{\zcalc{##1}}{\zexprlist}%
+%%% #1=\zcaccum}
+%%%
+%%%\def \gcalculate #1=#2{% {\reg} = {expression}
+%%% \commalist{\zexprlist}{#2}%
+%%% \zcaccum = 0pt
+%%% \def \zoper {+}%
+%%% \setflag \zexprpos = \true
+%%% \maplist{\zcalc{##1}}{\zexprlist}%
+%%% \global #1=\zcaccum}
+%%%
+%%%\def \zcalc #1{% {token}
+%%% \if \zexprpos
+%%% \zcalcb{#1}%
+%%% \setflag \zexprpos = \false
+%%% \else
+%%% \def \zoper {#1}%
+%%% \setflag \zexprpos = \true
+%%% \fi}
+%%%
+%%%\def \zcalcb #1{% {operand}
+%%% \if \codeeqlp{\zoper}{+}% % Add.
+%%% \advance \zcaccum by #1%
+%%% \else\if \codeeqlp{\zoper}{-}% % Subtract.
+%%% \advance \zcaccum by -#1%
+%%% \else\if \codeeqlp{\zoper}{*}% % Multiply.
+%%% \multiply \zcaccum by #1%
+%%% \else\if \codeeqlp{\zoper}{/}% % Divide.
+%%% \divide \zcaccum by #1%
+%%% \else\if \codeeqlp{\zoper}{P}%
+%%% \divide \zcaccum by 100
+%%% \expandafter \zcaccum #1\zcaccum
+%%% \else\if \codeeqlp{\zoper}{R}% % Compute ratio (in points).
+%%% \zcalct = #1%
+%%% \divide \zcalct by 4096
+%%% \divide \zcaccum by \zcalct
+%%% \multiply \zcaccum by 16\relax
+%%% \else\if \codeeqlp{\zoper}{S}% % Scale (in points).
+%%% \zcaccum = \thefactor#1\zcaccum
+%%% \else
+%%% \error{invoper}{Invalid operator `\zoper' in expression}%
+%%% \fi\fi\fi\fi\fi\fi\fi}
+
+% The Vertical Context
+% --- -------- -------
+
+
+% This is in here because we need registers. Otherwise it would be
+% in ZZTEX.TEX
+
+
+\definecount{\zvcontextdepth}{0}
+
+\definetoks{\zeveryvcontext}
+\global\zeveryvcontext = {}
+
+
+\def \zdeclareeveryvcontext #1{%
+ \global\zeveryvcontext = \expandafter{\the\zeveryvcontext #1}}
+
+\def \zpushvcontext {%
+ \global\increment \zvcontextdepth
+ \withname\gdef{\zvcontextstack\romannumeral\zvcontextdepth}{}%
+ \the\zeveryvcontext}
+
+\def \zpopvcontext {%
+ {\globaldefs = 1\relax
+ \name{\zvcontextstack\romannumeral\zvcontextdepth}}%
+ \global\decrement \zvcontextdepth}
+
+\def \zsavevcontext #1{%
+ {\ztoksa = \expandafterthrice{%
+ \name{\zvcontextstack\romannumeral\zvcontextdepth}}%
+ \withname\xdef{\zvcontextstack\romannumeral\zvcontextdepth}%
+ {\the\ztoksa #1}}}