syntax.dtx 88 KB

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