\message{<Paul Taylor's ordinal drawing macros, 3 Dec 1996>}
%
%  \ordinal{<expression>} prints a picture of the ordinal <expression>
%
% <expression> is a sum (delimited by +) of powers of \omega
% can use ^ for powers, optional *, number must come last.
%
% testing and examples:
%\def\trace{\tracingmacros1 \tracingcommands1 \tracingonline1 }
%\def\do#1{{$#1=\ord{#1}$\par}}
%\def\examples{\do0 \do1 \do2 \do3 \do4 \do{10} \do{3+3}
%\do\omega \do{\omega+1} \do{\omega2} \do{\omega3+5}\do{\omega^2+\omega2+6}}

% doesn't handle 2\omega correctly

\def\ordinal#1{{%
\dimen9=1.1em \dimen8=0pt \omk
\ordreset
\ordx#1}}

\newcount\omegapower
\newcount\ordrepeat

\def\ordx{\futurelet\ordval\ordxx}

\def\ordxx{%
                                % if followed by:
\ifx+\ordval                    % - ``+''
   \ifnum\ordrepeat>0           % --- execute
      \omkx%
   \fi
   \ordreset
   \let\next\ordom              %       discard ``+'' and repeat
\else\ifx*\ordval               % - ``*''
   \let\next\ordnum             % --- discard
\else\ifcat\noexpand\ordval\egroup      % - close brace
   \ifnum\ordrepeat>0           % --- execute
      \omkx%
   \fi
   \let\next\relax
\else\ifcat\noexpand\ordval^%   % - ^
   \let\next\ordup              % --- get power
\else\ifx\ordval\omega          % - \omega
   \advance\omegapower1\relax   %
   \ordrepeat=1\relax           %       number defaults to 1
   \let\next\ordom              %       discard \omega & repeat
\else                           % - something else, presumably number
   \let\next\ordnum             % --- get number, execute & repeat
\fi\fi\fi\fi\fi
\next
}

\def\ordom#1{\ordx}
\let\ordz0
\def\ordnum{\afterassignment\ordnumx\ordrepeat=}

\def\ordup#1#2{\advance\omegapower-1
%\afterassignment\ordx
\advance\omegapower#2\relax
\ordx}

\def\ordnumx{%
\loop
\ifnum\ordrepeat>0
   \omkx%
   \advance\ordrepeat-1
\repeat
\ordreset
\ordx}

\def\omkx{{%
\ifnum\omegapower>0
   \advance\omegapower-1
   \omkrpt{\omkx}%
\else
   \omk
\fi
}}

\def\ordreset{%
\ordrepeat=0\relax
\omegapower=0\relax
\dimen9=1.5em             % height of first stroke
\dimen8=.1em            % its width
}

\def\omk{{% draw ordinal mark
\dimen2=\fontdimen22\the\textfont 2 % maths axis height
\advance\dimen2 .5\dimen9 % add half the mark height, getting height of top
\dimen3-\dimen2 \advance\dimen3\dimen9 % depth of bottom
\vrule height\dimen2 depth\dimen3 width\dimen8
\kern 3\dimen8}}
%
\def\omks#1#2#3{{% draw omega-sequence of #3-marks
% geometrically scaling vertically by #1, horizontally by #2
\loop
\ifdim\dimen9>.2pt
   {#3}%
   \dimen9=#1\dimen9
   \dimen8=#2\dimen8
\repeat}}
%
\def\omkrpt{\omks{.7}{.9}}
%
%
%
