1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878 |
- % \begin{meta-comment}
- %
- % $Id$
- %
- % Syntax typesetting package for LaTeX 2e
- %
- % (c) 1996 Mark Wooding
- %
- %----- Revision history -----------------------------------------------------
- %
- % $Log$
- % Revision 1.1 2000-07-13 09:10:21 michael
- % + Initial import
- %
- % Revision 1.1 1998/09/21 10:19:01 michael
- % Initial implementation
- %
- % Revision 1.9 1996/11/28 00:19:10 mdw
- % Added abbreviations for syntax diagram constructions. These have been
- % getting on my nerves for too long now...
- %
- % Revision 1.8 1996/11/19 21:02:15 mdw
- % Entered into RCS
- %
- %
- % \end{meta-comment}
- %
- % \begin{meta-comment} <general public licence>
- %%
- %% syntax package -- typesetting syntax descriptions
- %% Copyright (c) 1996 Mark Wooding
- %%
- %% This program is free software; you can redistribute it and/or modify
- %% it under the terms of the GNU General Public License as published by
- %% the Free Software Foundation; either version 2 of the License, or
- %% (at your option) any later version.
- %%
- %% This program is distributed in the hope that it will be useful,
- %% but WITHOUT ANY WARRANTY; without even the implied warranty of
- %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- %% GNU General Public License for more details.
- %%
- %% You should have received a copy of the GNU General Public License
- %% along with this program; if not, write to the Free Software
- %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- %%
- % \end{meta-comment}
- %
- % \begin{meta-comment} <Package preamble>
- %<+package>\NeedsTeXFormat{LaTeX2e}
- %<+package>\ProvidesPackage{syntax}
- %<+package> [1996/05/17 1.9 Syntax typesetting (MDW)]
- % \end{meta-comment}
- %
- % \CheckSum{1465}
- %% \CharacterTable
- %% {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
- %% 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
- %% Digits \0\1\2\3\4\5\6\7\8\9
- %% Exclamation \! Double quote \" Hash (number) \#
- %% Dollar \$ Percent \% Ampersand \&
- %% Acute accent \' Left paren \( Right paren \)
- %% Asterisk \* Plus \+ Comma \,
- %% Minus \- Point \. Solidus \/
- %% Colon \: Semicolon \; Less than \<
- %% Equals \= Greater than \> Question mark \?
- %% Commercial at \@ Left bracket \[ Backslash \\
- %% Right bracket \] Circumflex \^ Underscore \_
- %% Grave accent \` Left brace \{ Vertical bar \|
- %% Right brace \} Tilde \~}
- %%
- %
- % \begin{meta-comment} <driver>
- %
- %<*driver>
- %
- % This hacking will remember the old default underscore character. Even if
- % T1 fonts are being used, it will get the grotty version. Why is it that
- % all of the encoding handling ends up looking like this?
- %
- \expandafter\let\expandafter\oldus\csname?\string\textunderscore\endcsname
- %
- \input{mdwtools}
- \describespackage{syntax}
- \DeclareRobustCommand\syn{\package{syntax}}
- \mdwdoc
- %</driver>
- %
- % \end{meta-comment}
- %
- % \section{User guide}
- %
- % \subsection{Introduction}
- %
- % The \syn\ package provides a number of commands and environments which
- % extend \LaTeX\ and allow you to typeset good expositions of syntax.
- %
- % The package provides several different types of features: probably not all
- % of these will be required by every document which needs the package:
- % \begin{itemize}
- % \item A system of abbreviated forms for typesetting syntactic items.
- % \item An environment for typesetting BNF-type grammars
- % \item A collection of environments for building syntax diagrams.
- % \end{itemize}
- %
- % The package also includes some other features which, while not necessarily
- % syntax-related, will probably come in handy for similar types of document:
- % \begin{itemize}
- % \item An abbreviated notation for verbatim text, similar to the
- % \package{shortvrb} package.
- % \item A slightly different underscore character, which works as expected
- % in text and maths modes.
- % \end{itemize}
- %
- % \subsection{The abbreviated verbatim notation}
- %
- % In documents describing programming languages and libraries, it can become
- % tedious to type "\verb|...|" every time. Like Frank Mittelbach's
- % \package{shortvrb} package, \syn\ provides a way of setting up single-^^A
- % character abbreviations. The only real difference between the two is that
- % the declarations provided by \syn\ obey \LaTeX's normal scoping rules.
- %
- % \DescribeMacro\shortverb
- % You can set up a character as a `verbatim shorthand' character using the
- % |\shortverb| command. This takes a single argument, which should be a
- % single-character control sequence containing the character you want to use.
- % So, for example, the command
- % \begin{listing}
- %\shortverb{\|}
- % \end{listing}
- % would set up the `"|"' character to act as a verbatim delimiter. While a
- % |\shortverb| declaration is in force, any text surrounded by (in this case)
- % vertical bar characters will be typeset as if using the normal |\verb|
- % command.
- %
- % \DescribeEnv{shortverb}
- % Since \LaTeX\ allows any declaration to be used as an environment, you can
- % use a \env{shortverb} environment to delimit the text over which your
- % character is active:
- % \begin{listing}
- %Some text...
- %\begin{shortverb}{\|}
- %...
- %\end{shortverb}
- % \end{listing}
- %
- % \DescribeMacro\unverb
- % If you want to disable a |\shortverb| character without ending the scope
- % of other declarations, you can use the |\unverb| command, passing it
- % a character as a control sequence, in the same way as above.
- %
- % The default \TeX/\LaTeX\ underscore character is rather too short for
- % use in identifiers. For example:
- %
- % \begingroup \let\_=\oldus
- % \begin{demo}{Old-style underscores}
- %Typing long underscore-filled
- %names, like big\_function\_name,
- %is normally tedious. The normal
- %positioning of the underscore
- %is wrong, too.
- % \end{demo}
- % \endgroup
- %
- % The \syn\ package redefines the |\_| command to draw a more attractive
- % underscore character. It also allows you to use the |_|~character
- % directly to produce an underscore outside of maths mode: |_|~behaves
- % as a subscript character as usual inside maths mode.
- %
- % \begin{demo}{New \syn\ underscores}
- %You can use underscore-filled
- %names, like big_function_name,
- %simply and naturally. Of
- %course, subscripts still work
- %normally in maths mode, e.g.,
- %$x_i$.
- % \end{demo}
- %
- % \subsection{Typesetting syntactic items}
- % \begin{synshorts}
- %
- % The \syn\ package provides some simple commands for typesetting syntactic
- % items.
- %
- % \DescribeMacro\synt
- % Typing "\\synt{"<text>"}" typesets <text> as a \lq non-terminal',
- % in italics and surrounded by angle brackets. If you use "\\synt" a lot,
- % you can use the incantation
- % \begin{listing}
- %\def\<#1>{\synt{#1}}
- % \end{listing}
- % to allow you to type "\\<"<text>">" as an alternative to
- % "\\synt{"<text>"}".
- %
- % \DescribeMacro\lit
- % You can also display literal text, which the reader should type directly,
- % using the "\\lit" command.
- %
- % \begin{demo}{Use of \cmd\lit}
- %Type \lit{ls} to display a
- %list of files.
- % \end{demo}
- %
- % Note that the literal text appears in quotes. To suppress the quotes,
- % use the `*' variant.
- %
- % The "\\lit" command produces slightly better output than "\\verb" for
- % running text, since the spaces are somewhat narrower. However, "\\verb"
- % allows you to type arbitrary characters, which are treated literally,
- % whereas you must use commands such as "\\{" to use special characters
- % within the argument to "\\lit". Of course, you can use "\\lit" anywhere
- % in the document: "\\verb" mustn't be used inside a command argument.
- % \end{synshorts}
- %
- % \subsection{Abbreviated forms for syntactic items}
- %
- % It would be very tedious to require the use of commands like |\synt|
- % when building syntax descriptions like BNF grammars. It would also make
- % your \LaTeX\ source hard to read. Therefore, \syn\ provides some
- % abbreviated forms which make typesetting syntax quicker and easier.
- %
- % Since the abbreviated forms use several characters which you may want to
- % use in normal text, they aren't enabled by default. They only work
- % with special commands and environments provided by the \syn\ package.
- %
- % The abbreviated forms are shown in the table below:
- %
- % \begin{tab}[\synshorts]{ll} \hline
- % \bf Input & \bf Output \\ \hline
- % "<some text>" & <some text> \\
- % "`some text'" & `some text' \\
- % "\"some text\"" & "some text" \\ \hline
- % \end{tab}
- %
- % Within one of these abbreviated forms, text is treated more-or-less
- % verbatim:
- % \begin{itemize}
- %
- % \item Any |$|, |%|, |^|, |&|, |{|, |}|, |~| or |#| characters are treated
- % literally: their normal special meanings are ignored.
- %
- % \item Other special characters, with the exception of |\|, are also treated
- % literally: this includes any characters made special by |\shortverb|.
- %
- % \end{itemize}
- %
- % However, the |\| character retains its meaning. Since the brace
- % characters are not recognised, most commands can't be used within
- % abbreviated forms. However, you can use special commands to type some
- % of the remaining special characters:
- %
- % \begin{tab}[\synshorts]{ll} \hline
- % \bf Command & \bf Result \\ \hline
- % "\\\\" & A `\\' character \\
- % "\\>" & A `>' character \\
- % "\\'" & A `\'' character \\
- % "\\\"" & A `"' character \\
- % "\\\ " & A `\ ' character (not a space) \\ \hline
- % \end{tab}
- %
- % Note that |\\|, |\>|, |\"| and \verb*|\ | are only useful in a |\tt| font,
- % i.e., inside |`...'| and |"..."| forms, since the characters don't exist
- % in normal fonts. The |\>|, |\"| and |\'| commands are only provided so
- % you can use these characters within |<...>|, |"..."| and |`...'| forms
- % respectively: in the other forms, there is no need to use the special
- % command.
- %
- % In addition, when the above abbreviations are enabled, the character "|"
- % is set to typeset a \syntax{|} symbol, which is conventionally used to
- % separate alternatives in syntax descriptions.
- %
- % \DescribeMacro\syntax
- % Normally, these abbreviated forms are enabled only within special
- % environments, such as \env{grammar} and \env{syntdiag}. To use them
- % in running text, use the |\syntax| command. The abbreviations are made
- % active within the argument of the |\syntax| command.\footnote{^^A
- % The argument of the \cmd\syntax\ command may contain commands such
- % as \cmd\verb, which are normally not allowed within arguments.
- % } Note that you cannot use the |\syntax| command within the argument
- % of another command.
- %
- % \DescribeMacro\synshorts
- % \DescribeEnv{synshorts}
- % You can also enable the syntax shortcuts using the |\synshorts| declaration
- % or the \env{synshorts} environment. This enables the syntax shortcuts
- % until the scope of the declaration ends.
- %
- % \DescribeMacro\synshortsoff
- % If syntax shortcuts are enabled, you can disable them using the
- % |\synshortsoff| declaration.
- %
- % \subsection{The \env{grammar} environment}
- %
- % \DescribeEnv{grammar}
- % For typesetting formal grammars, for example, of programming languages,
- % the \syn\ package provides a \env{grammar} environment. Within this
- % environment, the abbreviated forms described above are enabled.
- %
- % Within the environment, separate production rules should be separated by
- % blank lines. You can use the normal |\\| command to perform line-breaking
- % of a production rule. Note that a production rule must begin with a
- % nonterminal name enclosed in angle brackets (|<| \dots |>|), followed by
- % whitespace, then some kind of production operator (usually `::=') and then
- % some more whitespace. You can control how this text is actually typeset,
- % however.
- %
- % \DescribeMacro{\[[}
- % \DescribeMacro{\]]}
- % You can use syntax diagrams (see below) instead of a straight piece of BNF
- % by enclosing it in a |\[[| \dots |\]]| pair. Note that you can't mix
- % syntax diagrams and BNF in a production rule, and you will get something
- % which looks very strange if you try.
- %
- % \DescribeMacro\alt
- % In addition, a command |\alt| is provided for splitting long production
- % rules over several lines: the |\alt| command starts a new line and places
- % a \syntax{|} character slightly in the left margin. This is useful when
- % a symbol has many alternative productions.
- %
- % \begin{demo}[w]{The \env{grammar} environment}
- %\begin{grammar}
- %<statement> ::= <ident> `=' <expr>
- % \alt `for' <ident> `=' <expr> `to' <expr> `do' <statement>
- % \alt `{' <stat-list> `}'
- % \alt <empty>
- %
- %<stat-list> ::= <statement> `;' <stat-list> | <statement>
- %\end{grammar}
- % \end{demo}
- %
- % You can modify the appearance of grammars using three length parameters:
- %
- % \begin{description} \def\makelabel{\hskip\labelsep\cmd}
- %
- % \item [\grammarparsep] is the amount of space inserted between production
- % rules. It is a rubber length whose default value is 8\,pt, with
- % 1\,pt of stretch and shrink.
- %
- % \item [\grammarindent] is the amount by which the right hand side of a
- % production rule is indented from the left margin. It is a rigid
- % length. Its default value is 2\,em.
- %
- % \end{description}
- %
- % \DescribeMacro\grammarlabel
- % You can also control how the `label' is typeset by redefining the
- % |\grammarlabel| command. The command is given two arguments: the name of
- % the nonterminal (which was enclosed in angle brackets), and the `production
- % operator'. The command is expected to produce the label. By default, it
- % typesets the nonterminal name using |\synt| and the operator at opposite
- % ends of the label, separated by an |\hfill|.
- %
- % \subsection{Syntax diagrams}
- %
- % A full formal BNF grammar can be somewhat overwhelming for less technical
- % readers. Documents aimed at such readers tend to display grammatical
- % structures as \emph{syntax diagrams}.
- %
- % \DescribeEnv{syntdiag}
- % A syntax diagram is always enclosed in a \env{syntdiag} environment. You
- % should think of the environment as enclosing a new sort of \LaTeX\ mode:
- % trying to type normal text into a syntax diagram will result in very ugly
- % output. \LaTeX\ ignores spaces and return characters while in syntax
- % diagram mode.
- %
- % The syntax of the environment is very simple:
- %
- % \begin{grammar}
- % <synt-diag-env> ::= \[[
- % "\\begin{syntdiag}"
- % \begin{stack} \\ "[" <decls> "]" \end{stack}
- % <text>
- % "\\end{syntdiag}"
- % \]]
- % \end{grammar}
- %
- % The \<decls> contain any declarations you want to insert, to control
- % the environment. The parameters to tweak are described below.
- %
- % Within a syntax diagram, you can include syntactic items using the
- % abbreviated forms described elsewhere. The output from these forms is
- % modified slightly in syntax diagram mode so that the diagram looks
- % right.
- %
- % I probably ought to point out now that the syntax diagram typesetting
- % commands produce beautiful-looking diagrams with all the rules and curves
- % accurately positioned. Some device drivers don't position these objects
- % correctly in their output. I've had particular trouble with |dvips|. I'll
- % say it again: it's not my fault!
- %
- % \DescribeEnv{syntdiag*}
- % The \env{syntdiag} environment only works in paragraph mode, and it acts
- % rather like a paragraph, splitting over several lines when appropriate.
- % If you just want to typeset a snippet of a syntax diagram, you can
- % use the starred environment \env{syntdiag$*$}.
- %
- % \begin{grammar}
- % <synt-diag-star-env> ::= \[[
- % "\\begin{syntdiag*}"
- % \begin{stack} \\ "[" <decls> "]" \end{stack}
- % \begin{stack} \\ "[" <width> "]" \end{stack}
- % <text>
- % "\\end{syntdiag*}"
- % \]]
- % \end{grammar}
- %
- % When typesetting little demos like this, it's not normal to fully adorn
- % the syntax diagram with the full double arrows
- % (`\begin{syntdiag*}[\left{>>-}\right{-><}]\tok{$\cdots$}\end{syntdiag*}').
- % The two declarations \syntax{"\\left{"<arrow>"}" and "\\right{"<arrow>"}"}
- % allow you to choose the arrows on each side of the syntax diagram snippet.
- % The possible values of \<arrow> are shown in the table-ette below:
- %
- % ^^A Time to remember what I learned about tables while writing mdwtab.
- % ^^A Just for the embarassment factor, here's the number of attempts I
- % ^^A took to get the table below to look right: __6. Hmm... not as bad
- % ^^A as I expected. Most of them were fine-tuning things.
- %
- % \medskip ^^A Leave a vertical gap
- % \hbox to\columnwidth{\hfil\vbox{\tabskip=0pt ^^A Centre it horizontally
- % \sdsize \csname sd@setsize\endcsname ^^A Position syntdiag arrows
- % \halign to .5\columnwidth{ ^^A Set the table width
- % &\ttfamily\ignorespaces#\unskip\hfil\tabskip=0pt ^^A Typeset the name
- % &\quad\csname sd@arr@#\endcsname\hfil ^^A Typeset the arrow
- % &\setbox0=\hbox{#}\tabskip=0pt plus 1fil\cr ^^A Stretch between columns
- % >>-&>>-& &>-&>-& &->&->\cr
- % -><&-><& &...&...& &-&-\cr
- % }}\hfil} ^^A Close the boxing
- % \medskip ^^A And leave another gap
- %
- % These declarations should be used only in the optional argument to the
- % \env{syntdiag$*$} command. The second optional argument to the
- % environment, if specified, fixes the width of the syntax diagram snippet;
- % if you omit this argument, the diagram is made just wide enough to
- % fit everything in.
- %
- % \begin{figure}
- % \begin{demo}[w]{Example of \env{syntdiag$*$}}
- %\newcommand{\bs}[2]{%
- % \begin{minipage}{1.6in}%
- % \begin{syntdiag*}[\left{#1}\right{#2}][1.6in]%
- %}
- %\newcommand{\es}{\end{syntdiag*}\end{minipage}}
- %
- %\begin{center}
- %\begin{tabular}{cl} \\ \hline
- %\bf Construction & \bf Meaning \\ \hline
- %\bs {>>-} {...} \es & Start of syntax diagram \\
- %\bs {...} {-><} \es & End of syntax diagram \\
- %\bs {>-} {...} \es & Continued on next line \\
- %\bs {...} {->} \es & Continued from previous line \\ \hline
- %\bs {...} {...}
- % \begin{stack} <option-a> \\ <option-b> \\ <option-c> \end{stack}
- %\es & Alternatives: choose any one \\
- %\bs {...} {...}
- % \begin{rep} <repeat-me> \\ <separator> \end{rep}
- %\es & One or more items, with separators \\ \hline
- %\end{tabular}
- %\end{center}
- % \end{demo}
- % \end{figure}
- %
- % \DescribeMacro\tok
- % You can also include text using the |\tok| command. The argument of this
- % command is typeset in \LaTeX's LR~mode and inserted into the diagram.
- % Syntax abbreviations are allowed within the argument, so you can, for
- % example, include textual descriptions like
- % \begin{listing}
- %\tok{any <char> except `"'}
- % \end{listing}
- %
- % \DescribeEnv{stack}
- % Within a syntax diagram, a choice between several different items is
- % shown by stacking the alternatives vertically. In \LaTeX, this is done
- % by enclosing the items in a \env{stack} environment. Each individual item
- % is separated by |\\| commands, as in the \env{array} and \env{tabular}
- % environments. Each row may contain any syntax diagram material, including
- % |\tok| commands and other \env{stack} environments.
- %
- % Note if you end a \env{stack} environment with a |\\| command, a blank
- % row is added to the bottom of the stack, indicating that none of the items
- % need be specified.
- %
- % The commands |\(| and |\)| are abbreviations for `|\begin{stack}|' and
- % `|\end{stack}|' respectively. Also, |\[| is `|\begin{stack}\\|' and
- % |\]| is `|\end{stack}|' -- these two are useful for stacks in which the
- % first item is blank (i.e., none of the options need be taken).
- %
- % \DescribeEnv{rep}
- % Text which can be repeated is enclosed in a \env{rep} environment: the
- % text is displayed with a backwards pointing arrow drawn over it, showing
- % that it may be repeated. Optionally, you can specify text to be
- % displayed in the arrow, separating it from the main text with a |\\|
- % command.
- %
- % Note that items on the backwards arrow of a \env{rep} construction should
- % be displayed \emph{backwards}. You must put the individual items in
- % reverse order when building this part of your diagrams. \syn\ will
- % correctly reverse the arrows on \env{rep} structures, but apart from
- % this, you must cope on your own. You are recommended to keep these parts
- % of your diagrams as simple as possible to avoid confusing readers.
- %
- % The commands |\<| and |\>| are abbreviations for `|\begin{rep}|' and
- % `|\end{rep}|' respectively.
- %
- % \begin{demo}[w]{A syntax diagram}
- %\begin{syntdiag}
- %<ident> `('
- % \begin{rep} \begin{stack} \\
- % <type> \begin{stack} \\ <ident> \end{stack}
- % \end{stack} \\ `,' \end{rep}
- %\begin{stack} \\ `...' \end{stack} `)'
- %\end{syntdiag}
- % \end{demo}
- %
- % \subsubsection{Line breaking in syntax diagrams}
- %
- % Syntax diagrams are automatically broken over lines and across pages.
- % Lines are only broken between items on the outermost level of the diagram:
- % i.e., not within \env{stack} or \env{rep} environments.
- %
- % You can force a line break at a particular place by using the |\\| command
- % as usual. This supports all the usual \LaTeX\ features: a `|*|' variant
- % which prohibits page breaking, and an optional argument specifying the
- % extra vertical space between lines.
- %
- % \subsubsection{Customising syntax diagrams}
- %
- % There are two basic styles of syntax diagrams supported:
- %
- % \begin{description}
- %
- % \item [square] Lines in the syntax diagram join at squared-off corners.
- % This appears to be the standard way of displaying syntax diagrams
- % in IBM manuals, and most other documents I've seen.
- %
- % \item [rounded] Lines curve around corners. Also, no arrows are drawn
- % around repeating loops: the curving of the lines provides this
- % information instead. This style is used in various texts on
- % Pascal, and appears to be more popular in academic circles.
- %
- % \end{description}
- %
- % You can specify the style you want to use for syntax diagrams by giving
- % the style name as an option on the |\usepackage| command. For example,
- % to force rounded edges to be used, you could say
- %
- % \begin{listing}
- %\usepackage[rounded]{syntax}
- % \end{listing}
- %
- % \DescribeMacro\sdsize
- % \DescribeMacro\sdlengths
- % The \env{syntdiag} environment takes an option argument, which should
- % contain declarations which are obeyed while the environment is set up.
- % The default value of this argument is `|\sdsize\sdlengths|'. The
- % |\sdsize| command sets the default type size for the environment: this is
- % normally |\small|. |\sdlengths| sets the values of the length parameters
- % used by the environment based on the current text size. These parameters
- % are described below.
- %
- % For example, if you wanted to reduce the type size of the diagrams still
- % further, you could use the command
- % \begin{listing}
- %\begin{syntdiag}[\tiny\sdlengths]
- % \end{listing}
- %
- % The following length parameters may be altered:
- %
- % \begin{description} \def\makelabel{\hskip\labelsep\cmd}
- %
- % \item [\sdstartspace] The length of the rule between the arrows which
- % begin each line of the syntax diagram and the first item on the line.
- % Note that most objects have some space on either side of them as
- % well. This is a rubber length. Its default value is 1\,em, although
- % it can shrink by up to 10\,pt.
- %
- % \item [\sdendspace] The length of the rule between the last item on a
- % line and the arrow at the very end. Note that the final line also
- % has extra rubber space on the end. This is a rubber length. Its
- % default value is 1\,em, although it will shrink by up to 10\,pt.
- %
- % \item [\sdmidskip] The length of the rule on either side of a large
- % construction (either a \env{stack} or a \env{rep}). It is a rubber
- % length. Its default value is \smallf 1/2\,em, with a very small
- % amount of infinite stretch.
- %
- % \item [\sdtokskip] The length of the rule on either side of a |\tok|
- % item or syntax abbreviation. It is a rubber length. Its default
- % value is \smallf 1/4\,em, with a very small amount of inifnite
- % stretch.
- %
- % \item [\sdfinalskip] The length of the rule which finishes the last line
- % of a syntax diagram. It is a rubber length. Its default value is
- % \smallf 1/2\,em, with 10000\,fil of stretch, which will left-align
- % the items on the line.\footnote{^^A
- % This is a little \TeX nical. The idea is that if a stray 1\,fil
- % of stretch is added to the end of the line, it won't be noticed.
- % However, the alignment of the text on the line can still be
- % modified using \cmd{\sd@rule}\cmd{\hfill}, if you're feeling
- % brave.
- % }
- %
- % \item [\sdrulewidth] Half the width of the rules used in the diagram.
- % It is a rigid length. Its default value is 0.2\,pt.
- %
- % \item [\sdcirclediam] The diameter of the circle from which the quadrants
- % used in rounded-style diagrams are taken. This must be a multiple
- % of 4\,pt, or else the lines on the diagram won't match up.
- %
- % \end{description}
- %
- % In addition, you should call |\sdsetstrut| passing it the total height
- % (\({\rm height}+{\rm depth}\)) of a normal line of text at the current
- % size. Normally, the value of |\baselineskip| will be appropriate.
- %
- % You can also alter the appearance of \env{stack}s and \env{rep}s by using
- % their optional positioning arguments. By default, \env{stack}s descend
- % below the main line of the diagram, and \env{rep}s extend above it.
- % Specifying an optional argument of |[b]| for either environment reverses
- % this, putting \env{stack}s above and \env{rep}s below the line.
- %
- % \subsection{Changing the presentation styles}
- %
- % You can change the way in which the syntax items are typeset by altering
- % some simple commands (using |\renewcommand|). Each item (nonterminals,
- % as typeset by |\synt|, and quoted and unquoted terminals, as typeset by
- % |\lit| and |\lit*|) has two style commands associated with it, as shown
- % in the table below.
- %
- % \begin{tab}{lll} \hline
- % \bf Syntax item & \bf Left command & \bf Right command \\ \hline
- % Nonterminals & |\syntleft| & |\syntright| \\
- % Quoted terminals & |\litleft| & |\litright| \\
- % Unquoted terminals & |\ulitleft| & |\ulitright| \\ \hline
- % \end{tab}
- %
- % It's not too hard to see how this works. For example, if you look at
- % the implementation for |\syntleft| and |\syntright| in the implementation
- % section, you'll notice that they're defined like this:
- % \begin{listing}
- %\newcommand{\syntleft}{$\langle$\normalfont\itshape}
- %\newcommand{\syntright}{$\rangle$}
- % \end{listing}
- % I think this is fairly simple, if you understand things like font changing.
- %
- % Note that changing these style commands alters the appearance of all syntax
- % objects of the appropriate types, as created by the |\synt| and |\lit|
- % commands, in \env{grammar} environments, and in syntax diagrams.
- %
- %
- % \section{Change history}
- %
- % \subsection*{Version 1.9}
- %
- % Added abbreviations for syntax diagram constructions. These clobber some
- % common abbreviations for maths, but that's not too worrying really; it's
- % not likely for people to do maths in syntax diagrams.
- %
- % \subsection*{Version 1.8}
- %
- % Added to RCS (so changed version numbering style).
- %
- % \subsection*{Version 1.07}
- %
- % \begin{itemize}
- % \item Fixed problem with underscore hacking in a \env{tabbing} environment.
- % \end{itemize}
- %
- % \subsection*{Version 1.06}
- %
- % \begin{itemize}
- % \item Added style hooks for syntax items.
- % \item Improved colour handling in syntax diagrams, thanks to the |\doafter|
- % package.
- % \item Fixed some nasty bugs in the \env{grammar} environment which confused
- % other lists and ruined the spacing. The \env{grammar} handling is
- % now much tidier in general.
- % \end{itemize}
- %
- % \subsection*{Version 1.05}
- %
- % \begin{itemize}
- % \item Fixed `the bug' in the syntax diagram typesetting. It now breaks
- % lines almost psychically, and doesn't break in the wrong places.
- % \item Almost rewrote the \env{grammar} environment. It now does lots of
- % the list handling itself, to allow more versatile typesetting of the
- % left hand sides. There's lots of evil in there now.
- % \item Added some more configurability. In particular, two new settings
- % have been added to control \env{grammar} environments, and a neat
- % way of adding new syntax diagram structures has been introduced.
- % \end{itemize}
- %
- % \subsection*{Version 1.04}
- %
- % \begin{itemize}
- % \item Changed the vertical positioning of the rules, to make all the text
- % line up properly. While the old version was elegant and simple, it
- % had the drawback of looking nasty.
- % \item Allow line breaks at underscores, but don't if there's another one
- % afterwards. Also, prevent losing following space if underscore is
- % written to a file.
- % \end{itemize}
- %
- % \subsection*{Version 1.02}
- %
- % \begin{itemize}
- % \item Added support for rounded corners in syntax diagrams.
- % \item Changed lots of |\hskip| commands to |\kern|s, to prevent possible
- % line breaks.
- % \end{itemize}
- %
- % \subsection*{Version 1.01}
- %
- % \begin{itemize}
- % \item Allowed disabling of underscore active character, to avoid messing
- % up filenames.
- % \item Added |\grammarparsep| and |\grammarindent| length parameters to
- % control the appearance of grammars.
- % \end{itemize}
- %
- % \implementation
- %
- % \section{Implementation of \syn}
- %
- % \begin{macrocode}
- %<*package>
- % \end{macrocode}
- %
- % \subsection{Options handling}
- %
- % We define all the options we know about, and then see what's been put
- % on the usepackage line.
- %
- % The options we provide currently are as follows:
- %
- % \begin{description}
- % \item [rounded] draws neatly rounded edges on the diagram.
- % \item [square] draws squared-off edges on the diagram. This is the
- % default.
- % \item [nounderscore] disables the undescore active character, The |\_|
- % command still produces the nice version created here.
- % \end{description}
- %
- % \begin{macrocode}
- \DeclareOption{rounded}{\sd@roundtrue}
- \DeclareOption{square}{\sd@roundfalse}
- \DeclareOption{nounderscore}{\@uscorefalse}
- % \end{macrocode}
- %
- % Now process the options:
- %
- % \begin{macrocode}
- \newif\ifsd@round
- \newif\if@uscore\@uscoretrue
- \ExecuteOptions{square}
- \ProcessOptions
- % \end{macrocode}
- %
- % \subsection{Special character handling}
- %
- % A lot of the \syn\ package requires the use special active characters.
- % These must be added to two lists: |\dospecials|, which is used by |\verb|
- % and friends, and |\@sanitize|, which is used by |\index|. The two macros
- % here, |\addspecial| and |\remspecial|, provide these registration
- % facilities.
- %
- % Two similar macros are found in Frank Mittelbach's \package{doc} package:
- % these have the disadvantage of global operation. My macros here are based
- % on Frank's, which in turn appear to be based on Donald Knuth's list
- % handling code presented in Appendix~D of \textit{The \TeX book}.
- %
- % Both these macros take a single argument: a single-character control
- % sequence containing the special character to be added to or removed from
- % the lists.
- %
- % \begin{macro}{\addspecial}
- %
- % This is reasonably straightforward. We remove the sequence from the lists,
- % in case it's already there, and add it in in the obvious way. This
- % requires a little bit of fun with |\expandafter|.
- %
- % \begin{macrocode}
- \def\addspecial#1{%
- \remspecial{#1}%
- \expandafter\def\expandafter\dospecials\expandafter{\dospecials\do#1}%
- \expandafter\def\expandafter\@santize\expandafter{%
- \@sanitize\@makeother#1}%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\remspecial}
- %
- % This is the difficult bit. Since |\dospecials| and |\@sanitize| have the
- % form of list macros, we can redefine |\do| and |\@makeother| to do the
- % job for us. We must be careful to put the old meaning of |\@makeother|
- % back. The current implementation assumes it knows what |\@makeother| does.
- %
- % \begin{macrocode}
- \def\remspecial#1{%
- \def\do##1{\ifnum`#1=`##1 \else\noexpand\do\noexpand##1\fi}%
- \edef\dospecials{\dospecials}%
- \def\@makeother##1{\ifnum`#1=`##1 \else%
- \noexpand\@makeother\noexpand##1\fi}%
- \edef\@sanitize{\@sanitize}%
- \def\@makeother##1{\catcode`##112}%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsection{Underscore handling}
- %
- % When typing a lot of identifiers, it can be irksome to have to escape
- % all `|_|' characters in the manuscript. We make the underscore character
- % active, so that it typesets an underscore in horizontal mode, and does
- % its usual job as a subscript operator in maths mode. Underscore must
- % already be in the special character lists, because of its use as a
- % subscript character, so this doesn't cause us a problem.
- %
- % \begin{macro}{\underscore}
- %
- % The |\underscore| macro typesets an underline character, using a horizontal
- % rule. This is positioned slightly below the baseline, and is also slightly
- % wider than the default \TeX\ underscore. This code is based on a similar
- % implementation found in the \package{lgrind} package.
- %
- % \begin{macrocode}
- \def\underscore{%
- \leavevmode%
- \kern.06em%
- \vbox{%
- \hrule\@width.6em\@depth.4ex\@height-.34ex%
- }%
- \ifdim\fontdimen\@ne\font=\z@%
- \kern.06em%
- \fi%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\@foundunderscore}
- %
- % This macro is called by the `|_|' active character to sort out what to do.
- %
- % If this is maths mode, we use the |\sb| macro, which is already defined
- % to do subscripting. Otherwise, we call |\textunderscore|, which picks the
- % nicest underscore it can find.
- %
- % There's some extra cunningness here, because I'd like to be able to
- % hyphenate after underscores usually, but not when there's another one
- % following. And then, because \env{tabbing} redefines |\_|, there's some
- % more yukkiness to handle that: the usual |\@tabacckludge| mechanism doesn't
- % cope with this particular case.
- %
- % \begin{macrocode}
- \let\usc@builtindischyphen\-
- \def\@uscore.{%
- \ifmmode%
- \expandafter\@firstoftwo%
- \else%
- \expandafter\@secondoftwo%
- \fi%
- \sb%
- {\textunderscore\@ifnextchar_{}{\usc@builtindischyphen}}%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % Now we set up the active character. Note the |\protect|, which makes
- % underscores work reasonably well in moving arguments. Note also the way
- % we end with a some funny stuff to prevent spaces being lost if this is
- % written to a file.
- %
- % \begin{macrocode}
- \if@uscore
- \AtBeginDocument{%
- \catcode`\_\active%
- \begingroup%
- \lccode`\~`\_%
- \lowercase{\endgroup\def~{\protect\@uscore.}}%
- }
- \fi
- % \end{macrocode}
- %
- % Finally, we redefine the |\_| macro to use our own |\underscore|, because
- % it's prettier. Actually, we don't: we just redefine the
- % |\?\textunderscore| command (funny name, isn't it?).
- %
- % \begin{macrocode}
- \expandafter\let\csname?\string\textunderscore\endcsname\underscore
- % \end{macrocode}
- %
- % \subsection{Abbreviated verbatim notation}
- %
- % In similar style to the \package{doc} package, we allow the user to set up
- % characters which delimit verbatim text. Unlike \package{doc}, we make
- % such changes local to the current group. This is performed through the
- % |\shortverb| and |\unverb| commands.
- %
- % The implementations of these commands are based upon the |\MakeShortVerb|
- % and |\DeleteShortVerb| commands of the \package{doc} package, although
- % these versions have effect local to the current grouping level. This
- % prevents their redefinition of |\dospecials| from interfering with the
- % grammar shortcuts, which require local changes only.
- %
- % The command |\shortverb| takes a single argument: a single-character
- % control sequence defining which character to make into the verbatim text
- % delimiter. We store the old meaning of the active character in a control
- % sequence called |\mn@\|\<char>. Note that this control sequence
- % contains a backslash character, which is a little odd. We also define a
- % command |\cc@\|\<char> which will return everything to normal. This
- % is used by the |\unverb| command.
- %
- % \begin{macro}{\shortverb}
- %
- % Here we build the control sequences we need to make everything work nicely.
- % The active character is defined via |\lowercase|, using the |~| character:
- % this is already made active by \TeX\@.
- %
- % The actual code requires lots of fiddling with |\expandafter| and friends.
- %
- % \begin{macrocode}
- \def\shortverb#1{%
- % \end{macrocode}
- %
- % First, we check to see if the command |\cc@\|\<char> has been defined.
- %
- % \begin{macrocode}
- \@ifundefined{cc@\string#1}{%
- % \end{macrocode}
- %
- % If it hasn't been defined, we add the character to the specials list.
- %
- % \begin{macrocode}
- \addspecial#1%
- % \end{macrocode}
- %
- % Now we set our character to be the lowercase version of |~|, which allows
- % us to use it, even though we don't know what it is.
- %
- % \begin{macrocode}
- \begingroup%
- \lccode`\~`#1%
- % \end{macrocode}
- %
- % Finally, we reach the tricky bit. All of this is lowercased, so any
- % occurrences of |~| are replaced by the user's special character.
- %
- % \begin{macrocode}
- \lowercase{%
- \endgroup%
- % \end{macrocode}
- %
- % We remember the current meaning of the character, in case it has one. We
- % have to use |\csname| to build the rather strange name we use for this.
- %
- % \begin{macrocode}
- \expandafter\let\csname mn@\string#1\endcsname~%
- % \end{macrocode}
- %
- % Now we build |\cc@\|\<char>. This is done with |\edef|, since more
- % of this needs to be expanded now than not. In this way, the actual macros
- % we create end up being very short.
- %
- % \begin{macrocode}
- \expandafter\edef\csname cc@\string#1\endcsname{%
- % \end{macrocode}
- %
- % First, add a command to restore the character's old catcode.
- %
- % \begin{macrocode}
- \catcode`\noexpand#1\the\catcode`#1%
- % \end{macrocode}
- %
- % Now we restore the character's old meaning, using the version we saved
- % earlier.
- %
- % \begin{macrocode}
- \let\noexpand~\expandafter\noexpand%
- \csname mn@\string#1\endcsname%
- % \end{macrocode}
- %
- % Now we remove the character from the specials lists.
- %
- % \begin{macrocode}
- \noexpand\remspecial\noexpand#1%
- % \end{macrocode}
- %
- % Finally, we delete this macro, so that |\unverb| will generate a warning
- % if the character is |\unverb|ed again.
- %
- % \begin{macrocode}
- \let\csname cc@\string#1\endcsname\relax%
- }%
- % \end{macrocode}
- %
- % All of that's over now. We set up the new definition of the character,
- % in terms of |\verb|, and make the character active. The nasty |\syn@ttspace|
- % is there to make the spacing come out right. It's all right really. Honest.
- %
- % \begin{macrocode}
- \def~{\verb~\syn@ttspace}%
- }%
- \catcode`#1\active%
- % \end{macrocode}
- %
- % If our magic control sequence already existed, we can assume that the
- % character is already a verbatim delimiter, and raise a warning.
- %
- % \begin{macrocode}
- }{%
- \PackageWarning{syntax}{Character `\expandafter\@gobble\string#1'
- is already a verbatim\MessageBreak
- delimiter}%
- }%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\unverb}
- %
- % This is actually terribly easy: we just use the |\cc@\|\<char> command
- % we definied earlier, after making sure that it's been defined.
- %
- % \begin{macrocode}
- \def\unverb#1{%
- \@ifundefined{cc@\string#1}{%
- \PackageWarning{syntax}{Character `\expandafter\@gobble\string#1'
- is not a verbatim\MessageBreak
- delimiter}%
- }{%
- \csname cc@\string#1\endcsname%
- }%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsection{Style hooks for syntax forms}
- %
- % To allow the appearance of syntax things to be configured, we provide some
- % redefinable bits.
- %
- % The three types of objects (nonterminal symbols, and quoted and unquoted
- % terminals) each have two macros associated with them: one which does the
- % `left' bit of the typesetting, and one which does the `right' bit. The
- % items are typeset as LR~boxes. I'll be extra good while defining these
- % hooks, so that it's obvious what's going on; macho \TeX\ hacker things
- % resume after this section.
- %
- % \begin{macro}{\syntleft}
- % \begin{macro}{\syntright}
- %
- % I can't see why anyone would want to change the typesetting of
- % nonterminals, although I'll provide the hooks for symmetry's sake.
- %
- % \begin{macrocode}
- \newcommand{\syntleft}{$\langle$\normalfont\itshape}
- \newcommand{\syntright}{$\rangle$}
- % \end{macrocode}
- %
- % \end{macro}
- % \end{macro}
- %
- % \begin{macro}{\ulitleft}
- % \begin{macro}{\ulitright}
- % \begin{macro}{\litleft}
- % \begin{macro}{\litright}
- %
- % Now we can define the left and right parts of quoted and unquoted
- % terminals. US~readers may want to put double quotes around the quoted
- % terminals, for example.
- %
- % \begin{macrocode}
- \newcommand{\ulitleft}{\normalfont\ttfamily\syn@ttspace\frenchspacing}
- \newcommand{\ulitright}{}
- \newcommand{\litleft}{`\bgroup\ulitleft}
- \newcommand{\litright}{\ulitright\egroup'}
- % \end{macrocode}
- %
- % \end{macro}
- % \end{macro}
- % \end{macro}
- % \end{macro}
- %
- % \subsection{Simple syntax typesetting}
- %
- % In general text, we allow access to our typesetting conventions through
- % standard \LaTeX\ commands.
- %
- % \begin{macro}{\synt}
- %
- % The |\synt| macro typesets its argument as a syntactic quantity. It puts
- % the text of the argument in italics, and sets angle brackets around it.
- % Breaking of a |\synt| object across lines is forbidden.
- %
- % \begin{macrocode}
- \def\synt#1{\mbox{\syntleft{#1\/}\syntright}}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\lit}
- %
- % The |\lit| macro typesets its argument as literal text, to be typed in.
- % Normally, this means setting the text in |\tt| font, and putting quotes
- % around it, although the quotes can be suppressed by using the $*$-variant.
- %
- % The |\syn@ttspace| macro sets up the spacing for the text nicely: |\tt|
- % spaces tend to be a little wide.
- %
- % \begin{macrocode}
- \def\lit{\@ifstar{\lit@i\ulitleft\ulitright}{\lit@i\litleft\litright}}
- \def\lit@i#1#2#3{\mbox{#1{#3\/}#2}}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\syn@ttspace}
- %
- % This sets up the |\spaceskip| value for |\tt| text.
- %
- % \begin{macrocode}
- \def\syn@ttspace@{\spaceskip.35em\@plus.2em\@minus.15em\relax}
- % \end{macrocode}
- %
- % However, this isn't always the right thing to do.
- %
- % \begin{macrocode}
- \def\ttthinspace{\let\syn@ttspace\syn@ttspace@}
- \def\ttthickspace{\let\syn@ttspace\@empty}
- % \end{macrocode}
- %
- % I know what I like thoough.
- %
- % \begin{macrocode}
- \ttthinspace
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{The shortcuts}
- %
- % The easy part is over now. The next job is to set up the `grammar
- % shortcuts' which allow easy changing of styles.
- %
- % We support four shortcuts:
- % \begin{itemize}
- % \item |`literal text'| typesets \syntax{`literal text'}
- % \item |<non-terminal>| typesets \syntax{<non-terminal>}
- % \item |"unquoted text"| typesets \syntax{"unquoted text"}
- % \item \verb"|" typesets a \syntax{|} character
- % \end{itemize}
- % These are all implemented through active characters, which are enabled
- % using the |\syntaxShortcuts| macro, described below.
- %
- % \begin{macro}{\readupto}
- %
- % \syntax{"\\readupto{"<char>"}{"<decls>"}{"<command>"}"} will read all
- % characters up until the next occurrence of \<char>. Normally, all
- % special characters will be deactivated. However, you can reactivate some
- % characters, using the \<decls> argument, which is processed before the
- % text is read.
- %
- % The code is borrowed fairly obviously from the \LaTeXe\ source for the
- % |\verb| command.
- %
- % \begin{macrocode}
- \def\readupto#1#2#3{%
- \bgroup%
- \verb@eol@error%
- \let\do\@makeother\dospecials%
- #2%
- \catcode`#1\active%
- \lccode`\~`#1%
- \gdef\verb@balance@group{\verb@egroup%
- \@latex@error{\noexpand\verb illegal in command argument}\@ehc}%
- \def\@vhook{\verb@egroup#3}%
- \aftergroup\verb@balance@group%
- \lowercase{\let~\@vhook}%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\syn@assist}
- %
- % The |\syn@assist| macro is used for defining three of the shortcuts. It
- % is called as
- %
- % \begin{quote}
- % \syntax{"\\syn@assist{"<left-decls>"}{"<actives>"}{"<delimeter>"}" \\
- % \null \quad "{"<right-decls>"}{"<end-cmd>"}"}
- % \end{quote}
- %
- % It creates an hbox, sets up the escape sequences for quoting our magic
- % characters, and then typesets a box containing
- %
- % \begin{quote}
- % \syntax{<left-decls>"{"<delimited-text>"\\/}"<right-decls>}
- % \end{quote}
- %
- % The \<left-decls> and \<right-decls> can be |\relax| if they're not
- % required.
- %
- % The \<actives> argument is passed to |\readupto|, to allow some special
- % characters through. By default, we re-enable |\|, and make `\verb*" "'
- % typeset some space glue, rather than a space character. A macro
- % `\verb*"\ "' is defined to actually print a space character, which yield
- % `\verb*" "' in the `|\tt|' font.
- %
- % Finally, it defines a |\ch| command, which, given a single-character
- % control sequence as its argument, typesets the character. This is useful,
- % since |`| has been made active when we set up these calls, so the
- % direct |\char`\|\<char> doesn't work.
- %
- % \begin{macrocode}
- \def\syn@assist#1#2#3#4#5{%
- % \end{macrocode}
- %
- % First, we start the box, and open a group. We use |\mbox| because it
- % does all the messing with |\leavevmode| which is needed.
- %
- % \begin{macrocode}
- \mbox\bgroup%
- % \end{macrocode}
- %
- % Next job is to set up the escape sequences.
- %
- % \begin{macrocode}
- \chardef\\`\\%
- \chardef\>`\>%
- \chardef\'`\'%
- \chardef\"`\"%
- \chardef\ `\ %
- % \end{macrocode}
- %
- % Now to define |\ch|. This is done the obvious way.
- %
- % \begin{macrocode}
- \def\ch##1{\char`##1}%
- % \end{macrocode}
- %
- % For active characters, we do some fiddling with |\lccode|s.
- %
- % \begin{macrocode}
- \def\act##1{%
- \catcode`##1\active%
- \begingroup%
- \lccode`\~`##1%
- \lowercase{\endgroup\def~}%
- }%
- % \end{macrocode}
- %
- % Finally, we do the real work of setting the text. We use |\readupto| to
- % actually find the text we want.
- %
- % \begin{macrocode}
- #1%
- \begingroup%
- \readupto#3{%
- \catcode`\\0%
- \catcode`\ 10%
- #2%
- }{%
- \/\endgroup#4\egroup#5%
- }%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\syn@shorts}
- %
- % This macro actually defines the expansions for the active characters.
- % We have to do this separately because |`| must be active when we use it
- % in the |\def|, but we can't do that and use |\catcode| at the same time.
- % The arguments are commands to do before and after the actual command.
- % These are passed up from |\syntaxShortcuts|.
- %
- % All of the characters use |\syn@assist| in the obvious way except for
- % \verb"|", which drops into maths mode instead.
- %
- % Note that when changing the catcodes, we must save |`| until last.
- %
- % \begin{macrocode}
- \begingroup
- \catcode`\<\active
- \catcode`\|\active
- \catcode`\"\active
- \catcode`\`\active
- %
- \gdef\syn@shorts#1#2{%
- % \end{macrocode}
- %
- % The `|<|' character must typeset its argument in italics. We make `|_|'
- % do the same as the `|\_|' command.
- %
- % \begin{macrocode}
- \def<{%
- #1%
- \syn@assist%
- \syntleft%
- {\act_{\@foundunderscore}}%
- >%
- \syntright%
- {#2}%
- }%
- % \end{macrocode}
- %
- % The `|`|' and `|"|' characters should print its argument in |\tt| font.
- % We change the `|\tt|' space glue to provide nicer spacing on the line.
- %
- % \begin{macrocode}
- \def`{%
- #1%
- \syn@assist%
- \litleft%
- \relax%
- '%
- \litright%
- {#2}%
- }%
- \def"{%
- #1%
- \syn@assist%
- \ulitleft%
- \relax%
- "%
- \ulitright%
- {#2}%
- }%
- % \end{macrocode}
- %
- % Finally, the `\verb"|"' character is typeset by using the mysterious
- % |\textbar| command.
- %
- % \begin{macrocode}
- \def|{\textbar}%
- % \end{macrocode}
- %
- % We're finished here now.
- %
- % \begin{macrocode}
- }
- %
- \endgroup
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\syntaxShortcuts}
- %
- % This is a user-level command which enables the use of our shortcuts in the
- % current group. It uses |\addspecial|, defined below, to register the
- % active characters, sets up their definitions and activates them.
- %
- % The two arguments are commands to be performed before and after the
- % handling of the abbreviation. In this way, you can further process the
- % output.
- %
- % This command is not intended to be used directly by users: it should be
- % used by other macros and packages which wish to take advantage of the
- % facilities offered by this package. We provide a |\synshorts| declaration
- % (which may be used as an environment, of course) which is more `user
- % palatable'.
- %
- % \begin{macrocode}
- \def\syntaxShortcuts#1#2{%
- \syn@shorts{#1}{#2}%
- \addspecial\`%
- \addspecial\<%
- \addspecial\|%
- \addspecial\"%
- \catcode`\|\active%
- \catcode`\<\active%
- \catcode`\"\active%
- \catcode`\`\active%
- }
- %
- \def\synshorts{\syntaxShortcuts\relax\relax}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\synshortsoff}
- %
- % This macro can be useful occasionally: it disables the syntax shortcuts,
- % so you can type normal text for a while.
- %
- % \begin{macrocode}
- \def\synshortsoff{%
- \catcode`\|12%
- \catcode`\<12%
- \catcode`\"12%
- \catcode`\`12%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\syntax}
- %
- % The |\syntax| macro typesets its argument, allowing the use of our
- % shortcuts within the argument.
- %
- % Actually, we go to some trouble to ensure that the argument to |\syntax|
- % \emph{isn't} a real argument so we can change catcodes as we go. We
- % use the |\let\@let@token=| trick from \PlainTeX\ to do this.
- %
- % \begin{macrocode}
- \def\syntax#{\bgroup\syntaxShortcuts\relax\relax\let\@let@token}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{environment}{grammar}
- %
- % The \env{grammar} environment is the final object we have to define. It
- % allows typesetting of beautiful BNF grammars.
- %
- % First, we define the length parameters we need:
- %
- % \begin{macrocode}
- \newskip\grammarparsep
- \grammarparsep8\p@\@plus\p@\@minus\p@
- \newdimen\grammarindent
- \grammarindent2em
- % \end{macrocode}
- %
- % Now define the default label typesetting. This macro is designed to be
- % replaced by a user, so we'll be extra-well-behaved and use genuine \LaTeX\
- % commands. Well, almost \dots
- %
- % \begin{macrocode}
- \newcommand{\grammarlabel}[2]{%
- \synt{#1} \hfill#2%
- }
- % \end{macrocode}
- %
- % Now for a bit of hacking to make the item stuff work properly. This gets
- % done for every new paragraph that's started without an |\item| command.
- %
- % First, store the left hand side of the production in a box. Then I'll
- % end the paragraph, and insert some nasty glue to take up all the space,
- % so no-one will ever notice that there was a paragraph break there. The
- % strut just makes sure that I know exactly how high the line is.
- %
- % \begin{macrocode}
- \def\gr@implitem<#1> #2 {%
- \sbox\z@{\hskip\labelsep\grammarlabel{#1}{#2}}%
- \strut\@@par%
- \vskip-\parskip%
- \vskip-\baselineskip%
- % \end{macrocode}
- %
- % The |\item| command will notice that I've inserted these funny glues and
- % try to remove them: I'll stymie its efforts by inserting an invisible
- % rule. Then I'll insert the label using |\item| in the normal way.
- %
- % \begin{macrocode}
- \hrule\@height\z@\@depth\z@\relax%
- \item[\unhbox\z@]%
- % \end{macrocode}
- %
- % Just before I go, I'll make \lit{<} back into an active character.
- %
- % \begin{macrocode}
- \catcode`\<\active%
- }
- % \end{macrocode}
- %
- % As an abbreviation for syntax diagrams, I usurp the |\[| and |\]| commands.
- % Here are the old versions.
- %
- % \begin{macrocode}
- \let\gr@leftsq\[
- \let\gr@rightsq\]
- \def\[{\gr@leftsq}
- \def\]{\gr@rightsq}
- % \end{macrocode}
- %
- % Now for the environment proper. Deep down, it's a list environment, with
- % some nasty tricks to stop anyone from noticing.
- %
- % The first job is to set up the list from the parameters I'm given.
- %
- % \begin{macrocode}
- \newenvironment{grammar}{%
- \list{}{%
- \labelwidth\grammarindent%
- \leftmargin\grammarindent%
- \advance\grammarindent\labelsep
- \itemindent\z@%
- \listparindent\z@%
- \parsep\grammarparsep%
- }%
- % \end{macrocode}
- %
- % We have major problems in |\raggedright| layouts, which try to use |\par|
- % to start new lines. We go back to normal |\\| newlines to try and bodge
- % our way around these problems.
- %
- % \begin{macrocode}
- \let\\\@normalcr
- % \end{macrocode}
- %
- % Now to enable the shortcuts.
- %
- % \begin{macrocode}
- \syntaxShortcuts\relax\relax%
- % \end{macrocode}
- %
- % Now a little bit of magic. The |\alt| macro moves us to a new line, and
- % typesets a vertical bar in the margin. This allows typesetting of
- % multiline alternative productions in a pretty way.
- %
- % \begin{macrocode}
- \def\alt{\\\llap{\textbar\quad}}%
- % \end{macrocode}
- %
- % Now for another bit of magic. We set up some |\par| cleverness to spot
- % the start of each production rule and format it in some cunning and
- % user-defined way.
- %
- % \begin{macrocode}
- \def\gr@setpar{%
- \def\par{%
- \parshape\@ne\@totalleftmargin\linewidth%
- \@@par%
- \catcode`\<12%
- \everypar{%
- \everypar{}%
- \catcode`\<\active%
- \gr@implitem%
- }%
- }%
- }%
- \gr@setpar%
- \par%
- % \end{macrocode}
- %
- % Now set up the |\[[| and |\]]| commands to do the right thing. We have
- % to check the next character to see if it's correct, otherwise we'll
- % open a maths display as usual.
- %
- % \begin{macrocode}
- \def\gr@endsyntdiag]{\end{syntdiag}\gr@setpar\par}%
- \def\[{\@ifnextchar[{\begin{syntdiag}\@gobble}\gr@leftsq}%
- \def\]{\@ifnextchar]\gr@endsyntdiag\gr@rightsq}%
- % \end{macrocode}
- %
- % Well, that's it for this side of the environment.
- %
- % \begin{macrocode}
- }{%
- % \end{macrocode}
- %
- % Closing the environment is a simple matter of tidying away the list.
- %
- % \begin{macrocode}
- \@newlistfalse%
- \everypar{}%
- \endlist%
- }
- % \end{macrocode}
- %
- % \end{environment}
- %
- % \subsection{Syntax diagrams}
- %
- % Now we come to the final and most complicated part of the package.
- %
- % Syntax diagrams are drawn using arrow characters from \LaTeX's line font,
- % used in the \env{picture} environment, and rules. The horizontal rules
- % of the diagram are drawn along the baselines of the lines in which they
- % are placed. The text items in the diagram are placed in boxes and lowered
- % below the main baseline. Struts are added throughout to keep the vertical
- % spacing consistent.
- %
- % The vertical structures (stacks and loops) are all implemented with \TeX's
- % primitive |\halign| command.
- %
- % \subsubsection{User-configurable parameters}
- %
- % First, we allocate the \<dimen> and \<skip> arguments needed. Fixed
- % lengths, as the \LaTeX book calls them, are allocated as \<dimen>s, to
- % take some of the load off of all the \<skip> registers.
- %
- % \begin{macrocode}
- \newskip\sdstartspace
- \newskip\sdendspace
- \newskip\sdmidskip
- \newskip\sdtokskip
- \newskip\sdfinalskip
- \newdimen\sdrulewidth
- \newdimen\sdcirclediam
- \newdimen\sdindent
- % \end{macrocode}
- %
- % We need some \TeX\ \<dimen>s for our own purposes, to get everything in
- % the right places. We use labels for the `temporary' \TeX\ parameters
- % which we use, to avoid wasting registers.
- %
- % \begin{macrocode}
- \dimendef\sd@lower\z@
- \dimendef\sd@upper\tw@
- \dimendef\sd@mid4
- \dimendef\sd@topcirc6
- \dimendef\sd@botcirc8
- % \end{macrocode}
- %
- % \begin{macro}{\sd@setsize}
- % When the text size for syntax diagrams changes, it's necessary to work out
- % the height for various rules in the diagram.
- %
- % \begin{macrocode}
- \def\sd@setsize{%
- \sd@mid\ht\strutbox%
- \advance\sd@mid-\dp\strutbox%
- \[email protected]\sd@mid%
- \sd@upper\sdrulewidth%
- \advance\sd@upper\sd@mid%
- \sd@lower\sdrulewidth%
- \advance\sd@lower-\sd@mid%
- \[email protected]\sdcirclediam%
- \advance\sd@topcirc\sd@mid%
- \[email protected]\sdcirclediam%
- \advance\sd@botcirc-\sd@mid%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sdsize}
- %
- % You can set the default type size used by syntax diagrams by redefining
- % the |\sdsize| command, using the |\renewcommand| command.
- %
- % By default, syntax diagrams are set slightly smaller than the main body
- % text.\footnote{^^A
- % I've used pure \LaTeX\ commands for this and the \cmd\sdlengths\ macro,
- % to try and illustrate how these values might be changed by a user. The
- % rest of the code is almost obfuscted in its use of raw \TeX\ features,
- % in an attempt to dissuade more na\"\i ve users from fiddling with it.
- % I suppose this is what you get when you let assembler hackers loose with
- % something like \LaTeX.
- % }
- %
- % \begin{macrocode}
- \newcommand{\sdsize}{%
- \small%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sdlengths}
- %
- % Finally, the default length parameters are set in the |\sdlengths| command.
- % You can redefine the command using |\renewcommand|.
- %
- % We set up the length parameters here.
- %
- % \begin{macrocode}
- \newcommand{\sdlengths}{%
- \setlength{\sdstartspace}{1em minus 10pt}%
- \setlength{\sdendspace}{1em minus 10pt}%
- \setlength{\sdmidskip}{0.5em plus 0.0001fil}%
- \setlength{\sdtokskip}{0.25em plus 0.0001fil}%
- \setlength{\sdfinalskip}{0.5em plus 10000fil}%
- \setlength{\sdrulewidth}{0.2pt}%
- \setlength{\sdcirclediam}{8pt}%
- \setlength{\sdindent}{0pt}%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{Other declarations}
- %
- % We define four switches. The table shows what they're used for.
- %
- % \begin{table}
- % \begin{tab}{lp{3in}} \hline
- %
- % \bf Switch & \bf Meaning \\ \hline
- %
- % |\ifsd@base| & We are at `base level' in the diagram:
- % i.e., not in any other sorts of
- % constructions. This is used to decide
- % whether to allow line breaking. \\[2pt]
- %
- % |\ifsd@top| & The current loop construct is being
- % typeset with the loop arrow above the
- % baseline. \\[2pt]
- %
- % |\ifsd@toplayer| & We are typesetting the top layer of
- % a stack. This is used to ensure that
- % the vertical rules on either side are
- % typeset at the right height. \\[2pt]
- %
- % |\ifsd@backwards| & We're typesetting backwards, because
- % we're in the middle of a loop arrow.
- % the only difference this makes is that
- % any subloops have the arrow on the
- % side. \\ \hline
- %
- % \end{tab}
- % \caption{Syntax diagram switches}
- % \end{table}
- %
- % \begin{macrocode}
- \newif\ifsd@base
- \newif\ifsd@top
- \newif\ifsd@toplayer
- \newif\ifsd@backwards
- % \end{macrocode}
- %
- % \begin{macro}{\sd@err}
- %
- % We output our errors through this macro, which saves a little typing.
- %
- % \begin{macrocode}
- \def\sd@err{\PackageError{syntax}}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{Arrow-drawing}
- %
- % We need to draw some arrows. \LaTeX\ tries to make this as awkward as
- % possible, so we have to start moving the arrows around in boxes quite a
- % lot.
- %
- % The left and right pointing arrows are fairly simple: we just add some
- % horizontal spacing to prevent the width of the arrow looking odd.
- %
- % \begin{macrocode}
- \def\sd@arrow{%
- \ht\tw@\z@%
- \dp\tw@\z@%
- \raise\sd@mid\box\tw@%
- \egroup%
- }
- \def\sd@rightarr{%
- \bgroup%
- \setbox\tw@\hbox{\kern-6\p@\@linefnt\char'55}%
- \sd@arrow%
- }
- \def\sd@leftarr{%
- \bgroup%
- \raise\sd@mid\hbox{\@linefnt\char'33\kern-6\p@}%
- \sd@arrow%
- }
- % \end{macrocode}
- %
- % The up arrow is very strange. We need to bring the arrow down to base
- % level, and smash its height.
- %
- % \begin{macrocode}
- \def\sd@uparr{%
- \bgroup%
- \setbox\tw@\hb@xt@\z@{\kern-\sdrulewidth\@linefnt\char'66\hss}%
- \setbox\tw@\hbox{\lower10\p@\box\tw@}%
- \sd@arrow%
- }
- % \end{macrocode}
- %
- % The down arrow is similar, although it's already at the right height.
- % Thus, we can just smash the box.
- %
- % \begin{macrocode}
- \def\sd@downarr{%
- \bgroup%
- \setbox\tw@\hb@xt@\z@{\kern-\sdrulewidth\@linefnt\char'77\hss}%
- \sd@arrow%
- }
- % \end{macrocode}
- %
- % \subsubsection{Drawing curves}
- %
- % If the user has selected curved edges, we use the \LaTeX\ features provided
- % to obtain the curves. These are drawn slightly oddly to make it easier
- % to fit them into the diagram.
- %
- % Some explanation about the \LaTeX\ circle font is probably called for
- % before we go any further. The font consists of sets of four quadrants
- % of a particular size (and some other characters, which aren't important
- % at the moment). Each collection of quadrants fit together to form a
- % perfect circle of a given diameter. The individual quadrant characters
- % have strange bounding boxes, as described in the files \textit{lcircle.mf}
- % and \textit{ltpict.dtx}, and also in Appendix~D of \textit{The \TeX book}.
- % Our job here is to make these quadrants useful in the context of
- % drawing syntax diagrams.
- %
- % \begin{macro}{\sd@circ}
- % First, we define |\sd@circ|, which performs the common parts of the four
- % routines. Since the characters in the circle font are grouped together,
- % we can pick out a particular corner piece by specifying its index into
- % the group for the required size. The |\sd@circ| routine will pick out
- % the required character, given this index as an argument, and put it in
- % box~2, after fiddling with the sizes a little:
- % \begin{itemize}
- %
- % \item We clear the width to zero. The individual routines then add a kern
- % of the correct amount, so that the quadrant appears in the right
- % place.
- %
- % \item The piece is lowered by half the rule width. This positions the
- % top and bottom pieces of the circle to be half way over the baseline,
- % which is the correct position for the rest of the diagram.
- %
- % \end{itemize}
- %
- % Finally, we make sure we're in horizontal mode: horrific results occur
- % if this is not the case. I'm sure I don't need to explain this any more
- % graphically.
- %
- % \begin{macrocode}
- \def\sd@circ#1{%
- \@getcirc\sdcirclediam%
- \advance\@tempcnta#1%
- \setbox\tw@\hbox{\lower\sdrulewidth%
- \hbox{\@circlefnt\char\@tempcnta}}%
- \wd\tw@\z@%
- \leavevmode%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@tlcirc}
- % \begin{macro}{\sd@trcirc}
- % \begin{macro}{\sd@blcirc}
- % \begin{macro}{\sd@brcirc}
- %
- % These are the macros which actually draw quadrants of circles. They all
- % call |\sd@circ|, passing an appropriate index, and then fiddle with the
- % box sizes and apply kerning specific to the quadrant positioning.
- %
- % The exact requirements for positioning are as follows:
- %
- % \begin{itemize}
- %
- % \item The horizontal parts of the arcs must lie along the baseline (i.e.,
- % half the line must be above the baseline, and half must be below).
- % This is consistent with the horizontal rules used in the diagram.
- %
- % \item The vertical parts must overlap vertical rules on either side, so
- % that a |\vrule\sd@|\textit{xx}|circ| makes the arc appear to be
- % a real curve in the line. The requirements are actually somewhat
- % inconsistent; for example, the \env{stack} environment uses curves
- % \emph{before} the |\vrule|s. Special requirements like this are
- % handled as special cases later.
- %
- % \item The height and width of the arc are at least roughly correct.
- %
- % \end{itemize}
- %
- % \begin{macrocode}
- \def\sd@tlcirc{{%
- \sd@circ3%
- \ht\tw@\sdrulewidth%
- \dp\[email protected]\sdcirclediam%
- \kern-\tw@\sdrulewidth%
- \raise\sd@mid\box\tw@%
- \kern.5\sdcirclediam%
- }}
- % \end{macrocode}
- %
- % \begin{macrocode}
- \def\sd@trcirc{{%
- \sd@circ0%
- \ht\tw@\sdrulewidth%
- \dp\[email protected]\sdcirclediam%
- \kern.5\sdcirclediam%
- \raise\sd@mid\box\tw@%
- }}
- % \end{macrocode}
- %
- % \begin{macrocode}
- \def\sd@blcirc{{%
- \sd@circ2%
- \ht\[email protected]\sdcirclediam%
- \dp\tw@\sdrulewidth%
- \kern-\tw@\sdrulewidth%
- \raise\sd@mid\box\tw@%
- \kern.5\sdcirclediam%
- }}
- % \end{macrocode}
- %
- % \begin{macrocode}
- \def\sd@brcirc{{%
- \sd@circ1%
- \ht\[email protected]\sdcirclediam%
- \dp\tw@\sdrulewidth%
- \kern.5\sdcirclediam%
- \raise\sd@mid\box\tw@%
- }}
- % \end{macrocode}
- %
- % \end{macro}
- % \end{macro}
- % \end{macro}
- % \end{macro}
- %
- % \begin{macro}{\sd@llc}
- % \begin{macro}{\sd@rlc}
- %
- % In the \env{rep} environment, we need to be able to draw arcs with
- % horizontal lines running through them. The two macros here do the job
- % nicely. |\sd@llc| (which is short for left overlapping circle) is
- % analogous to |\llap|: it puts its argument in a box of zero width, sticking
- % out to the left. However, it also draws a rule along the baseline. This
- % is important, as it prevents text from overprinting the arc. |\sd@rlc|
- % is very similar, just the other way around.
- %
- % \begin{macrocode}
- \def\sd@llc#1{%
- \hb@[email protected]\sdcirclediam{%
- \sd@rule\hskip.5\sdcirclediam%
- \hss%
- #1%
- }%
- }
- % \end{macrocode}
- %
- % \begin{macrocode}
- \def\sd@rlc#1{%
- \hb@[email protected]\sdcirclediam{%
- #1%
- \hss%
- \sd@rule\hskip.5\sdcirclediam%
- }%
- }
- % \end{macrocode}
- %
- % \end{macro}
- % \end{macro}
- %
- % \subsubsection{Drawing rules}
- %
- % It's important to draw the rules \emph{along} the baseline, rather than
- % above it: hence, the depth of the rule must be equal to the height.
- %
- % \begin{macro}{\sd@rule}
- %
- % We use rule leaders instead of glue through most of the syntax diagrams.
- % The command \syntax{"\\sd@rule"<skip>} draws a rule of the correct
- % dimensions, which has the behaviour of an \syntax{"\\hskip"<skip>}.
- %
- % \begin{macrocode}
- \def\sd@rule{\leaders\hrule\@height\sd@upper\@depth\sd@lower}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@gap}
- %
- % The gap between elements is added using this macro. It will allow a
- % line break if we're at the top level of the diagram, using a rather
- % strange discretionary.
- %
- % This is called as \syntax{"\\sd@gap{"<skip-register>"}"}.
- %
- % \begin{macrocode}
- \def\sd@gap#1{%
- % \end{macrocode}
- %
- % First, we see if we're at the top level. Within constructs, we avoid the
- % overhead of a |\discretionary|. We put half of the width of the skip on
- % each side of the discretionary break.
- %
- % \begin{macrocode}
- \ifsd@base%
- \skip@#1%
- \divide\skip\z@\tw@%
- \nobreak\sd@rule\hskip\skip@%
- \discretionary{%
- \sd@qarrow{->}%
- }{%
- \hbox{%
- \sd@qarrow{>-}%
- \sd@rule\hskip\sdstartspace%
- \sd@rule\hskip3.5\p@%
- }%
- }{%
- }%
- \nobreak\sd@rule\hskip\skip@%
- % \end{macrocode}
- %
- % If we're not at the base level, we just put in a rule of the correct
- % width.
- %
- % \begin{macrocode}
- \else%
- \sd@rule\hskip#1%
- \fi%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{The \protect\env{syntdiag} environment}
- %
- % All syntax diagrams are contained within a \env{syntdiag} environment.
- %
- % \begin{environment}{syntdiag}
- %
- % The only argument is a collection of declarations, which by
- % default is
- %
- % \begin{listing}
- %\sdsize\sdlengths
- % \end{listing}
- %
- % However, if the optional argument is not specified, \TeX\ reads the first
- % character of the environment, which may not be catcoded correctly. We set
- % up the catcodes first, using the |\syntaxShortcuts| command, and then read
- % the argument. We don't use |\newcommand|, because that would involve
- % creating yet \emph{another} macro. Time to fiddle with |\@ifnextchar|
- % \dots
- %
- % \begin{macrocode}
- \def\syntdiag{%
- \syntaxShortcuts\sd@tok@i\sd@tok@ii%
- \@ifnextchar[\syntdiag@i{\syntdiag@i[]}%
- }
- % \end{macrocode}
- %
- % Now we actually do the job we're meant to.
- %
- % \begin{macrocode}
- \def\syntdiag@i[#1]{%
- % \end{macrocode}
- %
- % The first thing to do is execute the user's declarations. We then set
- % up things for the font size.
- %
- % \begin{macrocode}
- \sdsize\sdlengths%
- #1%
- \sd@setsize%
- % \end{macrocode}
- %
- % Next, we start a list, to change the text layout.
- %
- % \begin{macrocode}
- \list{}{%
- \leftmargin\sdindent%
- \rightmargin\leftmargin%
- \labelsep\z@%
- \labelwidth\z@%
- }%
- \item[]%
- % \end{macrocode}
- %
- % We reconfigure the paragraph format quite a lot now. We clear
- % |\parfillskip| to avoid any justification at the end of the paragraph.
- % We also turn off paragraph indentation.
- %
- % \begin{macrocode}
- \parfillskip\z@%
- \noindent%
- % \end{macrocode}
- %
- % Next, we add in the arrows on the beginning of the line, and a bit of
- % glue.
- %
- % \begin{macrocode}
- \sd@qarrow{>>-}%
- \nobreak\sd@rule\hskip\sdstartspace%
- % \end{macrocode}
- %
- % This is the base level of the diagram, so we enable line breaking.
- %
- % \begin{macrocode}
- \sd@basetrue%
- % \end{macrocode}
- %
- % Since the objects being broken are rather large, we enable sloppy line
- % breaking. We also try to avoid page breaks in mid-diagram, by upping the
- % |\interlinepenalty|.
- %
- % \begin{macrocode}
- \sloppy%
- \interlinepenalty100%
- \hyphenpenalty0%
- % \end{macrocode}
- %
- % We handle all the spacing within the environment, so we make \TeX\ ignore
- % spaces and newlines.
- %
- % \begin{macrocode}
- \catcode`\ 9%
- \catcode`\^^M9%
- % \end{macrocode}
- %
- % The environment names are rather cumbersome. I'll define some better names
- % for them here.
- %
- % \begin{macrocode}
- \def\gr@leftsq{\begin{stack}\\}%
- \def\gr@rightsq{\end{stack}}%
- \def\({\begin{stack}}%
- \def\){\end{stack}}%
- \def\<{\begin{rep}}%
- \def\>{\end{rep}}%
- % \end{macrocode}
- %
- % We now have to change the behaviour of |\\| to line-break syntax diagrams.
- %
- % \begin{macrocode}
- \let\\\sd@newline%
- \ignorespaces%
- }
- % \end{macrocode}
- %
- % When we end the diagram, we just have to add in the final fillskip, and
- % double arrow.
- %
- % \begin{macrocode}
- \def\endsyntdiag{%
- \unskip%
- \nobreak\sd@rule\hskip\sdmidskip%
- \sd@rule\hskip\sdfinalskip%
- \sd@qarrow{-><}%
- \endlist%
- }
- % \end{macrocode}
- %
- % \end{environment}
- %
- % \begin{environment}{syntdiag*}
- %
- % The starred form of \env{syntdiag} typesets a syntax diagram in LR-mode;
- % this is useful if you're describing parts of syntax diagrams, for example.
- %
- % This is in fact really easy. The first bit which checks for an optional
- % argument is almost identical to the non-$*$ version.
- %
- % \begin{macrocode}
- \@namedef{syntdiag*}{%
- \syntaxShortcuts\sd@tok@i\sd@tok@ii%
- \@ifnextchar[\syntdiag@s@i{\syntdiag@s@i[]}%
- }
- % \end{macrocode}
- %
- % Handle another optional argument giving the width of the box to fill.
- %
- % \begin{macrocode}
- \def\syntdiag@s@i[#1]{%
- \@ifnextchar[{\syntdiag@s@ii{#1}}{\syntdiag@s@iii{#1}{\hbox}}%
- }
- \def\syntdiag@s@ii#1[#2]{\syntdiag@s@iii{#1}{\hb@xt@#2}}
- % \end{macrocode}
- %
- % Now to actually start the display. This is mostly simple. Just to make
- % sure about the LR-ness of the typesetting, I'll put everything in an hbox.
- %
- % \begin{macrocode}
- \def\syntdiag@s@iii#1#2{%
- \leavevmode%
- #2\bgroup%
- % \end{macrocode}
- %
- % Now configure the typesetting according to the user's wishes.
- %
- % \begin{macrocode}
- \let\@@left\left%
- \let\@@right\right%
- \def\left##1{\def\sd@startarr{##1}}%
- \def\right##1{\def\sd@endarr{##1}}%
- \left{>-}\right{->}%
- \sdsize\sdlengths%
- #1%
- \sd@setsize%
- \let\left\@@left%
- \let\right\@@right%
- % \end{macrocode}
- %
- % Put in the initial double-arrow.
- %
- % \begin{macrocode}
- \sd@qarrow\sd@startarr%
- \sd@rule\hskip\sdmidskip%
- % \end{macrocode}
- %
- % We're in horizontal mode, so don't bother with linebreaking.
- %
- % \begin{macrocode}
- \sd@basefalse%
- % \end{macrocode}
- %
- % Finally, disable spaces and things.
- %
- % \begin{macrocode}
- \catcode`\ 9%
- \catcode`\^^M9%
- \ignorespaces%
- }
- % \end{macrocode}
- %
- % Ending the environment is very similar.
- %
- % \begin{macrocode}
- \@namedef{endsyntdiag*}{%
- \unskip%
- \sd@rule\hskip\sdmidskip%
- \sd@rule\hskip\sdfinalskip%
- \sd@qarrow\sd@endarr%
- \egroup%
- }
- % \end{macrocode}
- %
- % \end{environment}
- %
- % \begin{macro}{\sd@qarrow}
- %
- % This typesets the various left and right arrows required in syntax
- % diagrams. The argument is one of \syntax{`>>-', `->', `>-' or `-><'}.
- %
- % \begin{macrocode}
- \def\sd@qarrow#1{%
- \begingroup%
- \lccode`\~=`\<\lowercase{\def~{<}}%
- \hbox{\csname sd@arr@#1\endcsname}%
- \endgroup%
- }
- \@namedef{sd@arr@>>-}{\sd@rightarr\kern-.5\p@\sd@rightarr\kern-\p@}
- \@namedef{sd@arr@>-}{\sd@rightarr\kern-\p@}
- \@namedef{sd@arr@->}{\sd@rightarr}
- \@namedef{sd@arr@-><}{\sd@rightarr\kern-\p@\sd@leftarr}
- \@namedef{sd@arr@...}{$\cdots$}
- \@namedef{sd@arr@-}{}
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@newline}
- %
- % The line breaking within a syntax diagram is controlled by the
- % |\sd@newline| command, to which |\\| is assigned.
- %
- % We support all the standard \LaTeX\ features here. The line breaking
- % involves adding a fill skip and arrow, moving to the next line, adding
- % an arrow and a rule, and continuing.
- %
- % \begin{macrocode}
- \def\sd@newline{\@ifstar{\vadjust{\penalty\@M}\sd@nl@i}\sd@nl@i}
- \def\sd@nl@i{\@ifnextchar[\sd@nl@ii\sd@nl@iii}
- \def\sd@nl@ii[#1]{\vspace{#1}\sd@nl@iii}
- \def\sd@nl@iii{%
- \nobreak\sd@rule\hskip\sdmidskip%
- \sd@rule\hskip\sdfinalskip%
- \kern-3\p@%
- \sd@rightarr%
- \newline%
- \sd@rightarr%
- \nobreak\sd@rule\hskip\sdstartspace%
- \sd@rule\hskip3.5\p@%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{Putting things in the right place}
- %
- % Syntax diagrams have fairly stiff requirements on the positioning of text
- % relative to the diagram's rules. To help people (and me) to write
- % extensions to the syntax diagram typesetting which automatically put things
- % in the right place, I provide some simple macros.
- %
- % \begin{environment}{sdbox}
- %
- % By placing some text in the \env{sdbox} environment, it will be read into a
- % box and then output at the correct height for the syntax diagram. Note
- % that stuff in the box is set in horizontal (LR) mode, so you'll have to use
- % a \env{minipage} if you want formatted text. The macro also supplies rules
- % on either side of the box, with a length given in the environment's
- % argument.
- %
- % Macro writers are given explicit permission to use this environment through
- % the |\sdbox| and |\endsdbox| commands if this makes life easier.
- %
- % The calculation in the |\endsdbox| macro works out how to centre the box
- % vertically over the baseline. If the box's height is~$h$, and its depth
- % is~$d$, then its centre-line is $(h+d)/2$ from the bottom of the box.
- % Since the baseline is already $d$ from the bottom, we need to lower the box
- % by $(h+d)/2 - d$, or $h/2-d/2$.
- %
- % \begin{macrocode}
- \def\sdbox#1{%
- \@tempskipa#1\relax%
- \sd@gap\@tempskipa%
- \setbox\z@\hbox\bgroup%
- \begingroup%
- \catcode`\ 10%
- \catcode`\^^M5%
- \synshortsoff%
- }
- \def\endsdbox{%
- \endgroup%
- \egroup%
- \@tempdima\ht\z@%
- \advance\@tempdima-\dp\z@%
- \advance\@tempdima-\tw@\sd@mid%
- \lower.5\@tempdima\box\z@%
- \sd@gap\@tempskipa%
- }
- % \end{macrocode}
- %
- % \end{environment}
- %
- % \subsubsection{Typesetting syntactic items}
- %
- % Using the hooks built into the syntax abbreviations above, we typeset
- % the text into a box, and write it out, centred over the baseline. A strut
- % helps to keep the actual text baselines level for short pieces of text.
- %
- % \begin{macro}{\sd@tok@i}
- %
- % The preamble for a syntax abbreviation. We start a box, and set the
- % space and return characters to work again. A strut is added to the box to
- % ensure correct vertical spacing for normal text.
- %
- % \begin{macrocode}
- \def\sd@tok@i{%
- \sdbox\sdtokskip%
- \strut%
- \space%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@tok@ii}
- %
- % \begin{macrocode}
- \def\sd@tok@ii{%
- \space%
- \endsdbox%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{Inserting other pieces of text}
- %
- % Arbitrary text may be put into a syntax diagram through the use of the
- % |\tok| macro. Its `argument' is typeset in the same way as a syntactic
- % item (centred over the baseline). The implementation goes to some effort
- % to ensure that the text is not actually an argument, to allow category
- % codes to change while the text is being typeset.
- %
- % \begin{macro}{\tok}
- %
- % We start a box, and make space and return do their normal jobs. We use
- % |\aftergroup| to regain control once the box is finished. |\doafter| is
- % used to get control after the group finishes.
- %
- % \begin{macrocode}
- \def\tok#{%
- \sdbox\sdtokskip%
- \strut%
- \enspace%
- \syntaxShortcuts\relax\relax%
- \doafter\sd@tok%
- }
- % \end{macrocode}
- %
- % The |\sd@tok| macro is similar to |\sd@tok@ii| above.
- %
- % \begin{macrocode}
- \def\sd@tok{%
- \enspace%
- \endsdbox%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{The \protect\env{stack} environment}
- %
- % The \env{stack} environment is used to present alternatives in a syntax
- % diagram. The alternatives are separated by |\\| commands.
- %
- % \begin{macro}{\stack}
- %
- % The optional positioning argument is handled using \LaTeX's |\newcommand|
- % mechanism.
- %
- % \begin{macrocode}
- \newcommand\stack[1][t]{%
- % \end{macrocode}
- %
- % First, we add some horizontal space.
- %
- % \begin{macrocode}
- \sd@gap\sdmidskip%
- % \end{macrocode}
- %
- % We're within a complex construction, so we need to clear the |\ifsd@base|
- % flag.
- %
- % \begin{macrocode}
- \begingroup\sd@basefalse%
- % \end{macrocode}
- %
- % The top and bottom rows of the stack are different to the others, since
- % the vertical rules mustn't extend all the way up the side of the item.
- % The bottom row is handled separately by |\endstack| below. The top row
- % must be handled via a flag, |\ifsd@toplayer|.
- %
- % Initially, the flag must be set true.
- %
- % \begin{macrocode}
- \sd@toplayertrue%
- % \end{macrocode}
- %
- % We set the |\\| command to separate the items in the |\halign|.
- %
- % \begin{macrocode}
- \let\\\sd@stackcr%
- % \end{macrocode}
- %
- % The actual structure must be set in vertical mode, so we must place it
- % in a box. The position argument determines whether this must be a
- % |\vbox| or a |\vtop|. We also insert a bit of rounding if the options say
- % we must.
- %
- % \begin{macrocode}
- \if#1t%
- \let\@tempa\vtop%
- \sd@toptrue%
- \ifsd@round\llap{\sd@trcirc\kern\tw@\sdrulewidth}\fi%
- \else\if#1b%
- \let\@tempa\vbox%
- \sd@topfalse%
- \ifsd@round\llap{\sd@brcirc\kern\tw@\sdrulewidth}\fi%
- \else%
- \sd@err{Bad position argument passed to stack}%
- {The positioning argument must be one of `t' or `b'. I%
- have^^Jassumed you meant to type `t'.}%
- \let\@tempa\vtop%
- \fi\fi%
- % \end{macrocode}
- %
- % Now we start the box, which we will complete at the end of the environment.
- %
- % \begin{macrocode}
- \@tempa\bgroup%
- % \end{macrocode}
- %
- % We must remove any extra space between rows of the table, since the rules
- % will not join up correctly. We can use |\offinterlineskip| safely, since
- % each individual row contains a strut.
- %
- % \begin{macrocode}
- \offinterlineskip%
- % \end{macrocode}
- %
- % Now we can start the alignment. We actually use \PlainTeX's |\ialign|
- % macro, which also clears |\tabskip| for us.
- %
- % \begin{macrocode}
- \ialign\bgroup%
- % \end{macrocode}
- %
- % The preamble is trivial, since we must do all of the work ourselves
- %
- % \begin{macrocode}
- ##\cr%
- % \end{macrocode}
- %
- % We can now start putting the text into a box ready for typesetting later.
- % The strut makes the vertical spacing correct.
- %
- % \begin{macrocode}
- \setbox\z@\hbox\bgroup%
- \strut%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\endstack}
- %
- % The first part of this is similar to the |\sd@stackcr| macro below, except
- % that the vertical rules are different. We don't support rounded edges
- % on single-row stacks, although this isn't a great loss to humanity.
- %
- % \begin{macrocode}
- \def\endstack{%
- \egroup%
- \ifsd@toplayer%
- \sd@dostack\sd@upper\sd@lower\relax\relax%
- \else%
- \ifsd@round%
- \ifsd@top%
- \sd@dostack{\ht\z@}\sd@botcirc\sd@blcirc\sd@brcirc%
- \else%
- \sd@dostack{\ht\z@}\sd@botcirc\relax\relax%
- \fi%
- \else%
- \sd@dostack{\ht\z@}\sd@lower\relax\relax%
- \fi%
- \fi%
- % \end{macrocode}
- %
- % We now close the |\halign| and the vbox we created.
- %
- % \begin{macrocode}
- \egroup%
- \egroup%
- % \end{macrocode}
- %
- % Deal with any rounding we started off.
- %
- % \begin{macrocode}
- \ifsd@round%
- \ifsd@top
- \rlap{\kern\tw@\sdrulewidth\sd@tlcirc}%
- \else%
- \rlap{\kern\tw@\sdrulewidth\sd@blcirc}%
- \fi%
- \fi%
- % \end{macrocode}
- %
- % Finally, we add some horizontal glue to space the diagram out.
- %
- % \begin{macrocode}
- \endgroup\sd@gap\sdmidskip%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@stackcr}
- %
- % The |\\| command is set to this macro during a \env{stack} environment.
- %
- % \begin{macrocode}
- \def\sd@stackcr{%
- % \end{macrocode}
- %
- % The first job is to close the box containing the previous item.
- %
- % \begin{macrocode}
- \egroup%
- % \end{macrocode}
- %
- % Now we typeset the vertical rules differently depending on whether this is
- % the first item in the stack. This looks quite terrifying initially, but
- % it's just an enumeration of the possible cases for the different values
- % of |\ifsd@toplayer|, |\ifsd@top| and |\ifsd@round|, putting in appropriate
- % rules and arcs in the right places.
- %
- % \begin{macrocode}
- \ifsd@toplayer%
- \ifsd@round%
- \ifsd@top%
- \sd@dostack\sd@topcirc{\dp\z@}\relax\relax%
- \else%
- \sd@dostack\sd@topcirc{\dp\z@}\sd@tlcirc\sd@trcirc%
- \fi%
- \else%
- \sd@dostack\sd@upper{\dp\z@}\relax\relax%
- \fi%
- \else%
- \ifsd@round%
- \ifsd@top%
- \sd@dostack{\ht\z@}{\dp\z@}\sd@blcirc\sd@brcirc%
- \else%
- \sd@dostack{\ht\z@}{\dp\z@}\sd@tlcirc\sd@trcirc%
- \fi%
- \else%
- \sd@dostack{\ht\z@}{\dp\z@}\relax\relax%
- \fi%
- \fi%
- % \end{macrocode}
- %
- % The next item won't be the first, so we clear the flag.
- %
- % \begin{macrocode}
- \sd@toplayerfalse%
- % \end{macrocode}
- %
- % Now we have to set up the next cell. We put the text into a box again.
- %
- % \begin{macrocode}
- \setbox\z@\hbox\bgroup%
- \strut%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@dostack}
- %
- % Actually typesetting the text in a cell is performed here. The macro is
- % called as
- % \begin{quote}\synshorts
- % "\\sd@dostack{"<height>"}{"<depth>"}{"<left-arc>"}{"<right-arc>"}"
- % \end{quote}
- % where \<height> and \<depth> are the height and depth of the vertical
- % rules to put around the item, and \<left-arc> and \<right-arc> are
- % commands to draw rounded edges on the left and right hand sides of the
- % item.
- %
- % The values for the height and depth are quite often going to be the height
- % and depth of box~0. Since we empty box~0 in the course of typesetting the
- % row, we need to cache the sizes on entry.
- %
- % \begin{macrocode}
- \def\sd@dostack#1#2#3#4{%
- \@tempdima#1%
- \@tempdimb#2%
- \kern-\tw@\sdrulewidth%
- \vrule\@height\@tempdima\@depth\@tempdimb\@width\tw@\sdrulewidth%
- #3%
- \sd@rule\hfill%
- \sd@gap\sdtokskip%
- \unhbox\z@%
- \sd@gap\sdtokskip%
- \sd@rule\hfill%
- #4%
- \vrule\@height\@tempdima\@depth\@tempdimb\@width\tw@\sdrulewidth%
- \kern-\tw@\sdrulewidth%
- \cr%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsubsection{The \protect\env{rep} environment}
- %
- % The \env{rep} environment is used for typesetting loops in the diagram.
- % Again, we use |\halign| for the typesetting. Loops are simpler than
- % stacks, however, since there are always two rows. We store both rows in
- % box registers, and build the loop at the end.
- %
- % \begin{macro}{\rep}
- %
- % Again, we use |\newcommand| to process the optional argument.
- %
- % \begin{macrocode}
- \newcommand\rep[1][t]{%
- % \end{macrocode}
- %
- % First, leave a gap on the left side.
- %
- % \begin{macrocode}
- \sd@gap\sdmidskip%
- % \end{macrocode}
- %
- % We're not at base level any more, so disable linebreaking.
- %
- % \begin{macrocode}
- \begingroup\sd@basefalse%
- % \end{macrocode}
- %
- % Remember we're going backwards now.
- %
- % \begin{macrocode}
- \ifsd@backwards\sd@backwardsfalse\else\sd@backwardstrue\fi%
- % \end{macrocode}
- %
- % Define |\\| to separate the two parts of the loop.
- %
- % \begin{macrocode}
- \let\\\sd@loop%
- % \end{macrocode}
- %
- % Now check the argument, and use the appropriate type of box. In addition
- % to changing the typesetting, we must remember which way up to typeset the
- % loop, since the end code must always put the first argument on the
- % baseline, with the loop either above or below.
- %
- % \begin{macrocode}
- \if#1t%
- \let\@tempa\vbox%
- \sd@toptrue%
- \else\if#1b%
- \let\@tempa\vtop%
- \sd@topfalse%
- \else%
- \sd@err{Bad position argument passed to loop}%
- {The positioning argument must be `t' or `b'. I have^^J%
- assumed you meant to type `t'.}%
- \let\@tempa\vbox%
- \sd@toptrue%
- \fi\fi%
- % \end{macrocode}
- %
- % Now we start the box.
- %
- % \begin{macrocode}
- \@tempa\bgroup%
- % \end{macrocode}
- %
- % The loop is by default empty, apart from a strut. This is put into box~1.
- %
- % \begin{macrocode}
- \setbox\tw@\copy\strutbox%
- % \end{macrocode}
- %
- % Now start typesetting the main text in box~0.
- %
- % \begin{macrocode}
- \setbox\z@\hbox\bgroup\strut%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\endrep}
- %
- % The final code must first close whatever box was open.
- %
- % \begin{macrocode}
- \def\endrep{%
- \egroup%
- % \end{macrocode}
- %
- % Now we typeset the loop, depending on which way up it was meant to be.
- % Again, this terrifying piece of code is a simple list of possibile values
- % of our various flags.
- %
- % \begin{macrocode}
- \ifsd@top%
- \ifsd@round%
- \sd@doloop\tw@\z@\relax\relax%
- \sd@tlcirc\sd@trcirc{\sd@rlc\sd@blcirc}{\sd@llc\sd@brcirc}%
- \else%
- \sd@doloop\tw@\z@\relax\sd@downarr\relax\relax\relax\relax%
- \fi%
- \else%
- \ifsd@round%
- \sd@doloop\z@\tw@\relax\relax%
- {\sd@rlc\sd@tlcirc}{\sd@llc\sd@trcirc}\sd@blcirc\sd@brcirc%
- \else%
- \sd@doloop\z@\tw@\sd@uparr\relax\relax\relax\relax\relax%
- \fi%
- \fi%
- % \end{macrocode}
- %
- % Close the vbox we opened.
- %
- % \begin{macrocode}
- \egroup%
- % \end{macrocode}
- %
- % Finally, we leave a gap before the next structure.
- %
- % \begin{macrocode}
- \endgroup\sd@gap\sdmidskip%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@loop}
- %
- % This macro handles the |\\| command within a loop environment. We close
- % the current box, and start filling in box~1. We also redefine |\\| to
- % raise an error when the |\\| command is used again.
- %
- % \begin{macrocode}
- \def\sd@loop{%
- \egroup%
- \def\\{\sd@err{Too many \string\\\space commands in loop}\@ehc}%
- \setbox\tw@\hbox\bgroup\strut%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@doloop}
- %
- % This is the macro which actually creates the |\halign| for the loop. It
- % is called with four arguments, as:
- % \begin{quote}\synshorts
- % "\\sd@doloop{"<top-box>"}{"<bottom-box>"}"^^A
- % "{"<top-arrow>"}{"<btm-arrow>"}" \\
- % \hbox{}\quad "{"<top-left-arc>"}{"<top-right-arc>"}"^^A
- % "{"<bottom-left-arc>"}{"<btm-right-arc>"}"^^A
- % \kern-1in ^^A It may be overfull, but it looks OK to me ;-)
- % \end{quote}
- %
- % The two \<box> arguments give the numbers of boxes to extract in the top
- % and bottom rows of the alignment. The \<arrow> arguments specify
- % characters to typeset at the end of the top and bottom rows for arrows.
- % The various \<arc> arguments are commands which typeset arcs around the
- % various parts of the items.
- %
- % We calculate the height and depth of the two boxes, and store them in
- % \<dimen> registers, because the boxes are emptied before the right-hand
- % rules are typeset.
- %
- % Actually, the two rows of the alignment are typeset in a different macro:
- % we just pass the correct information on.
- %
- % \begin{macrocode}
- \def\sd@doloop#1#2#3#4#5#6#7#8{%
- \@tempdima\dp#1\relax%
- \@tempdimb\ht#2\relax%
- \offinterlineskip%
- \ialign{%
- ##\cr%
- \ifsd@round%
- \sd@doloop@i#1#3\sd@topcirc\@tempdima{#5}{#6}%
- \sd@doloop@i#2#4\@tempdimb\sd@botcirc{#7}{#8}%
- \else%
- \sd@doloop@i#1#3\sd@upper\@tempdima{#5}{#6}%
- \sd@doloop@i#2#4\@tempdimb\sd@lower{#7}{#8}%
- \fi%
- }%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \begin{macro}{\sd@doloop@i}
- %
- % Here we do the actual job of typesetting the rows of a loop alignment.
- % The four arguments are:
- % \begin{quote}\synshorts
- % "\\sd@doloop@i{"<box>"}{"<arrow>"}"^^A
- % "{"<rule-height>"}{"<rule-depth>"}" \\
- % \hbox{}\quad "{"<left-arc>"}{"<right-arc>"}"^^A
- % \end{quote}
- %
- % The arrow position is determined by the |\ifsd@backwards| flag. The rest
- % is fairly simple.
- %
- % \begin{macrocode}
- \def\sd@doloop@i#1#2#3#4#5#6{%
- \ifsd@backwards#2\fi%
- \kern-\tw@\sdrulewidth%
- \vrule\@height#3\@depth#4\@width\tw@\sdrulewidth%
- #5%
- \sd@rule\hfill%
- \sd@gap\sdtokskip%
- \unhbox#1%
- \sd@gap\sdtokskip%
- \sd@rule\hfill%
- #6%
- \vrule\@height#3\@depth#4\@width\tw@\sdrulewidth%
- \ifsd@backwards\else#2\fi%
- \kern-\tw@\sdrulewidth%
- \cr%
- }
- % \end{macrocode}
- %
- % \end{macro}
- %
- % \subsection{The end}
- %
- % Phew! That's all of it completed. I hope this collection of commands
- % and environments is of some help to someone.
- %
- % \begin{macrocode}
- %</package>
- % \end{macrocode}
- %
- % \hfill Mark Wooding, \today
- %
- % \Finale
- %
- \endinput
|