chiark / gitweb /
.mdw-build.conf: Don't try `vpath' builds with this package.
[mdwtools] / syntax.dtx
1 % \begin{meta-comment}
2 %
3 % syntax.dtx
4 %
5 % Syntax typesetting package for LaTeX 2e
6 %
7 % (c) 2003 Mark Wooding
8 %
9 % \end{meta-comment}
10 %
11 % \begin{meta-comment} <general public licence>
12 %%
13 %% syntax package -- typesetting syntax descriptions
14 %% Copyright (c) 2003 Mark Wooding
15 %%
16 %% This program is free software; you can redistribute it and/or modify
17 %% it under the terms of the GNU General Public License as published by
18 %% the Free Software Foundation; either version 2 of the License, or
19 %% (at your option) any later version.
20 %%
21 %% This program is distributed in the hope that it will be useful,
22 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
23 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 %% GNU General Public License for more details.
25 %%
26 %% You should have received a copy of the GNU General Public License
27 %% along with this program; if not, write to the Free Software
28 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 %%
30 % \end{meta-comment}
31 %
32 % \begin{meta-comment} <Package preamble>
33 %<+package>\NeedsTeXFormat{LaTeX2e}
34 %<+package>\ProvidesPackage{syntax}
35 %<+package>                [2003/08/25 1.08 Syntax typesetting (MDW)]
36 % \end{meta-comment}
37 %
38 % \CheckSum{1628}
39 %% \CharacterTable
40 %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
41 %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
42 %%   Digits        \0\1\2\3\4\5\6\7\8\9
43 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
44 %%   Dollar        \$     Percent       \%     Ampersand     \&
45 %%   Acute accent  \'     Left paren    \(     Right paren   \)
46 %%   Asterisk      \*     Plus          \+     Comma         \,
47 %%   Minus         \-     Point         \.     Solidus       \/
48 %%   Colon         \:     Semicolon     \;     Less than     \<
49 %%   Equals        \=     Greater than  \>     Question mark \?
50 %%   Commercial at \@     Left bracket  \[     Backslash     \\
51 %%   Right bracket \]     Circumflex    \^     Underscore    \_
52 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
53 %%   Right brace   \}     Tilde         \~}
54 %%
55 %
56 % \begin{meta-comment} <driver>
57 %
58 %<*driver>
59 %
60 % This hacking will remember the old default underscore character.  Even if
61 % T1 fonts are being used, it will get the grotty version.  Why is it that
62 % all of the encoding handling ends up looking like this?
63 %
64 \expandafter\let\expandafter\oldus\csname?\string\textunderscore\endcsname
65 %
66 \input{mdwtools}
67 \describespackage{syntax}
68 \DeclareRobustCommand\syn{\package{syntax}}
69 \mdwdoc
70 %</driver>
71 %
72 % \end{meta-comment}
73 %
74 % \section{User guide}
75 %
76 % \subsection{Introduction}
77 %
78 % The \syn\ package provides a number of commands and environments which
79 % extend \LaTeX\ and allow you to typeset good expositions of syntax.
80 %
81 % The package provides several different types of features: probably not all
82 % of these will be required by every document which needs the package:
83 % \begin{itemize}
84 % \item A system of abbreviated forms for typesetting syntactic items.
85 % \item An environment for typesetting BNF-type grammars
86 % \item A collection of environments for building syntax diagrams.
87 % \end{itemize}
88 %
89 % The package also includes some other features which, while not necessarily
90 % syntax-related, will probably come in handy for similar types of document:
91 % \begin{itemize}
92 % \item An abbreviated notation for verbatim text, similar to the
93 %       \package{shortvrb} package.
94 % \item A slightly different underscore character, which works as expected
95 %       in text and maths modes.
96 % \end{itemize}
97 %
98 % \subsection{The abbreviated verbatim notation}
99 %
100 % In documents describing programming languages and libraries, it can become
101 % tedious to type "\verb|...|" every time.  Like Frank Mittelbach's
102 % \package{shortvrb} package, \syn\ provides a way of setting up single-^^A
103 % character abbreviations.  The only real difference between the two is that
104 % the declarations provided by \syn\ obey \LaTeX's normal scoping rules.
105 %
106 % \DescribeMacro\shortverb
107 % You can set up a character as a `verbatim shorthand' character using the
108 % |\shortverb| command.  This takes a single argument, which should be a
109 % single-character control sequence containing the character you want to use.
110 % So, for example, the command
111 % \begin{listing}
112 %\shortverb{\|}
113 % \end{listing}
114 % would set up the `"|"' character to act as a verbatim delimiter.  While a
115 % |\shortverb| declaration is in force, any text surrounded by (in this case)
116 % vertical bar characters will be typeset as if using the normal |\verb|
117 % command.
118 %
119 % \DescribeEnv{shortverb}
120 % Since \LaTeX\ allows any declaration to be used as an environment, you can
121 % use a \env{shortverb} environment to delimit the text over which your
122 % character is active:
123 % \begin{listing}
124 %Some text...
125 %\begin{shortverb}{\|}
126 %...
127 %\end{shortverb}
128 % \end{listing}
129 %
130 % \DescribeMacro\unverb
131 % If you want to disable a |\shortverb| character without ending the scope
132 % of other declarations, you can use the |\unverb| command, passing it
133 % a character as a control sequence, in the same way as above.
134 %
135 % The default \TeX/\LaTeX\ underscore character is rather too short for
136 % use in identifiers.  For example:
137 %
138 % \begingroup \let\_=\oldus
139 % \begin{demo}{Old-style underscores}
140 %Typing long underscore-filled
141 %names, like big\_function\_name,
142 %is normally tedious.  The normal
143 %positioning of the underscore
144 %is wrong, too.
145 % \end{demo}
146 % \endgroup
147 %
148 % The \syn\ package redefines the |\_| command to draw a more attractive
149 % underscore character.  It also allows you to use the |_|~character
150 % directly to produce an underscore outside of maths mode: |_|~behaves
151 % as a subscript character as usual inside maths mode.
152 %
153 % \begin{demo}{New \syn\ underscores}
154 %You can use underscore-filled
155 %names, like big_function_name,
156 %simply and naturally.  Of
157 %course, subscripts still work
158 %normally in maths mode, e.g.,
159 %$x_i$.
160 % \end{demo}
161 %
162 % \subsection{Typesetting syntactic items}
163 % \begin{synshorts}
164 %
165 % The \syn\ package provides some simple commands for typesetting syntactic
166 % items.
167 %
168 % \DescribeMacro\synt
169 % Typing "\\synt{"<text>"}" typesets <text> as a \lq non-terminal',
170 % in italics and surrounded by angle brackets.  If you use "\\synt" a lot,
171 % you can use the incantation
172 % \begin{listing}
173 %\def\<#1>{\synt{#1}}
174 % \end{listing}
175 % to allow you to type "\\<"<text>">" as an alternative to
176 % "\\synt{"<text>"}".
177 %
178 % \DescribeMacro\lit
179 % You can also display literal text, which the reader should type directly,
180 % using the "\\lit" command.
181 %
182 % \begin{demo}{Use of \cmd\lit}
183 %Type \lit{ls} to display a
184 %list of files.
185 % \end{demo}
186 %
187 % Note that the literal text appears in quotes.  To suppress the quotes,
188 % use the `*' variant.
189 %
190 % The "\\lit" command produces slightly better output than "\\verb" for
191 % running text, since the spaces are somewhat narrower.  However, "\\verb"
192 % allows you to type arbitrary characters, which are treated literally,
193 % whereas you must use commands such as "\\{" to use special characters
194 % within the argument to "\\lit".  Of course, you can use "\\lit" anywhere
195 % in the document: "\\verb" mustn't be used inside a command argument.
196 % \end{synshorts}
197 %
198 % \subsection{Abbreviated forms for syntactic items}
199 %
200 % It would be very tedious to require the use of commands like |\synt|
201 % when building syntax descriptions like BNF grammars.  It would also make
202 % your \LaTeX\ source hard to read.  Therefore, \syn\ provides some
203 % abbreviated forms which make typesetting syntax quicker and easier.
204 %
205 % Since the abbreviated forms use several characters which you may want to
206 % use in normal text, they aren't enabled by default.  They only work
207 % with special commands and environments provided by the \syn\ package.
208 %
209 % The abbreviated forms are shown in the table below:
210 %
211 % \begin{tab}[\synshorts]{ll}                                       \hline
212 % \bf Input        & \bf Output                                  \\ \hline
213 % "<some text>"    & <some text>                                 \\
214 % "`some text'"    & `some text'                                 \\
215 % "\"some text\""  & "some text"                                 \\ \hline
216 % \end{tab}
217 %
218 % Within one of these abbreviated forms, text is treated more-or-less
219 % verbatim:
220 % \begin{itemize}
221 %
222 % \item Any |$|, |%|, |^|, |&|, |{|, |}|, |~| or |#| characters are treated
223 %       literally: their normal special meanings are ignored.
224 %
225 % \item Other special characters, with the exception of |\|, are also treated
226 %       literally: this includes any characters made special by |\shortverb|.
227 %
228 % \end{itemize}
229 %
230 % However, the |\| character retains its meaning.  Since the brace
231 % characters are not recognised, most commands can't be used within
232 % abbreviated forms.  However, you can use special commands to type some
233 % of the remaining special characters:
234 %
235 % \begin{tab}[\synshorts]{ll}                                       \hline
236 % \bf Command   & \bf Result                                     \\ \hline
237 % "\\\\"        & A `\\' character                               \\
238 % "\\>"         & A `>' character                                \\
239 % "\\'"         & A `\'' character                               \\
240 % "\\\""        & A `"' character                                \\
241 % "\\\ "        & A `\ ' character (not a space)                 \\ \hline
242 % \end{tab}
243 %
244 % Note that |\\|, |\>|, |\"| and \verb*|\ | are only useful in a |\tt| font,
245 % i.e., inside |`...'| and |"..."| forms, since the characters don't exist
246 % in normal fonts.  The |\>|, |\"| and |\'| commands are only provided so
247 % you can use these characters within |<...>|, |"..."| and |`...'| forms
248 % respectively: in the other forms, there is no need to use the special
249 % command.
250 %
251 % In addition, when the above abbreviations are enabled, the character "|"
252 % is set to typeset a \syntax{|} symbol, which is conventionally used to
253 % separate alternatives in syntax descriptions.
254 %
255 % \DescribeMacro\syntax
256 % Normally, these abbreviated forms are enabled only within special
257 % environments, such as \env{grammar} and \env{syntdiag}.  To use them
258 % in running text, use the |\syntax| command.  The abbreviations are made
259 % active within the argument of the |\syntax| command.\footnote{^^A
260 %   The argument of the \cmd\syntax\ command may contain commands such
261 %   as \cmd\verb, which are normally not allowed within arguments.
262 % }  Note that you cannot use the |\syntax| command within the argument
263 % of another command.
264 %
265 % \DescribeMacro\synshorts
266 % \DescribeEnv{synshorts}
267 % You can also enable the syntax shortcuts using the |\synshorts| declaration
268 % or the \env{synshorts} environment.  This enables the syntax shortcuts
269 % until the scope of the declaration ends.
270 %
271 % \DescribeMacro\synshortsoff
272 % If syntax shortcuts are enabled, you can disable them using the
273 % |\synshortsoff| declaration.
274 %
275 % \subsection{The \env{grammar} environment}
276 %
277 % \DescribeEnv{grammar}
278 % For typesetting formal grammars, for example, of programming languages,
279 % the \syn\ package provides a \env{grammar} environment.  Within this
280 % environment, the abbreviated forms described above are enabled.
281 %
282 % Within the environment, separate production rules should be separated by
283 % blank lines.  You can use the normal |\\| command to perform line-breaking
284 % of a production rule.  Note that a production rule must begin with a
285 % nonterminal name enclosed in angle brackets (|<| \dots |>|), followed by
286 % any decorative material, whitespace, some kind of production operator
287 % (usually `::=') and then some more whitespace.  You can control how this
288 % text is actually typeset, however.
289 %
290 % \DescribeMacro{\[[}
291 % \DescribeMacro{\]]}
292 % You can use syntax diagrams (see below) instead of a straight piece of BNF
293 % by enclosing it in a |\[[| \dots |\]]| pair.  Note that you can't mix
294 % syntax diagrams and BNF in a production rule, and you will get something
295 % which looks very strange if you try.
296 %
297 % \DescribeMacro\alt
298 % In addition, a command |\alt| is provided for splitting long production
299 % rules over several lines: the |\alt| command starts a new line and places
300 % a \syntax{|} character slightly in the left margin.  This is useful when
301 % a symbol has many alternative productions.
302 %
303 % \begin{demo}[w]{The \env{grammar} environment}
304 %\begin{grammar}
305 %<statement> ::= <ident> `=' <expr>
306 %  \alt `for' <ident> `=' <expr> `to' <expr> `do' <statement>
307 %  \alt `{' <stat-list> `}'
308 %  \alt <empty>
309 %
310 %<stat-list> ::= <statement> `;' <stat-list> | <statement>
311 %\end{grammar}
312 % \end{demo}
313 %
314 % You can modify the appearance of grammars using three length parameters:
315 %
316 % \begin{description} \def\makelabel{\hskip\labelsep\cmd}
317 %
318 % \item [\grammarparsep] is the amount of space inserted between production
319 %       rules.  It is a rubber length whose default value is 8\,pt, with
320 %       1\,pt of stretch and shrink.
321 %
322 % \item [\grammarindent] is the amount by which the right hand side of a
323 %       production rule is indented from the left margin.  It is a rigid
324 %       length.  Its default value is 2\,em.
325 %
326 % \end{description}
327 %
328 % \DescribeMacro\grammarlabelx
329 % You can also control how the `label' is typeset by redefining the
330 % |\grammarlabelx| command.  The command is given three arguments: the name
331 % of the nonterminal (which was enclosed in angle brackets), the following
332 % decorative material, and the `production operator'.  The command is
333 % expected to produce the label.  By default, it typesets the nonterminal
334 % name using |\synt| followed by the decoration, and the operator, at
335 % opposite ends of the label, separated by an |\hfill|.
336 %
337 % \DescribeMacro\grammarlabel
338 % For compatibility, if there is no decorative material, the macro
339 % |\grammarlabel| is called instead, with just two arguments: the nonterminal
340 % name and the operator.  The default implementation of |\grammarlabel| just
341 % calls |\grammarlabelx| with empty decoration.
342 %
343 % \subsection{Syntax diagrams}
344 %
345 % A full formal BNF grammar can be somewhat overwhelming for less technical
346 % readers.  Documents aimed at such readers tend to display grammatical
347 % structures as \emph{syntax diagrams}.
348 %
349 % \DescribeEnv{syntdiag}
350 % A syntax diagram is always enclosed in a \env{syntdiag} environment.  You
351 % should think of the environment as enclosing a new sort of \LaTeX\ mode:
352 % trying to type normal text into a syntax diagram will result in very ugly
353 % output.  \LaTeX\ ignores spaces and return characters while in syntax
354 % diagram mode.
355 %
356 % The syntax of the environment is very simple:
357 %
358 % \begin{grammar}
359 % <synt-diag-env> ::= \[[
360 %   "\\begin{syntdiag}"
361 %   \begin{stack} \\ "[" <decls> "]" \end{stack}
362 %   <text>
363 %   "\\end{syntdiag}"
364 % \]]
365 % \end{grammar}
366 %
367 % The \<decls> contain any declarations you want to insert, to control
368 % the environment.  The parameters to tweak are described below.
369 %
370 % Within a syntax diagram, you can include syntactic items using the
371 % abbreviated forms described elsewhere.  The output from these forms is
372 % modified slightly in syntax diagram mode so that the diagram looks
373 % right.
374 %
375 % I probably ought to point out now that the syntax diagram typesetting
376 % commands produce beautiful-looking diagrams with all the rules and curves
377 % accurately positioned.  Some device drivers don't position these objects
378 % correctly in their output.  I've had particular trouble with |dvips|.  I'll
379 % say it again: it's not my fault!
380 %
381 % \DescribeEnv{syntdiag*}
382 % The \env{syntdiag} environment only works in paragraph mode, and it acts
383 % rather like a paragraph, splitting over several lines when appropriate.
384 % If you just want to typeset a snippet of a syntax diagram, you can
385 % use the starred environment \env{syntdiag$*$}.
386 %
387 % \begin{grammar}
388 % <synt-diag-star-env> ::= \[[
389 %   "\\begin{syntdiag*}"
390 %   \begin{stack} \\ "[" <decls> "]" \end{stack}
391 %   \begin{stack} \\ "[" <width> "]" \end{stack}
392 %   <text>
393 %   "\\end{syntdiag*}"
394 % \]]
395 % \end{grammar}
396 %
397 % When typesetting little demos like this, it's not normal to fully adorn
398 % the syntax diagram with the full double arrows
399 % (`\begin{syntdiag*}[\left{>>-}\right{-><}]\tok{$\cdots$}\end{syntdiag*}').
400 % The two declarations \syntax{"\\left{"<arrow>"}" and "\\right{"<arrow>"}"}
401 % allow you to choose the arrows on each side of the syntax diagram snippet.
402 % The possible values of \<arrow> are shown in the table-ette below:
403 %
404 % ^^A Time to remember what I learned about tables while writing mdwtab.
405 % ^^A Just for the embarassment factor, here's the number of attempts I
406 % ^^A took to get the table below to look right: __6.  Hmm... not as bad
407 % ^^A as I expected.  Most of them were fine-tuning things.
408 %
409 % \medskip                                      ^^A Leave a vertical gap
410 % \hbox to\columnwidth{\hfil\vbox{\tabskip=0pt  ^^A Centre it horizontally
411 % \sdsize \csname sd@setsize\endcsname          ^^A Position syntdiag arrows
412 % \halign to .5\columnwidth{                    ^^A Set the table width
413 %   &\ttfamily\ignorespaces#\unskip\hfil\tabskip=0pt ^^A Typeset the name
414 %   &\quad\csname sd@arr@#\endcsname\hfil       ^^A Typeset the arrow
415 %   &\setbox0=\hbox{#}\tabskip=0pt plus 1fil\cr ^^A Stretch between columns
416 %   >>-&>>-&   &>-&>-&   &->&->\cr
417 %   -><&-><&   &...&...& &-&-\cr
418 % }}\hfil}                                      ^^A Close the boxing
419 % \medskip                                      ^^A And leave another gap
420 %
421 % These declarations should be used only in the optional argument to the
422 % \env{syntdiag$*$} command.  The second optional argument to the
423 % environment, if specified, fixes the width of the syntax diagram snippet;
424 % if you omit this argument, the diagram is made just wide enough to
425 % fit everything in.
426 %
427 % \begin{figure}
428 % \begin{demo}[w]{Example of \env{syntdiag$*$}}
429 %\newcommand{\bs}[2]{%
430 %  \begin{minipage}{1.6in}%
431 %  \begin{syntdiag*}[\left{#1}\right{#2}][1.6in]%
432 %}
433 %\newcommand{\es}{\end{syntdiag*}\end{minipage}}
434 %
435 %\begin{center}
436 %\begin{tabular}{cl}                                      \\ \hline
437 %\bf Construction    & \bf Meaning                        \\ \hline
438 %\bs {>>-} {...} \es & Start of syntax diagram            \\
439 %\bs {...} {-><} \es & End of syntax diagram              \\
440 %\bs {>-}  {...} \es & Continued on next line             \\
441 %\bs {...} {->}  \es & Continued from previous line       \\ \hline
442 %\bs {...} {...}
443 %  \begin{stack} <option-a> \\ <option-b> \\ <option-c> \end{stack}
444 %\es                 & Alternatives: choose any one       \\
445 %\bs {...} {...}
446 %  \begin{rep} <repeat-me> \\ <separator> \end{rep}
447 %\es                 & One or more items, with separators \\ \hline
448 %\end{tabular}
449 %\end{center}
450 % \end{demo}
451 % \end{figure}
452 %
453 % \DescribeMacro\tok
454 % You can also include text using the |\tok| command.  The argument of this
455 % command is typeset in \LaTeX's LR~mode and inserted into the diagram.
456 % Syntax abbreviations are allowed within the argument, so you can, for
457 % example, include textual descriptions like
458 % \begin{listing}
459 %\tok{any <char> except `"'}
460 % \end{listing}
461 %
462 % \DescribeEnv{stack}
463 % Within a syntax diagram, a choice between several different items is
464 % shown by stacking the alternatives vertically.  In \LaTeX, this is done
465 % by enclosing the items in a \env{stack} environment.  Each individual item
466 % is separated by |\\| commands, as in the \env{array} and \env{tabular}
467 % environments.  Each row may contain any syntax diagram material, including
468 % |\tok| commands and other \env{stack} environments.
469 %
470 % Note if you end a \env{stack} environment with a |\\| command, a blank
471 % row is added to the bottom of the stack, indicating that none of the items
472 % need be specified.
473 %
474 % \DescribeEnv{rep}
475 % Text which can be repeated is enclosed in a \env{rep} environment: the
476 % text is displayed with a backwards pointing arrow drawn over it, showing
477 % that it may be repeated.  Optionally, you can specify text to be
478 % displayed in the arrow, separating it from the main text with a |\\|
479 % command.
480 %
481 % Note that items on the backwards arrow of a \env{rep} construction should
482 % be displayed \emph{backwards}.  You must put the individual items in
483 % reverse order when building this part of your diagrams.  \syn\ will
484 % correctly reverse the arrows on \env{rep} structures, but apart from
485 % this, you must cope on your own.  You are recommended to keep these parts
486 % of your diagrams as simple as possible to avoid confusing readers.
487 %
488 % \begin{demo}[w]{A syntax diagram}
489 %\begin{syntdiag}
490 %<ident> `('
491 %  \begin{rep} \begin{stack} \\
492 %    <type> \begin{stack} \\ <ident> \end{stack}
493 %  \end{stack} \\ `,' \end{rep}
494 %\begin{stack} \\ `...' \end{stack} `)'
495 %\end{syntdiag}
496 % \end{demo}
497 %
498 % \DescribeMacro\(
499 % \DescribeMacro\)
500 % \DescribeMacro\<
501 % \DescribeMacro\>
502 % \DescribeMacro\[
503 % \DescribeMacro\]
504 % The environments \env{stack} and \env{rep} are rather cumbersome to use.
505 % As an alternative, the commands |\(| and |\)| are equivalent to
506 % |\begin{stack}| and |\end{stack}| respectively, and |\<| and |\>| are
507 % equivalent to |\begin{rep}| and |\end{rep}|.  Also, |\[| and |\]| are
508 % like |\begin{stack}| and |\end{stack}| except that an empty initial row is
509 % implicitly added.
510 %
511 % \subsubsection{Line breaking in syntax diagrams}
512 %
513 % Syntax diagrams are automatically broken over lines and across pages.
514 % Lines are only broken between items on the outermost level of the diagram:
515 % i.e., not within \env{stack} or \env{rep} environments.
516 %
517 % You can force a line break at a particular place by using the |\\| command
518 % as usual.  This supports all the usual \LaTeX\ features: a `|*|' variant
519 % which prohibits page breaking, and an optional argument specifying the
520 % extra vertical space between lines.
521 %
522 % \subsubsection{Customising syntax diagrams}
523 %
524 % There are two basic styles of syntax diagrams supported:
525 %
526 % \begin{description}
527 %
528 % \item [square] Lines in the syntax diagram join at squared-off corners.
529 %       This appears to be the standard way of displaying syntax diagrams
530 %       in IBM manuals, and most other documents I've seen.
531 %
532 % \item [rounded] Lines curve around corners.  Also, no arrows are drawn
533 %       around repeating loops: the curving of the lines provides this
534 %       information instead.  This style is used in various texts on
535 %       Pascal, and appears to be more popular in academic circles.
536 %
537 % \end{description}
538 %
539 % You can specify the style you want to use for syntax diagrams by giving
540 % the style name as an option on the |\usepackage| command.  For example,
541 % to force rounded edges to be used, you could say
542 %
543 % \begin{listing}
544 %\usepackage[rounded]{syntax}
545 % \end{listing}
546 %
547 % \DescribeMacro\sdsize
548 % \DescribeMacro\sdlengths
549 % The \env{syntdiag} environment takes an option argument, which should
550 % contain declarations which are obeyed while the environment is set up.
551 % The default value of this argument is `|\sdsize\sdlengths|'.  The
552 % |\sdsize| command sets the default type size for the environment: this is
553 % normally |\small|.  |\sdlengths| sets the values of the length parameters
554 % used by the environment based on the current text size.  These parameters
555 % are described below.
556 %
557 % For example, if you wanted to reduce the type size of the diagrams still
558 % further, you could use the command
559 % \begin{listing}
560 %\begin{syntdiag}[\tiny\sdlengths]
561 % \end{listing}
562 %
563 % The following length parameters may be altered:
564 %
565 % \begin{description} \def\makelabel{\hskip\labelsep\cmd}
566 %
567 % \item [\sdstartspace] The length of the rule between the arrows which
568 %       begin each line of the syntax diagram and the first item on the line.
569 %       Note that most objects have some space on either side of them as
570 %       well.  This is a rubber length.  Its default value is 1\,em, although
571 %       it can shrink by up to 10\,pt.
572 %
573 % \item [\sdendspace] The length of the rule between the last item on a
574 %       line and the arrow at the very end.  Note that the final line also
575 %       has extra rubber space on the end.  This is a rubber length.  Its
576 %       default value is 1\,em, although it will shrink by up to 10\,pt.
577 %
578 % \item [\sdmidskip] The length of the rule on either side of a large
579 %       construction (either a \env{stack} or a \env{rep}).  It is a rubber
580 %       length.  Its default value is \smallf 1/2\,em, with a very small
581 %       amount of infinite stretch.
582 %
583 % \item [\sdtokskip] The length of the rule on either side of a |\tok|
584 %       item or syntax abbreviation.  It is a rubber length.  Its default
585 %       value is \smallf 1/4\,em, with a very small amount of inifnite
586 %       stretch.
587 %
588 % \item [\sdfinalskip] The length of the rule which finishes the last line
589 %       of a syntax diagram.  It is a rubber length.  Its default value is
590 %       \smallf 1/2\,em, with 10000\,fil of stretch, which will left-align
591 %       the items on the line.\footnote{^^A
592 %         This is a little \TeX nical.  The idea is that if a stray 1\,fil
593 %         of stretch is added to the end of the line, it won't be noticed.
594 %         However, the alignment of the text on the line can still be
595 %         modified using \cmd{\sd@rule}\cmd{\hfill}, if you're feeling
596 %         brave.
597 %       }
598 %
599 % \item [\sdrulewidth] Half the width of the rules used in the diagram.
600 %       It is a rigid length.  Its default value is 0.2\,pt.
601 %
602 % \item [\sdcirclediam] The diameter of the circle from which the quadrants
603 %       used in rounded-style diagrams are taken.  This must be a multiple
604 %       of 4\,pt, or else the lines on the diagram won't match up.
605 %
606 % \end{description}
607 %
608 % In addition, you should call |\sdsetstrut| passing it the total height
609 % (\({\rm height}+{\rm depth}\)) of a normal line of text at the current
610 % size.  Normally, the value of |\baselineskip| will be appropriate.
611 %
612 % You can also alter the appearance of \env{stack}s and \env{rep}s by using
613 % their optional positioning arguments.  By default, \env{stack}s descend
614 % below the main line of the diagram, and \env{rep}s extend above it.
615 % Specifying an optional argument of |[b]| for either environment reverses
616 % this, putting \env{stack}s above and \env{rep}s below the line.
617 %
618 % \subsection{Changing the presentation styles}
619 %
620 % You can change the way in which the syntax items are typeset by altering
621 % some simple commands (using |\renewcommand|).  Each item (nonterminals,
622 % as typeset by |\synt|, and quoted and unquoted terminals, as typeset by
623 % |\lit| and |\lit*|) has two style commands associated with it, as shown
624 % in the table below.
625 %
626 % \begin{tab}{lll}                                                 \hline
627 % \bf Syntax item       & \bf Left command & \bf Right command  \\ \hline
628 % Nonterminals          & |\syntleft|      & |\syntright|       \\
629 % Quoted terminals      & |\litleft|       & |\litright|        \\
630 % Unquoted terminals    & |\ulitleft|      & |\ulitright|       \\ \hline
631 % \end{tab}
632 %
633 % It's not too hard to see how this works.  For example, if you look at
634 % the implementation for |\syntleft| and |\syntright| in the implementation
635 % section, you'll notice that they're defined like this:
636 % \begin{listing}
637 %\newcommand{\syntleft}{$\langle$\normalfont\itshape}
638 %\newcommand{\syntright}{$\rangle$}
639 % \end{listing}
640 % I think this is fairly simple, if you understand things like font changing.
641 %
642 % Note that changing these style commands alters the appearance of all syntax
643 % objects of the appropriate types, as created by the |\synt| and |\lit|
644 % commands, in \env{grammar} environments, and in syntax diagrams.
645 %
646 %
647 % \implementation
648 %
649 % \section{Implementation of \syn}
650 %
651 %    \begin{macrocode}
652 %<*package>
653 %    \end{macrocode}
654 %
655 % \subsection{Options handling}
656 %
657 % We define all the options we know about, and then see what's been put
658 % on the usepackage line.
659 %
660 % The options we provide currently are as follows:
661 %
662 % \begin{description}
663 % \item [rounded] draws neatly rounded edges on the diagram.
664 % \item [square] draws squared-off edges on the diagram.  This is the
665 %       default.
666 % \item [nounderscore] disables the undescore active character,  The |\_|
667 %       command still produces the nice version created here.
668 % \end{description}
669 %
670 %    \begin{macrocode}
671 \DeclareOption{rounded}{\sd@roundtrue}
672 \DeclareOption{square}{\sd@roundfalse}
673 \DeclareOption{nounderscore}{\@uscorefalse}
674 %    \end{macrocode}
675 %
676 % Now process the options:
677 %
678 %    \begin{macrocode}
679 \newif\ifsd@round
680 \newif\if@uscore\@uscoretrue
681 \newif\ifsd@left\newif\ifsd@right
682 \ExecuteOptions{square}
683 \ProcessOptions
684 %    \end{macrocode}
685 %
686 % \subsection{Special character handling}
687 %
688 % A lot of the \syn\ package requires the use special active characters.
689 % These must be added to two lists: |\dospecials|, which is used by |\verb|
690 % and friends, and |\@sanitize|, which is used by |\index|.  The two macros
691 % here, |\addspecial| and |\remspecial|, provide these registration
692 % facilities.
693 %
694 % Two similar macros are found in Frank Mittelbach's \package{doc} package:
695 % these have the disadvantage of global operation.  My macros here are based
696 % on Frank's, which in turn appear to be based on Donald Knuth's list
697 % handling code presented in Appendix~D of \textit{The \TeX book}.
698 %
699 % Both these macros take a single argument: a single-character control
700 % sequence containing the special character to be added to or removed from
701 % the lists.
702 %
703 % \begin{macro}{\addspecial}
704 %
705 % This is reasonably straightforward.  We remove the sequence from the lists,
706 % in case it's already there, and add it in in the obvious way.  This
707 % requires a little bit of fun with |\expandafter|.
708 %
709 %    \begin{macrocode}
710 \def\addspecial#1{%
711   \remspecial{#1}%
712   \expandafter\def\expandafter\dospecials\expandafter{\dospecials\do#1}%
713   \expandafter\def\expandafter\@santize\expandafter{%
714     \@sanitize\@makeother#1}%
715 }
716 %    \end{macrocode}
717 %
718 % \end{macro}
719 %
720 % \begin{macro}{\remspecial}
721 %
722 % This is the difficult bit.  Since |\dospecials| and |\@sanitize| have the
723 % form of list macros, we can redefine |\do| and |\@makeother| to do the
724 % job for us.  We must be careful to put the old meaning of |\@makeother|
725 % back.  The current implementation assumes it knows what |\@makeother| does.
726 %
727 %    \begin{macrocode}
728 \def\remspecial#1{%
729   \def\do##1{\ifnum`#1=`##1 \else\noexpand\do\noexpand##1\fi}%
730   \edef\dospecials{\dospecials}%
731   \def\@makeother##1{\ifnum`#1=`##1 \else%
732     \noexpand\@makeother\noexpand##1\fi}%
733   \edef\@sanitize{\@sanitize}%
734   \def\@makeother##1{\catcode`##112}%
735 }
736 %    \end{macrocode}
737 %
738 % \end{macro}
739 %
740 % \subsection{Underscore handling}
741 %
742 % When typing a lot of identifiers, it can be irksome to have to escape
743 % all `|_|' characters in the manuscript.  We make the underscore character
744 % active, so that it typesets an underscore in horizontal mode, and does
745 % its usual job as a subscript operator in maths mode.  Underscore must
746 % already be in the special character lists, because of its use as a
747 % subscript character, so this doesn't cause us a problem.
748 %
749 % \begin{macro}{\underscore}
750 %
751 % The |\underscore| macro typesets an underline character, using a horizontal
752 % rule.  This is positioned slightly below the baseline, and is also slightly
753 % wider than the default \TeX\ underscore.  This code is based on a similar
754 % implementation found in the \package{lgrind} package.
755 %
756 %    \begin{macrocode}
757 \def\underscore{%
758   \leavevmode%
759   \kern.06em%
760   \vbox{%
761     \hrule\@width.6em\@depth.4ex\@height-.34ex%
762   }%
763   \ifdim\fontdimen\@ne\font=\z@%
764     \kern.06em%
765   \fi%
766 }
767 %    \end{macrocode}
768 %
769 % \end{macro}
770 %
771 % \begin{macro}{\@foundunderscore}
772 %
773 % This macro is called by the `|_|' active character to sort out what to do.
774 %
775 % If this is maths mode, we use the |\sb| macro, which is already defined
776 % to do subscripting.  Otherwise, we call |\textunderscore|, which picks the
777 % nicest underscore it can find.
778 %
779 % There's some extra cunningness here, because I'd like to be able to
780 % hyphenate after underscores usually, but not when there's another one
781 % following.  And then, because \env{tabbing} redefines |\_|, there's some
782 % more yukkiness to handle that: the usual |\@tabacckludge| mechanism doesn't
783 % cope with this particular case.
784 %
785 %    \begin{macrocode}
786 \let\usc@builtindischyphen\-
787 \def\@uscore.{%
788   \ifmmode%
789     \expandafter\@firstoftwo%
790   \else%
791     \expandafter\@secondoftwo%
792   \fi%
793   \sb%
794   {\textunderscore\@ifnextchar_{}{\usc@builtindischyphen}}%
795 }
796 %    \end{macrocode}
797 %
798 % \end{macro}
799 %
800 % Now we set up the active character.  Note the |\protect|, which makes
801 % underscores work reasonably well in moving arguments.  Note also the way
802 % we end with a some funny stuff to prevent spaces being lost if this is
803 % written to a file.
804 %
805 %    \begin{macrocode}
806 \if@uscore
807   \AtBeginDocument{%
808     \catcode`\_\active%
809     \begingroup%
810     \lccode`\~`\_%
811     \lowercase{\endgroup\def~{\protect\@uscore.}}%
812   }
813 \fi
814 %    \end{macrocode}
815 %
816 % Finally, we redefine the |\_| macro to use our own |\underscore|, because
817 % it's prettier.  Actually, we don't: we just redefine the
818 % |\?\textunderscore| command (funny name, isn't it?).
819 %
820 %    \begin{macrocode}
821 \expandafter\let\csname?\string\textunderscore\endcsname\underscore
822 %    \end{macrocode}
823 %
824 % \subsection{Abbreviated verbatim notation}
825 %
826 %  In similar style to the \package{doc} package, we allow the user to set up
827 % characters which delimit verbatim text.  Unlike \package{doc}, we make
828 % such changes local to the current group.  This is performed through the
829 % |\shortverb| and |\unverb| commands.
830 %
831 % The implementations of these commands are based upon the |\MakeShortVerb|
832 % and |\DeleteShortVerb| commands of the \package{doc} package, although
833 % these versions have effect local to the current grouping level.  This
834 % prevents their redefinition of |\dospecials| from interfering with the
835 % grammar shortcuts, which require local changes only.
836 %
837 % The command |\shortverb| takes a single argument: a single-character
838 % control sequence defining which character to make into the verbatim text
839 % delimiter.  We store the old meaning of the active character in a control
840 % sequence called |\mn@\|\<char>.  Note that this control sequence
841 % contains a backslash character, which is a little odd.  We also define a
842 % command |\cc@\|\<char> which will return everything to normal.  This
843 % is used by the |\unverb| command.
844 %
845 % \begin{macro}{\shortverb}
846 %
847 % Here we build the control sequences we need to make everything work nicely.
848 % The active character is defined via |\lowercase|, using the |~| character:
849 % this is already made active by \TeX\@.
850 %
851 % The actual code requires lots of fiddling with |\expandafter| and friends.
852 %
853 %    \begin{macrocode}
854 \def\shortverb#1{%
855 %    \end{macrocode}
856 %
857 % First, we check to see if the command |\cc@\|\<char> has been defined.
858 %
859 %    \begin{macrocode}
860   \@ifundefined{cc@\string#1}{%
861 %    \end{macrocode}
862 %
863 % If it hasn't been defined, we add the character to the specials list.
864 %
865 %    \begin{macrocode}
866     \addspecial#1%
867 %    \end{macrocode}
868 %
869 % Now we set our character to be the lowercase version of |~|, which allows
870 % us to use it, even though we don't know what it is.
871 %
872 %    \begin{macrocode}
873     \begingroup%
874     \lccode`\~`#1%
875 %    \end{macrocode}
876 %
877 % Finally, we reach the tricky bit.  All of this is lowercased, so any
878 % occurrences of |~| are replaced by the user's special character.
879 %
880 %    \begin{macrocode}
881     \lowercase{%
882       \endgroup%
883 %    \end{macrocode}
884 %
885 % We remember the current meaning of the character, in case it has one.  We
886 % have to use |\csname| to build the rather strange name we use for this.
887 %
888 %    \begin{macrocode}
889       \expandafter\let\csname mn@\string#1\endcsname~%
890 %    \end{macrocode}
891 %
892 % Now we build |\cc@\|\<char>.  This is done with |\edef|, since more
893 % of this needs to be expanded now than not.  In this way, the actual macros
894 % we create end up being very short.
895 %
896 %    \begin{macrocode}
897       \expandafter\edef\csname cc@\string#1\endcsname{%
898 %    \end{macrocode}
899 %
900 % First, add a command to restore the character's old catcode.
901 %
902 %    \begin{macrocode}
903         \catcode`\noexpand#1\the\catcode`#1%
904 %    \end{macrocode}
905 %
906 % Now we restore the character's old meaning, using the version we saved
907 % earlier.
908 %
909 %    \begin{macrocode}
910         \let\noexpand~\expandafter\noexpand%
911           \csname mn@\string#1\endcsname%
912 %    \end{macrocode}
913 %
914 % Now we remove the character from the specials lists.
915 %
916 %    \begin{macrocode}
917         \noexpand\remspecial\noexpand#1%
918 %    \end{macrocode}
919 %
920 % Finally, we delete this macro, so that |\unverb| will generate a warning
921 % if the character is |\unverb|ed again.
922 %
923 %    \begin{macrocode}
924         \let\csname cc@\string#1\endcsname\relax%
925       }%
926 %    \end{macrocode}
927 %
928 % All of that's over now.  We set up the new definition of the character,
929 % in terms of |\verb|, and make the character active.  The nasty |\syn@ttspace|
930 % is there to make the spacing come out right.  It's all right really.  Honest.
931 %
932 %    \begin{macrocode}
933       \def~{\verb~\syn@ttspace}%
934     }%
935     \catcode`#1\active%
936 %    \end{macrocode}
937 %
938 % If our magic control sequence already existed, we can assume that the
939 % character is already a verbatim delimiter, and raise a warning.
940 %
941 %    \begin{macrocode}
942   }{%
943     \PackageWarning{syntax}{Character `\expandafter\@gobble\string#1'
944                             is already a verbatim\MessageBreak
945                             delimiter}%
946   }%
947 }
948 %    \end{macrocode}
949 %
950 % \end{macro}
951 %
952 % \begin{macro}{\unverb}
953 %
954 % This is actually terribly easy: we just use the |\cc@\|\<char> command
955 % we definied earlier, after making sure that it's been defined.
956 %
957 %    \begin{macrocode}
958 \def\unverb#1{%
959   \@ifundefined{cc@\string#1}{%
960     \PackageWarning{syntax}{Character `\expandafter\@gobble\string#1'
961                             is not a verbatim\MessageBreak
962                             delimiter}%
963   }{%
964     \csname cc@\string#1\endcsname%
965   }%
966 }
967 %    \end{macrocode}
968 %
969 % \end{macro}
970 %
971 % \subsection{Style hooks for syntax forms}
972 %
973 % To allow the appearance of syntax things to be configured, we provide some
974 % redefinable bits.
975 %
976 % The three types of objects (nonterminal symbols, and quoted and unquoted
977 % terminals) each have two macros associated with them: one which does the
978 % `left' bit of the typesetting, and one which does the `right' bit.  The
979 % items are typeset as LR~boxes.  I'll be extra good while defining these
980 % hooks, so that it's obvious what's going on; macho \TeX\ hacker things
981 % resume after this section.
982 %
983 % \begin{macro}{\syntleft}
984 % \begin{macro}{\syntright}
985 %
986 % I can't see why anyone would want to change the typesetting of
987 % nonterminals, although I'll provide the hooks for symmetry's sake.
988 %
989 %     \begin{macrocode}
990 \newcommand{\syntleft}{$\langle$\normalfont\itshape}
991 \newcommand{\syntright}{$\rangle$}
992 %    \end{macrocode}
993 %
994 % \end{macro}
995 % \end{macro}
996 %
997 % \begin{macro}{\ulitleft}
998 % \begin{macro}{\ulitright}
999 % \begin{macro}{\litleft}
1000 % \begin{macro}{\litright}
1001 %
1002 % Now we can define the left and right parts of quoted and unquoted
1003 % terminals.  US~readers may want to put double quotes around the quoted
1004 % terminals, for example.
1005 %
1006 %    \begin{macrocode}
1007 \newcommand{\ulitleft}{\normalfont\ttfamily\syn@ttspace\frenchspacing}
1008 \newcommand{\ulitright}{}
1009 \newcommand{\litleft}{`\bgroup\ulitleft}
1010 \newcommand{\litright}{\ulitright\egroup'}
1011 %    \end{macrocode}
1012 %
1013 % \end{macro}
1014 % \end{macro}
1015 % \end{macro}
1016 % \end{macro}
1017 %
1018 % \subsection{Simple syntax typesetting}
1019 %
1020 % In general text, we allow access to our typesetting conventions through
1021 % standard \LaTeX\ commands.
1022 %
1023 % \begin{macro}{\synt}
1024 %
1025 % The |\synt| macro typesets its argument as a syntactic quantity.  It puts
1026 % the text of the argument in italics, and sets angle brackets around it.
1027 % Breaking of a |\synt| object across lines is forbidden.
1028 %
1029 %    \begin{macrocode}
1030 \def\synt#1{\mbox{\syntleft{#1\/}\syntright}}
1031 %    \end{macrocode}
1032 %
1033 % \end{macro}
1034 %
1035 % \begin{macro}{\lit}
1036 %
1037 % The |\lit| macro typesets its argument as literal text, to be typed in.
1038 % Normally, this means setting the text in |\tt| font, and putting quotes
1039 % around it, although the quotes can be suppressed by using the $*$-variant.
1040 %
1041 % The |\syn@ttspace| macro sets up the spacing for the text nicely: |\tt|
1042 % spaces tend to be a little wide.
1043 %
1044 %    \begin{macrocode}
1045 \def\lit{\@ifstar{\lit@i\ulitleft\ulitright}{\lit@i\litleft\litright}}
1046 \def\lit@i#1#2#3{\mbox{#1{#3\/}#2}}
1047 %    \end{macrocode}
1048 %
1049 % \end{macro}
1050 %
1051 % \begin{macro}{\syn@ttspace}
1052 %
1053 % This sets up the |\spaceskip| value for |\tt| text.
1054 %
1055 %    \begin{macrocode}
1056 \def\syn@ttspace@{\spaceskip.35em\@plus.2em\@minus.15em\relax}
1057 %    \end{macrocode}
1058 %
1059 % However, this isn't always the right thing to do.
1060 %
1061 %    \begin{macrocode}
1062 \def\ttthinspace{\let\syn@ttspace\syn@ttspace@}
1063 \def\ttthickspace{\let\syn@ttspace\@empty}
1064 %    \end{macrocode}
1065 %
1066 % I know what I like thoough.
1067 %
1068 %    \begin{macrocode}
1069 \ttthinspace
1070 %    \end{macrocode}
1071 %
1072 % \end{macro}
1073 %
1074 % \subsubsection{The shortcuts}
1075 %
1076 % The easy part is over now.  The next job is to set up the `grammar
1077 % shortcuts' which allow easy changing of styles.
1078 %
1079 % We support four shortcuts:
1080 % \begin{itemize}
1081 % \item |`literal text'| typesets \syntax{`literal text'}
1082 % \item |<non-terminal>| typesets \syntax{<non-terminal>}
1083 % \item |"unquoted text"| typesets \syntax{"unquoted text"}
1084 % \item \verb"|" typesets a \syntax{|} character
1085 % \end{itemize}
1086 % These are all implemented through active characters, which are enabled
1087 % using the |\syntaxShortcuts| macro, described below.
1088 %
1089 % \begin{macro}{\readupto}
1090 %
1091 % \syntax{"\\readupto{"<char>"}{"<decls>"}{"<command>"}"} will read all
1092 % characters up until the next occurrence of \<char>.  Normally, all
1093 % special characters will be deactivated.  However, you can reactivate some
1094 % characters, using the \<decls> argument, which is processed before the
1095 % text is read.
1096 %
1097 % The code is borrowed fairly obviously from the \LaTeXe\ source for the
1098 % |\verb| command.
1099 %
1100 %    \begin{macrocode}
1101 \def\readupto#1#2#3{%
1102   \bgroup%
1103   \verb@eol@error%
1104   \let\do\@makeother\dospecials%
1105   \@noligs%
1106   #2%
1107   \catcode`#1\active%
1108   \lccode`\~`#1%
1109   \gdef\verb@balance@group{\verb@egroup%
1110      \@latex@error{\noexpand\verb illegal in command argument}\@ehc}%
1111   \def\@vhook{\verb@egroup#3}%
1112   \aftergroup\verb@balance@group%
1113   \lowercase{\let~\@vhook}%
1114 }
1115 %    \end{macrocode}
1116 %
1117 % \end{macro}
1118 %
1119 % \begin{macro}{\syn@assist}
1120 %
1121 % The |\syn@assist| macro is used for defining three of the shortcuts.  It
1122 % is called as
1123 %
1124 % \begin{quote}
1125 % \syntax{"\\syn@assist{"<left-decls>"}{"<actives>"}{"<delimeter>"}" \\
1126 % \null \quad "{"<right-decls>"}{"<end-cmd>"}"}
1127 % \end{quote}
1128 %
1129 % It creates an hbox, sets up the escape sequences for quoting our magic
1130 % characters, and then typesets a box containing
1131 %
1132 % \begin{quote}
1133 % \syntax{<left-decls>"{"<delimited-text>"\\/}"<right-decls>}
1134 % \end{quote}
1135 %
1136 % The \<left-decls> and \<right-decls> can be |\relax| if they're not
1137 % required.
1138 %
1139 % The \<actives> argument is passed to |\readupto|, to allow some special
1140 % characters through.  By default, we re-enable |\|, and make `\verb*" "'
1141 % typeset some space glue, rather than a space character.  A macro
1142 % `\verb*"\ "' is defined to actually print a space character, which yield
1143 % `\verb*" "' in the `|\tt|' font.
1144 %
1145 % Finally, it defines a |\ch| command, which, given a single-character
1146 % control sequence as its argument, typesets the character.  This is useful,
1147 % since |`| has been made active when we set up these calls, so the
1148 % direct |\char`\|\<char> doesn't work.
1149 %
1150 %    \begin{macrocode}
1151 \def\syn@assist#1#2#3#4#5{%
1152 %    \end{macrocode}
1153 %
1154 % First, we start the box, and open a group.  We use |\mbox| because it
1155 % does all the messing with |\leavevmode| which is needed.
1156 %
1157 %    \begin{macrocode}
1158   \leavevmode\hbox\bgroup%
1159 %    \end{macrocode}
1160 %
1161 % Next job is to set up the escape sequences.
1162 %
1163 %    \begin{macrocode}
1164   \chardef\\`\\%
1165   \chardef\>`\>%
1166   \chardef\'`\'%
1167   \chardef\"`\"%
1168   \chardef\ `\ %
1169 %    \end{macrocode}
1170 %
1171 % Now to define |\ch|.  This is done the obvious way.
1172 %
1173 %    \begin{macrocode}
1174   \def\ch##1{\char`##1}%
1175 %    \end{macrocode}
1176 %
1177 % For active characters, we do some fiddling with |\lccode|s.
1178 %
1179 %    \begin{macrocode}
1180   \def\act##1{%
1181     \catcode`##1\active%
1182     \begingroup%
1183     \lccode`\~`##1%
1184     \lowercase{\endgroup\def~}%
1185   }%
1186 %    \end{macrocode}
1187 %
1188 % Finally, we do the real work of setting the text.  We use |\readupto| to
1189 % actually find the text we want.
1190 %
1191 %    \begin{macrocode}
1192   #1%
1193   \begingroup%
1194   \readupto#3{%
1195     \catcode`\\0%
1196     \catcode`\ 10%
1197     #2%
1198   }{%
1199     \/\endgroup#4\egroup#5%
1200   }%
1201 }
1202 %    \end{macrocode}
1203 %
1204 % \end{macro}
1205 %
1206 % \begin{macro}{\syn@shorts}
1207 %
1208 % This macro actually defines the expansions for the active characters.
1209 % We have to do this separately because |`| must be active when we use it
1210 % in the |\def|, but we can't do that and use |\catcode| at the same time.
1211 % The arguments are commands to do before and after the actual command.
1212 % These are passed up from |\syntaxShortcuts|.
1213 %
1214 % All of the characters use |\syn@assist| in the obvious way except for
1215 % \verb"|", which drops into maths mode instead.
1216 %
1217 % Note that when changing the catcodes, we must save |`| until last.
1218 %
1219 %    \begin{macrocode}
1220 \begingroup
1221 \catcode`\<\active
1222 \catcode`\|\active
1223 \catcode`\"\active
1224 \catcode`\`\active
1225 %
1226 \gdef\syn@shorts#1#2{%
1227 %    \end{macrocode}
1228 %
1229 % The `|<|' character must typeset its argument in italics.  We make `|_|'
1230 % do the same as the `|\_|' command.
1231 %
1232 %    \begin{macrocode}
1233   \def<{%
1234     #1%
1235     \syn@assist%
1236       \syntleft%
1237       {\act_{\@uscore.}}%
1238       >%
1239       \syntright%
1240       {#2}%
1241   }%
1242 %    \end{macrocode}
1243 %
1244 % The `|`|' and `|"|' characters should print its argument in |\tt| font.
1245 % We change the `|\tt|' space glue to provide nicer spacing on the line.
1246 %
1247 %    \begin{macrocode}
1248   \def`{%
1249     #1%
1250     \syn@assist%
1251       \litleft%
1252       \relax%
1253       '%
1254       \litright%
1255       {#2}%
1256   }%
1257   \def"{%
1258     #1%
1259     \syn@assist%
1260       \ulitleft%
1261       \relax%
1262       "%
1263       \ulitright%
1264       {#2}%
1265   }%
1266 %    \end{macrocode}
1267 %
1268 % Finally, the `\verb"|"' character is typeset by using the mysterious
1269 % |\textbar| command.
1270 %
1271 %    \begin{macrocode}
1272   \def|{\textbar}%
1273 %    \end{macrocode}
1274 %
1275 % We're finished here now.
1276 %
1277 %    \begin{macrocode}
1278 }
1279 %
1280 \endgroup
1281 %    \end{macrocode}
1282 %
1283 % \end{macro}
1284 %
1285 % \begin{macro}{\syntaxShortcuts}
1286 %
1287 % This is a user-level command which enables the use of our shortcuts in the
1288 % current group.  It uses |\addspecial|, defined below, to register the
1289 % active characters, sets up their definitions and activates them.
1290 %
1291 % The two arguments are commands to be performed before and after the
1292 % handling of the abbreviation.  In this way, you can further process the
1293 % output.
1294 %
1295 % This command is not intended to be used directly by users: it should be
1296 % used by other macros and packages which wish to take advantage of the
1297 % facilities offered by this package.  We provide a |\synshorts| declaration
1298 % (which may be used as an environment, of course) which is more `user
1299 % palatable'.
1300 %
1301 %    \begin{macrocode}
1302 \def\syntaxShortcuts#1#2{%
1303   \syn@shorts{#1}{#2}%
1304   \addspecial\`%
1305   \addspecial\<%
1306   \addspecial\|%
1307   \addspecial\"%
1308   \catcode`\|\active%
1309   \catcode`\<\active%
1310   \catcode`\"\active%
1311   \catcode`\`\active%
1312 }
1313 %
1314 \def\synshorts{\syntaxShortcuts\relax\relax}
1315 %    \end{macrocode}
1316 %
1317 % \end{macro}
1318 %
1319 % \begin{macro}{\synshortsoff}
1320 %
1321 % This macro can be useful occasionally: it disables the syntax shortcuts,
1322 % so you can type normal text for a while.
1323 %
1324 %    \begin{macrocode}
1325 \def\synshortsoff{%
1326   \catcode`\|12%
1327   \catcode`\<12%
1328   \catcode`\"12%
1329   \catcode`\`12%
1330 }
1331 %    \end{macrocode}
1332 %
1333 % \end{macro}
1334 %
1335 % \begin{macro}{\syntax}
1336 %
1337 % The |\syntax| macro typesets its argument, allowing the use of our
1338 % shortcuts within the argument.
1339 %
1340 % Actually, we go to some trouble to ensure that the argument to |\syntax|
1341 % \emph{isn't} a real argument so we can change catcodes as we go.  We
1342 % use the |\let\@let@token=| trick from \PlainTeX\ to do this.
1343 %
1344 %    \begin{macrocode}
1345 \def\syntax#{\bgroup\syntaxShortcuts\relax\relax\let\@let@token}
1346 %    \end{macrocode}
1347 %
1348 % \end{macro}
1349 %
1350 % \begin{environment}{grammar}
1351 %
1352 % The \env{grammar} environment is the final object we have to define.  It
1353 % allows typesetting of beautiful BNF grammars.
1354 %
1355 % First, we define the length parameters we need:
1356 %
1357 %    \begin{macrocode}
1358 \newskip\grammarparsep
1359   \grammarparsep8\p@\@plus\p@\@minus\p@
1360 \newdimen\grammarindent
1361   \grammarindent2em
1362 %    \end{macrocode}
1363 %
1364 % Now define the default label typesetting.  This macro is designed to be
1365 % replaced by a user, so we'll be extra-well-behaved and use genuine \LaTeX\
1366 % commands.  Well, almost \dots
1367 %
1368 %    \begin{macrocode}
1369 \newcommand{\grammarlabel}[2]{\grammarlabelx{#1}{}{#2}}
1370 \newcommand{\grammarlabelx}[3]{\synt{#1}#2 \hfill#3}
1371 %    \end{macrocode}
1372 %
1373 % Now for a bit of hacking to make the item stuff work properly.  This gets
1374 % done for every new paragraph that's started without an |\item| command.
1375 %
1376 % First, store the left hand side of the production in a box.  Then I'll
1377 % end the paragraph, and insert some nasty glue to take up all the space,
1378 % so no-one will ever notice that there was a paragraph break there.  The
1379 % strut just makes sure that I know exactly how high the line is.
1380 %
1381 %    \begin{macrocode}
1382 \def\gr@implitem<#1>#2 #3 {%
1383   \sbox\z@{%
1384     \hskip\labelsep%
1385     \def\@tempa{#2}%
1386     \ifx\@tempa\@empty\grammarlabel{#1}{#3}%
1387     \else\grammarlabelx{#1}{#2}{#3}\fi%
1388   }%
1389   \strut\@@par%
1390   \vskip-\parskip%
1391   \vskip-\baselineskip%
1392 %    \end{macrocode}
1393 %
1394 % The |\item| command will notice that I've inserted these funny glues and
1395 % try to remove them: I'll stymie its efforts by inserting an invisible
1396 % rule.  Then I'll insert the label using |\item| in the normal way.
1397 %
1398 %    \begin{macrocode}
1399   \hrule\@height\z@\@depth\z@\relax%
1400   \item[\unhbox\z@]%
1401 %    \end{macrocode}
1402 %
1403 % Just before I go, I'll make \lit{<} back into an active character.
1404 %
1405 %    \begin{macrocode}
1406   \catcode`\<\active%
1407 }
1408 %    \end{macrocode}
1409 %
1410 % Now for the environment proper.  Deep down, it's a list environment, with
1411 % some nasty tricks to stop anyone from noticing.
1412 %
1413 % The first job is to set up the list from the parameters I'm given.
1414 %
1415 %    \begin{macrocode}
1416 \newenvironment{grammar}{%
1417   \list{}{%
1418     \labelwidth\grammarindent%
1419     \leftmargin\grammarindent%
1420     \advance\grammarindent\labelsep
1421     \itemindent\z@%
1422     \listparindent\z@%
1423     \parsep\grammarparsep%
1424   }%
1425 %    \end{macrocode}
1426 %
1427 % We have major problems in |\raggedright| layouts, which try to use |\par|
1428 % to start new lines.  We go back to normal |\\| newlines to try and bodge
1429 % our way around these problems.
1430 %
1431 %    \begin{macrocode}
1432   \let\\\@normalcr
1433 %    \end{macrocode}
1434 %
1435 % Now to enable the shortcuts.
1436 %
1437 %    \begin{macrocode}
1438   \syntaxShortcuts\relax\relax%
1439 %    \end{macrocode}
1440 %
1441 % Now a little bit of magic.  The |\alt| macro moves us to a new line, and
1442 % typesets a vertical bar in the margin.  This allows typesetting of
1443 % multiline alternative productions in a pretty way.
1444 %
1445 %    \begin{macrocode}
1446   \def\alt{\\\llap{\textbar\quad}}%
1447 %    \end{macrocode}
1448 %
1449 % Now for another bit of magic.  We set up some |\par| cleverness to spot
1450 % the start of each production rule and format it in some cunning and
1451 % user-defined way.
1452 %
1453 %    \begin{macrocode}
1454   \def\gr@setpar{%
1455     \def\par{%
1456       \parshape\@ne\@totalleftmargin\linewidth%
1457       \@@par%
1458       \catcode`\<12%
1459       \everypar{%
1460         \everypar{}%
1461         \catcode`\<\active%
1462         \gr@implitem%
1463       }%
1464     }%
1465   }%
1466   \gr@setpar%
1467   \par%
1468 %    \end{macrocode}
1469 %
1470 % Now set up the |\[[| and |\]]| commands to do the right thing.  We have
1471 % to check the next character to see if it's correct, otherwise we'll
1472 % open a maths display as usual.
1473 %
1474 %    \begin{macrocode}
1475   \let\gr@leftsq\[%
1476   \let\gr@rightsq\]%
1477   \def\gr@endsyntdiag]{\end{syntdiag}\gr@setpar\par}%
1478   \def\[{\@ifnextchar[{\begin{syntdiag}\@gobble}\gr@leftsq}%
1479   \def\]{\@ifnextchar]\gr@endsyntdiag\gr@rightsq}%
1480 %    \end{macrocode}
1481 %
1482 % Well, that's it for this side of the environment.
1483 %
1484 %    \begin{macrocode}
1485 }{%
1486 %    \end{macrocode}
1487 %
1488 % Closing the environment is a simple matter of tidying away the list.
1489 %
1490 %    \begin{macrocode}
1491   \@newlistfalse%
1492   \everypar{}%
1493   \endlist%
1494 }
1495 %    \end{macrocode}
1496 %
1497 % \end{environment}
1498 %
1499 % \subsection{Syntax diagrams}
1500 %
1501 % Now we come to the final and most complicated part of the package.
1502 %
1503 % Syntax diagrams are drawn using arrow characters from \LaTeX's line font,
1504 % used in the \env{picture} environment, and rules.  The horizontal rules
1505 % of the diagram are drawn along the baselines of the lines in which they
1506 % are placed.  The text items in the diagram are placed in boxes and lowered
1507 % below the main baseline.  Struts are added throughout to keep the vertical
1508 % spacing consistent.
1509 %
1510 % The vertical structures (stacks and loops) are all implemented with \TeX's
1511 % primitive |\halign| command.
1512 %
1513 % \subsubsection{User-configurable parameters}
1514 %
1515 % First, we allocate the \<dimen> and \<skip> arguments needed.  Fixed
1516 % lengths, as the \LaTeX book calls them, are allocated as \<dimen>s, to
1517 % take some of the load off of all the \<skip> registers.
1518 %
1519 %    \begin{macrocode}
1520 \newskip\sdstartspace
1521 \newskip\sdendspace
1522 \newskip\sdmidskip
1523 \newskip\sdtokskip
1524 \newskip\sdfinalskip
1525 \newdimen\sdrulewidth
1526 \newdimen\sdcirclediam
1527 \newdimen\sdindent
1528 %    \end{macrocode}
1529 %
1530 % We need some \TeX\ \<dimen>s for our own purposes, to get everything in
1531 % the right places.  We use labels for the `temporary' \TeX\ parameters
1532 % which we use, to avoid wasting registers.
1533 %
1534 %    \begin{macrocode}
1535 \dimendef\sd@lower\z@
1536 \dimendef\sd@upper\tw@
1537 \dimendef\sd@mid4
1538 \dimendef\sd@topcirc6
1539 \dimendef\sd@botcirc8
1540 \skipdef\sd@qskip2
1541 %    \end{macrocode}
1542 %
1543 % \begin{macro}{\sd@setsize}
1544 % When the text size for syntax diagrams changes, it's necessary to work out
1545 % the height for various rules in the diagram.
1546 %
1547 %    \begin{macrocode}
1548 \def\sd@setsize{%
1549   \sd@mid\ht\strutbox%
1550   \advance\sd@mid-\dp\strutbox%
1551   \sd@mid.5\sd@mid%
1552   \sd@upper\sdrulewidth%
1553     \advance\sd@upper\sd@mid%
1554   \sd@lower\sdrulewidth%
1555     \advance\sd@lower-\sd@mid%
1556   \sd@topcirc-.5\sdcirclediam%
1557     \advance\sd@topcirc\sd@mid%
1558   \sd@botcirc-.5\sdcirclediam%
1559     \advance\sd@botcirc-\sd@mid%
1560 }
1561 %    \end{macrocode}
1562 %
1563 % \end{macro}
1564 %
1565 % \begin{macro}{\sdsize}
1566 %
1567 % You can set the default type size used by syntax diagrams by redefining
1568 % the |\sdsize| command, using the |\renewcommand| command.
1569 %
1570 % By default, syntax diagrams are set slightly smaller than the main body
1571 % text.\footnote{^^A
1572 %   I've used pure \LaTeX\ commands for this and the \cmd\sdlengths\ macro,
1573 %   to try and illustrate how these values might be changed by a user.  The
1574 %   rest of the code is almost obfuscted in its use of raw \TeX\ features,
1575 %   in an attempt to dissuade more na\"\i ve users from fiddling with it.
1576 %   I suppose this is what you get when you let assembler hackers loose with
1577 %   something like \LaTeX.
1578 % }
1579 %
1580 %    \begin{macrocode}
1581 \newcommand{\sdsize}{%
1582   \small%
1583 }
1584 %    \end{macrocode}
1585 %
1586 % \end{macro}
1587 %
1588 % \begin{macro}{\sdlengths}
1589 %
1590 % Finally, the default length parameters are set in the |\sdlengths| command.
1591 % You can redefine the command using |\renewcommand|.
1592 %
1593 % We set up the length parameters here.
1594 %
1595 %    \begin{macrocode}
1596 \newcommand{\sdlengths}{%
1597   \setlength{\sdstartspace}{1em minus 10pt}%
1598   \setlength{\sdendspace}{1em minus 10pt}%
1599   \setlength{\sdmidskip}{0.5em plus 1em}%
1600   \setlength{\sdtokskip}{0.25em plus 1em}%
1601   \setlength{\sdfinalskip}{0.5em plus 10000fil}%
1602   \setlength{\sdrulewidth}{0.2pt}%
1603   \setlength{\sdcirclediam}{8pt}%
1604   \setlength{\sdindent}{0pt}%
1605 }
1606 %    \end{macrocode}
1607 %
1608 % \end{macro}
1609 %
1610 % \subsubsection{Other declarations}
1611 %
1612 % We define four switches.  The table shows what they're used for.
1613 %
1614 % \begin{table}
1615 % \begin{tab}{lp{3in}}                                              \hline
1616 %
1617 % \bf Switch        & \bf Meaning                                \\ \hline
1618 %
1619 % |\ifsd@base|      & We are at `base level' in the diagram:
1620 %                     i.e., not in any other sorts of
1621 %                     constructions.  This is used to decide
1622 %                     whether to allow line breaking.            \\[2pt]
1623 %
1624 % |\ifsd@top|       & The current loop construct is being
1625 %                     typeset with the loop arrow above the
1626 %                     baseline.                                  \\[2pt]
1627 %
1628 % |\ifsd@toplayer|  & We are typesetting the top layer of
1629 %                     a stack.  This is used to ensure that
1630 %                     the vertical rules on either side are
1631 %                     typeset at the right height.               \\[2pt]
1632 %
1633 % |\ifsd@backwards| & We're typesetting backwards, because
1634 %                     we're in the middle of a loop arrow.
1635 %                     the only difference this makes is that
1636 %                     any subloops have the arrow on the
1637 %                     side.                                      \\ \hline
1638 %
1639 % \end{tab}
1640 % \caption{Syntax diagram switches}
1641 % \end{table}
1642 %
1643 %    \begin{macrocode}
1644 \newif\ifsd@base
1645 \newif\ifsd@top
1646 \newif\ifsd@toplayer
1647 \newif\ifsd@backwards
1648 %    \end{macrocode}
1649 %
1650 % \begin{macro}{\sd@err}
1651 %
1652 % We output our errors through this macro, which saves a little typing.
1653 %
1654 %    \begin{macrocode}
1655 \def\sd@err{\PackageError{syntax}}
1656 %    \end{macrocode}
1657 %
1658 % \end{macro}
1659 %
1660 % \subsubsection{Arrow-drawing}
1661 %
1662 % We need to draw some arrows.  \LaTeX\ tries to make this as awkward as
1663 % possible, so we have to start moving the arrows around in boxes quite a
1664 % lot.
1665 %
1666 % The left and right pointing arrows are fairly simple: we just add some
1667 % horizontal spacing to prevent the width of the arrow looking odd.
1668 %
1669 %    \begin{macrocode}
1670 \def\sd@arrow{%
1671   \ht\tw@\z@%
1672   \dp\tw@\z@%
1673   \raise\sd@mid\box\tw@%
1674   \egroup%
1675 }
1676 \def\sd@rightarr{%
1677   \bgroup%
1678   \setbox\tw@\hbox{\kern-6\p@\@linefnt\char'55}%
1679   \sd@arrow%
1680 }
1681 \def\sd@leftarr{%
1682   \bgroup%
1683   \setbox\tw@\hbox{\@linefnt\char'33\kern-6\p@}%
1684   \sd@arrow%
1685 }
1686 %    \end{macrocode}
1687 %
1688 % The up arrow is very strange.  We need to bring the arrow down to base
1689 % level, and smash its height.
1690 %
1691 %    \begin{macrocode}
1692 \def\sd@uparr{%
1693   \bgroup%
1694   \setbox\tw@\hb@xt@\z@{\kern-\sdrulewidth\@linefnt\char'66\hss}%
1695   \setbox\tw@\hbox{\lower10\p@\box\tw@}%
1696   \sd@arrow%
1697 }
1698 %    \end{macrocode}
1699 %
1700 % The down arrow is similar, although it's already at the right height.
1701 % Thus, we can just smash the box.
1702 %
1703 %    \begin{macrocode}
1704 \def\sd@downarr{%
1705   \bgroup%
1706   \setbox\tw@\hb@xt@\z@{\kern-\sdrulewidth\@linefnt\char'77\hss}%
1707   \sd@arrow%
1708 }
1709 %    \end{macrocode}
1710 %
1711 % \subsubsection{Drawing curves}
1712 %
1713 % If the user has selected curved edges, we use the \LaTeX\ features provided
1714 % to obtain the curves.  These are drawn slightly oddly to make it easier
1715 % to fit them into the diagram.
1716 %
1717 % Some explanation about the \LaTeX\ circle font is probably called for
1718 % before we go any further.  The font consists of sets of four quadrants
1719 % of a particular size (and some other characters, which aren't important
1720 % at the moment).  Each collection of quadrants fit together to form a
1721 % perfect circle of a given diameter.  The individual quadrant characters
1722 % have strange bounding boxes, as described in the files \textit{lcircle.mf}
1723 % and \textit{ltpict.dtx}, and also in Appendix~D of \textit{The \TeX book}.
1724 % Our job here is to make these quadrants useful in the context of
1725 % drawing syntax diagrams.
1726 %
1727 % \begin{macro}{\sd@circ}
1728 % First, we define |\sd@circ|, which performs the common parts of the four
1729 % routines.  Since the characters in the circle font are grouped together,
1730 % we can pick out a particular corner piece by specifying its index into
1731 % the group for the required size.  The |\sd@circ| routine will pick out
1732 % the required character, given this index as an argument, and put it in
1733 % box~2, after fiddling with the sizes a little:
1734 % \begin{itemize}
1735 %
1736 % \item We clear the width to zero.  The individual routines then add a kern
1737 %       of the correct amount, so that the quadrant appears in the right
1738 %       place.
1739 %
1740 % \item The piece is lowered by half the rule width.  This positions the
1741 %       top and bottom pieces of the circle to be half way over the baseline,
1742 %       which is the correct position for the rest of the diagram.
1743 %
1744 % \end{itemize}
1745 %
1746 % Finally, we make sure we're in horizontal mode: horrific results occur
1747 % if this is not the case.  I'm sure I don't need to explain this any more
1748 % graphically.
1749 %
1750 %    \begin{macrocode}
1751 \def\sd@circ#1{%
1752   \@getcirc\sdcirclediam%
1753   \advance\@tempcnta#1%
1754   \setbox\tw@\hbox{\lower\sdrulewidth%
1755     \hbox{\@circlefnt\char\@tempcnta}}%
1756   \wd\tw@\z@%
1757   \leavevmode%
1758 }
1759 %    \end{macrocode}
1760 %
1761 % \end{macro}
1762 %
1763 % \begin{macro}{\sd@tlcirc}
1764 % \begin{macro}{\sd@trcirc}
1765 % \begin{macro}{\sd@blcirc}
1766 % \begin{macro}{\sd@brcirc}
1767 %
1768 % These are the macros which actually draw quadrants of circles.  They all
1769 % call |\sd@circ|, passing an appropriate index, and then fiddle with the
1770 % box sizes and apply kerning specific to the quadrant positioning.
1771 %
1772 % The exact requirements for positioning are as follows:
1773 %
1774 % \begin{itemize}
1775 %
1776 % \item The horizontal parts of the arcs must lie along the baseline (i.e.,
1777 %       half the line must be above the baseline, and half must be below).
1778 %       This is consistent with the horizontal rules used in the diagram.
1779 %
1780 % \item The vertical parts must overlap vertical rules on either side, so
1781 %       that a |\vrule\sd@|\textit{xx}|circ| makes the arc appear to be
1782 %       a real curve in the line.  The requirements are actually somewhat
1783 %       inconsistent; for example, the \env{stack} environment uses curves
1784 %       \emph{before} the |\vrule|s.  Special requirements like this are
1785 %       handled as special cases later.
1786 %
1787 % \item The height and width of the arc are at least roughly correct.
1788 %
1789 % \end{itemize}
1790 %
1791 %    \begin{macrocode}
1792 \def\sd@tlcirc{{%
1793   \sd@circ3%
1794   \ht\tw@\sdrulewidth%
1795   \dp\tw@.5\sdcirclediam%
1796   \kern-\tw@\sdrulewidth%
1797   \raise\sd@mid\box\tw@%
1798   \kern.5\sdcirclediam%
1799 }}
1800 %    \end{macrocode}
1801 %
1802 %    \begin{macrocode}
1803 \def\sd@trcirc{{%
1804   \sd@circ0%
1805   \ht\tw@\sdrulewidth%
1806   \dp\tw@.5\sdcirclediam%
1807   \kern.5\sdcirclediam%
1808   \raise\sd@mid\box\tw@%
1809 }}
1810 %    \end{macrocode}
1811 %
1812 %    \begin{macrocode}
1813 \def\sd@blcirc{{%
1814   \sd@circ2%
1815   \ht\tw@.5\sdcirclediam%
1816   \dp\tw@\sdrulewidth%
1817   \kern-\tw@\sdrulewidth%
1818   \raise\sd@mid\box\tw@%
1819   \kern.5\sdcirclediam%
1820 }}
1821 %    \end{macrocode}
1822 %
1823 %    \begin{macrocode}
1824 \def\sd@brcirc{{%
1825   \sd@circ1%
1826   \ht\tw@.5\sdcirclediam%
1827   \dp\tw@\sdrulewidth%
1828   \kern.5\sdcirclediam%
1829   \raise\sd@mid\box\tw@%
1830 }}
1831 %    \end{macrocode}
1832 %
1833 %    \begin{macrocode}
1834 \def\sd@nocirc{\sd@rule\hskip.5\sdcirclediam\relax}
1835 %    \end{macrocode}
1836 %
1837 % \end{macro}
1838 % \end{macro}
1839 % \end{macro}
1840 % \end{macro}
1841 %
1842 % \begin{macro}{\sd@llc}
1843 % \begin{macro}{\sd@rlc}
1844 %
1845 % In the \env{rep} environment, we need to be able to draw arcs with
1846 % horizontal lines running through them.  The two macros here do the job
1847 % nicely.  |\sd@llc| (which is short for left overlapping circle) is
1848 % analogous to |\llap|: it puts its argument in a box of zero width, sticking
1849 % out to the left.  However, it also draws a rule along the baseline.  This
1850 % is important, as it prevents text from overprinting the arc.  |\sd@rlc|
1851 % is very similar, just the other way around.
1852 %
1853 %    \begin{macrocode}
1854 \def\sd@llc#1{%
1855   \hb@xt@.5\sdcirclediam{%
1856     \sd@rule\hskip.5\sdcirclediam%
1857     \hss%
1858     #1%
1859   }%
1860 }
1861 %    \end{macrocode}
1862 %
1863 %    \begin{macrocode}
1864 \def\sd@rlc#1{%
1865   \hb@xt@.5\sdcirclediam{%
1866     #1%
1867     \hss%
1868     \sd@rule\hskip.5\sdcirclediam%
1869   }%
1870 }
1871 %    \end{macrocode}
1872 %
1873 % \end{macro}
1874 % \end{macro}
1875 %
1876 % \subsubsection{Drawing rules}
1877 %
1878 % It's important to draw the rules \emph{along} the baseline, rather than
1879 % above it: hence, the depth of the rule must be equal to the height.
1880 %
1881 % \begin{macro}{\sd@rule}
1882 %
1883 % We use rule leaders instead of glue through most of the syntax diagrams.
1884 % The command \syntax{"\\sd@rule"<skip>} draws a rule of the correct
1885 % dimensions, which has the behaviour of an \syntax{"\\hskip"<skip>}.
1886 %
1887 %    \begin{macrocode}
1888 \def\sd@rule{\leaders\hrule\@height\sd@upper\@depth\sd@lower}
1889 %    \end{macrocode}
1890 %
1891 % \end{macro}
1892 %
1893 % \begin{macro}{\sd@gap}
1894 %
1895 % The gap between elements is added using this macro.  It will allow a
1896 % line break if we're at the top level of the diagram, using a rather
1897 % strange discretionary.
1898 %
1899 % This is called as \syntax{"\\sd@gap{"<skip-register>"}"}.
1900 %
1901 %    \begin{macrocode}
1902 \def\sd@gap#1{%
1903 %    \end{macrocode}
1904 %
1905 % First, we see if we're at the top level.  Within constructs, we avoid the
1906 % overhead of a |\discretionary|.  We put half of the width of the skip on
1907 % each side of the discretionary break.
1908 %
1909 %    \begin{macrocode}
1910   \ifsd@left%
1911     \ifsd@base%
1912       \skip@#1%
1913         \divide\skip\z@\tw@%
1914       \nobreak\sd@rule\hskip\skip@%
1915       \discretionary{%
1916         \sd@qarrow{->}%
1917       }{%
1918         \hbox{%
1919           \sd@qarrow{>-}%
1920           \sd@rule\hskip\sdstartspace%
1921           \sd@rule\hskip3.5\p@%
1922         }%
1923       }{%
1924       }%
1925       \nobreak\sd@rule\hskip\skip@%
1926 %    \end{macrocode}
1927 %
1928 % If we're not at the base level, we just put in a rule of the correct
1929 % width.
1930 %
1931 %    \begin{macrocode}
1932     \else%
1933       \sd@rule\hskip#1%
1934     \fi%
1935   \fi%
1936 }
1937 %    \end{macrocode}
1938 %
1939 % \end{macro}
1940 %
1941 % \begin{macro}{\sd@qgap}
1942 % \begin{macro}{\sd@dequeue}
1943 %
1944 % This is the high-level interface to spacing in syntax diagrams.  Stuff only
1945 % gets printed if the diagram's actually started yet, and hasn't finished.
1946 %
1947 %    \begin{macrocode}
1948 \def\sd@qgap#1{%
1949   \ifsd@left%
1950     \ifsd@right\advance\sd@qskip#1\relax%
1951     \else\sd@gap#1\fi%
1952   \fi%
1953 }
1954 \def\sd@dequeue{\ifsd@left\sd@gap\sd@qskip\sd@qskip\z@\fi}
1955 %    \end{macrocode}
1956 %
1957 % \end{macro}
1958 % \end{macro}
1959 %
1960 % \begin{macro}{\sd@abbrev}
1961 %
1962 % Sets up syntax diagram abbreviations.
1963 %
1964 %    \begin{macrocode}
1965 \def\sd@abbrev{%
1966   \def\({\begin{stack}}%
1967   \def\){\end{stack}}%
1968   \def\<{\begin{rep}}%
1969   \def\>{\end{rep}}%
1970   \expandafter\def%
1971     \csname\ifx\gr@leftsq\@@undefined[\else gr@leftsq\fi\endcsname%
1972     {\begin{stack}\\}%
1973   \expandafter\let%
1974     \csname\ifx\gr@rightsq\@@undefined]\else gr@rightsq\fi\endcsname%
1975     \)%
1976 }
1977 %    \end{macrocode}
1978 %
1979 % \end{macro}
1980 %
1981 % \subsubsection{The \protect\env{syntdiag} environment}
1982 %
1983 % All syntax diagrams are contained within a \env{syntdiag} environment.
1984 %
1985 % \begin{environment}{syntdiag}
1986 %
1987 % The only argument is a collection of declarations, which by
1988 % default is
1989 %
1990 % \begin{listing}
1991 %\sdsize\sdlengths
1992 % \end{listing}
1993 %
1994 % However, if the optional argument is not specified, \TeX\ reads the first
1995 % character of the environment, which may not be catcoded correctly.  We set
1996 % up the catcodes first, using the |\syntaxShortcuts| command, and then read
1997 % the argument.  We don't use |\newcommand|, because that would involve
1998 % creating yet \emph{another} macro.  Time to fiddle with |\@ifnextchar|
1999 % \dots
2000 %
2001 %    \begin{macrocode}
2002 \def\syntdiag{%
2003   \syntaxShortcuts\sd@tok@i\sd@tok@ii%
2004   \sd@abbrev%
2005   \@ifnextchar[\syntdiag@i{\syntdiag@i[]}%
2006 }
2007 \def\syntdiag@i[#1]{\@ifnextchar[{\syntdiag@ii{#1}}{\syntdiag@ii{#1}[b]}}
2008 %    \end{macrocode}
2009 %
2010 % Now we actually do the job we're meant to.
2011 %
2012 %    \begin{macrocode}
2013 \def\syntdiag@ii#1[#2]{%
2014 %    \end{macrocode}
2015 %
2016 % The first thing to do is execute the user's declarations.  We then set
2017 % up things for the font size.
2018 %
2019 %    \begin{macrocode}
2020   \sdsize\sdlengths%
2021   #1%
2022   \sd@setsize%
2023 %    \end{macrocode}
2024 %
2025 % Sort out the omission of left or right sides.
2026 %
2027 %    \begin{macrocode}
2028   \sd@lefttrue\sd@righttrue%
2029   \if#2l\sd@rightfalse\fi%
2030   \if#2r\sd@leftfalse\fi%
2031 %    \end{macrocode}
2032 %
2033 % Next, we start a list, to change the text layout.
2034 %
2035 %    \begin{macrocode}
2036   \list{}{%
2037     \leftmargin\sdindent%
2038     \rightmargin\leftmargin%
2039     \labelsep\z@%
2040     \labelwidth\z@%
2041   }%
2042   \item[]%
2043 %    \end{macrocode}
2044 %
2045 % We reconfigure the paragraph format quite a lot now.  We clear
2046 % |\parfillskip| to avoid any justification at the end of the paragraph.
2047 % We also turn off paragraph indentation.
2048 %
2049 %    \begin{macrocode}
2050   \parfillskip\z@%
2051   \noindent%
2052 %    \end{macrocode}
2053 %
2054 % Next, we add in the arrows on the beginning of the line, and a bit of
2055 % glue.
2056 %
2057 %    \begin{macrocode}
2058   \ifsd@left%
2059     \sd@qarrow{>>-}%
2060     \nobreak\sd@rule\hskip\sdstartspace%
2061    \fi%
2062 %    \end{macrocode}
2063 %
2064 % This is the base level of the diagram, so we enable line breaking.
2065 %
2066 %    \begin{macrocode}
2067   \sd@basetrue%
2068 %    \end{macrocode}
2069 %
2070 % Since the objects being broken are rather large, we enable sloppy line
2071 % breaking.  We also try to avoid page breaks in mid-diagram, by upping the
2072 % |\interlinepenalty|.
2073 %
2074 %    \begin{macrocode}
2075   \sloppy%
2076   \interlinepenalty100%
2077   \hyphenpenalty0%
2078 %    \end{macrocode}
2079 %
2080 % We handle all the spacing within the environment, so we make \TeX\ ignore
2081 % spaces and newlines.
2082 %
2083 %    \begin{macrocode}
2084   \catcode`\ 9%
2085   \catcode`\^^M9%
2086 %    \end{macrocode}
2087 %
2088 % We now have to change the behaviour of |\\| to line-break syntax diagrams.
2089 %
2090 %    \begin{macrocode}
2091   \let\\\sd@newline%
2092   \ignorespaces%
2093 }
2094 %    \end{macrocode}
2095 %
2096 % When we end the diagram, we just have to add in the final fillskip, and
2097 % double arrow.
2098 %
2099 %    \begin{macrocode}
2100 \def\endsyntdiag{%
2101   \unskip%
2102   \ifsd@right%
2103     \nobreak\sd@rule\hskip\sdmidskip%
2104     \sd@rule\hskip\sdfinalskip%
2105     \sd@qarrow{-><}%
2106   \else%
2107     \hskip\sdfinalskip%
2108     \vadjust{}%
2109   \fi%
2110   \endlist%
2111 }
2112 %    \end{macrocode}
2113 %
2114 % \end{environment}
2115 %
2116 % \begin{environment}{syntdiag*}
2117 %
2118 % The starred form of \env{syntdiag} typesets a syntax diagram in LR-mode;
2119 % this is useful if you're describing parts of syntax diagrams, for example.
2120 %
2121 % This is in fact really easy.  The first bit which checks for an optional
2122 % argument is almost identical to the non-$*$ version.
2123 %
2124 %    \begin{macrocode}
2125 \@namedef{syntdiag*}{%
2126   \syntaxShortcuts\sd@tok@i\sd@tok@ii%
2127   \sd@abbrev%
2128   \@tempswatrue%
2129   \@ifnextchar[\syntdiag@s@i{\syntdiag@s@i[]}%
2130 }
2131 %    \end{macrocode}
2132 %
2133 % Handle another optional argument giving the width of the box to fill.
2134 %
2135 %    \begin{macrocode}
2136 \def\syntdiag@s@i[#1]{%
2137   \@ifnextchar[{\syntdiag@s@ii{#1}}{\syntdiag@s@iii{#1}{\hbox}}%
2138 }
2139 \def\syntdiag@s@ii#1[#2]{%
2140   \def\@tempa{#2}\def\@tempb{*}%
2141   \ifx\@tempa\@tempb%
2142     \@tempswafalse%
2143     \syntdiag@s@iii{#1}{}%
2144   \else%
2145     \syntdiag@s@iii{#1}{\hb@xt@#2}%
2146   \fi%
2147 }
2148 %    \end{macrocode}
2149 %
2150 % Now to actually start the display.  This is mostly simple.  Just to make
2151 % sure about the LR-ness of the typesetting, I'll put everything in an hbox.
2152 %
2153 %    \begin{macrocode}
2154 \def\syntdiag@s@iii#1#2{%
2155   \leavevmode%
2156   #2\bgroup%
2157 %    \end{macrocode}
2158 %
2159 % Now configure the typesetting according to the user's wishes.
2160 %
2161 %    \begin{macrocode}
2162   \let\@@left\left%
2163   \let\@@right\right%
2164   \def\left##1{\def\sd@startarr{##1}}%
2165   \def\right##1{\def\sd@endarr{##1}}%
2166   \left{>-}\right{->}%
2167   \sdsize\sdlengths%
2168   #1%
2169   \sd@setsize%
2170   \let\left\@@left%
2171   \let\right\@@right%
2172   \sd@lefttrue\sd@righttrue%
2173   \ifx\sd@startarr\@empty\sd@leftfalse\fi%
2174   \ifx\sd@endarr\@empty\sd@rightfalse\fi%
2175 %    \end{macrocode}
2176 %
2177 % Put in the initial double-arrow.
2178 %
2179 %    \begin{macrocode}
2180   \ifsd@left%
2181     \sd@qarrow\sd@startarr%
2182     \sd@rule\hskip\sdmidskip%
2183   \fi%
2184 %    \end{macrocode}
2185 %
2186 % We're in horizontal mode, so don't bother with linebreaking.
2187 %
2188 %    \begin{macrocode}
2189   \if@tempswa\sd@basefalse\else\sd@basetrue\fi%
2190 %    \end{macrocode}
2191 %
2192 % Finally, disable spaces and things.
2193 %
2194 %    \begin{macrocode}
2195   \catcode`\ 9%
2196   \catcode`\^^M9%
2197   \ignorespaces%
2198 }
2199 %    \end{macrocode}
2200 %
2201 % Ending the environment is very similar.
2202 %
2203 %    \begin{macrocode}
2204 \@namedef{endsyntdiag*}{%
2205   \unskip%
2206   \ifsd@right%
2207     \sd@rule\hskip\sdmidskip%
2208     \ifsd@base\else\sd@rule\hskip\sdfinalskip\fi%
2209     \sd@qarrow\sd@endarr%
2210   \else%
2211     \hskip\sdmidskip%
2212     \ifsd@base\else\hskip\sdfinalskip\fi%
2213   \fi%
2214   \egroup%
2215 }
2216 %    \end{macrocode}
2217 %
2218 % \end{environment}
2219 %
2220 % \begin{macro}{\sd@qarrow}
2221 %
2222 % This typesets the various left and right arrows required in syntax
2223 % diagrams.  The argument is one of \syntax{`>>-', `->', `>-' or `-><'}.
2224 %
2225 %    \begin{macrocode}
2226 \def\sd@qarrow#1{%
2227   \begingroup%
2228   \lccode`\~=`\<\lowercase{\def~{<}}%
2229   \hbox{\csname sd@arr@#1\endcsname}%
2230   \endgroup%
2231 }
2232 \@namedef{sd@arr@>>-}{\sd@rightarr\kern-.5\p@\sd@rightarr\kern-\p@}
2233 \@namedef{sd@arr@>-}{\sd@rightarr\kern-\p@}
2234 \@namedef{sd@arr@->}{\sd@rightarr}
2235 \@namedef{sd@arr@-><}{\sd@rightarr\kern-\p@\sd@leftarr}
2236 \@namedef{sd@arr@...}{$\cdots$}
2237 \@namedef{sd@arr@-}{}
2238 \@namedef{sd@arr@}{}
2239 %    \end{macrocode}
2240 %
2241 % \end{macro}
2242 %
2243 % \begin{macro}{\sd@newline}
2244 %
2245 % The line breaking within a syntax diagram is controlled by the
2246 % |\sd@newline| command, to which |\\| is assigned.
2247 %
2248 % We support all the standard \LaTeX\ features here.  The line breaking
2249 % involves adding a fill skip and arrow, moving to the next line, adding
2250 % an arrow and a rule, and continuing.
2251 %
2252 %    \begin{macrocode}
2253 \def\sd@newline{\@ifstar{\vadjust{\penalty\@M}\sd@nl@i}\sd@nl@i}
2254 \def\sd@nl@i{\@ifnextchar[\sd@nl@ii\sd@nl@iii}
2255 \def\sd@nl@ii[#1]{\vspace{#1}\sd@nl@iii}
2256 \def\sd@nl@iii{%
2257   \nobreak\sd@rule\hskip\sdmidskip%
2258   \sd@rule\hskip\sdfinalskip%
2259   \kern-3\p@%
2260   \sd@rightarr%
2261   \newline%
2262   \sd@rightarr%
2263   \nobreak\sd@rule\hskip\sdstartspace%
2264   \sd@rule\hskip3.5\p@%
2265 }
2266 %    \end{macrocode}
2267 %
2268 % \end{macro}
2269 %
2270 % \subsubsection{Putting things in the right place}
2271 %
2272 % Syntax diagrams have fairly stiff requirements on the positioning of text
2273 % relative to the diagram's rules.  To help people (and me) to write
2274 % extensions to the syntax diagram typesetting which automatically put things
2275 % in the right place, I provide some simple macros.
2276 %
2277 % \begin{environment}{sdbox}
2278 %
2279 % By placing some text in the \env{sdbox} environment, it will be read into a
2280 % box and then output at the correct height for the syntax diagram.  Note
2281 % that stuff in the box is set in horizontal (LR) mode, so you'll have to use
2282 % a \env{minipage} if you want formatted text.  The macro also supplies rules
2283 % on either side of the box, with a length given in the environment's
2284 % argument.
2285 %
2286 % Macro writers are given explicit permission to use this environment through
2287 % the |\sdbox| and |\endsdbox| commands if this makes life easier.
2288 %
2289 % The calculation in the |\endsdbox| macro works out how to centre the box
2290 % vertically over the baseline.  If the box's height is~$h$, and its depth
2291 % is~$d$, then its centre-line is $(h+d)/2$ from the bottom of the box.
2292 % Since the baseline is already $d$ from the bottom, we need to lower the box
2293 % by $(h+d)/2 - d$, or $h/2-d/2$.
2294 %
2295 %    \begin{macrocode}
2296 \def\sdbox#1{%
2297   \@tempskipa#1\relax%
2298   \sd@gap\@tempskipa%
2299   \setbox\z@\hbox\bgroup%
2300     \begingroup%
2301     \catcode`\ 10%
2302     \catcode`\^^M5%
2303     \synshortsoff%
2304 }
2305 \def\endsdbox{%
2306     \endgroup%
2307   \egroup%
2308   \@tempdima\ht\z@%
2309   \advance\@tempdima-\dp\z@%
2310   \advance\@tempdima-\tw@\sd@mid%
2311   \lower.5\@tempdima\box\z@%
2312   \sd@lefttrue%
2313   \sd@gap\@tempskipa%
2314 }
2315 %    \end{macrocode}
2316 %
2317 % \end{environment}
2318 %
2319 % \subsubsection{Typesetting syntactic items}
2320 %
2321 % Using the hooks built into the syntax abbreviations above, we typeset
2322 % the text into a box, and write it out, centred over the baseline.  A strut
2323 % helps to keep the actual text baselines level for short pieces of text.
2324 %
2325 % \begin{macro}{\sd@tok@i}
2326 %
2327 % The preamble for a syntax abbreviation.  We start a box, and set the
2328 % space and return characters to work again.  A strut is added to the box to
2329 % ensure correct vertical spacing for normal text.
2330 %
2331 %    \begin{macrocode}
2332 \def\sd@tok@i{%
2333   \sdbox\sdtokskip%
2334   \strut%
2335   \space%
2336 }
2337 %    \end{macrocode}
2338 %
2339 % \end{macro}
2340 %
2341 % \begin{macro}{\sd@tok@ii}
2342 %
2343 %    \begin{macrocode}
2344 \def\sd@tok@ii{%
2345   \space%
2346   \endsdbox%
2347 }
2348 %    \end{macrocode}
2349 %
2350 % \end{macro}
2351 %
2352 % \subsubsection{Inserting other pieces of text}
2353 %
2354 % Arbitrary text may be put into a syntax diagram through the use of the
2355 % |\tok| macro.  Its `argument' is typeset in the same way as a syntactic
2356 % item (centred over the baseline).  The implementation goes to some effort
2357 % to ensure that the text is not actually an argument, to allow category
2358 % codes to change while the text is being typeset.
2359 %
2360 % \begin{macro}{\tok}
2361 %
2362 % We start a box, and make space and return do their normal jobs.  We use
2363 % |\aftergroup| to regain control once the box is finished.  |\doafter| is
2364 % used to get control after the group finishes.
2365 %
2366 %    \begin{macrocode}
2367 \def\tok#{%
2368   \sdbox\sdtokskip%
2369   \strut%
2370   \enspace%
2371   \syntaxShortcuts\relax\relax%
2372   \doafter\sd@tok%
2373 }
2374 %    \end{macrocode}
2375 %
2376 % The |\sd@tok| macro is similar to |\sd@tok@ii| above.
2377 %
2378 %    \begin{macrocode}
2379 \def\sd@tok{%
2380   \enspace%
2381   \endsdbox%
2382 }
2383 %    \end{macrocode}
2384 %
2385 % \end{macro}
2386 %
2387 % \subsubsection{The \protect\env{stack} environment}
2388 %
2389 % The \env{stack} environment is used to present alternatives in a syntax
2390 % diagram.  The alternatives are separated by |\\| commands.
2391 %
2392 % \begin{macro}{\stack}
2393 %
2394 % Handle the optional arguments.
2395 %
2396 %    \begin{macrocode}
2397 \def\stack{\@ifnextchar[\stack@i{\stack@i[t]}}
2398 \def\stack@i[#1]{\@ifnextchar[{\stack@ii{#1}}{\stack@ii{#1}[b]}}
2399 \def\stack@ii#1[#2]{%
2400 %    \end{macrocode}
2401 %
2402 % First, we add some horizontal space.
2403 %
2404 %    \begin{macrocode}
2405   \sd@gap\sdmidskip%
2406 %    \end{macrocode}
2407 %
2408 % We're within a complex construction, so we need to clear the |\ifsd@base|
2409 % flag.
2410 %
2411 %    \begin{macrocode}
2412   \begingroup\sd@basefalse%
2413 %    \end{macrocode}
2414 %
2415 % The top and bottom rows of the stack are different to the others, since
2416 % the vertical rules mustn't extend all the way up the side of the item.
2417 % The bottom row is handled separately by |\endstack| below.  The top row
2418 % must be handled via a flag, |\ifsd@toplayer|.
2419 %
2420 % Initially, the flag must be set true.
2421 %
2422 %    \begin{macrocode}
2423   \sd@toplayertrue%
2424 %    \end{macrocode}
2425 %
2426 % We set the |\\| command to separate the items in the |\halign|.
2427 %
2428 %    \begin{macrocode}
2429   \let\\\sd@stackcr%
2430 %    \end{macrocode}
2431 %
2432 % Sort out which sides of the construction are actually emitted.
2433 %
2434 %    \begin{macrocode}
2435   \sd@righttrue\if#2l\sd@rightfalse\fi%
2436 %    \end{macrocode}
2437 %
2438 % The actual structure must be set in vertical mode, so we must place it
2439 % in a box.  The position argument determines whether this must be a
2440 % |\vbox| or a |\vtop|.  We also insert a bit of rounding if the options say
2441 % we must.
2442 %
2443 %    \begin{macrocode}
2444   \if#1t%
2445     \let\@tempa\vtop%
2446     \sd@toptrue%
2447     \ifsd@left\ifsd@round\llap{\sd@trcirc\kern\tw@\sdrulewidth}\fi\fi%
2448   \else\if#1b%
2449     \let\@tempa\vbox%
2450     \sd@topfalse%
2451     \ifsd@left\ifsd@round\llap{\sd@brcirc\kern\tw@\sdrulewidth}\fi\fi%
2452   \else%
2453     \sd@err{Bad position argument passed to stack}%
2454            {The positioning argument must be one of `t' or `b'.  I%
2455             have^^Jassumed you meant to type `t'.}%
2456     \let\@tempa\vtop%
2457   \fi\fi%
2458 %    \end{macrocode}
2459 %
2460 % Now we start the box, which we will complete at the end of the environment.
2461 %
2462 %    \begin{macrocode}
2463   \@tempa\bgroup%
2464 %    \end{macrocode}
2465 %
2466 % We must remove any extra space between rows of the table, since the rules
2467 % will not join up correctly.  We can use |\offinterlineskip| safely, since
2468 % each individual row contains a strut.
2469 %
2470 %    \begin{macrocode}
2471   \offinterlineskip%
2472 %    \end{macrocode}
2473 %
2474 % Now we can start the alignment.  We actually use \PlainTeX's |\ialign|
2475 % macro, which also clears |\tabskip| for us.
2476 %
2477 %    \begin{macrocode}
2478   \ialign\bgroup%
2479 %    \end{macrocode}
2480 %
2481 % The preamble is trivial, since we must do all of the work ourselves
2482 %
2483 %    \begin{macrocode}
2484     ##\cr%
2485 %    \end{macrocode}
2486 %
2487 % We can now start putting the text into a box ready for typesetting later.
2488 % The strut makes the vertical spacing correct.
2489 %
2490 %    \begin{macrocode}
2491   \setbox\z@\hbox\bgroup%
2492     \strut%
2493 }
2494 %    \end{macrocode}
2495 %
2496 % \end{macro}
2497 %
2498 % \begin{macro}{\endstack}
2499 %
2500 % The first part of this is similar to the |\sd@stackcr| macro below, except
2501 % that the vertical rules are different.  We don't support rounded edges
2502 % on single-row stacks, although this isn't a great loss to humanity.
2503 %
2504 %    \begin{macrocode}
2505 \def\endstack{%
2506   \ifsd@right\else\unskip\fi%
2507   \egroup%
2508   \ifsd@toplayer%
2509     \sd@dostack\sd@upper\sd@lower\sd@nocirc\sd@nocirc%
2510   \else%
2511     \ifsd@round%
2512       \ifsd@top%
2513         \sd@dostack{\ht\z@}\sd@botcirc\sd@blcirc\sd@brcirc%
2514       \else%
2515         \sd@dostack{\ht\z@}\sd@botcirc\sd@nocirc\sd@nocirc%
2516       \fi%
2517     \else%
2518       \sd@dostack{\ht\z@}\sd@lower\relax\relax%
2519     \fi%
2520   \fi%
2521 %    \end{macrocode}
2522 %
2523 % We now close the |\halign| and the vbox we created.
2524 %
2525 %    \begin{macrocode}
2526   \egroup%
2527   \egroup%
2528 %    \end{macrocode}
2529 %
2530 % Deal with any rounding we started off.
2531 %
2532 %    \begin{macrocode}
2533   \ifsd@right\ifsd@round%
2534     \ifsd@top
2535       \rlap{\kern\tw@\sdrulewidth\sd@tlcirc}%
2536     \else%
2537       \rlap{\kern\tw@\sdrulewidth\sd@blcirc}%
2538     \fi%
2539   \fi\fi%
2540 %    \end{macrocode}
2541 %
2542 % Finally, we add some horizontal glue to space the diagram out.
2543 %
2544 %    \begin{macrocode}
2545   \endgroup\sd@lefttrue\ifsd@right\sd@gap\sdmidskip\fi%
2546 }
2547 %    \end{macrocode}
2548 %
2549 % \end{macro}
2550 %
2551 % \begin{macro}{\sd@stackcr}
2552 %
2553 % The |\\| command is set to this macro during a \env{stack} environment.
2554 %
2555 %    \begin{macrocode}
2556 \def\sd@stackcr{%
2557 %    \end{macrocode}
2558 %
2559 % The first job is to close the box containing the previous item.
2560 %
2561 %    \begin{macrocode}
2562   \ifsd@right\else\unskip\fi%
2563   \egroup%
2564 %    \end{macrocode}
2565 %
2566 % Now we typeset the vertical rules differently depending on whether this is
2567 % the first item in the stack.  This looks quite terrifying initially, but
2568 % it's just an enumeration of the possible cases for the different values
2569 % of |\ifsd@toplayer|, |\ifsd@top| and |\ifsd@round|, putting in appropriate
2570 % rules and arcs in the right places.
2571 %
2572 %    \begin{macrocode}
2573   \ifsd@toplayer%
2574     \ifsd@round%
2575       \ifsd@top%
2576         \sd@dostack\sd@topcirc{\dp\z@}\sd@nocirc\sd@nocirc%
2577       \else%
2578         \sd@dostack\sd@topcirc{\dp\z@}\sd@tlcirc\sd@trcirc%
2579       \fi%
2580     \else%
2581       \sd@dostack\sd@upper{\dp\z@}\relax\relax%
2582     \fi%
2583   \else%
2584     \ifsd@round%
2585       \ifsd@top%
2586         \sd@dostack{\ht\z@}{\dp\z@}\sd@blcirc\sd@brcirc%
2587       \else%
2588         \sd@dostack{\ht\z@}{\dp\z@}\sd@tlcirc\sd@trcirc%
2589       \fi%
2590     \else%
2591       \sd@dostack{\ht\z@}{\dp\z@}\relax\relax%
2592     \fi%
2593   \fi%
2594 %    \end{macrocode}
2595 %
2596 % The next item won't be the first, so we clear the flag.
2597 %
2598 %    \begin{macrocode}
2599   \sd@toplayerfalse%
2600 %    \end{macrocode}
2601 %
2602 % Now we have to set up the next cell.  We put the text into a box again.
2603 %
2604 %    \begin{macrocode}
2605   \setbox\z@\hbox\bgroup%
2606     \strut%
2607 }
2608 %    \end{macrocode}
2609 %
2610 % \end{macro}
2611 %
2612 % \begin{macro}{\sd@dostack}
2613 %
2614 % Actually typesetting the text in a cell is performed here.  The macro is
2615 % called as
2616 % \begin{quote}\synshorts
2617 % "\\sd@dostack{"<height>"}{"<depth>"}{"<left-arc>"}{"<right-arc>"}"
2618 % \end{quote}
2619 % where \<height> and \<depth> are the height and depth of the vertical
2620 % rules to put around the item, and \<left-arc> and \<right-arc> are
2621 % commands to draw rounded edges on the left and right hand sides of the
2622 % item.
2623 %
2624 % The values for the height and depth are quite often going to be the height
2625 % and depth of box~0.  Since we empty box~0 in the course of typesetting the
2626 % row, we need to cache the sizes on entry.
2627 %
2628 %    \begin{macrocode}
2629 \def\sd@dostack#1#2#3#4{%
2630   \@tempdima#1%
2631   \@tempdimb#2%
2632   \ifsd@left%
2633     \kern-\tw@\sdrulewidth%
2634     \vrule\@height\@tempdima\@depth\@tempdimb\@width\tw@\sdrulewidth%
2635     #3%
2636     \sd@rule\hfil%
2637     \sd@gap\sdtokskip%
2638   \else%
2639     \hfill%
2640   \fi%
2641   \unhbox\z@%
2642   \ifsd@right%
2643     \sd@gap\sdtokskip%
2644     \sd@rule\hfil%
2645     #4%
2646     \vrule\@height\@tempdima\@depth\@tempdimb\@width\tw@\sdrulewidth%
2647     \kern-\tw@\sdrulewidth%
2648   \else%
2649     \hfill%
2650   \fi%
2651   \cr%
2652 }
2653 %    \end{macrocode}
2654 %
2655 % \end{macro}
2656 %
2657 % \subsubsection{The \protect\env{rep} environment}
2658 %
2659 % The \env{rep} environment is used for typesetting loops in the diagram.
2660 % Again, we use |\halign| for the typesetting.  Loops are simpler than
2661 % stacks, however, since there are always two rows.  We store both rows in
2662 % box registers, and build the loop at the end.
2663 %
2664 % \begin{macro}{\rep}
2665 %
2666 % Again, we use |\newcommand| to process the optional argument.
2667 %
2668 %    \begin{macrocode}
2669 \newcommand\rep[1][t]{%
2670 %    \end{macrocode}
2671 %
2672 % First, leave a gap on the left side.
2673 %
2674 %    \begin{macrocode}
2675   \sd@gap\sdmidskip%
2676 %    \end{macrocode}
2677 %
2678 % We're not at base level any more, so disable linebreaking.
2679 %
2680 %    \begin{macrocode}
2681   \begingroup\sd@basefalse%
2682 %    \end{macrocode}
2683 %
2684 % Remember we're going backwards now.
2685 %
2686 %    \begin{macrocode}
2687   \ifsd@backwards\sd@backwardsfalse\else\sd@backwardstrue\fi%
2688 %    \end{macrocode}
2689 %
2690 % Define |\\| to separate the two parts of the loop.
2691 %
2692 %    \begin{macrocode}
2693    \let\\\sd@loop%
2694 %    \end{macrocode}
2695 %
2696 % Now check the argument, and use the appropriate type of box.  In addition
2697 % to changing the typesetting, we must remember which way up to typeset the
2698 % loop, since the end code must always put the first argument on the
2699 % baseline, with the loop either above or below.
2700 %
2701 %    \begin{macrocode}
2702   \if#1t%
2703     \let\@tempa\vbox%
2704     \sd@toptrue%
2705   \else\if#1b%
2706     \let\@tempa\vtop%
2707     \sd@topfalse%
2708   \else%
2709     \sd@err{Bad position argument passed to loop}%
2710            {The positioning argument must be `t' or `b'.  I have^^J%
2711             assumed you meant to type `t'.}%
2712     \let\@tempa\vbox%
2713     \sd@toptrue%
2714   \fi\fi%
2715 %    \end{macrocode}
2716 %
2717 % Now we start the box.
2718 %
2719 %    \begin{macrocode}
2720   \@tempa\bgroup%
2721 %    \end{macrocode}
2722 %
2723 % The loop is by default empty, apart from a strut.  This is put into box~1.
2724 %
2725 %    \begin{macrocode}
2726   \setbox\tw@\copy\strutbox%
2727 %    \end{macrocode}
2728 %
2729 % Now start typesetting the main text in box~0.
2730 %
2731 %    \begin{macrocode}
2732   \setbox\z@\hbox\bgroup\strut%
2733 }
2734 %    \end{macrocode}
2735 %
2736 % \end{macro}
2737 %
2738 % \begin{macro}{\endrep}
2739 %
2740 % The final code must first close whatever box was open.
2741 %
2742 %    \begin{macrocode}
2743 \def\endrep{%
2744   \egroup%
2745 %    \end{macrocode}
2746 %
2747 % Now we typeset the loop, depending on which way up it was meant to be.
2748 % Again, this terrifying piece of code is a simple list of possibile values
2749 % of our various flags.
2750 %
2751 %    \begin{macrocode}
2752   \ifsd@top%
2753     \ifsd@round%
2754       \sd@doloop\tw@\z@\relax\relax%
2755         \sd@tlcirc\sd@trcirc{\sd@rlc\sd@blcirc}{\sd@llc\sd@brcirc}%
2756     \else%
2757       \sd@doloop\tw@\z@\relax\sd@downarr\relax\relax\relax\relax%
2758     \fi%
2759   \else%
2760     \ifsd@round%
2761       \sd@doloop\z@\tw@\relax\relax%
2762         {\sd@rlc\sd@tlcirc}{\sd@llc\sd@trcirc}\sd@blcirc\sd@brcirc%
2763     \else%
2764       \sd@doloop\z@\tw@\sd@uparr\relax\relax\relax\relax\relax%
2765     \fi%
2766   \fi%
2767 %    \end{macrocode}
2768 %
2769 % Close the vbox we opened.
2770 %
2771 %    \begin{macrocode}
2772   \egroup%
2773 %    \end{macrocode}
2774 %
2775 % Finally, we leave a gap before the next structure.
2776 %
2777 %    \begin{macrocode}
2778   \endgroup\sd@gap\sdmidskip%
2779 }
2780 %    \end{macrocode}
2781 %
2782 % \end{macro}
2783 %
2784 % \begin{macro}{\sd@loop}
2785 %
2786 % This macro handles the |\\| command within a loop environment.  We close
2787 % the current box, and start filling in box~1.  We also redefine |\\| to
2788 % raise an error when the |\\| command is used again.
2789 %
2790 %    \begin{macrocode}
2791 \def\sd@loop{%
2792   \egroup%
2793   \def\\{\sd@err{Too many \string\\\space commands in loop}\@ehc}%
2794   \setbox\tw@\hbox\bgroup\strut%
2795 }
2796 %    \end{macrocode}
2797 %
2798 % \end{macro}
2799 %
2800 % \begin{macro}{\sd@doloop}
2801 %
2802 % This is the macro which actually creates the |\halign| for the loop.  It
2803 % is called with four arguments, as:
2804 % \begin{quote}\synshorts
2805 % "\\sd@doloop{"<top-box>"}{"<bottom-box>"}"^^A
2806 %                "{"<top-arrow>"}{"<btm-arrow>"}" \\
2807 % \hbox{}\quad "{"<top-left-arc>"}{"<top-right-arc>"}"^^A
2808 %                "{"<bottom-left-arc>"}{"<btm-right-arc>"}"^^A
2809 % \kern-1in ^^A It may be overfull, but it looks OK to me ;-)
2810 % \end{quote}
2811 %
2812 % The two \<box> arguments give the numbers of boxes to extract in the top
2813 % and bottom rows of the alignment.  The \<arrow> arguments specify
2814 % characters to typeset at the end of the top and bottom rows for arrows.
2815 % The various \<arc> arguments are commands which typeset arcs around the
2816 % various parts of the items.
2817 %
2818 % We calculate the height and depth of the two boxes, and store them in
2819 % \<dimen> registers, because the boxes are emptied before the right-hand
2820 % rules are typeset.
2821 %
2822 % Actually, the two rows of the alignment are typeset in a different macro:
2823 % we just pass the correct information on.
2824 %
2825 %    \begin{macrocode}
2826 \def\sd@doloop#1#2#3#4#5#6#7#8{%
2827   \@tempdima\dp#1\relax%
2828   \@tempdimb\ht#2\relax%
2829   \offinterlineskip%
2830   \ialign{%
2831     ##\cr%
2832     \ifsd@round%
2833       \sd@doloop@i#1#3\sd@topcirc\@tempdima{#5}{#6}%
2834       \sd@doloop@i#2#4\@tempdimb\sd@botcirc{#7}{#8}%
2835     \else%
2836       \sd@doloop@i#1#3\sd@upper\@tempdima{#5}{#6}%
2837       \sd@doloop@i#2#4\@tempdimb\sd@lower{#7}{#8}%
2838     \fi%
2839   }%
2840 }
2841 %    \end{macrocode}
2842 %
2843 % \end{macro}
2844 %
2845 % \begin{macro}{\sd@doloop@i}
2846 %
2847 % Here we do the actual job of typesetting the rows of a loop alignment.
2848 % The four arguments are:
2849 % \begin{quote}\synshorts
2850 % "\\sd@doloop@i{"<box>"}{"<arrow>"}"^^A
2851 %              "{"<rule-height>"}{"<rule-depth>"}" \\
2852 % \hbox{}\quad "{"<left-arc>"}{"<right-arc>"}"^^A
2853 % \end{quote}
2854 %
2855 % The arrow position is determined by the |\ifsd@backwards| flag.  The rest
2856 % is fairly simple.
2857 %
2858 %    \begin{macrocode}
2859 \def\sd@doloop@i#1#2#3#4#5#6{%
2860   \ifsd@backwards#2\fi%
2861   \kern-\tw@\sdrulewidth%
2862   \vrule\@height#3\@depth#4\@width\tw@\sdrulewidth%
2863   #5%
2864   \sd@rule\hfill%
2865   \sd@gap\sdtokskip%
2866   \unhbox#1%
2867   \sd@gap\sdtokskip%
2868   \sd@rule\hfill%
2869   #6%
2870   \vrule\@height#3\@depth#4\@width\tw@\sdrulewidth%
2871   \ifsd@backwards\else#2\fi%
2872   \kern-\tw@\sdrulewidth%
2873   \cr%
2874 }
2875 %    \end{macrocode}
2876 %
2877 % \end{macro}
2878 %
2879 % \subsection{The end}
2880 %
2881 % Phew!  That's all of it completed.  I hope this collection of commands
2882 % and environments is of some help to someone.
2883 %
2884 %    \begin{macrocode}
2885 %</package>
2886 %    \end{macrocode}
2887 %
2888 % \hfill Mark Wooding, \today
2889 %
2890 % \Finale
2891 %
2892 \endinput