User Manual first draft.
[Faustine.git] / doc / user-manual-src / rail.sty
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 }