ProgTutorial/document/rail.sty
changeset 189 069d525f8f1d
parent 29 3e117bbf8316
equal deleted inserted replaced
188:8939b8fd8603 189:069d525f8f1d
       
     1 % rail.sty - style file to support railroad diagrams
       
     2 %
       
     3 % 09-Jul-90 L. Rooijakkers
       
     4 % 08-Oct-90 L. Rooijakkers	fixed centering bug when \rail@tmpc<0.
       
     5 % 07-Feb-91 L. Rooijakkers	added \railoptions command, indexing
       
     6 % 08-Feb-91 L. Rooijakkers	minor fixes
       
     7 % 28-Jun-94 K. Barthelmann	turned into LaTeX2e package
       
     8 % 08-Dec-96 K. Barthelmann	replaced \@writefile
       
     9 % 13-Dec-96 K. Barthelmann	cleanup
       
    10 %
       
    11 % This style file needs to be used in conjunction with the 'rail'
       
    12 % program. Running LaTeX as 'latex file' produces file.rai, which should be
       
    13 % processed by Rail with 'rail file'. This produces file.rao, which will
       
    14 % be picked up by LaTeX on the next 'latex file' run.
       
    15 %
       
    16 % LaTeX will warn if there is no file.rao or it's out of date.
       
    17 %
       
    18 % The macros in this file thus consist of two parts: those that read and
       
    19 % write the .rai and .rao files, and those that do the actual formatting
       
    20 % of the railroad diagrams.
       
    21 
       
    22 \NeedsTeXFormat{LaTeX2e}
       
    23 \ProvidesPackage{rail}[1996/12/13]
       
    24 
       
    25 % railroad diagram formatting parameters (user level)
       
    26 % all of these are copied into their internal versions by \railinit
       
    27 %
       
    28 % \railunit : \unitlength within railroad diagrams
       
    29 % \railextra : extra length at outside of diagram
       
    30 % \railboxheight : height of ovals and frames
       
    31 % \railboxskip : vertical space between lines
       
    32 % \railboxleft : space to the left of a box
       
    33 % \railboxright : space to the right of a box
       
    34 % \railovalspace : extra space around contents of oval
       
    35 % \railframespace : extra space around contents of frame
       
    36 % \railtextleft : space to the left of text
       
    37 % \railtextright : space to the right of text
       
    38 % \railtextup : space to lift text up
       
    39 % \railjoinsize : circle size of join/split arcs
       
    40 % \railjoinadjust : space to adjust join
       
    41 %
       
    42 % \railnamesep : separator between name and rule body
       
    43 
       
    44 \newlength\railunit
       
    45 \newlength\railextra
       
    46 \newlength\railboxheight
       
    47 \newlength\railboxskip
       
    48 \newlength\railboxleft
       
    49 \newlength\railboxright
       
    50 \newlength\railovalspace
       
    51 \newlength\railframespace
       
    52 \newlength\railtextleft
       
    53 \newlength\railtextright
       
    54 \newlength\railtextup
       
    55 \newlength\railjoinsize
       
    56 \newlength\railjoinadjust
       
    57 \newlength\railnamesep
       
    58 
       
    59 % initialize the parameters
       
    60 
       
    61 \setlength\railunit{1sp}
       
    62 \setlength\railextra{4ex}
       
    63 \setlength\railboxleft{1ex}
       
    64 \setlength\railboxright{1ex}
       
    65 \setlength\railovalspace{2ex}
       
    66 \setlength\railframespace{2ex}
       
    67 \setlength\railtextleft{1ex}
       
    68 \setlength\railtextright{1ex}
       
    69 \setlength\railjoinadjust{0pt}
       
    70 \setlength\railnamesep{1ex}
       
    71 
       
    72 \DeclareOption{10pt}{
       
    73   \setlength\railboxheight{16pt}
       
    74   \setlength\railboxskip{24pt}
       
    75   \setlength\railtextup{5pt}
       
    76   \setlength\railjoinsize{16pt}
       
    77 }
       
    78 \DeclareOption{11pt}{
       
    79   \setlength\railboxheight{16pt}
       
    80   \setlength\railboxskip{24pt}
       
    81   \setlength\railtextup{5pt}
       
    82   \setlength\railjoinsize{16pt}
       
    83 }
       
    84 \DeclareOption{12pt}{
       
    85   \setlength\railboxheight{20pt}
       
    86   \setlength\railboxskip{28pt}
       
    87   \setlength\railtextup{6pt}
       
    88   \setlength\railjoinsize{20pt}
       
    89 }
       
    90 
       
    91 \ExecuteOptions{10pt}
       
    92 \ProcessOptions
       
    93 
       
    94 % internal versions of the formatting parameters
       
    95 %
       
    96 % \rail@extra   : \railextra
       
    97 % \rail@boxht   : \railboxheight
       
    98 % \rail@boxsp   : \railboxskip
       
    99 % \rail@boxlf   : \railboxleft
       
   100 % \rail@boxrt   : \railboxright
       
   101 % \rail@boxhht  : \railboxheight / 2
       
   102 % \rail@ovalsp  : \railovalspace
       
   103 % \rail@framesp : \railframespace
       
   104 % \rail@textlf	: \railtextleft
       
   105 % \rail@textrt	: \railtextright
       
   106 % \rail@textup	: \railtextup
       
   107 % \rail@joinsz  : \railjoinsize
       
   108 % \rail@joinhsz : \railjoinsize / 2
       
   109 % \rail@joinadj : \railjoinadjust
       
   110 %
       
   111 % \railinit : internalize all of the parameters.
       
   112 
       
   113 \newcount\rail@extra
       
   114 \newcount\rail@boxht
       
   115 \newcount\rail@boxsp
       
   116 \newcount\rail@boxlf
       
   117 \newcount\rail@boxrt
       
   118 \newcount\rail@boxhht
       
   119 \newcount\rail@ovalsp
       
   120 \newcount\rail@framesp
       
   121 \newcount\rail@textlf
       
   122 \newcount\rail@textrt
       
   123 \newcount\rail@textup
       
   124 \newcount\rail@joinsz
       
   125 \newcount\rail@joinhsz
       
   126 \newcount\rail@joinadj
       
   127 
       
   128 \newcommand\railinit{
       
   129 \rail@extra=\railextra
       
   130 \divide\rail@extra by \railunit
       
   131 \rail@boxht=\railboxheight
       
   132 \divide\rail@boxht by \railunit
       
   133 \rail@boxsp=\railboxskip
       
   134 \divide\rail@boxsp by \railunit
       
   135 \rail@boxlf=\railboxleft
       
   136 \divide\rail@boxlf by \railunit
       
   137 \rail@boxrt=\railboxright
       
   138 \divide\rail@boxrt by \railunit
       
   139 \rail@boxhht=\railboxheight
       
   140 \divide\rail@boxhht by \railunit
       
   141 \divide\rail@boxhht by 2
       
   142 \rail@ovalsp=\railovalspace
       
   143 \divide\rail@ovalsp by \railunit
       
   144 \rail@framesp=\railframespace
       
   145 \divide\rail@framesp by \railunit
       
   146 \rail@textlf=\railtextleft
       
   147 \divide\rail@textlf by \railunit
       
   148 \rail@textrt=\railtextright
       
   149 \divide\rail@textrt by \railunit
       
   150 \rail@textup=\railtextup
       
   151 \divide\rail@textup by \railunit
       
   152 \rail@joinsz=\railjoinsize
       
   153 \divide\rail@joinsz by \railunit
       
   154 \rail@joinhsz=\railjoinsize
       
   155 \divide\rail@joinhsz by \railunit
       
   156 \divide\rail@joinhsz by 2
       
   157 \rail@joinadj=\railjoinadjust
       
   158 \divide\rail@joinadj by \railunit
       
   159 }
       
   160 
       
   161 \AtBeginDocument{\railinit}
       
   162 
       
   163 % \rail@param : declarations for list environment
       
   164 %
       
   165 % \railparam{TEXT} : sets \rail@param to TEXT
       
   166 
       
   167 \def\rail@param{}
       
   168 
       
   169 \newcommand\railparam[1]{
       
   170 \def\rail@param{#1}
       
   171 }
       
   172 
       
   173 % \rail@tokenfont : format setup for \railtoken identifiers
       
   174 %
       
   175 % \rail@termfont : format setup for terminals
       
   176 %
       
   177 % \rail@nontfont : format setup for nonterminals
       
   178 %
       
   179 % \rail@annofont : format setup for annotations
       
   180 %
       
   181 % \rail@rulefont : format setup for rule names
       
   182 %
       
   183 % \rail@indexfont : format setup for index entry
       
   184 %
       
   185 % \railtermfont{TEXT} : set terminal format setup to TEXT
       
   186 %
       
   187 % \railnontermfont{TEXT} : set nonterminal format setup to TEXT
       
   188 %
       
   189 % \railannotatefont{TEXT} : set annotation format setup to TEXT
       
   190 %
       
   191 % \railnamefont{TEXT} : set rule name format setup to TEXT
       
   192 %
       
   193 % \railindexfont{TEXT} : set index entry format setup to TEXT
       
   194 
       
   195 \def\rail@termfont{\ttfamily\upshape}
       
   196 \def\rail@nontfont{\rmfamily\upshape}
       
   197 \def\rail@annofont{\rmfamily\itshape}
       
   198 \def\rail@namefont{\rmfamily\itshape}
       
   199 \def\rail@indexfont{\rmfamily\itshape}
       
   200 
       
   201 \newcommand\railtermfont[1]{
       
   202 \def\rail@termfont{#1}
       
   203 }
       
   204 
       
   205 \newcommand\railnontermfont[1]{
       
   206 \def\rail@nontfont{#1}
       
   207 }
       
   208 
       
   209 \newcommand\railannotatefont[1]{
       
   210 \def\rail@annofont{#1}
       
   211 }
       
   212 
       
   213 \newcommand\railnamefont[1]{
       
   214 \def\rail@namefont{#1}
       
   215 }
       
   216 
       
   217 \newcommand\railindexfont[1]{
       
   218 \def\rail@indexfont{#1}
       
   219 }
       
   220 
       
   221 % railroad read/write macros
       
   222 %
       
   223 % \begin{rail} TEXT \end{rail} : TEXT is written out to the .rai file,
       
   224 %                                as \rail@i{NR}{TEXT}. Then the matching
       
   225 %                                \rail@o{NR}{FMT} from the .rao file is
       
   226 %                                executed (if defined).
       
   227 %
       
   228 % \railoptions{OPTIONS} : OPTIONS are written out to the .rai file,
       
   229 %                         as \rail@p{OPTIONS}.
       
   230 %
       
   231 % \railterm{IDENT,IDENT,...} : format IDENT as terminals. writes out
       
   232 %                              \rail@t{IDENT} to the .rai file
       
   233 %
       
   234 % \railalias{IDENT}{TEXT} : format IDENT as TEXT. defines \rail@t@IDENT as
       
   235 %                           TEXT.
       
   236 %
       
   237 % \rail@nr : railroad diagram counter
       
   238 %
       
   239 % \ifrail@match : current \rail@i{NR}{TEXT} matches
       
   240 %
       
   241 % \rail@first :	actions to be done first. read in .rao file,
       
   242 %               open .rai file if \@filesw true, undefine \rail@first.
       
   243 %               executed from \begin{rail} and \railtoken.
       
   244 %
       
   245 % \rail@i{NR}{TEXT} : defines \rail@i@NR as TEXT. written to the .rai
       
   246 %                     file by \rail, read from the .rao file by
       
   247 %                     \rail@first
       
   248 %
       
   249 % \rail@t{IDENT} : tells Rail that IDENT is to be custom formatted,
       
   250 %                  written to the .rai file by \railterm.
       
   251 %
       
   252 % \rail@o{NR}{TEXT} : defines \rail@o@NR as TEXT, read from the .rao
       
   253 %                     file by \rail@first.
       
   254 %
       
   255 % \rail@p{OPTIONS} : pass options to rail, written to the .rai file by
       
   256 %                    \railoptions
       
   257 %
       
   258 % \rail@write{TEXT} : write TEXT to the .rai file
       
   259 %
       
   260 % \rail@warn : warn user for mismatching diagrams
       
   261 %
       
   262 % \rail@endwarn : either \relax or \rail@warn
       
   263 %
       
   264 % \ifrail@all : checked at the end of the document
       
   265 
       
   266 \newcount\rail@nr
       
   267 
       
   268 \newif\ifrail@all
       
   269 \rail@alltrue
       
   270 
       
   271 \newif\ifrail@match
       
   272 
       
   273 \def\rail@first{
       
   274 \makeatletter
       
   275 \InputIfFileExists{\jobname.rao}{}{\PackageInfo{rail}{No file \jobname.rao}}
       
   276 \makeatother
       
   277 \if@filesw
       
   278 \newwrite\tf@rai
       
   279 \immediate\openout\tf@rai=\jobname.rai
       
   280 \fi
       
   281 \global\let\rail@first=\relax
       
   282 }
       
   283 
       
   284 \long\def\rail@body#1\end{
       
   285 \begingroup
       
   286 \let\\=\relax
       
   287 \xdef\rail@i@{#1}
       
   288 \rail@write{\string\rail@i{\number\rail@nr}{\rail@i@}}
       
   289 \endgroup
       
   290 \end
       
   291 }
       
   292 
       
   293 \newenvironment{rail}{
       
   294 \global\advance\rail@nr by 1
       
   295 \rail@first
       
   296 \rail@body
       
   297 }{
       
   298 \rail@matchtrue
       
   299 \@ifundefined{rail@o@\number\rail@nr}{\rail@matchfalse}{}
       
   300 \expandafter\ifx\csname rail@i@\number\rail@nr\endcsname\rail@i@
       
   301 \else
       
   302 \rail@matchfalse
       
   303 \fi
       
   304 \ifrail@match
       
   305 \csname rail@o@\number\rail@nr\endcsname
       
   306 \else
       
   307 \PackageWarning{rail}{Railroad diagram {\number\rail@nr} doesn't match}
       
   308 \global\let\rail@endwarn=\rail@warn
       
   309 \begin{list}{}{\rail@param}
       
   310 \rail@begin{1}{}
       
   311 \rail@setbox{\bfseries ???}
       
   312 \rail@oval
       
   313 \rail@end
       
   314 \end{list}
       
   315 \fi
       
   316 }
       
   317 
       
   318 \newcommand\railoptions[1]{
       
   319 \rail@first
       
   320 \rail@write{\string\rail@p{#1}}
       
   321 }
       
   322 
       
   323 \newcommand\railterm[1]{
       
   324 \rail@first
       
   325 \@for\rail@@:=#1\do{
       
   326 \rail@write{\string\rail@t{\rail@@}}
       
   327 }
       
   328 }
       
   329 
       
   330 \newcommand\railalias[2]{
       
   331 \expandafter\def\csname rail@t@#1\endcsname{#2}
       
   332 }
       
   333 
       
   334 \long\def\rail@i#1#2{
       
   335 \expandafter\gdef\csname rail@i@#1\endcsname{#2}
       
   336 }
       
   337 
       
   338 \def\rail@o#1#2{
       
   339 \expandafter\gdef\csname rail@o@#1\endcsname{
       
   340 \begin{list}{}{\rail@param}#2\end{list}
       
   341 }
       
   342 }
       
   343 
       
   344 \def\rail@t#1{}
       
   345 
       
   346 \def\rail@p#1{}
       
   347 
       
   348 \def\rail@write#1{\@ifundefined{tf@rai}{}{\immediate\write\tf@rai{#1}}}
       
   349 
       
   350 \def\rail@warn{
       
   351 \PackageWarningNoLine{rail}{Railroad diagram(s) may have changed.
       
   352                             Use 'rail' and rerun}
       
   353 }
       
   354 
       
   355 \let\rail@endwarn=\relax
       
   356 
       
   357 \AtEndDocument{\rail@endwarn}
       
   358 
       
   359 % index entry macro
       
   360 %
       
   361 % \rail@index{IDENT} : add index entry for IDENT
       
   362 
       
   363 \def\rail@index#1{
       
   364 \index{\rail@indexfont#1}
       
   365 }
       
   366 
       
   367 % railroad formatting primitives
       
   368 %
       
   369 % \rail@x : current x
       
   370 % \rail@y : current y
       
   371 % \rail@ex : current end x
       
   372 % \rail@sx : starting x for \rail@cr
       
   373 % \rail@rx : rightmost previous x for \rail@cr
       
   374 %
       
   375 % \rail@tmpa : temporary count
       
   376 % \rail@tmpb : temporary count
       
   377 % \rail@tmpc : temporary count
       
   378 %
       
   379 % \rail@put : put at (\rail@x,\rail@y)
       
   380 %
       
   381 % \rail@eline : end line by drawing from \rail@ex to \rail@x
       
   382 %
       
   383 % \rail@sety{LEVEL} : set \rail@y to level LEVEL
       
   384 
       
   385 \newcount\rail@x
       
   386 \newcount\rail@y
       
   387 \newcount\rail@ex
       
   388 \newcount\rail@sx
       
   389 \newcount\rail@rx
       
   390 
       
   391 \newcount\rail@tmpa
       
   392 \newcount\rail@tmpb
       
   393 \newcount\rail@tmpc
       
   394 
       
   395 \def\rail@put{\put(\number\rail@x,\number\rail@y)}
       
   396 
       
   397 \def\rail@eline{
       
   398 \rail@tmpb=\rail@x
       
   399 \advance\rail@tmpb by -\rail@ex
       
   400 \rail@put{\line(-1,0){\number\rail@tmpb}}
       
   401 }
       
   402 
       
   403 \def\rail@sety#1{
       
   404 \rail@y=#1
       
   405 \multiply\rail@y by -\rail@boxsp
       
   406 \advance\rail@y by -\rail@boxht
       
   407 }
       
   408 
       
   409 % \rail@begin{HEIGHT}{NAME} : begin a railroad diagram of height HEIGHT
       
   410 %
       
   411 % \rail@end : end a railroad diagram
       
   412 %
       
   413 % \rail@expand{IDENT} : expand IDENT
       
   414 
       
   415 \def\rail@begin#1#2{
       
   416 \item[]
       
   417 \begin{minipage}[t]{\linewidth}
       
   418 \ifx\@empty#2\else
       
   419 {\rail@namefont \rail@expand{#2}}\\*[\railnamesep]
       
   420 \fi
       
   421 \unitlength=\railunit
       
   422 \rail@tmpa=#1
       
   423 \multiply\rail@tmpa by \rail@boxsp
       
   424 \begin{picture}(0,\number\rail@tmpa)(0,-\number\rail@tmpa)
       
   425 \rail@ex=0
       
   426 \rail@rx=0
       
   427 \rail@x=\rail@extra
       
   428 \rail@sx=\rail@x
       
   429 \rail@sety{0}
       
   430 }
       
   431 
       
   432 \def\rail@end{
       
   433 \advance\rail@x by \rail@extra
       
   434 \rail@eline
       
   435 \end{picture}
       
   436 \end{minipage}
       
   437 }
       
   438 
       
   439 \def\rail@expand#1{\@ifundefined{rail@t@#1}{#1}{\csname rail@t@#1\endcsname}}
       
   440 
       
   441 % \rail@token{TEXT}[ANNOT] : format token TEXT with annotation
       
   442 %
       
   443 % \rail@ctoken{TEXT}[ANNOT] : format token TEXT centered with annotation
       
   444 %
       
   445 % \rail@nont{TEXT}[ANNOT] : format nonterminal TEXT with annotation
       
   446 %
       
   447 % \rail@cnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation
       
   448 %
       
   449 % \rail@term{TEXT}[ANNOT] : format terminal TEXT with annotation
       
   450 %
       
   451 % \rail@cterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation
       
   452 %
       
   453 % \rail@annote[TEXT] : format TEXT as annotation
       
   454 
       
   455 \def\rail@token#1[#2]{
       
   456 \rail@setbox{%
       
   457 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   458 }
       
   459 \rail@oval
       
   460 }
       
   461 
       
   462 \def\rail@ctoken#1[#2]{
       
   463 \rail@setbox{%
       
   464 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   465 }
       
   466 \rail@coval
       
   467 }
       
   468 
       
   469 \def\rail@nont#1[#2]{
       
   470 \rail@setbox{%
       
   471 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   472 }
       
   473 \rail@frame
       
   474 }
       
   475 
       
   476 \def\rail@cnont#1[#2]{
       
   477 \rail@setbox{%
       
   478 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   479 }
       
   480 \rail@cframe
       
   481 }
       
   482 
       
   483 \def\rail@term#1[#2]{
       
   484 \rail@setbox{%
       
   485 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   486 }
       
   487 \rail@oval
       
   488 }
       
   489 
       
   490 \def\rail@cterm#1[#2]{
       
   491 \rail@setbox{%
       
   492 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
       
   493 }
       
   494 \rail@coval
       
   495 }
       
   496 
       
   497 \def\rail@annote[#1]{
       
   498 \rail@setbox{\rail@annofont #1}
       
   499 \rail@text
       
   500 }
       
   501 
       
   502 % \rail@box : temporary box for \rail@oval and \rail@frame
       
   503 %
       
   504 % \rail@setbox{TEXT} : set \rail@box to TEXT, set \rail@tmpa to width
       
   505 %
       
   506 % \rail@oval : format \rail@box of width \rail@tmpa inside an oval
       
   507 %
       
   508 % \rail@coval : same as \rail@oval, but centered between \rail@x and
       
   509 %               \rail@mx
       
   510 %
       
   511 % \rail@frame : format \rail@box of width \rail@tmpa inside a frame
       
   512 %
       
   513 % \rail@cframe : same as \rail@frame, but centered between \rail@x and
       
   514 %                \rail@mx
       
   515 %
       
   516 % \rail@text : format \rail@box of width \rail@tmpa above the line
       
   517 
       
   518 \newbox\rail@box
       
   519 
       
   520 \def\rail@setbox#1{
       
   521 \setbox\rail@box\hbox{\strut#1}
       
   522 \rail@tmpa=\wd\rail@box
       
   523 \divide\rail@tmpa by \railunit
       
   524 }
       
   525 
       
   526 \def\rail@oval{
       
   527 \advance\rail@x by \rail@boxlf
       
   528 \rail@eline
       
   529 \advance\rail@tmpa by \rail@ovalsp
       
   530 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
       
   531 \rail@tmpb=\rail@tmpa
       
   532 \divide\rail@tmpb by 2
       
   533 \advance\rail@y by -\rail@boxhht
       
   534 \rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
       
   535 \advance\rail@y by \rail@boxhht
       
   536 \advance\rail@x by \rail@tmpb
       
   537 \rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}
       
   538 \advance\rail@x by \rail@tmpb
       
   539 \rail@ex=\rail@x
       
   540 \advance\rail@x by \rail@boxrt
       
   541 }
       
   542 
       
   543 \def\rail@coval{
       
   544 \rail@tmpb=\rail@tmpa
       
   545 \advance\rail@tmpb by \rail@ovalsp
       
   546 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
       
   547 \advance\rail@tmpb by \rail@boxlf
       
   548 \advance\rail@tmpb by \rail@boxrt
       
   549 \rail@tmpc=\rail@mx
       
   550 \advance\rail@tmpc by -\rail@x
       
   551 \advance\rail@tmpc by -\rail@tmpb
       
   552 \divide\rail@tmpc by 2
       
   553 \ifnum\rail@tmpc>0
       
   554 \advance\rail@x by \rail@tmpc
       
   555 \fi
       
   556 \rail@oval
       
   557 }
       
   558 
       
   559 \def\rail@frame{
       
   560 \advance\rail@x by \rail@boxlf
       
   561 \rail@eline
       
   562 \advance\rail@tmpa by \rail@framesp
       
   563 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
       
   564 \advance\rail@y by -\rail@boxhht
       
   565 \rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
       
   566 \advance\rail@y by \rail@boxhht
       
   567 \advance\rail@x by \rail@tmpa
       
   568 \rail@ex=\rail@x
       
   569 \advance\rail@x by \rail@boxrt
       
   570 }
       
   571 
       
   572 \def\rail@cframe{
       
   573 \rail@tmpb=\rail@tmpa
       
   574 \advance\rail@tmpb by \rail@framesp
       
   575 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
       
   576 \advance\rail@tmpb by \rail@boxlf
       
   577 \advance\rail@tmpb by \rail@boxrt
       
   578 \rail@tmpc=\rail@mx
       
   579 \advance\rail@tmpc by -\rail@x
       
   580 \advance\rail@tmpc by -\rail@tmpb
       
   581 \divide\rail@tmpc by 2
       
   582 \ifnum\rail@tmpc>0
       
   583 \advance\rail@x by \rail@tmpc
       
   584 \fi
       
   585 \rail@frame
       
   586 }
       
   587 
       
   588 \def\rail@text{
       
   589 \advance\rail@x by \rail@textlf
       
   590 \advance\rail@y by \rail@textup
       
   591 \rail@put{\box\rail@box}
       
   592 \advance\rail@y by -\rail@textup
       
   593 \advance\rail@x by \rail@tmpa
       
   594 \advance\rail@x by \rail@textrt
       
   595 }
       
   596 
       
   597 % alternatives
       
   598 %
       
   599 % \rail@jx \rail@jy : current join point
       
   600 %
       
   601 % \rail@gx \rail@gy \rail@gex \rail@grx : global versions of \rail@x etc,
       
   602 %                                         to pass values over group closings
       
   603 %
       
   604 % \rail@mx : maximum x so far
       
   605 %
       
   606 % \rail@sy : starting \rail@y for alternatives
       
   607 %
       
   608 % \rail@jput : put at (\rail@jx,\rail@jy)
       
   609 %
       
   610 % \rail@joval[PART] : put \oval[PART] with adjust
       
   611 
       
   612 \newcount\rail@jx
       
   613 \newcount\rail@jy
       
   614 
       
   615 \newcount\rail@gx
       
   616 \newcount\rail@gy
       
   617 \newcount\rail@gex
       
   618 \newcount\rail@grx
       
   619 
       
   620 \newcount\rail@sy
       
   621 \newcount\rail@mx
       
   622 
       
   623 \def\rail@jput{
       
   624 \put(\number\rail@jx,\number\rail@jy)
       
   625 }
       
   626 
       
   627 \def\rail@joval[#1]{
       
   628 \advance\rail@jx by \rail@joinadj
       
   629 \rail@jput{\oval(\number\rail@joinsz,\number\rail@joinsz)[#1]}
       
   630 \advance\rail@jx by -\rail@joinadj
       
   631 }
       
   632 
       
   633 % \rail@barsplit : incoming split for '|'
       
   634 %
       
   635 % \rail@plussplit : incoming split for '+'
       
   636 %
       
   637 
       
   638 \def\rail@barsplit{
       
   639 \advance\rail@jy by -\rail@joinhsz
       
   640 \rail@joval[tr]
       
   641 \advance\rail@jx by \rail@joinhsz
       
   642 }
       
   643 
       
   644 \def\rail@plussplit{
       
   645 \advance\rail@jy by -\rail@joinhsz
       
   646 \advance\rail@jx by \rail@joinsz
       
   647 \rail@joval[tl]
       
   648 \advance\rail@jx by -\rail@joinhsz
       
   649 }
       
   650 
       
   651 % \rail@alt{SPLIT} : start alternatives with incoming split SPLIT
       
   652 %
       
   653 
       
   654 \def\rail@alt#1{
       
   655 \rail@sy=\rail@y
       
   656 \rail@jx=\rail@x
       
   657 \rail@jy=\rail@y
       
   658 \advance\rail@x by \rail@joinsz
       
   659 \rail@mx=0
       
   660 \let\rail@list=\@empty
       
   661 \let\rail@comma=\@empty
       
   662 \let\rail@split=#1
       
   663 \begingroup
       
   664 \rail@sx=\rail@x
       
   665 \rail@rx=0
       
   666 }
       
   667 
       
   668 % \rail@nextalt{FIX}{Y} : start next alternative at vertical position Y
       
   669 %                         and fix-up FIX
       
   670 %
       
   671 
       
   672 \def\rail@nextalt#1#2{
       
   673 \global\rail@gx=\rail@x
       
   674 \global\rail@gy=\rail@y
       
   675 \global\rail@gex=\rail@ex
       
   676 \global\rail@grx=\rail@rx
       
   677 \endgroup
       
   678 #1
       
   679 \ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi
       
   680 \ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi
       
   681 \edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}
       
   682 \def\rail@comma{,}
       
   683 \rail@split
       
   684 \let\rail@split=\@empty
       
   685 \rail@sety{#2}
       
   686 \rail@tmpa=\rail@jy
       
   687 \advance\rail@tmpa by -\rail@y
       
   688 \advance\rail@tmpa by -\rail@joinhsz
       
   689 \rail@jput{\line(0,-1){\number\rail@tmpa}}
       
   690 \rail@jy=\rail@y
       
   691 \advance\rail@jy by \rail@joinhsz
       
   692 \advance\rail@jx by \rail@joinhsz
       
   693 \rail@joval[bl]
       
   694 \advance\rail@jx by -\rail@joinhsz
       
   695 \rail@ex=\rail@x
       
   696 \begingroup
       
   697 \rail@sx=\rail@x
       
   698 \rail@rx=0
       
   699 }
       
   700 
       
   701 % \rail@barjoin : outgoing join for first '|' alternative
       
   702 %
       
   703 % \rail@plusjoin : outgoing join for first '+' alternative
       
   704 %
       
   705 % \rail@altjoin : join for subsequent alternative
       
   706 %
       
   707 
       
   708 \def\rail@barjoin{
       
   709 \ifnum\rail@y<\rail@sy
       
   710 \global\rail@gex=\rail@jx
       
   711 \else
       
   712 \global\rail@gex=\rail@ex
       
   713 \fi
       
   714 \advance\rail@jy by -\rail@joinhsz
       
   715 \rail@joval[tl]
       
   716 \advance\rail@jx by -\rail@joinhsz
       
   717 \ifnum\rail@y<\rail@sy
       
   718 \rail@altjoin
       
   719 \fi
       
   720 }
       
   721 
       
   722 \def\rail@plusjoin{
       
   723 \global\rail@gex=\rail@ex
       
   724 \advance\rail@jy by -\rail@joinhsz
       
   725 \advance\rail@jx by -\rail@joinsz
       
   726 \rail@joval[tr]
       
   727 \advance\rail@jx by \rail@joinhsz
       
   728 }
       
   729 
       
   730 \def\rail@altjoin{
       
   731 \rail@eline
       
   732 \rail@tmpa=\rail@jy
       
   733 \advance\rail@tmpa by -\rail@y
       
   734 \advance\rail@tmpa by -\rail@joinhsz
       
   735 \rail@jput{\line(0,-1){\number\rail@tmpa}}
       
   736 \rail@jy=\rail@y
       
   737 \advance\rail@jy by \rail@joinhsz
       
   738 \advance\rail@jx by -\rail@joinhsz
       
   739 \rail@joval[br]
       
   740 \advance\rail@jx by \rail@joinhsz
       
   741 }
       
   742 
       
   743 % \rail@eltsplit EX:Y; : split EX:Y into \rail@ex \rail@y
       
   744 %
       
   745 % \rail@endalt{JOIN} : end alternatives with outgoing join JOIN
       
   746 
       
   747 \def\rail@eltsplit#1:#2;{\rail@ex=#1\rail@y=#2}
       
   748 
       
   749 \def\rail@endalt#1{
       
   750 \global\rail@gx=\rail@x
       
   751 \global\rail@gy=\rail@y
       
   752 \global\rail@gex=\rail@ex
       
   753 \global\rail@grx=\rail@rx
       
   754 \endgroup
       
   755 \ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi
       
   756 \ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi
       
   757 \edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}
       
   758 \rail@x=\rail@mx
       
   759 \rail@jx=\rail@x
       
   760 \rail@jy=\rail@sy
       
   761 \advance\rail@jx by \rail@joinsz
       
   762 \let\rail@join=#1
       
   763 \@for\rail@elt:=\rail@list\do{
       
   764 \expandafter\rail@eltsplit\rail@elt;
       
   765 \rail@join
       
   766 \let\rail@join=\rail@altjoin
       
   767 }
       
   768 \rail@x=\rail@mx
       
   769 \rail@y=\rail@sy
       
   770 \rail@ex=\rail@gex
       
   771 \advance\rail@x by \rail@joinsz
       
   772 }
       
   773 
       
   774 % \rail@bar : start '|' alternatives
       
   775 %
       
   776 % \rail@nextbar : next '|' alternative
       
   777 %
       
   778 % \rail@endbar : end '|' alternatives
       
   779 %
       
   780 
       
   781 \def\rail@bar{
       
   782 \rail@alt\rail@barsplit
       
   783 }
       
   784 
       
   785 \def\rail@nextbar{
       
   786 \rail@nextalt\relax
       
   787 }
       
   788 
       
   789 \def\rail@endbar{
       
   790 \rail@endalt\rail@barjoin
       
   791 }
       
   792 
       
   793 % \rail@plus : start '+' alternatives
       
   794 %
       
   795 % \rail@nextplus: next '+' alternative
       
   796 %
       
   797 % \rail@endplus : end '+' alternatives
       
   798 %
       
   799 
       
   800 \def\rail@plus{
       
   801 \rail@alt\rail@plussplit
       
   802 }
       
   803 
       
   804 \def\rail@nextplus{
       
   805 \rail@nextalt\rail@fixplus
       
   806 }
       
   807 
       
   808 \def\rail@fixplus{
       
   809 \ifnum\rail@gy<\rail@sy
       
   810 \begingroup
       
   811 \rail@x=\rail@gx
       
   812 \rail@y=\rail@gy
       
   813 \rail@ex=\rail@gex
       
   814 \rail@rx=\rail@grx
       
   815 \ifnum\rail@x<\rail@rx
       
   816 \rail@x=\rail@rx
       
   817 \fi
       
   818 \rail@eline
       
   819 \rail@jx=\rail@x
       
   820 \rail@jy=\rail@y
       
   821 \advance\rail@jy by \rail@joinhsz
       
   822 \rail@joval[br]
       
   823 \advance\rail@jx by \rail@joinhsz
       
   824 \rail@tmpa=\rail@sy
       
   825 \advance\rail@tmpa by -\rail@joinhsz
       
   826 \advance\rail@tmpa by -\rail@jy
       
   827 \rail@jput{\line(0,1){\number\rail@tmpa}}
       
   828 \rail@jy=\rail@sy
       
   829 \advance\rail@jy by -\rail@joinhsz
       
   830 \advance\rail@jx by \rail@joinhsz
       
   831 \rail@joval[tl]
       
   832 \advance\rail@jy by \rail@joinhsz
       
   833 \global\rail@gx=\rail@jx
       
   834 \global\rail@gy=\rail@jy
       
   835 \global\rail@gex=\rail@gx
       
   836 \global\rail@grx=\rail@rx
       
   837 \endgroup
       
   838 \fi
       
   839 }
       
   840 
       
   841 \def\rail@endplus{
       
   842 \rail@endalt\rail@plusjoin
       
   843 }
       
   844 
       
   845 % \rail@cr{Y} : carriage return to vertical position Y
       
   846 
       
   847 \def\rail@cr#1{
       
   848 \rail@tmpa=\rail@sx
       
   849 \advance\rail@tmpa by \rail@joinsz
       
   850 \ifnum\rail@x<\rail@tmpa\rail@x=\rail@tmpa\fi
       
   851 \rail@eline
       
   852 \rail@jx=\rail@x
       
   853 \rail@jy=\rail@y
       
   854 \advance\rail@x by \rail@joinsz
       
   855 \ifnum\rail@x>\rail@rx\rail@rx=\rail@x\fi
       
   856 \advance\rail@jy by -\rail@joinhsz
       
   857 \rail@joval[tr]
       
   858 \advance\rail@jx by \rail@joinhsz
       
   859 \rail@sety{#1}
       
   860 \rail@tmpa=\rail@jy
       
   861 \advance\rail@tmpa by -\rail@y
       
   862 \advance\rail@tmpa by -\rail@boxsp
       
   863 \advance\rail@tmpa by -\rail@joinhsz
       
   864 \rail@jput{\line(0,-1){\number\rail@tmpa}}
       
   865 \rail@jy=\rail@y
       
   866 \advance\rail@jy by \rail@boxsp
       
   867 \advance\rail@jy by \rail@joinhsz
       
   868 \advance\rail@jx by -\rail@joinhsz
       
   869 \rail@joval[br]
       
   870 \advance\rail@jy by -\rail@joinhsz
       
   871 \rail@tmpa=\rail@jx
       
   872 \advance\rail@tmpa by -\rail@sx
       
   873 \advance\rail@tmpa by -\rail@joinhsz
       
   874 \rail@jput{\line(-1,0){\number\rail@tmpa}}
       
   875 \rail@jx=\rail@sx
       
   876 \advance\rail@jx by \rail@joinhsz
       
   877 \advance\rail@jy by -\rail@joinhsz
       
   878 \rail@joval[tl]
       
   879 \advance\rail@jx by -\rail@joinhsz
       
   880 \rail@tmpa=\rail@boxsp
       
   881 \advance\rail@tmpa by -\rail@joinsz
       
   882 \rail@jput{\line(0,-1){\number\rail@tmpa}}
       
   883 \advance\rail@jy by -\rail@tmpa
       
   884 \advance\rail@jx by \rail@joinhsz
       
   885 \rail@joval[bl]
       
   886 \rail@x=\rail@jx
       
   887 \rail@ex=\rail@x
       
   888 }