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