doc-src/rail.sty
author wenzelm
Tue Jul 31 21:19:23 2007 +0200 (2007-07-31)
changeset 24101 bdcefe679ced
parent 13044 c049910774cb
permissions -rw-r--r--
with_charset: setmp_noncritical;
     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 % 22-Feb-98 K. Barthelmann	fixed catcodes of special characters
    11 % 18-Apr-98 K. Barthelmann	fixed \par handling
    12 % 19-May-98 J. Olsson		Added new macros to support arrow heads.
    13 % 26-Jul-98 K. Barthelmann	changed \par to output newlines
    14 %
    15 % This style file needs to be used in conjunction with the 'rail'
    16 % program. Running LaTeX as 'latex file' produces file.rai, which should be
    17 % processed by Rail with 'rail file'. This produces file.rao, which will
    18 % be picked up by LaTeX on the next 'latex file' run.
    19 %
    20 % LaTeX will warn if there is no file.rao or it's out of date.
    21 %
    22 % The macros in this file thus consist of two parts: those that read and
    23 % write the .rai and .rao files, and those that do the actual formatting
    24 % of the railroad diagrams.
    25 
    26 \NeedsTeXFormat{LaTeX2e}
    27 \ProvidesPackage{rail}[1998/05/19]
    28 
    29 % railroad diagram formatting parameters (user level)
    30 % all of these are copied into their internal versions by \railinit
    31 %
    32 % \railunit : \unitlength within railroad diagrams
    33 % \railextra : extra length at outside of diagram
    34 % \railboxheight : height of ovals and frames
    35 % \railboxskip : vertical space between lines
    36 % \railboxleft : space to the left of a box
    37 % \railboxright : space to the right of a box
    38 % \railovalspace : extra space around contents of oval
    39 % \railframespace : extra space around contents of frame
    40 % \railtextleft : space to the left of text
    41 % \railtextright : space to the right of text
    42 % \railtextup : space to lift text up
    43 % \railjoinsize : circle size of join/split arcs
    44 % \railjoinadjust : space to adjust join
    45 %
    46 % \railnamesep : separator between name and rule body
    47 
    48 \newlength\railunit
    49 \newlength\railextra
    50 \newlength\railboxheight
    51 \newlength\railboxskip
    52 \newlength\railboxleft
    53 \newlength\railboxright
    54 \newlength\railovalspace
    55 \newlength\railframespace
    56 \newlength\railtextleft
    57 \newlength\railtextright
    58 \newlength\railtextup
    59 \newlength\railjoinsize
    60 \newlength\railjoinadjust
    61 \newlength\railnamesep
    62 
    63 % initialize the parameters
    64 
    65 \setlength\railunit{1sp}
    66 \setlength\railextra{4ex}
    67 \setlength\railboxleft{1ex}
    68 \setlength\railboxright{1ex}
    69 \setlength\railovalspace{2ex}
    70 \setlength\railframespace{2ex}
    71 \setlength\railtextleft{1ex}
    72 \setlength\railtextright{1ex}
    73 \setlength\railjoinadjust{0pt}
    74 \setlength\railnamesep{1ex}
    75 
    76 \DeclareOption{10pt}{
    77   \setlength\railboxheight{16pt}
    78   \setlength\railboxskip{24pt}
    79   \setlength\railtextup{5pt}
    80   \setlength\railjoinsize{16pt}
    81 }
    82 \DeclareOption{11pt}{
    83   \setlength\railboxheight{16pt}
    84   \setlength\railboxskip{24pt}
    85   \setlength\railtextup{5pt}
    86   \setlength\railjoinsize{16pt}
    87 }
    88 \DeclareOption{12pt}{
    89   \setlength\railboxheight{20pt}
    90   \setlength\railboxskip{28pt}
    91   \setlength\railtextup{6pt}
    92   \setlength\railjoinsize{20pt}
    93 }
    94 
    95 \ExecuteOptions{10pt}
    96 \ProcessOptions
    97 
    98 % internal versions of the formatting parameters
    99 %
   100 % \rail@extra   : \railextra
   101 % \rail@boxht   : \railboxheight
   102 % \rail@boxsp   : \railboxskip
   103 % \rail@boxlf   : \railboxleft
   104 % \rail@boxrt   : \railboxright
   105 % \rail@boxhht  : \railboxheight / 2
   106 % \rail@ovalsp  : \railovalspace
   107 % \rail@framesp : \railframespace
   108 % \rail@textlf  : \railtextleft
   109 % \rail@textrt  : \railtextright
   110 % \rail@textup  : \railtextup
   111 % \rail@joinsz  : \railjoinsize
   112 % \rail@joinhsz : \railjoinsize / 2
   113 % \rail@joinadj : \railjoinadjust
   114 %
   115 % \railinit : internalize all of the parameters.
   116 
   117 \newcount\rail@extra
   118 \newcount\rail@boxht
   119 \newcount\rail@boxsp
   120 \newcount\rail@boxlf
   121 \newcount\rail@boxrt
   122 \newcount\rail@boxhht
   123 \newcount\rail@ovalsp
   124 \newcount\rail@framesp
   125 \newcount\rail@textlf
   126 \newcount\rail@textrt
   127 \newcount\rail@textup
   128 \newcount\rail@joinsz
   129 \newcount\rail@joinhsz
   130 \newcount\rail@joinadj
   131 
   132 \newcommand\railinit{
   133 \rail@extra=\railextra
   134 \divide\rail@extra by \railunit
   135 \rail@boxht=\railboxheight
   136 \divide\rail@boxht by \railunit
   137 \rail@boxsp=\railboxskip
   138 \divide\rail@boxsp by \railunit
   139 \rail@boxlf=\railboxleft
   140 \divide\rail@boxlf by \railunit
   141 \rail@boxrt=\railboxright
   142 \divide\rail@boxrt by \railunit
   143 \rail@boxhht=\railboxheight
   144 \divide\rail@boxhht by \railunit
   145 \divide\rail@boxhht by 2
   146 \rail@ovalsp=\railovalspace
   147 \divide\rail@ovalsp by \railunit
   148 \rail@framesp=\railframespace
   149 \divide\rail@framesp by \railunit
   150 \rail@textlf=\railtextleft
   151 \divide\rail@textlf by \railunit
   152 \rail@textrt=\railtextright
   153 \divide\rail@textrt by \railunit
   154 \rail@textup=\railtextup
   155 \divide\rail@textup by \railunit
   156 \rail@joinsz=\railjoinsize
   157 \divide\rail@joinsz by \railunit
   158 \rail@joinhsz=\railjoinsize
   159 \divide\rail@joinhsz by \railunit
   160 \divide\rail@joinhsz by 2
   161 \rail@joinadj=\railjoinadjust
   162 \divide\rail@joinadj by \railunit
   163 }
   164 
   165 \AtBeginDocument{\railinit}
   166 
   167 % \rail@param : declarations for list environment
   168 %
   169 % \railparam{TEXT} : sets \rail@param to TEXT
   170 %
   171 % \rail@reserved : characters reserved for grammar
   172 
   173 \newcommand\railparam[1]{
   174 \def\rail@param{
   175   \setlength\leftmargin{0pt}\setlength\rightmargin{0pt}
   176   \setlength\labelwidth{0pt}\setlength\labelsep{0pt}
   177   \setlength\itemindent{0pt}\setlength\listparindent{0pt}
   178   #1
   179 }
   180 }
   181 \railparam{}
   182 
   183 \newtoks\rail@reserved
   184 \rail@reserved={:;|*+?[]()'"}
   185 
   186 % \rail@termfont : format setup for terminals
   187 %
   188 % \rail@nontfont : format setup for nonterminals
   189 %
   190 % \rail@annofont : format setup for annotations
   191 %
   192 % \rail@rulefont : format setup for rule names
   193 %
   194 % \rail@indexfont : format setup for index entry
   195 %
   196 % \railtermfont{TEXT} : set terminal format setup to TEXT
   197 %
   198 % \railnontermfont{TEXT} : set nonterminal format setup to TEXT
   199 %
   200 % \railannotatefont{TEXT} : set annotation format setup to TEXT
   201 %
   202 % \railnamefont{TEXT} : set rule name format setup to TEXT
   203 %
   204 % \railindexfont{TEXT} : set index entry format setup to TEXT
   205 
   206 \def\rail@termfont{\ttfamily\upshape}
   207 \def\rail@nontfont{\rmfamily\upshape}
   208 \def\rail@annofont{\rmfamily\itshape}
   209 \def\rail@namefont{\rmfamily\itshape}
   210 \def\rail@indexfont{\rmfamily\itshape}
   211 
   212 \newcommand\railtermfont[1]{
   213 \def\rail@termfont{#1}
   214 }
   215 
   216 \newcommand\railnontermfont[1]{
   217 \def\rail@nontfont{#1}
   218 }
   219 
   220 \newcommand\railannotatefont[1]{
   221 \def\rail@annofont{#1}
   222 }
   223 
   224 \newcommand\railnamefont[1]{
   225 \def\rail@namefont{#1}
   226 }
   227 
   228 \newcommand\railindexfont[1]{
   229 \def\rail@indexfont{#1}
   230 }
   231 
   232 % railroad read/write macros
   233 %
   234 % \begin{rail} TEXT \end{rail} : TEXT is written out to the .rai file,
   235 %                                as \rail@i{NR}{TEXT}. Then the matching
   236 %                                \rail@o{NR}{FMT} from the .rao file is
   237 %                                executed (if defined).
   238 %
   239 % \railoptions{OPTIONS} : OPTIONS are written out to the .rai file,
   240 %                         as \rail@p{OPTIONS}.
   241 %
   242 % \railterm{IDENT,IDENT,...} : format IDENT as terminals. writes out
   243 %                              \rail@t{IDENT} to the .rai file
   244 %
   245 % \railalias{IDENT}{TEXT} : format IDENT as TEXT. defines \rail@t@IDENT as
   246 %                           TEXT.
   247 %
   248 % \railtoken{IDENT}{TEXT} : abbreviates \railalias{IDENT}{TEXT}\railterm{IDENT}
   249 %                           (for backward compatibility)
   250 %
   251 % \rail@setcodes : guards special characters
   252 %
   253 % \rail@makeother{CHARACTER} : sets \catcode of CHARACTER to "other"
   254 %                              used inside a loop for \rail@setcodes
   255 %
   256 % \rail@nr : railroad diagram counter
   257 %
   258 % \ifrail@match : current \rail@i{NR}{TEXT} matches
   259 %
   260 % \rail@first : actions to be done first. read in .rao file,
   261 %               open .rai file if \@filesw true, undefine \rail@first.
   262 %               executed from \begin{rail}, \railoptions and \railterm.
   263 %
   264 % \rail@i{NR}{TEXT} : defines \rail@i@NR as TEXT. written to the .rai
   265 %                     file by \rail, read from the .rao file by
   266 %                     \rail@first
   267 %
   268 % \rail@t{IDENT} : tells Rail that IDENT is to be custom formatted,
   269 %                  written to the .rai file by \railterm.
   270 %
   271 % \rail@o{NR}{TEXT} : defines \rail@o@NR as TEXT, read from the .rao
   272 %                     file by \rail@first.
   273 %
   274 % \rail@p{OPTIONS} : pass options to rail, written to the .rai file by
   275 %                    \railoptions
   276 %
   277 % \rail@write{TEXT} : write TEXT to the .rai file
   278 %
   279 % \rail@warn : warn user for mismatching diagrams
   280 %
   281 % \rail@endwarn : either \relax or \rail@warn
   282 %
   283 % \ifrail@all : checked at the end of the document
   284 
   285 \def\rail@makeother#1{
   286   \expandafter\catcode\expandafter`\csname\string #1\endcsname=12
   287 }
   288 
   289 \def\rail@setcodes{
   290 \let\par=\relax
   291 \let\\=\relax
   292 \expandafter\@tfor\expandafter\rail@symbol\expandafter:\expandafter=%
   293   \the\rail@reserved
   294 \do{\expandafter\rail@makeother\rail@symbol}
   295 }
   296 
   297 \newcount\rail@nr
   298 
   299 \newif\ifrail@all
   300 \rail@alltrue
   301 
   302 \newif\ifrail@match
   303 
   304 \def\rail@first{
   305 \begingroup
   306 \makeatletter
   307 \rail@setcodes
   308 \InputIfFileExists{\jobname.rao}{}{\PackageInfo{rail}{No file \jobname.rao}}
   309 \makeatother
   310 \endgroup
   311 \if@filesw
   312 \newwrite\tf@rai
   313 \immediate\openout\tf@rai=\jobname.rai
   314 \fi
   315 \global\let\rail@first=\relax
   316 }
   317 
   318 \long\def\rail@body#1\end{
   319 {
   320 \newlinechar=`^^J
   321 \def\par{\string\par^^J}
   322 \rail@write{\string\rail@i{\number\rail@nr}{#1}}
   323 }
   324 \xdef\rail@i@{#1}
   325 \end
   326 }
   327 
   328 \newenvironment{rail}{
   329 \global\advance\rail@nr by 1
   330 \rail@first
   331 \begingroup
   332 \rail@setcodes
   333 \rail@body
   334 }{
   335 \endgroup
   336 \rail@matchtrue
   337 \@ifundefined{rail@o@\number\rail@nr}{\rail@matchfalse}{}
   338 \expandafter\ifx\csname rail@i@\number\rail@nr\endcsname\rail@i@
   339 \else
   340 \rail@matchfalse
   341 \fi
   342 \ifrail@match
   343 \csname rail@o@\number\rail@nr\endcsname
   344 \else
   345 \PackageWarning{rail}{Railroad diagram {\number\rail@nr} doesn't match}
   346 \global\let\rail@endwarn=\rail@warn
   347 \begin{list}{}{\rail@param}
   348 \rail@begin{1}{}
   349 \rail@setbox{\bfseries ???}
   350 \rail@oval
   351 \rail@end
   352 \end{list}
   353 \fi
   354 }
   355 
   356 \newcommand\railoptions[1]{
   357 \rail@first
   358 \rail@write{\string\rail@p{#1}}
   359 }
   360 
   361 \newcommand\railterm[1]{
   362 \rail@first
   363 \@for\rail@@:=#1\do{
   364 \rail@write{\string\rail@t{\rail@@}}
   365 }
   366 }
   367 
   368 \newcommand\railalias[2]{
   369 \expandafter\def\csname rail@t@#1\endcsname{#2}
   370 }
   371 
   372 \newcommand\railtoken[2]{\railalias{#1}{#2}\railterm{#1}}
   373 
   374 \long\def\rail@i#1#2{
   375 \expandafter\gdef\csname rail@i@#1\endcsname{#2}
   376 }
   377 
   378 \def\rail@o#1#2{
   379 \expandafter\gdef\csname rail@o@#1\endcsname{
   380 \begin{list}{}{\rail@param}
   381 #2
   382 \end{list}
   383 }
   384 }
   385 
   386 \def\rail@t#1{}
   387 
   388 \def\rail@p#1{}
   389 
   390 \long\def\rail@write#1{\@ifundefined{tf@rai}{}{\immediate\write\tf@rai{#1}}}
   391 
   392 \def\rail@warn{
   393 \PackageWarningNoLine{rail}{Railroad diagram(s) may have changed.
   394                             Use 'rail' and rerun}
   395 }
   396 
   397 \let\rail@endwarn=\relax
   398 
   399 \AtEndDocument{\rail@endwarn}
   400 
   401 % index entry macro
   402 %
   403 % \rail@index{IDENT} : add index entry for IDENT
   404 
   405 \def\rail@index#1{
   406 \index{\rail@indexfont#1}
   407 }
   408 
   409 % railroad formatting primitives
   410 %
   411 % \rail@x : current x
   412 % \rail@y : current y
   413 % \rail@ex : current end x
   414 % \rail@sx : starting x for \rail@cr
   415 % \rail@rx : rightmost previous x for \rail@cr
   416 %
   417 % \rail@tmpa : temporary count
   418 % \rail@tmpb : temporary count
   419 % \rail@tmpc : temporary count
   420 %
   421 % \rail@put : put at (\rail@x,\rail@y)
   422 % \rail@vput : put vector at (\rail@x,\rail@y)
   423 %
   424 % \rail@eline : end line by drawing from \rail@ex to \rail@x
   425 %
   426 % \rail@vreline : end line by drawing a vector from \rail@x to \rail@ex
   427 %
   428 % \rail@vleline : end line by drawing a vector from \rail@ex to \rail@x
   429 %
   430 % \rail@sety{LEVEL} : set \rail@y to level LEVEL
   431 
   432 \newcount\rail@x
   433 \newcount\rail@y
   434 \newcount\rail@ex
   435 \newcount\rail@sx
   436 \newcount\rail@rx
   437 
   438 \newcount\rail@tmpa
   439 \newcount\rail@tmpb
   440 \newcount\rail@tmpc
   441 
   442 \def\rail@put{\put(\number\rail@x,\number\rail@y)}
   443 
   444 \def\rail@vput{\put(\number\rail@ex,\number\rail@y)}
   445 
   446 \def\rail@eline{
   447 \rail@tmpb=\rail@x
   448 \advance\rail@tmpb by -\rail@ex
   449 \rail@put{\line(-1,0){\number\rail@tmpb}}
   450 }
   451 
   452 \def\rail@vreline{
   453 \rail@tmpb=\rail@x
   454 \advance\rail@tmpb by -\rail@ex
   455 \rail@vput{\vector(1,0){\number\rail@tmpb}}
   456 }
   457 
   458 \def\rail@vleline{
   459 \rail@tmpb=\rail@x
   460 \advance\rail@tmpb by -\rail@ex
   461 \rail@put{\vector(-1,0){\number\rail@tmpb}}
   462 }
   463 
   464 \def\rail@sety#1{
   465 \rail@y=#1
   466 \multiply\rail@y by -\rail@boxsp
   467 \advance\rail@y by -\rail@boxht
   468 }
   469 
   470 % \rail@begin{HEIGHT}{NAME} : begin a railroad diagram of height HEIGHT
   471 %
   472 % \rail@end : end a railroad diagram
   473 %
   474 % \rail@expand{IDENT} : expand IDENT
   475 
   476 \def\rail@begin#1#2{
   477 \item
   478 \begin{minipage}[t]{\linewidth}
   479 \ifx\@empty#2\else
   480 {\rail@namefont \rail@expand{#2}}\\*[\railnamesep]
   481 \fi
   482 \unitlength=\railunit
   483 \rail@tmpa=#1
   484 \multiply\rail@tmpa by \rail@boxsp
   485 \begin{picture}(0,\number\rail@tmpa)(0,-\number\rail@tmpa)
   486 \rail@ex=0
   487 \rail@rx=0
   488 \rail@x=\rail@extra
   489 \rail@sx=\rail@x
   490 \rail@sety{0}
   491 }
   492 
   493 \def\rail@end{
   494 \advance\rail@x by \rail@extra
   495 \rail@eline
   496 \end{picture}
   497 \end{minipage}
   498 }
   499 
   500 \def\rail@vend{
   501 \advance\rail@x by \rail@extra
   502 \rail@vreline
   503 \end{picture}
   504 \end{minipage}
   505 }
   506 
   507 \def\rail@expand#1{\@ifundefined{rail@t@#1}{#1}{\csname rail@t@#1\endcsname}}
   508 
   509 % \rail@token{TEXT}[ANNOT] : format token TEXT with annotation
   510 % \rail@ltoken{TEXT}[ANNOT] : format token TEXT with annotation, arrow left
   511 % \rail@rtoken{TEXT}[ANNOT] : format token TEXT with annotation, arrow right
   512 %
   513 % \rail@ctoken{TEXT}[ANNOT] : format token TEXT centered with annotation
   514 % \rail@lctoken{TEXT}[ANNOT] : format token TEXT centered with annotation, arrow left
   515 % \rail@rctoken{TEXT}[ANNOT] : format token TEXT centered with annotation, arrow right
   516 %
   517 % \rail@nont{TEXT}[ANNOT] : format nonterminal TEXT with annotation
   518 % \rail@lnont{TEXT}[ANNOT] : format nonterminal TEXT with annotation, arrow left
   519 % \rail@rnont{TEXT}[ANNOT] : format nonterminal TEXT with annotation. arrow right
   520 %
   521 % \rail@cnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation
   522 % \rail@lcnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation,
   523 %                             arrow left
   524 % \rail@rcnont{TEXT}[ANNOT] : format nonterminal TEXT centered with annotation,
   525 %                             arrow right
   526 %
   527 % \rail@term{TEXT}[ANNOT] : format terminal TEXT with annotation
   528 % \rail@lterm{TEXT}[ANNOT] : format terminal TEXT with annotation, arrow left
   529 % \rail@rterm{TEXT}[ANNOT] : format terminal TEXT with annotation, arrow right
   530 %
   531 % \rail@cterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation
   532 % \rail@lcterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation, arrow left
   533 % \rail@rcterm{TEXT}[ANNOT] : format terminal TEXT centered with annotation,
   534 %                             arrow right
   535 %
   536 % \rail@annote[TEXT] : format TEXT as annotation
   537 
   538 \def\rail@token#1[#2]{
   539 \rail@setbox{%
   540 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   541 }
   542 \rail@oval
   543 }
   544 
   545 \def\rail@ltoken#1[#2]{
   546 \rail@setbox{%
   547 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   548 }
   549 \rail@vloval
   550 }
   551 
   552 \def\rail@rtoken#1[#2]{
   553 \rail@setbox{%
   554 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   555 }
   556 \rail@vroval
   557 }
   558 
   559 \def\rail@ctoken#1[#2]{
   560 \rail@setbox{%
   561 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   562 }
   563 \rail@coval
   564 }
   565 
   566 \def\rail@lctoken#1[#2]{
   567 \rail@setbox{%
   568 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   569 }
   570 \rail@vlcoval
   571 }
   572 
   573 \def\rail@rctoken#1[#2]{
   574 \rail@setbox{%
   575 {\rail@termfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   576 }
   577 \rail@vrcoval
   578 }
   579 
   580 \def\rail@nont#1[#2]{
   581 \rail@setbox{%
   582 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   583 }
   584 \rail@frame
   585 }
   586 
   587 \def\rail@lnont#1[#2]{
   588 \rail@setbox{%
   589 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   590 }
   591 \rail@vlframe
   592 }
   593 
   594 \def\rail@rnont#1[#2]{
   595 \rail@setbox{%
   596 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   597 }
   598 \rail@vrframe
   599 }
   600 
   601 \def\rail@cnont#1[#2]{
   602 \rail@setbox{%
   603 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   604 }
   605 \rail@cframe
   606 }
   607 
   608 \def\rail@lcnont#1[#2]{
   609 \rail@setbox{%
   610 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   611 }
   612 \rail@vlcframe
   613 }
   614 
   615 \def\rail@rcnont#1[#2]{
   616 \rail@setbox{%
   617 {\rail@nontfont \rail@expand{#1}}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   618 }
   619 \rail@vrcframe
   620 }
   621 
   622 \def\rail@term#1[#2]{
   623 \rail@setbox{%
   624 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   625 }
   626 \rail@oval
   627 }
   628 
   629 \def\rail@lterm#1[#2]{
   630 \rail@setbox{%
   631 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   632 }
   633 \rail@vloval
   634 }
   635 
   636 \def\rail@rterm#1[#2]{
   637 \rail@setbox{%
   638 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   639 }
   640 \rail@vroval
   641 }
   642 
   643 \def\rail@cterm#1[#2]{
   644 \rail@setbox{%
   645 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   646 }
   647 \rail@coval
   648 }
   649 
   650 \def\rail@lcterm#1[#2]{
   651 \rail@setbox{%
   652 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   653 }
   654 \rail@vlcoval
   655 }
   656 
   657 \def\rail@rcterm#1[#2]{
   658 \rail@setbox{%
   659 {\rail@termfont #1}\ifx\@empty#2\else\ {\rail@annofont #2}\fi
   660 }
   661 \rail@vrcoval
   662 }
   663 
   664 \def\rail@annote[#1]{
   665 \rail@setbox{\rail@annofont #1}
   666 \rail@text
   667 }
   668 
   669 % \rail@box : temporary box for \rail@oval and \rail@frame
   670 %
   671 % \rail@setbox{TEXT} : set \rail@box to TEXT, set \rail@tmpa to width
   672 %
   673 % \rail@oval : format \rail@box of width \rail@tmpa inside an oval
   674 % \rail@vloval : format \rail@box of width \rail@tmpa inside an oval, vector left
   675 % \rail@vroval : format \rail@box of width \rail@tmpa inside an oval, vector right
   676 %
   677 % \rail@coval : same as \rail@oval, but centered between \rail@x and
   678 %               \rail@mx
   679 % \rail@vlcoval : same as \rail@oval, but centered between \rail@x and
   680 %                 \rail@mx, vector left
   681 % \rail@vrcoval : same as \rail@oval, but centered between \rail@x and
   682 %                 \rail@mx, vector right
   683 %
   684 % \rail@frame : format \rail@box of width \rail@tmpa inside a frame
   685 % \rail@vlframe : format \rail@box of width \rail@tmpa inside a frame, vector left
   686 % \rail@vrframe : format \rail@box of width \rail@tmpa inside a frame, vector right
   687 %
   688 % \rail@cframe : same as \rail@frame, but centered between \rail@x and
   689 %                \rail@mx
   690 % \rail@vlcframe : same as \rail@frame, but centered between \rail@x and
   691 %                  \rail@mx, vector left
   692 % \rail@vrcframe : same as \rail@frame, but centered between \rail@x and
   693 %                  \rail@mx, vector right
   694 %
   695 % \rail@text : format \rail@box of width \rail@tmpa above the line
   696 
   697 \newbox\rail@box
   698 
   699 \def\rail@setbox#1{
   700 \setbox\rail@box\hbox{\strut#1}
   701 \rail@tmpa=\wd\rail@box
   702 \divide\rail@tmpa by \railunit
   703 }
   704 
   705 \def\rail@oval{
   706 \advance\rail@x by \rail@boxlf
   707 \rail@eline
   708 \advance\rail@tmpa by \rail@ovalsp
   709 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   710 \rail@tmpb=\rail@tmpa
   711 \divide\rail@tmpb by 2
   712 \advance\rail@y by -\rail@boxhht
   713 \rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   714 \advance\rail@y by \rail@boxhht
   715 \advance\rail@x by \rail@tmpb
   716 \rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}
   717 \advance\rail@x by \rail@tmpb
   718 \rail@ex=\rail@x
   719 \advance\rail@x by \rail@boxrt
   720 }
   721 
   722 \def\rail@vloval{
   723 \advance\rail@x by \rail@boxlf
   724 \rail@eline
   725 \advance\rail@tmpa by \rail@ovalsp
   726 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   727 \rail@tmpb=\rail@tmpa
   728 \divide\rail@tmpb by 2
   729 \advance\rail@y by -\rail@boxhht
   730 \rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   731 \advance\rail@y by \rail@boxhht
   732 \advance\rail@x by \rail@tmpb
   733 \rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}
   734 \advance\rail@x by \rail@tmpb
   735 \rail@ex=\rail@x
   736 \advance\rail@x by \rail@boxrt
   737 \rail@vleline
   738 }
   739 
   740 \def\rail@vroval{
   741 \advance\rail@x by \rail@boxlf
   742 \rail@vreline
   743 \advance\rail@tmpa by \rail@ovalsp
   744 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   745 \rail@tmpb=\rail@tmpa
   746 \divide\rail@tmpb by 2
   747 \advance\rail@y by -\rail@boxhht
   748 \rail@put{\makebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   749 \advance\rail@y by \rail@boxhht
   750 \advance\rail@x by \rail@tmpb
   751 \rail@put{\oval(\number\rail@tmpa,\number\rail@boxht)}
   752 \advance\rail@x by \rail@tmpb
   753 \rail@ex=\rail@x
   754 \advance\rail@x by \rail@boxrt
   755 }
   756 
   757 \def\rail@coval{
   758 \rail@tmpb=\rail@tmpa
   759 \advance\rail@tmpb by \rail@ovalsp
   760 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   761 \advance\rail@tmpb by \rail@boxlf
   762 \advance\rail@tmpb by \rail@boxrt
   763 \rail@tmpc=\rail@mx
   764 \advance\rail@tmpc by -\rail@x
   765 \advance\rail@tmpc by -\rail@tmpb
   766 \divide\rail@tmpc by 2
   767 \ifnum\rail@tmpc>0
   768 \advance\rail@x by \rail@tmpc
   769 \fi
   770 \rail@oval
   771 }
   772 
   773 \def\rail@vlcoval{
   774 \rail@tmpb=\rail@tmpa
   775 \advance\rail@tmpb by \rail@ovalsp
   776 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   777 \advance\rail@tmpb by \rail@boxlf
   778 \advance\rail@tmpb by \rail@boxrt
   779 \rail@tmpc=\rail@mx
   780 \advance\rail@tmpc by -\rail@x
   781 \advance\rail@tmpc by -\rail@tmpb
   782 \divide\rail@tmpc by 2
   783 \ifnum\rail@tmpc>0
   784 \advance\rail@x by \rail@tmpc
   785 \fi
   786 \rail@vloval
   787 }
   788 
   789 \def\rail@vrcoval{
   790 \rail@tmpb=\rail@tmpa
   791 \advance\rail@tmpb by \rail@ovalsp
   792 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   793 \advance\rail@tmpb by \rail@boxlf
   794 \advance\rail@tmpb by \rail@boxrt
   795 \rail@tmpc=\rail@mx
   796 \advance\rail@tmpc by -\rail@x
   797 \advance\rail@tmpc by -\rail@tmpb
   798 \divide\rail@tmpc by 2
   799 \ifnum\rail@tmpc>0
   800 \advance\rail@x by \rail@tmpc
   801 \fi
   802 \rail@vroval
   803 }
   804 
   805 \def\rail@frame{
   806 \advance\rail@x by \rail@boxlf
   807 \rail@eline
   808 \advance\rail@tmpa by \rail@framesp
   809 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   810 \advance\rail@y by -\rail@boxhht
   811 \rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   812 \advance\rail@y by \rail@boxhht
   813 \advance\rail@x by \rail@tmpa
   814 \rail@ex=\rail@x
   815 \advance\rail@x by \rail@boxrt
   816 }
   817 
   818 \def\rail@vlframe{
   819 \advance\rail@x by \rail@boxlf
   820 \rail@eline
   821 \advance\rail@tmpa by \rail@framesp
   822 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   823 \advance\rail@y by -\rail@boxhht
   824 \rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   825 \advance\rail@y by \rail@boxhht
   826 \advance\rail@x by \rail@tmpa
   827 \rail@ex=\rail@x
   828 \advance\rail@x by \rail@boxrt
   829 \rail@vleline
   830 }
   831 
   832 \def\rail@vrframe{
   833 \advance\rail@x by \rail@boxlf
   834 \rail@vreline
   835 \advance\rail@tmpa by \rail@framesp
   836 \ifnum\rail@tmpa<\rail@boxht\rail@tmpa=\rail@boxht\fi
   837 \advance\rail@y by -\rail@boxhht
   838 \rail@put{\framebox(\number\rail@tmpa,\number\rail@boxht){\box\rail@box}}
   839 \advance\rail@y by \rail@boxhht
   840 \advance\rail@x by \rail@tmpa
   841 \rail@ex=\rail@x
   842 \advance\rail@x by \rail@boxrt
   843 }
   844 
   845 \def\rail@cframe{
   846 \rail@tmpb=\rail@tmpa
   847 \advance\rail@tmpb by \rail@framesp
   848 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   849 \advance\rail@tmpb by \rail@boxlf
   850 \advance\rail@tmpb by \rail@boxrt
   851 \rail@tmpc=\rail@mx
   852 \advance\rail@tmpc by -\rail@x
   853 \advance\rail@tmpc by -\rail@tmpb
   854 \divide\rail@tmpc by 2
   855 \ifnum\rail@tmpc>0
   856 \advance\rail@x by \rail@tmpc
   857 \fi
   858 \rail@frame
   859 }
   860 
   861 \def\rail@vlcframe{
   862 \rail@tmpb=\rail@tmpa
   863 \advance\rail@tmpb by \rail@framesp
   864 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   865 \advance\rail@tmpb by \rail@boxlf
   866 \advance\rail@tmpb by \rail@boxrt
   867 \rail@tmpc=\rail@mx
   868 \advance\rail@tmpc by -\rail@x
   869 \advance\rail@tmpc by -\rail@tmpb
   870 \divide\rail@tmpc by 2
   871 \ifnum\rail@tmpc>0
   872 \advance\rail@x by \rail@tmpc
   873 \fi
   874 \rail@vlframe
   875 }
   876 
   877 \def\rail@vrcframe{
   878 \rail@tmpb=\rail@tmpa
   879 \advance\rail@tmpb by \rail@framesp
   880 \ifnum\rail@tmpb<\rail@boxht\rail@tmpb=\rail@boxht\fi
   881 \advance\rail@tmpb by \rail@boxlf
   882 \advance\rail@tmpb by \rail@boxrt
   883 \rail@tmpc=\rail@mx
   884 \advance\rail@tmpc by -\rail@x
   885 \advance\rail@tmpc by -\rail@tmpb
   886 \divide\rail@tmpc by 2
   887 \ifnum\rail@tmpc>0
   888 \advance\rail@x by \rail@tmpc
   889 \fi
   890 \rail@vrframe
   891 }
   892 
   893 \def\rail@text{
   894 \advance\rail@x by \rail@textlf
   895 \advance\rail@y by \rail@textup
   896 \rail@put{\box\rail@box}
   897 \advance\rail@y by -\rail@textup
   898 \advance\rail@x by \rail@tmpa
   899 \advance\rail@x by \rail@textrt
   900 }
   901 
   902 % alternatives
   903 %
   904 % \rail@jx \rail@jy : current join point
   905 %
   906 % \rail@gx \rail@gy \rail@gex \rail@grx : global versions of \rail@x etc,
   907 %                                         to pass values over group closings
   908 %
   909 % \rail@mx : maximum x so far
   910 %
   911 % \rail@sy : starting \rail@y for alternatives
   912 %
   913 % \rail@jput : put at (\rail@jx,\rail@jy)
   914 %
   915 % \rail@joval[PART] : put \oval[PART] with adjust
   916 
   917 \newcount\rail@jx
   918 \newcount\rail@jy
   919 
   920 \newcount\rail@gx
   921 \newcount\rail@gy
   922 \newcount\rail@gex
   923 \newcount\rail@grx
   924 
   925 \newcount\rail@sy
   926 \newcount\rail@mx
   927 
   928 \def\rail@jput{
   929 \put(\number\rail@jx,\number\rail@jy)
   930 }
   931 
   932 \def\rail@joval[#1]{
   933 \advance\rail@jx by \rail@joinadj
   934 \rail@jput{\oval(\number\rail@joinsz,\number\rail@joinsz)[#1]}
   935 \advance\rail@jx by -\rail@joinadj
   936 }
   937 
   938 % \rail@barsplit : incoming split for '|'
   939 %
   940 % \rail@plussplit : incoming split for '+'
   941 %
   942 
   943 \def\rail@barsplit{
   944 \advance\rail@jy by -\rail@joinhsz
   945 \rail@joval[tr]
   946 \advance\rail@jx by \rail@joinhsz
   947 }
   948 
   949 \def\rail@plussplit{
   950 \advance\rail@jy by -\rail@joinhsz
   951 \advance\rail@jx by \rail@joinsz
   952 \rail@joval[tl]
   953 \advance\rail@jx by -\rail@joinhsz
   954 }
   955 
   956 % \rail@alt{SPLIT} : start alternatives with incoming split SPLIT
   957 %
   958 
   959 \def\rail@alt#1{
   960 \rail@sy=\rail@y
   961 \rail@jx=\rail@x
   962 \rail@jy=\rail@y
   963 \advance\rail@x by \rail@joinsz
   964 \rail@mx=0
   965 \let\rail@list=\@empty
   966 \let\rail@comma=\@empty
   967 \let\rail@split=#1
   968 \begingroup
   969 \rail@sx=\rail@x
   970 \rail@rx=0
   971 }
   972 
   973 % \rail@nextalt{FIX}{Y} : start next alternative at vertical position Y
   974 %                         and fix-up FIX
   975 %
   976 
   977 \def\rail@nextalt#1#2{
   978 \global\rail@gx=\rail@x
   979 \global\rail@gy=\rail@y
   980 \global\rail@gex=\rail@ex
   981 \global\rail@grx=\rail@rx
   982 \endgroup
   983 #1
   984 \ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi
   985 \ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi
   986 \edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}
   987 \def\rail@comma{,}
   988 \rail@split
   989 \let\rail@split=\@empty
   990 \rail@sety{#2}
   991 \rail@tmpa=\rail@jy
   992 \advance\rail@tmpa by -\rail@y
   993 \advance\rail@tmpa by -\rail@joinhsz
   994 \rail@jput{\line(0,-1){\number\rail@tmpa}}
   995 \rail@jy=\rail@y
   996 \advance\rail@jy by \rail@joinhsz
   997 \advance\rail@jx by \rail@joinhsz
   998 \rail@joval[bl]
   999 \advance\rail@jx by -\rail@joinhsz
  1000 \rail@ex=\rail@x
  1001 \begingroup
  1002 \rail@sx=\rail@x
  1003 \rail@rx=0
  1004 }
  1005 
  1006 % \rail@barjoin : outgoing join for first '|' alternative
  1007 %
  1008 % \rail@plusjoin : outgoing join for first '+' alternative
  1009 %
  1010 % \rail@altjoin : join for subsequent alternative
  1011 %
  1012 
  1013 \def\rail@barjoin{
  1014 \ifnum\rail@y<\rail@sy
  1015 \global\rail@gex=\rail@jx
  1016 \else
  1017 \global\rail@gex=\rail@ex
  1018 \fi
  1019 \advance\rail@jy by -\rail@joinhsz
  1020 \rail@joval[tl]
  1021 \advance\rail@jx by -\rail@joinhsz
  1022 \ifnum\rail@y<\rail@sy
  1023 \rail@altjoin
  1024 \fi
  1025 }
  1026 
  1027 \def\rail@plusjoin{
  1028 \global\rail@gex=\rail@ex
  1029 \advance\rail@jy by -\rail@joinhsz
  1030 \advance\rail@jx by -\rail@joinsz
  1031 \rail@joval[tr]
  1032 \advance\rail@jx by \rail@joinhsz
  1033 }
  1034 
  1035 \def\rail@altjoin{
  1036 \rail@eline
  1037 \rail@tmpa=\rail@jy
  1038 \advance\rail@tmpa by -\rail@y
  1039 \advance\rail@tmpa by -\rail@joinhsz
  1040 \rail@jput{\line(0,-1){\number\rail@tmpa}}
  1041 \rail@jy=\rail@y
  1042 \advance\rail@jy by \rail@joinhsz
  1043 \advance\rail@jx by -\rail@joinhsz
  1044 \rail@joval[br]
  1045 \advance\rail@jx by \rail@joinhsz
  1046 }
  1047 
  1048 % \rail@eltsplit EX:Y; : split EX:Y into \rail@ex \rail@y
  1049 %
  1050 % \rail@endalt{JOIN} : end alternatives with outgoing join JOIN
  1051 
  1052 \def\rail@eltsplit#1:#2;{\rail@ex=#1\rail@y=#2}
  1053 
  1054 \def\rail@endalt#1{
  1055 \global\rail@gx=\rail@x
  1056 \global\rail@gy=\rail@y
  1057 \global\rail@gex=\rail@ex
  1058 \global\rail@grx=\rail@rx
  1059 \endgroup
  1060 \ifnum\rail@gx>\rail@mx\rail@mx=\rail@gx\fi
  1061 \ifnum\rail@grx>\rail@mx\rail@mx=\rail@grx\fi
  1062 \edef\rail@list{\rail@list\rail@comma\number\rail@gex:\number\rail@gy}
  1063 \rail@x=\rail@mx
  1064 \rail@jx=\rail@x
  1065 \rail@jy=\rail@sy
  1066 \advance\rail@jx by \rail@joinsz
  1067 \let\rail@join=#1
  1068 \@for\rail@elt:=\rail@list\do{
  1069 \expandafter\rail@eltsplit\rail@elt;
  1070 \rail@join
  1071 \let\rail@join=\rail@altjoin
  1072 }
  1073 \rail@x=\rail@mx
  1074 \rail@y=\rail@sy
  1075 \rail@ex=\rail@gex
  1076 \advance\rail@x by \rail@joinsz
  1077 }
  1078 
  1079 % \rail@bar : start '|' alternatives
  1080 %
  1081 % \rail@nextbar : next '|' alternative
  1082 %
  1083 % \rail@endbar : end '|' alternatives
  1084 %
  1085 
  1086 \def\rail@bar{
  1087 \rail@alt\rail@barsplit
  1088 }
  1089 
  1090 \def\rail@nextbar{
  1091 \rail@nextalt\relax
  1092 }
  1093 
  1094 \def\rail@endbar{
  1095 \rail@endalt\rail@barjoin
  1096 }
  1097 
  1098 % \rail@plus : start '+' alternatives
  1099 %
  1100 % \rail@nextplus: next '+' alternative
  1101 %
  1102 % \rail@endplus : end '+' alternatives
  1103 %
  1104 
  1105 \def\rail@plus{
  1106 \rail@alt\rail@plussplit
  1107 }
  1108 
  1109 \def\rail@nextplus{
  1110 \rail@nextalt\rail@fixplus
  1111 }
  1112 
  1113 \def\rail@fixplus{
  1114 \ifnum\rail@gy<\rail@sy
  1115 \begingroup
  1116 \rail@x=\rail@gx
  1117 \rail@y=\rail@gy
  1118 \rail@ex=\rail@gex
  1119 \rail@rx=\rail@grx
  1120 \ifnum\rail@x<\rail@rx
  1121 \rail@x=\rail@rx
  1122 \fi
  1123 \rail@eline
  1124 \rail@jx=\rail@x
  1125 \rail@jy=\rail@y
  1126 \advance\rail@jy by \rail@joinhsz
  1127 \rail@joval[br]
  1128 \advance\rail@jx by \rail@joinhsz
  1129 \rail@tmpa=\rail@sy
  1130 \advance\rail@tmpa by -\rail@joinhsz
  1131 \advance\rail@tmpa by -\rail@jy
  1132 \rail@jput{\line(0,1){\number\rail@tmpa}}
  1133 \rail@jy=\rail@sy
  1134 \advance\rail@jy by -\rail@joinhsz
  1135 \advance\rail@jx by \rail@joinhsz
  1136 \rail@joval[tl]
  1137 \advance\rail@jy by \rail@joinhsz
  1138 \global\rail@gx=\rail@jx
  1139 \global\rail@gy=\rail@jy
  1140 \global\rail@gex=\rail@gx
  1141 \global\rail@grx=\rail@rx
  1142 \endgroup
  1143 \fi
  1144 }
  1145 
  1146 \def\rail@endplus{
  1147 \rail@endalt\rail@plusjoin
  1148 }
  1149 
  1150 % \rail@cr{Y} : carriage return to vertical position Y
  1151 
  1152 \def\rail@cr#1{
  1153 \rail@tmpa=\rail@sx
  1154 \advance\rail@tmpa by \rail@joinsz
  1155 \ifnum\rail@x<\rail@tmpa\rail@x=\rail@tmpa\fi
  1156 \rail@eline
  1157 \rail@jx=\rail@x
  1158 \rail@jy=\rail@y
  1159 \advance\rail@x by \rail@joinsz
  1160 \ifnum\rail@x>\rail@rx\rail@rx=\rail@x\fi
  1161 \advance\rail@jy by -\rail@joinhsz
  1162 \rail@joval[tr]
  1163 \advance\rail@jx by \rail@joinhsz
  1164 \rail@sety{#1}
  1165 \rail@tmpa=\rail@jy
  1166 \advance\rail@tmpa by -\rail@y
  1167 \advance\rail@tmpa by -\rail@boxsp
  1168 \advance\rail@tmpa by -\rail@joinhsz
  1169 \rail@jput{\line(0,-1){\number\rail@tmpa}}
  1170 \rail@jy=\rail@y
  1171 \advance\rail@jy by \rail@boxsp
  1172 \advance\rail@jy by \rail@joinhsz
  1173 \advance\rail@jx by -\rail@joinhsz
  1174 \rail@joval[br]
  1175 \advance\rail@jy by -\rail@joinhsz
  1176 \rail@tmpa=\rail@jx
  1177 \advance\rail@tmpa by -\rail@sx
  1178 \advance\rail@tmpa by -\rail@joinhsz
  1179 \rail@jput{\line(-1,0){\number\rail@tmpa}}
  1180 \rail@jx=\rail@sx
  1181 \advance\rail@jx by \rail@joinhsz
  1182 \advance\rail@jy by -\rail@joinhsz
  1183 \rail@joval[tl]
  1184 \advance\rail@jx by -\rail@joinhsz
  1185 \rail@tmpa=\rail@boxsp
  1186 \advance\rail@tmpa by -\rail@joinsz
  1187 \rail@jput{\line(0,-1){\number\rail@tmpa}}
  1188 \advance\rail@jy by -\rail@tmpa
  1189 \advance\rail@jx by \rail@joinhsz
  1190 \rail@joval[bl]
  1191 \rail@x=\rail@jx
  1192 \rail@ex=\rail@x
  1193 }