syntax.dtx 87 KB

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