% rail.sty - style file to support railroad diagrams%% 09-Jul-90 L. Rooijakkers% 08-Oct-90 L. Rooijakkers fixed centering bug when \rail@tmpc<0.% 07-Feb-91 L. Rooijakkers added \railoptions command, indexing% 08-Feb-91 L. Rooijakkers minor fixes% 28-Jun-94 K. Barthelmann turned into LaTeX2e package% 08-Dec-96 K. Barthelmann replaced \@writefile% 13-Dec-96 K. Barthelmann cleanup% 22-Feb-98 K. Barthelmann fixed catcodes of special characters% 18-Apr-98 K. Barthelmann fixed \par handling% 19-May-98 J. Olsson Added new macros to support arrow heads.% 26-Jul-98 K. Barthelmann changed \par to output newlines%% This style file needs to be used in conjunction with the 'rail'% program. Running LaTeX as 'latex file' produces file.rai, which should be% processed by Rail with 'rail file'. This produces file.rao, which will% be picked up by LaTeX on the next 'latex file' run.%% LaTeX will warn if there is no file.rao or it's out of date.%% The macros in this file thus consist of two parts: those that read and% write the .rai and .rao files, and those that do the actual formatting% of the railroad diagrams.\NeedsTeXFormat{LaTeX2e}\ProvidesPackage{rail}[1998/05/19]% railroad diagram formatting parameters (user level)% all of these are copied into their internal versions by \railinit%% \railunit : \unitlength within railroad diagrams% \railextra : extra length at outside of diagram% \railboxheight : height of ovals and frames% \railboxskip : vertical space between lines% \railboxleft : space to the left of a box% \railboxright : space to the right of a box% \railovalspace : extra space around contents of oval% \railframespace : extra space around contents of frame% \railtextleft : space to the left of text% \railtextright : space to the right of text% \railtextup : space to lift text up% \railjoinsize : circle size of join/split arcs% \railjoinadjust : space to adjust join%% \railnamesep : separator between name and rule body\newlength\railunit\newlength\railextra\newlength\railboxheight\newlength\railboxskip\newlength\railboxleft\newlength\railboxright\newlength\railovalspace\newlength\railframespace\newlength\railtextleft\newlength\railtextright\newlength\railtextup\newlength\railjoinsize\newlength\railjoinadjust\newlength\railnamesep% initialize the parameters\setlength\railunit{1sp}\setlength\railextra{4ex}\setlength\railboxleft{1ex}\setlength\railboxright{1ex}\setlength\railovalspace{2ex}\setlength\railframespace{2ex}\setlength\railtextleft{1ex}\setlength\railtextright{1ex}\setlength\railjoinadjust{0pt}\setlength\railnamesep{1ex}\DeclareOption{10pt}{ \setlength\railboxheight{16pt} \setlength\railboxskip{24pt} \setlength\railtextup{5pt} \setlength\railjoinsize{16pt}}\DeclareOption{11pt}{ \setlength\railboxheight{16pt} \setlength\railboxskip{24pt} \setlength\railtextup{5pt} \setlength\railjoinsize{16pt}}\DeclareOption{12pt}{ \setlength\railboxheight{20pt} \setlength\railboxskip{28pt} \setlength\railtextup{6pt} \setlength\railjoinsize{20pt}}\ExecuteOptions{10pt}\ProcessOptions% internal versions of the formatting parameters%% \rail@extra : \railextra% \rail@boxht : \railboxheight% \rail@boxsp : \railboxskip% \rail@boxlf : \railboxleft% \rail@boxrt : \railboxright% \rail@boxhht : \railboxheight / 2% \rail@ovalsp : \railovalspace% \rail@framesp : \railframespace% \rail@textlf : \railtextleft% \rail@textrt : \railtextright% \rail@textup : \railtextup% \rail@joinsz : \railjoinsize% \rail@joinhsz : \railjoinsize / 2% \rail@joinadj : \railjoinadjust%% \railinit : internalize all of the parameters.\newcount\rail@extra\newcount\rail@boxht\newcount\rail@boxsp\newcount\rail@boxlf\newcount\rail@boxrt\newcount\rail@boxhht\newcount\rail@ovalsp\newcount\rail@framesp\newcount\rail@textlf\newcount\rail@textrt\newcount\rail@textup\newcount\rail@joinsz\newcount\rail@joinhsz\newcount\rail@joinadj\newcommand\railinit{\rail@extra=\railextra\divide\rail@extra by \railunit\rail@boxht=\railboxheight\divide\rail@boxht by \railunit\rail@boxsp=\railboxskip\divide\rail@boxsp by \railunit\rail@boxlf=\railboxleft\divide\rail@boxlf by \railunit\rail@boxrt=\railboxright\divide\rail@boxrt by \railunit\rail@boxhht=\railboxheight\divide\rail@boxhht by \railunit\divide\rail@boxhht by 2\rail@ovalsp=\railovalspace\divide\rail@ovalsp by \railunit\rail@framesp=\railframespace\divide\rail@framesp by \railunit\rail@textlf=\railtextleft\divide\rail@textlf by \railunit\rail@textrt=\railtextright\divide\rail@textrt by \railunit\rail@textup=\railtextup\divide\rail@textup by \railunit\rail@joinsz=\railjoinsize\divide\rail@joinsz by \railunit\rail@joinhsz=\railjoinsize\divide\rail@joinhsz by \railunit\divide\rail@joinhsz by 2\rail@joinadj=\railjoinadjust\divide\rail@joinadj by \railunit}\AtBeginDocument{\railinit}% \rail@param : declarations for list environment%% \railparam{TEXT} : sets \rail@param to TEXT%% \rail@reserved : characters reserved for grammar\newcommand\railparam[1]{\def\rail@param{ \setlength\leftmargin{0pt}\setlength\rightmargin{0pt} \setlength\labelwidth{0pt}\setlength\labelsep{0pt} \setlength\itemindent{0pt}\setlength\listparindent{0pt} #1}}\railparam{}\newtoks\rail@reserved\rail@reserved={:;|*+?[]()'"}% \rail@termfont : format setup for terminals%% \rail@nontfont : format setup for nonterminals%% \rail@annofont : format setup for annotations%% \rail@rulefont : format setup for rule names%% \rail@indexfont : format setup for index entry%% \railtermfont{TEXT} : set terminal format setup to TEXT%% \railnontermfont{TEXT} : set nonterminal format setup to TEXT%% \railannotatefont{TEXT} : set annotation format setup to TEXT%% \railnamefont{TEXT} : set rule name format setup to TEXT%% \railindexfont{TEXT} : set index entry format setup to TEXT\def\rail@termfont{\ttfamily\upshape}\def\rail@nontfont{\rmfamily\upshape}\def\rail@annofont{\rmfamily\itshape}\def\rail@namefont{\rmfamily\itshape}\def\rail@indexfont{\rmfamily\itshape}\newcommand\railtermfont[1]{\def\rail@termfont{#1}}\newcommand\railnontermfont[1]{\def\rail@nontfont{#1}}\newcommand\railannotatefont[1]{\def\rail@annofont{#1}}\newcommand\railnamefont[1]{\def\rail@namefont{#1}}\newcommand\railindexfont[1]{\def\rail@indexfont{#1}}% railroad read/write macros%% \begin{rail} TEXT \end{rail} : TEXT is written out to the .rai file,% as \rail@i{NR}{TEXT}. Then the matching% \rail@o{NR}{FMT} from the .rao file is% executed (if defined).%% \railoptions{OPTIONS} : OPTIONS are written out to the .rai file,% as \rail@p{OPTIONS}.%% \railterm{IDENT,IDENT,...} : format IDENT as terminals. writes out% \rail@t{IDENT} to the .rai file%% \railalias{IDENT}{TEXT} : format IDENT as TEXT. defines \rail@t@IDENT as% TEXT.%% \railtoken{IDENT}{TEXT} : abbreviates \railalias{IDENT}{TEXT}\railterm{IDENT}% (for backward compatibility)%% \rail@setcodes : guards special characters%% \rail@makeother{CHARACTER} : sets \catcode of CHARACTER to "other"% used inside a loop for \rail@setcodes%% \rail@nr : railroad diagram counter%% \ifrail@match : current \rail@i{NR}{TEXT} matches%% \rail@first : actions to be done first. read in .rao file,% open .rai file if \@filesw true, undefine \rail@first.% executed from \begin{rail}, \railoptions and \railterm.%% \rail@i{NR}{TEXT} : defines \rail@i@NR as TEXT. written to the .rai% file by \rail, read from the .rao file by% \rail@first%% \rail@t{IDENT} : tells Rail that IDENT is to be custom formatted,% written to the .rai file by \railterm.%% \rail@o{NR}{TEXT} : defines \rail@o@NR as TEXT, read from the .rao% file by \rail@first.%% \rail@p{OPTIONS} : pass options to rail, written to the .rai file by% \railoptions%% \rail@write{TEXT} : write TEXT to the .rai file%% \rail@warn : warn user for mismatching diagrams%% \rail@endwarn : either \relax or \rail@warn%% \ifrail@all : checked at the end of the document\def\rail@makeother#1{ \expandafter\catcode\expandafter`\csname\string #1\endcsname=12}\def\rail@setcodes{\let\par=\relax\let\\=\relax\expandafter\@tfor\expandafter\rail@symbol\expandafter:\expandafter=% \the\rail@reserved\do{\expandafter\rail@makeother\rail@symbol}}\newcount\rail@nr\newif\ifrail@all\rail@alltrue\newif\ifrail@match\def\rail@first{\begingroup\makeatletter\rail@setcodes\InputIfFileExists{\jobname.rao}{}{\PackageInfo{rail}{No file \jobname.rao}}\makeatother\endgroup\if@filesw\newwrite\tf@rai\immediate\openout\tf@rai=\jobname.rai\fi\global\let\rail@first=\relax}\long\def\rail@body#1\end{{\newlinechar=`^^J\def\par{\string\par^^J}\rail@write{\string\rail@i{\number\rail@nr}{#1}}}\xdef\rail@i@{#1}\end}\newenvironment{rail}{\global\advance\rail@nr by 1\rail@first\begingroup\rail@setcodes\rail@body}{\endgroup\rail@matchtrue\@ifundefined{rail@o@\number\rail@nr}{\rail@matchfalse}{}\expandafter\ifx\csname rail@i@\number\rail@nr\endcsname\rail@i@\else\rail@matchfalse\fi\ifrail@match\csname rail@o@\number\rail@nr\endcsname\else\PackageWarning{rail}{Railroad diagram {\number\rail@nr} doesn't match}\global\let\rail@endwarn=\rail@warn\begin{list}{}{\rail@param}\rail@begin{1}{}\rail@setbox{\bfseries ???}\rail@oval\rail@end\end{list}\fi}\newcommand\railoptions[1]{\rail@first\rail@write{\string\rail@p{#1}}}\newcommand\railterm[1]{\rail@first\@for\rail@@:=#1\do{\rail@write{\string\rail@t{\rail@@}}}}\newcommand\railalias[2]{\expandafter\def\csname rail@t@#1\endcsname{#2}}\newcommand\railtoken[2]{\railalias{#1}{#2}\railterm{#1}}\long\def\rail@i#1#2{\expandafter\gdef\csname rail@i@#1\endcsname{#2}}\def\rail@o#1#2{\expandafter\gdef\csname rail@o@#1\endcsname{\begin{list}{}{\rail@param}#2\end{list}}}\def\rail@t#1{}\def\rail@p#1{}\long\def\rail@write#1{\@ifundefined{tf@rai}{}{\immediate\write\tf@rai{#1}}}\def\rail@warn{\PackageWarningNoLine{rail}{Railroad diagram(s) may have changed. Use 'rail' and rerun}}\let\rail@endwarn=\relax\AtEndDocument{\rail@endwarn}% index entry macro%% \rail@index{IDENT} : add index entry for IDENT\def\rail@index#1{\index{\rail@indexfont#1}}% railroad formatting primitives%% \rail@x : current x% \rail@y : current y% \rail@ex : current end x% \rail@sx : starting x for \rail@cr% \rail@rx : rightmost previous x for \rail@cr%% \rail@tmpa : temporary count% \rail@tmpb : temporary count% \rail@tmpc : temporary count%% \rail@put : put at (\rail@x,\rail@y)% \rail@vput : put vector at (\rail@x,\rail@y)%% \rail@eline : end line by drawing from \rail@ex to \rail@x%% \rail@vreline : end line by drawing a vector from \rail@x to \rail@ex%% \rail@vleline : end line by drawing a vector from \rail@ex to \rail@x%% \rail@sety{LEVEL} : set \rail@y to level LEVEL\newcount\rail@x\newcount\rail@y\newcount\rail@ex\newcount\rail@sx\newcount\rail@rx\newcount\rail@tmpa\newcount\rail@tmpb\newcount\rail@tmpc\def\rail@put{\put(\number\rail@x,\number\rail@y)}\def\rail@vput{\put(\number\rail@ex,\number\rail@y)}\def\rail@eline{\rail@tmpb=\rail@x\advance\rail@tmpb by -\rail@ex\rail@put{\line(-1,0){\number\rail@tmpb}}}\def\rail@vreline{\rail@tmpb=\rail@x\advance\rail@tmpb by -\rail@ex\rail@vput{\vector(1,0){\number\rail@tmpb}}}\def\rail@vleline{\rail@tmpb=\rail@x\advance\rail@tmpb by -\rail@ex\rail@put{\vector(-1,0){\number\rail@tmpb}}}\def\rail@sety#1{\rail@y=#1\multiply\rail@y by -\rail@boxsp\advance\rail@y by -\rail@boxht}% \rail@begin{HEIGHT}{NAME} : begin a railroad diagram of height HEIGHT%% \rail@end : end a railroad diagram%% \rail@expand{IDENT} : expand IDENT\def\rail@begin#1#2{\item\begin{minipage}[t]{\linewidth}\ifx\@empty#2\else{\rail@namefont \rail@expand{#2}}\\*[\railnamesep]\fi\unitlength=\railunit\rail@tmpa=#1\multiply\rail@tmpa by \rail@boxsp\begin{picture}(0,\number\rail@tmpa)(0,-\number\rail@tmpa)\rail@ex=0\rail@rx=0\rail@x=\rail@extra\rail@sx=\rail@x\rail@sety{0}}\def\rail@end{\advance\rail@x by \rail@extra\rail@eline\end{picture}\end{minipage}}\def\rail@vend{\advance\rail@x by \rail@extra\rail@vreline\end{picture}\end{minipage}}\def\rail@expand#1{\@ifundefined{rail@t@#1}{#1}{\csname rail@t@#1\endcsname}}% \rail@token{TEXT}[ANNOT] : format token TEXT with annotation% \rail@ltoken{TEXT}[ANNOT] : format token TEXT with annotation, arrow left% \rail@rtoken{TEXT}[ANNOT] : format token TEXT with annotation, arrow right%% \rail@ctoken{TEXT}[ANNOT] : format token TEXT centered with annotation% \rail@lctoken{TEXT}[ANNOT] : format token TEXT centered with annotation, arrow left% \rail@rctoken{TEXT}[ANNOT] : format token TEXT centered with annotation, arrow right%% \rail@nont{TEXT}[ANNOT] : format nonterminal TEXT with annotation% \rail@lnont{TEXT}[ANNOT] : format nonterminal TEXT with annotation, arrow left% \rail@rnont{TEXT}[ANNOT] : format nonterminal TEXT with annotation. arrow right%% \rail@cnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation% \rail@lcnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation,% arrow left% \rail@rcnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation,% arrow right%% \rail@term{TEXT}[ANNOT] : format terminal TEXT with annotation% \rail@lterm{TEXT}[ANNOT] : format terminal TEXT with annotation, arrow left% \rail@rterm{TEXT}[ANNOT] : format terminal TEXT with annotation, arrow right%% \rail@cterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation% \rail@lcterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation, arrow left% \rail@rcterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation,% arrow right%% \rail@annote[TEXT] : format TEXT as annotation\def\rail@token#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@oval}\def\rail@ltoken#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vloval}\def\rail@rtoken#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vroval}\def\rail@ctoken#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@coval}\def\rail@lctoken#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vlcoval}\def\rail@rctoken#1[#2]{\rail@setbox{%{\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vrcoval}\def\rail@nont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@frame}\def\rail@lnont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vlframe}\def\rail@rnont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vrframe}\def\rail@cnont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@cframe}\def\rail@lcnont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vlcframe}\def\rail@rcnont#1[#2]{\rail@setbox{%{\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vrcframe}\def\rail@term#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@oval}\def\rail@lterm#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vloval}\def\rail@rterm#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vroval}\def\rail@cterm#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@coval}\def\rail@lcterm#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vlcoval}\def\rail@rcterm#1[#2]{\rail@setbox{%{\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi}\rail@vrcoval}\def\rail@annote[#1]{\rail@setbox{\rail@annofont #1}\rail@text}% \rail@box : temporary box for \rail@oval and \rail@frame%% \rail@setbox{TEXT} : set \rail@box to TEXT, set \rail@tmpa to width%% \rail@oval : format \rail@box of width \rail@tmpa inside an oval% \rail@vloval : format \rail@box of width \rail@tmpa inside an oval, vector left% \rail@vroval : format \rail@box of width \rail@tmpa inside an oval, vector right%% \rail@coval : same as \rail@oval, but centered between \rail@x and% \rail@mx% \rail@vlcoval : same as \rail@oval, but centered between \rail@x and% \rail@mx, vector left% \rail@vrcoval : same as \rail@oval, but centered between \rail@x and% \rail@mx, vector right%% \rail@frame : format \rail@box of width \rail@tmpa inside a frame% \rail@vlframe : format \rail@box of width \rail@tmpa inside a frame, vector left% \rail@vrframe : format \rail@box of width \rail@tmpa inside a frame, vector right%% \rail@cframe : same as \rail@frame, but centered between \rail@x and% \rail@mx% \rail@vlcframe : same as \rail@frame, but centered between \rail@x and% \rail@mx, vector left% \rail@vrcframe : same as \rail@frame, but centered between \rail@x and% \rail@mx, vector right%% \rail@text : format \rail@box of width \rail@tmpa above the line\newbox\rail@box\def\rail@setbox#1{\setbox\rail@box\hbox{\strut#1}\rail@tmpa=\wd\rail@box\divide\rail@tmpa by \railunit}\def\rail@oval{\advance\rail@x by \rail@boxlf\rail@eline\advance\rail@tmpa by \rail@ovalsp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\rail@tmpb=\rail@tmpa\divide\rail@tmpb by 2\advance\rail@y by -\rail@boxhht\rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpb\rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}\advance\rail@x by \rail@tmpb\rail@ex=\rail@x\advance\rail@x by \rail@boxrt}\def\rail@vloval{\advance\rail@x by \rail@boxlf\rail@eline\advance\rail@tmpa by \rail@ovalsp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\rail@tmpb=\rail@tmpa\divide\rail@tmpb by 2\advance\rail@y by -\rail@boxhht\rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpb\rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}\advance\rail@x by \rail@tmpb\rail@ex=\rail@x\advance\rail@x by \rail@boxrt\rail@vleline}\def\rail@vroval{\advance\rail@x by \rail@boxlf\rail@vreline\advance\rail@tmpa by \rail@ovalsp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\rail@tmpb=\rail@tmpa\divide\rail@tmpb by 2\advance\rail@y by -\rail@boxhht\rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpb\rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}\advance\rail@x by \rail@tmpb\rail@ex=\rail@x\advance\rail@x by \rail@boxrt}\def\rail@coval{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@ovalsp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@oval}\def\rail@vlcoval{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@ovalsp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@vloval}\def\rail@vrcoval{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@ovalsp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@vroval}\def\rail@frame{\advance\rail@x by \rail@boxlf\rail@eline\advance\rail@tmpa by \rail@framesp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\advance\rail@y by -\rail@boxhht\rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpa\rail@ex=\rail@x\advance\rail@x by \rail@boxrt}\def\rail@vlframe{\advance\rail@x by \rail@boxlf\rail@eline\advance\rail@tmpa by \rail@framesp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\advance\rail@y by -\rail@boxhht\rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpa\rail@ex=\rail@x\advance\rail@x by \rail@boxrt\rail@vleline}\def\rail@vrframe{\advance\rail@x by \rail@boxlf\rail@vreline\advance\rail@tmpa by \rail@framesp\ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi\advance\rail@y by -\rail@boxhht\rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}\advance\rail@y by \rail@boxhht\advance\rail@x by \rail@tmpa\rail@ex=\rail@x\advance\rail@x by \rail@boxrt}\def\rail@cframe{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@framesp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@frame}\def\rail@vlcframe{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@framesp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@vlframe}\def\rail@vrcframe{\rail@tmpb=\rail@tmpa\advance\rail@tmpb by \rail@framesp\ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi\advance\rail@tmpb by \rail@boxlf\advance\rail@tmpb by \rail@boxrt\rail@tmpc=\rail@mx\advance\rail@tmpc by -\rail@x\advance\rail@tmpc by -\rail@tmpb\divide\rail@tmpc by 2\ifnum\rail@tmpc>0\advance\rail@x by \rail@tmpc\fi\rail@vrframe}\def\rail@text{\advance\rail@x by \rail@textlf\advance\rail@y by \rail@textup\rail@put{\box\rail@box}\advance\rail@y by -\rail@textup\advance\rail@x by \rail@tmpa\advance\rail@x by \rail@textrt}% alternatives%% \rail@jx \rail@jy : current join point%% \rail@gx \rail@gy \rail@gex \rail@grx : global versions of \rail@x etc,% to pass values over group closings%% \rail@mx : maximum x so far%% \rail@sy : starting \rail@y for alternatives%% \rail@jput : put at (\rail@jx,\rail@jy)%% \rail@joval[PART] : put \oval[PART] with adjust\newcount\rail@jx\newcount\rail@jy\newcount\rail@gx\newcount\rail@gy\newcount\rail@gex\newcount\rail@grx\newcount\rail@sy\newcount\rail@mx\def\rail@jput{\put(\number\rail@jx,\number\rail@jy)}\def\rail@joval[#1]{\advance\rail@jx by \rail@joinadj\rail@jput{\oval(\number\rail@joinsz,\number\rail@joinsz)[#1]}\advance\rail@jx by -\rail@joinadj}% \rail@barsplit : incoming split for '|'%% \rail@plussplit : incoming split for '+'%\def\rail@barsplit{\advance\rail@jy by -\rail@joinhsz\rail@joval[tr]\advance\rail@jx by \rail@joinhsz}\def\rail@plussplit{\advance\rail@jy by -\rail@joinhsz\advance\rail@jx by \rail@joinsz\rail@joval[tl]\advance\rail@jx by -\rail@joinhsz}% \rail@alt{SPLIT} : start alternatives with incoming split SPLIT%\def\rail@alt#1{\rail@sy=\rail@y\rail@jx=\rail@x\rail@jy=\rail@y\advance\rail@x by \rail@joinsz\rail@mx=0\let\rail@list=\@empty\let\rail@comma=\@empty\let\rail@split=#1\begingroup\rail@sx=\rail@x\rail@rx=0}% \rail@nextalt{FIX}{Y} : start next alternative at vertical position Y% and fix-up FIX%\def\rail@nextalt#1#2{\global\rail@gx=\rail@x\global\rail@gy=\rail@y\global\rail@gex=\rail@ex\global\rail@grx=\rail@rx\endgroup#1\ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi\ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi\edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}\def\rail@comma{,}\rail@split\let\rail@split=\@empty\rail@sety{#2}\rail@tmpa=\rail@jy\advance\rail@tmpa by -\rail@y\advance\rail@tmpa by -\rail@joinhsz\rail@jput{\line(0,-1){\number\rail@tmpa}}\rail@jy=\rail@y\advance\rail@jy by \rail@joinhsz\advance\rail@jx by \rail@joinhsz\rail@joval[bl]\advance\rail@jx by -\rail@joinhsz\rail@ex=\rail@x\begingroup\rail@sx=\rail@x\rail@rx=0}% \rail@barjoin : outgoing join for first '|' alternative%% \rail@plusjoin : outgoing join for first '+' alternative%% \rail@altjoin : join for subsequent alternative%\def\rail@barjoin{\ifnum\rail@y<\rail@sy\global\rail@gex=\rail@jx\else\global\rail@gex=\rail@ex\fi\advance\rail@jy by -\rail@joinhsz\rail@joval[tl]\advance\rail@jx by -\rail@joinhsz\ifnum\rail@y<\rail@sy\rail@altjoin\fi}\def\rail@plusjoin{\global\rail@gex=\rail@ex\advance\rail@jy by -\rail@joinhsz\advance\rail@jx by -\rail@joinsz\rail@joval[tr]\advance\rail@jx by \rail@joinhsz}\def\rail@altjoin{\rail@eline\rail@tmpa=\rail@jy\advance\rail@tmpa by -\rail@y\advance\rail@tmpa by -\rail@joinhsz\rail@jput{\line(0,-1){\number\rail@tmpa}}\rail@jy=\rail@y\advance\rail@jy by \rail@joinhsz\advance\rail@jx by -\rail@joinhsz\rail@joval[br]\advance\rail@jx by \rail@joinhsz}% \rail@eltsplit EX:Y; : split EX:Y into \rail@ex \rail@y%% \rail@endalt{JOIN} : end alternatives with outgoing join JOIN\def\rail@eltsplit#1:#2;{\rail@ex=#1\rail@y=#2}\def\rail@endalt#1{\global\rail@gx=\rail@x\global\rail@gy=\rail@y\global\rail@gex=\rail@ex\global\rail@grx=\rail@rx\endgroup\ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi\ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi\edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}\rail@x=\rail@mx\rail@jx=\rail@x\rail@jy=\rail@sy\advance\rail@jx by \rail@joinsz\let\rail@join=#1\@for\rail@elt:=\rail@list\do{\expandafter\rail@eltsplit\rail@elt;\rail@join\let\rail@join=\rail@altjoin}\rail@x=\rail@mx\rail@y=\rail@sy\rail@ex=\rail@gex\advance\rail@x by \rail@joinsz}% \rail@bar : start '|' alternatives%% \rail@nextbar : next '|' alternative%% \rail@endbar : end '|' alternatives%\def\rail@bar{\rail@alt\rail@barsplit}\def\rail@nextbar{\rail@nextalt\relax}\def\rail@endbar{\rail@endalt\rail@barjoin}% \rail@plus : start '+' alternatives%% \rail@nextplus: next '+' alternative%% \rail@endplus : end '+' alternatives%\def\rail@plus{\rail@alt\rail@plussplit}\def\rail@nextplus{\rail@nextalt\rail@fixplus}\def\rail@fixplus{\ifnum\rail@gy<\rail@sy\begingroup\rail@x=\rail@gx\rail@y=\rail@gy\rail@ex=\rail@gex\rail@rx=\rail@grx\ifnum\rail@x<\rail@rx\rail@x=\rail@rx\fi\rail@eline\rail@jx=\rail@x\rail@jy=\rail@y\advance\rail@jy by \rail@joinhsz\rail@joval[br]\advance\rail@jx by \rail@joinhsz\rail@tmpa=\rail@sy\advance\rail@tmpa by -\rail@joinhsz\advance\rail@tmpa by -\rail@jy\rail@jput{\line(0,1){\number\rail@tmpa}}\rail@jy=\rail@sy\advance\rail@jy by -\rail@joinhsz\advance\rail@jx by \rail@joinhsz\rail@joval[tl]\advance\rail@jy by \rail@joinhsz\global\rail@gx=\rail@jx\global\rail@gy=\rail@jy\global\rail@gex=\rail@gx\global\rail@grx=\rail@rx\endgroup\fi}\def\rail@endplus{\rail@endalt\rail@plusjoin}% \rail@cr{Y} : carriage return to vertical position Y\def\rail@cr#1{\rail@tmpa=\rail@sx\advance\rail@tmpa by \rail@joinsz\ifnum\rail@x<\rail@tmpa\rail@x=\rail@tmpa\fi\rail@eline\rail@jx=\rail@x\rail@jy=\rail@y\advance\rail@x by \rail@joinsz\ifnum\rail@x>\rail@rx\rail@rx=\rail@x\fi\advance\rail@jy by -\rail@joinhsz\rail@joval[tr]\advance\rail@jx by \rail@joinhsz\rail@sety{#1}\rail@tmpa=\rail@jy\advance\rail@tmpa by -\rail@y\advance\rail@tmpa by -\rail@boxsp\advance\rail@tmpa by -\rail@joinhsz\rail@jput{\line(0,-1){\number\rail@tmpa}}\rail@jy=\rail@y\advance\rail@jy by \rail@boxsp\advance\rail@jy by \rail@joinhsz\advance\rail@jx by -\rail@joinhsz\rail@joval[br]\advance\rail@jy by -\rail@joinhsz\rail@tmpa=\rail@jx\advance\rail@tmpa by -\rail@sx\advance\rail@tmpa by -\rail@joinhsz\rail@jput{\line(-1,0){\number\rail@tmpa}}\rail@jx=\rail@sx\advance\rail@jx by \rail@joinhsz\advance\rail@jy by -\rail@joinhsz\rail@joval[tl]\advance\rail@jx by -\rail@joinhsz\rail@tmpa=\rail@boxsp\advance\rail@tmpa by -\rail@joinsz\rail@jput{\line(0,-1){\number\rail@tmpa}}\advance\rail@jy by -\rail@tmpa\advance\rail@jx by \rail@joinhsz\rail@joval[bl]\rail@x=\rail@jx\rail@ex=\rail@x}