sverb.dtx 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. % \begin{meta-comment}
  2. %
  3. % $Id$
  4. %
  5. % Verbatim typesetting done properly (ahem)
  6. %
  7. % (c) 1996 Mark Wooding
  8. %
  9. %----- Revision history -----------------------------------------------------
  10. %
  11. % $Log$
  12. % Revision 1.1 1998-09-21 10:19:01 michael
  13. % Initial implementation
  14. %
  15. % Revision 1.3 1996/11/19 21:01:18 mdw
  16. % Entered into RCS
  17. %
  18. %
  19. % \end{meta-comment}
  20. %
  21. % \begin{meta-comment} <general public licence>
  22. %%
  23. %% sverb package -- handling of verbatim text
  24. %% Copyright (c) 1996 Mark Wooding
  25. %%
  26. %% This program is free software; you can redistribute it and/or modify
  27. %% it under the terms of the GNU General Public License as published by
  28. %% the Free Software Foundation; either version 2 of the License, or
  29. %% (at your option) any later version.
  30. %%
  31. %% This program is distributed in the hope that it will be useful,
  32. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. %% GNU General Public License for more details.
  35. %%
  36. %% You should have received a copy of the GNU General Public License
  37. %% along with this program; if not, write to the Free Software
  38. %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  39. %%
  40. % \end{meta-comment}
  41. %
  42. % \begin{meta-comment} <Package preamble>
  43. %<+package>\NeedsTeXFormat{LaTeX2e}
  44. %<+package>\ProvidesPackage{sverb}
  45. %<+package> [1996/05/08 1.3 Verbatim typesetting]
  46. % \end{meta-comment}
  47. %
  48. % \CheckSum{651}
  49. %% \CharacterTable
  50. %% {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
  51. %% 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
  52. %% Digits \0\1\2\3\4\5\6\7\8\9
  53. %% Exclamation \! Double quote \" Hash (number) \#
  54. %% Dollar \$ Percent \% Ampersand \&
  55. %% Acute accent \' Left paren \( Right paren \)
  56. %% Asterisk \* Plus \+ Comma \,
  57. %% Minus \- Point \. Solidus \/
  58. %% Colon \: Semicolon \; Less than \<
  59. %% Equals \= Greater than \> Question mark \?
  60. %% Commercial at \@ Left bracket \[ Backslash \\
  61. %% Right bracket \] Circumflex \^ Underscore \_
  62. %% Grave accent \` Left brace \{ Vertical bar \|
  63. %% Right brace \} Tilde \~}
  64. %%
  65. %
  66. % \begin{meta-comment}
  67. %
  68. %<*driver>
  69. \input{mdwtools}
  70. \describespackage{sverb}
  71. \mdwdoc
  72. %</driver>
  73. %
  74. % \end{meta-comment}
  75. %
  76. % \section{User guide}
  77. %
  78. % The \package{sverb} package provides some useful commands and environments
  79. % for doing things with verbatim text. I prefer this code to the standard
  80. % \package{verbatim} package (by Rainer Sch\"opf et al.)\ although I'm
  81. % biased.
  82. %
  83. % The package was written to fulfil a particular purpose: I wanted to be able
  84. % to typeset ARM assembler code, 77~columns wide, on A5~paper, with the
  85. % fields separated by \textit{tab} characters. It's grown up fairly
  86. % organically from that, and I've tidied it when I've seen the code get too
  87. % ugly.
  88. %
  89. % The current features are:
  90. %
  91. % \begin{itemize}
  92. %
  93. % \item A `listing' environment which typesets verbatim text nicely.
  94. %
  95. % \item A command to read verbatim text from an external file.
  96. %
  97. % \item Support for arbitrary-sized chunks of text without overflowing \TeX's
  98. % memory.
  99. %
  100. % \item Support for \textit{tab} characters in the verbatim text.
  101. %
  102. % \item An environment for typesetting demonstrations of \LaTeX\ markup.
  103. %
  104. % \item It all works correctly with the \package{doc} system for documenting
  105. % \LaTeX\ packages.
  106. %
  107. % \item A fairly hairy but quite powerful programmer interface to the yukky
  108. % bits of the package.
  109. %
  110. % \end{itemize}
  111. %
  112. % The interface is described in its own section, so that more timid readers
  113. % can avoid it. That said, some of the stuff in this section gets rather
  114. % technical.
  115. %
  116. % Note that this package doesn't even try to do anything with short bits of
  117. % verbatim text (as handled by the |\verb:...:| command). I have a separate
  118. % package (\package{syntax}) which does all sorts of horrible things along
  119. % those lines.
  120. %
  121. % \subsection{The \env{listing} environment}
  122. %
  123. % \DescribeEnv{listing}
  124. % The main method for typesetting verbatim text is the \env{listing}
  125. % environment. This works pretty much the same as the standard
  126. % \env{verbatim} environment, with some exceptions, which are described
  127. % below.
  128. %
  129. % So that you know exactly what you're getting, here are the rules by which
  130. % \package{sverb} decides what the verbatim text actually is:
  131. %
  132. % \begin{itemize}
  133. %
  134. % \item If there's any text, other than spaces, on the same line as the
  135. % `|\begin{listing}|', then the contents of the environment begins
  136. % immediately after the closing brace (with all leading spaces
  137. % preserved). Otherwise, the text begins on the following line.
  138. %
  139. % \item If there is any text, other than spaces, before the
  140. % `|\end{listing}|', but on the same line, this is considered to be the
  141. % last line of the text; otherwise the text is presumed to have ended
  142. % at the end of the previous line.
  143. %
  144. % \item Any text following the |\end{listing}| on the same line is thrown
  145. % away. There are good reasons for this, but they're technical.
  146. % Essentially there's nothing I can do about it.
  147. %
  148. % \end{itemize}
  149. %
  150. % \begin{figure}
  151. % \begin{demo}[w]{The \env{listing} environment}
  152. %\dots in the following code:
  153. %
  154. %\begin{listing}
  155. %init MOV R0,#200 ;Version 2.00 please
  156. % LDR R1,=&4B534154 ;Magic number (`TASK')
  157. % ADR R2,appName ;Find application name
  158. % SWI Wimp_Initialise ;Register as a WIMP task
  159. %\end{listing}
  160. %
  161. %The next step is to \dots
  162. % \end{demo}
  163. % \end{figure}
  164. %
  165. % Tab characters are supported within the environment: tab stops are set
  166. % every eighth column, although this can be modified.
  167. %
  168. % \subsubsection{Configuring the \env{listing} environment}
  169. %
  170. % The text size used in the \env{listing} environment is set by the
  171. % |\listingsize| command. By default, this is set to |\small|, although you
  172. % can redefine it in the document preamble, or it can be set in the document
  173. % class.
  174. %
  175. % The amount by which the listing text is indented is controlled by the
  176. % |\listingindent| length parameter. This is a fixed length, whose default
  177. % value is 1\,em.
  178. %
  179. % \subsubsection{Choosing a different end-text}
  180. %
  181. % \DescribeEnv{listing*}
  182. % The \env{listing} environment is terminated by the exact character sequence
  183. % `|\end{listing}|'. This isn't too much of a problem, unless you want to
  184. % include this string in the text. This is achieved by the \env{listing$*$}
  185. % environment, which allows you to specify the end-text to find as an
  186. % argument.
  187. %
  188. % For example:
  189. %
  190. % \begin{demo}{The \env{listing$*$} environment}
  191. %Type a listing as follows:
  192. %
  193. %\begin{listing*}{<end-listing*>}
  194. %\begin{listing}
  195. %This is a listing. Yes.
  196. %\end{listing}
  197. %<end-listing*>
  198. %\end{demo}
  199. %
  200. % Don't include `special' characters in your chosen end-text unless you know
  201. % what you're doing.
  202. %
  203. % \subsection{Writing text to a file}
  204. %
  205. % \DescribeEnv{verbwrite}
  206. % You can write verbatim text to a file using the \env{verbwrite}
  207. % environment. The syntax is fairly straightforward:
  208. %
  209. % \begin{quote}
  210. % \syntax{"\\begin{verbwrite}{"<file-name>"}" \dots "\\end{verbwrite}"}
  211. % \end{quote}
  212. %
  213. % The text of the environment is written to the named file. The rules about
  214. % where the text actually starts and ends are the same as for the
  215. % \env{listing} environment.
  216. %
  217. % There is also a $*$-variant, like \env{listing$*$}, which allows you to
  218. % choose the end-text. The end-text is the first argument, the filename
  219. % comes second.
  220. %
  221. % There is a restriction on the characters you can write to the file: they
  222. % must all be considered `printable' by \TeX; otherwise they will be read
  223. % back in as `\syntax{"^^"<chars>}' which isn't too good. Unfortunately,
  224. % this includes tab characters, so you can't write them.\footnote{^^A
  225. % Well, not without doing serious surgery on \TeX\ itself, anyway. }
  226. %
  227. % \iffalse [Example time... Ho hum. There is evilness here.] \fi
  228. %\begin{verbwrite*}{<end-write>}{wrdemo1.tmp}
  229. %\begin{verbwrite}{wrdemo.tmp}
  230. %This is some text written to
  231. %a file near the beginning of
  232. %the file.
  233. %\end{verbwrite}
  234. %<end-write>
  235. %
  236. % For example: \verbinput{wrdemo1.tmp}
  237. %
  238. % \input{wrdemo1.tmp} \iffalse [Now build the file ;-) ] \fi
  239. %
  240. % \subsection{The \cmd\verbinput\ command}
  241. %
  242. % \DescribeMacro{\verbinput}
  243. % You can input a pre-prepared text file exactly as it is in the input using
  244. % the |\verbinput| command. The filename is given as an argument. For
  245. % example:
  246. %
  247. % \begin{demo}{The \cmd\verbinput\ command}
  248. %\verbinput{wrdemo.tmp}
  249. % \end{demo}
  250. %
  251. % \subsection{The \env{demo} environment}
  252. %
  253. % Package authors need to document their packages, and it's common to want
  254. % to display examples showing the original text and the output side-by-side
  255. % (or, when space doesn't permit this, one above the other). Both the
  256. % \LaTeX\ book and \textit{The \LaTeX\ Companion} contain such examples.
  257. %
  258. % The \env{demo} environment allows such displays to be created easily. The
  259. % syntax of the environment is as follows:
  260. %
  261. % \begin{quote}
  262. % \syntax{"\\begin{demo}["<shape>"]{"<title>"}" \dots "\\end{demo}"}
  263. % \end{quote}
  264. %
  265. % The optional \synt{shape} argument can be either `|w|' (wide), or `|n|'
  266. % (narrow). A `wide' shape places the input and output one above the other,
  267. % while the `narrow' shape puts them side-by-side. The default shape is
  268. % `narrow'. An attractive border is drawn around the display to finish it
  269. % off nicely.
  270. %
  271. % An example:
  272. %
  273. %\begin{demo*}{<end-demo>}[w]{The \env{demo} environment}
  274. %\begin{demo}{From the \textit{\TeX book}}
  275. %\[ \sum_{p\;\rm prime}
  276. % f(p) = \int_{t>1}
  277. % f(t)\,{\rm d}\pi(t) \]
  278. %\end{demo}
  279. %<end-demo>
  280. %
  281. % \DescribeEnv{demo*}
  282. % As with the other environments created by this package, there's a
  283. % $*$-variant which takes the end-text as an argument.
  284. %
  285. %
  286. % \section{Programmer interface}
  287. %
  288. % This section describes the publicly available routines provided by the
  289. % \package{sverb} package. Routines not described here are libable to be
  290. % changed or even removed without warning, so don't use them.
  291. %
  292. % \subsection{Environment hooks}
  293. %
  294. % Each of the environments created here works in the same way. For each
  295. % environment \env{foo}, there's a main command responsible for doing the
  296. % work, called |\sv@foo|. This is given all the arguments of the normal
  297. % environment, and two more:
  298. %
  299. % \begin{itemize}
  300. %
  301. % \item The `end-text' to search for, which marks the end of the environment.
  302. %
  303. % \item Some actions to perform after the text has been read and processed.
  304. % This allows the calling macro to do some extra actions, like closing
  305. % boxes, etc.
  306. %
  307. % \end{itemize}
  308. %
  309. % All the environments do is call the main command with appropriate
  310. % arguments.
  311. %
  312. % \subsection{Reading the verbatim text}
  313. %
  314. % \DescribeMacro{\sv@read}
  315. % The main scanning routine is |\sv@read|. It is called with three
  316. % arguments:
  317. %
  318. % \begin{itemize}
  319. %
  320. % \item The end-text marking the end of the environment.
  321. %
  322. % \item The name of a macro (which must be a single token) which is called
  323. % with a line of text as its single argument. This is given each
  324. % line of text which is read from the environment in turn.
  325. %
  326. % \item A macro, or other sort of action, which is to be done when the text
  327. % has been read and processed.
  328. %
  329. % \end{itemize}
  330. %
  331. % The macro |\sv@read| assumes that the caller has already made some
  332. % provision for removing the category codes of the following text, by either
  333. % calling |\@verbatim| or using the construction
  334. % \begin{listing}
  335. %\let\do=\@makeother
  336. %\dospecials
  337. % \end{listing}
  338. %
  339. % \DescribeMacro{\sv@safespc}
  340. % Note that any space characters you read using |\sv@read| will be catcoded
  341. % as |\active|. Normally this is OK because |\obeyspaces| (or
  342. % |\@vobeyspaces|) will be in effect. If you're doing something more exotic,
  343. % like writing text to a file or building a command string, you can call
  344. % |\sv@safespc| which defines the active-space character to be a normal
  345. % whitespace-space when expanded.
  346. %
  347. % \implementation
  348. %
  349. % \section{Implementation}
  350. %
  351. % This section defines several macros and environments which allow verbatim
  352. % typing, with a high degree of configurability. OK, so this sort of
  353. % thing's been done so often before that it isn't true, but I don't really
  354. % care.
  355. %
  356. % \begin{macrocode}
  357. %<*package>
  358. % \end{macrocode}
  359. %
  360. % \subsection{Simple things}
  361. %
  362. % To help us build funny macros which involve strange and different category
  363. % codes, I'll write some simple macros which I can use while building my
  364. % complicated and clever ones.
  365. %
  366. % \begin{macro}{\@cspecials}
  367. %
  368. % This macro is used to assist the definition of some of the environments.
  369. % It makes `|\|', `|{|' and `|}|' into `other' characters, and replaces them
  370. % with `\verb"|"', `|<|' and `|>|' respectively. Note that `|[|' and `|]|'
  371. % aren't used, because they make defining commands which take optional
  372. % arguments awkward. Note that we open a group here. This should be closed
  373. % using \verb"|endgroup" at the end of the special section.
  374. %
  375. % \begin{macrocode}
  376. \def\@cspecials{%
  377. \begingroup%
  378. \catcode`|0%
  379. \catcode`<1%
  380. \catcode`>2%
  381. \catcode`\{12%
  382. \catcode`\}12%
  383. \catcode`\\12%
  384. }
  385. % \end{macrocode}
  386. % \end{macro}
  387. %
  388. % \begin{macro}{\sv@startlisting}
  389. %
  390. % This macro sets everything up nicely for a \env{listing}-type verbatim
  391. % environment.
  392. %
  393. % \begin{macrocode}
  394. \def\sv@startlisting{%
  395. \def\par{\@@par\penalty\interlinepenalty}%
  396. \@@par%
  397. \leftskip\@totalleftmargin%
  398. \obeylines%
  399. \@noligs%
  400. \let\do\@makeother\dospecials%
  401. \verbatim@font%
  402. \frenchspacing%
  403. \@vobeyspaces%
  404. \settabwidth%
  405. \catcode9\active%
  406. \lccode`\~9\lowercase{\let~\sv@vtab}%
  407. \lccode`\~13\lowercase{\let~\vinput@cr}%
  408. \interlinepenalty500%
  409. }
  410. % \end{macrocode}
  411. %
  412. % \end{macro}
  413. %
  414. % \subsection{Tab character handling}
  415. %
  416. % One of the things we want to do here is handle tab characters properly.
  417. % (Here, `properly' means `moving to the next column which is a multiple of
  418. % eight', the way these things were always meant to.)
  419. %
  420. % \begin{macro}{\settabwidth}
  421. %
  422. % The tabs used by our tabbed verbatim environments are set up by this
  423. % routine. It sets the tab width parameter |\svtab| to 8 times the width
  424. % of a |\tt| space. If you really want, you can redefine this macro.
  425. %
  426. % \begin{macrocode}
  427. \newdimen\svtab
  428. \def\settabwidth{\setbox\z@\hbox{\texttt{\space}}\svtab8\wd\z@}
  429. % \end{macrocode}
  430. %
  431. % \end{macro}
  432. %
  433. % \begin{macro}{\sv@vtab}
  434. %
  435. % Here we handle tabs inside verbatim environments. We expect each line to
  436. % be typeset as a box, using something like
  437. %
  438. % \begin{listing}
  439. %\setbox0\hbox{#1}
  440. %\leavevmode
  441. %\box0
  442. %\par
  443. % \end{listing}
  444. %
  445. % The idea is that you make tab active, and set it to this macro. We stop
  446. % the current box, stretch it to the right width, and start another one
  447. % straight after, so nobody know the difference. The code here is straight
  448. % from Appendix~D of \textit{The \TeX book}.
  449. %
  450. % \begin{macrocode}
  451. \def\sv@vtab{%
  452. \hfill\egroup%
  453. \@tempdima\wd\z@%
  454. \divide\@tempdima\svtab%
  455. \multiply\@tempdima\svtab%
  456. \advance\@tempdima\svtab%
  457. \wd\z@\@tempdima%
  458. \leavevmode\box\z@%
  459. \setbox\z@\hbox\bgroup%
  460. }
  461. % \end{macrocode}
  462. %
  463. % \end{macro}
  464. %
  465. % \begin{macro}{\verbinput}
  466. %
  467. % We allow input from a file, by the |\verbinput| command. We display the
  468. % text pretty much the same as the \env{listing} environment below.
  469. %
  470. % We set tab and return active, and get them to do appropriate things. This
  471. % isn't actually all that hard.
  472. %
  473. % \begin{macrocode}
  474. \def\verbinput#1{%
  475. \begin{listinglist}%
  476. \listingsize%
  477. \sv@startlisting%
  478. \setbox\z@\hbox\bgroup%
  479. \input{#1}%
  480. \sv@stripspc%
  481. \egroup%
  482. \ifdim\wd\z@=\z@%
  483. \ifhmode\par\fi%
  484. \else%
  485. \leavevmode\box\z@\par%
  486. \fi%
  487. \end{listinglist}%
  488. }
  489. % \end{macrocode}
  490. %
  491. % \end{macro}
  492. %
  493. % \begin{macro}{\vinput@cr}
  494. %
  495. % This macro handles return characters while inputting text in |\verbinput|.
  496. % We just output our current box, and start another.
  497. %
  498. % \begin{macrocode}
  499. \def\vinput@cr{%
  500. \egroup%
  501. \leavevmode\box\z@%
  502. \par%
  503. \setbox\z@\hbox\bgroup%
  504. }
  505. % \end{macrocode}
  506. %
  507. % \end{macro}
  508. %
  509. % \subsection{Reading verbatim text}
  510. %
  511. % The traditional way of reading verbatim text is to use a delimited
  512. % argument, as described in the \textit{\TeX book}. This works well-ish if
  513. % the text isn't very long. A better solution would be to pick out the text
  514. % line-by-line and process it like that. So this is what we do.
  515. %
  516. % \begin{macro}{\matcher}
  517. %
  518. % For long verbatim environments, we need to be able to find the end text.
  519. % This is rather tricky. The solution here is rather horrible. The
  520. % environment picks out each line of the text at a time, as an argument, and
  521. % tests to see if it contains the text we're after. We do the test in a
  522. % particularly yukky way: we add the actual target text to the end of the
  523. % line, and inspect the text following the match to see if the match is at
  524. % the end.
  525. %
  526. % The |\matcher| macro creates a `matcher' which will test strings to see if
  527. % they contain something interesting.
  528. %
  529. % To create a matcher, say
  530. % \syntax{"\\matcher{"<cmd-name>"}{"<target>"}{"<process-cmd>"}"}. The
  531. % command \synt{cmd-name} accepts a line of text as an argument and calls
  532. % the \synt{process-cmd} with the text of the line before the match, or the
  533. % whole lot. It also sets |\@ifmatched| appropriately.
  534. %
  535. % (Having spent ages coming up with this cruft myself, I found some very
  536. % similar, but slightly better, code in Appendix~D. So I've changed mine to
  537. % match Donald's. Anyway, credit where it's due: cheers Don.)
  538. %
  539. % \begin{macrocode}
  540. \newif\if@matched
  541. \def\matcher#1#2#3{%
  542. \expandafter\def\csname\string#1$match\endcsname##1#2##2##3\end{%
  543. \ifx##2\relax%
  544. \@matchedfalse%
  545. \else%
  546. \@matchedtrue%
  547. \fi%
  548. #3{##1}%
  549. }%
  550. \expandafter\def\expandafter#1\expandafter##\expandafter1\expandafter{%
  551. \csname\string#1$match\endcsname##1#2\relax\end%
  552. }%
  553. }
  554. % \end{macrocode}
  555. %
  556. % \end{macro}
  557. %
  558. % \begin{macro}{\sv@stripspc}
  559. %
  560. % This macro strips any trailing glue in the current horizontal list. This
  561. % is fairly simple, actually: we just loop while glue is the last item. It's
  562. % slightly complicated by penalties which \TeX\ puts into the list between
  563. % the glue items, but we just remove them too.
  564. %
  565. % \begin{macrocode}
  566. \def\sv@stripspc{%
  567. \unpenalty%
  568. \ifdim\lastskip=\z@\else%
  569. \unskip\expandafter\sv@stripspc%
  570. \fi%
  571. }
  572. % \end{macrocode}
  573. %
  574. % \end{macro}
  575. %
  576. % \begin{macro}{\sv@percent}
  577. %
  578. % This macro strips a single leading percent character if there is one, and
  579. % if the \env{doc} package is loaded. We store the possibly stripped text in
  580. % |\@tempa|.
  581. %
  582. % \begin{macrocode}
  583. \begingroup
  584. \catcode`\%=12
  585. \gdef\sv@percent#1#2\relax
  586. {\ifx\check@percent\@@undefined
  587. \ifx#1\relax\def\@tempa{}\else
  588. \def\@tempa{#1#2}\fi\else
  589. \ifx#1\relax\def\@tempa{}\else
  590. \ifx#1%\def\@tempa{#2}\else
  591. \def\@tempa{#1#2}\fi\fi\fi}
  592. \endgroup
  593. % \end{macrocode}
  594. %
  595. % \end{macro}
  596. %
  597. % \begin{macro}{\@isspaces}
  598. %
  599. % We want to avoid writing the first and last lines of the environment to the
  600. % file if there's nothing in them. To do this, we need to know whether a
  601. % piece of text contains only space characters. This macro does this, in a
  602. % rather nasty way. See the other macros below for details of how this
  603. % works.
  604. %
  605. % We define |\sv@safespc| at the same time: this makes space active and
  606. % expand to a space character which is not active. Neat, huh?
  607. %
  608. % \begin{macrocode}
  609. \lccode`\~32
  610. \lccode`\!32
  611. \lowercase{%
  612. \def\@isspaces#1{%
  613. \ifx#1\relax%
  614. \def\@tempb{\@tempswafalse}%
  615. \else\ifx#1~%
  616. \let\@tempb\@isspaces%
  617. \else%
  618. \def\@tempb##1\relax{}%
  619. \fi\fi%
  620. \@tempb%
  621. }
  622. \def\sv@safespc{%
  623. \catcode32\active%
  624. \def~{ }%
  625. }
  626. }
  627. % \end{macrocode}
  628. %
  629. % \end{macro}
  630. %
  631. % \begin{macro}{\sv@read}
  632. %
  633. % This macro does the main job of reading a chunk of verbatim text. You call
  634. % it like this:
  635. %
  636. % \begin{quote}
  637. % \syntax{"\\sv@read{"<end-text>"}{"<process-line-proc>"}{"<end-proc>"}"}
  638. % \end{quote}
  639. %
  640. % The \synt{end-text} is the text to find at the end of the `environment': we
  641. % stop when we find it.
  642. %
  643. % The \synt{process-line-proc} is a macro which is passed as an argument each
  644. % line which we read from the text.
  645. %
  646. % The \synt{end-proc} is a macro to call once we've finished reading all of
  647. % the text. This can tidy up an environment or close a file or whatever.
  648. %
  649. % We read the text by picking out newlines using a delimited macro. We have
  650. % to be a little clever, because newlines are active in verbatim text.
  651. %
  652. % We will also strip `|%|' signs off the beginning if the \package{doc}
  653. % package is here (\package{doc} tries to play with \LaTeX's verbatim stuff,
  654. % and doesn't understand the way we do things).
  655. %
  656. % \begin{macrocode}
  657. \def\sv@read#1#2#3{%
  658. % \end{macrocode}
  659. %
  660. % This code does all sorts of evil things, so I'll start by opening a group.
  661. %
  662. % \begin{macrocode}
  663. \begingroup%
  664. % \end{macrocode}
  665. %
  666. % So that I can spot the end-text, I'll create a matcher macro.
  667. %
  668. % \begin{macrocode}
  669. \matcher\@match{#1}\sv@read@ii%
  670. % \end{macrocode}
  671. %
  672. % So that I can identify line ends, I'll make them active. I'll also make
  673. % spaces active so that they can expand to whatever they ought to expand
  674. % to (spaces in files, or funny \verb*" " characters or whatever.
  675. %
  676. % \begin{macrocode}
  677. \catcode13\active%
  678. \catcode32\active%
  679. % \end{macrocode}
  680. %
  681. % I'll use the |\if@tempswa| flag to tell me whether I ought to output the
  682. % current line. This is a little messy, so I'll describe it later. I'll
  683. % initialise it to false because this is the correct thing to do.
  684. %
  685. % \begin{macrocode}
  686. \@tempswafalse%
  687. % \end{macrocode}
  688. %
  689. % Most of the job is done by two submacros. I'll define them in terms of
  690. % my current arguments (to save lots of token munging). The first just
  691. % extracts the next line (which ends at the next newline character) and
  692. % tries to match it.
  693. %
  694. % \begin{macrocode}
  695. \lccode`\~13\lowercase{%
  696. \def\sv@read@i##1~{\@match{##1}}%
  697. }%
  698. % \end{macrocode}
  699. %
  700. % The results of the match get passed here, along with the text of the
  701. % line up to the matched text.
  702. %
  703. % \begin{macrocode}
  704. \def\sv@read@ii##1{%
  705. % \end{macrocode}
  706. %
  707. % The first job to do is to maybe strip off percent signs from the beginning,
  708. % to keep \package{doc} happy.
  709. %
  710. % \begin{macrocode}
  711. \sv@percent##1\relax\relax%
  712. % \end{macrocode}
  713. %
  714. % Now I need to decide whether I ought to output this line. The method goes
  715. % like this: if this is the first line (|\if@tempswa| is false) or the last
  716. % (|\if@matched| is true), \emph{and} the text consists only of spaces, then
  717. % I'll ignore it.
  718. %
  719. % The first thing to do is to notice the last line -- if |\if@matched| is
  720. % true, then I'll make |\if@tempswa| false to make the first-line and
  721. % last-line cases work the same way.
  722. %
  723. % \begin{macrocode}
  724. \if@matched\@tempswafalse\fi%
  725. % \end{macrocode}
  726. %
  727. % Now if this is the first or last line, I'll examine it for spaces. This
  728. % is done in a separate macro. It will set |\if@tempswa| false if the
  729. % text contains only spaces.
  730. %
  731. % \begin{macrocode}
  732. \if@tempswa\else\@tempswatrue\expandafter\@isspaces\@tempa\relax\fi%
  733. % \end{macrocode}
  734. %
  735. % Now, if |\if@tempswa| is still true, perform the \<process-line-proc> on
  736. % the line of text. I'll provide a group, so that it doesn't upset me
  737. % too much.
  738. %
  739. % \begin{macrocode}
  740. \if@tempswa%
  741. \begingroup%
  742. \expandafter#2\expandafter{\@tempa}%
  743. \endgroup%
  744. \fi%
  745. % \end{macrocode}
  746. %
  747. % The next line won't be the first one, so I'll set the flag true in
  748. % readiness.
  749. %
  750. % \begin{macrocode}
  751. \@tempswatrue%
  752. % \end{macrocode}
  753. %
  754. % Now, if that wasn't the last line, go round again; otherwise end the group
  755. % I started ages ago, and do the user's \<end-proc>.
  756. %
  757. % \begin{macrocode}
  758. \if@matched\def\@tempa{\endgroup#3}\else\let\@tempa\sv@read@i\fi%
  759. \@tempa%
  760. }%
  761. % \end{macrocode}
  762. %
  763. % Now to start the thing up. I'll read the first line.
  764. %
  765. % \begin{macrocode}
  766. \sv@read@i%
  767. }
  768. % \end{macrocode}
  769. %
  770. % \end{macro}
  771. %
  772. % \begin{macro}{\sv@readenv}
  773. %
  774. % This macro works out an appropriate end-text for the current environment.
  775. % If you say \syntax{"\\sv@readenv{"<macro-name>"}"}, it will expand do
  776. % \begin{listinglist} \listingsize \synshorts
  777. % <macro-name>"{\\"$_{12}$"end{"$_{12}$<current-env-name>"}"$_{12}$"}"^^A
  778. % "{\\end{"<current-env-name>"}}"
  779. % \end{listinglist}
  780. % Easy, no?
  781. %
  782. % This is all done with mirrors. No, err\dots\ it's done with
  783. % |\expandafter|.
  784. %
  785. % \begin{macrocode}
  786. \begingroup
  787. \lccode`\<=`\{
  788. \lccode`\>=`\}
  789. \lccode`\|=`\\
  790. \lowercase{\endgroup
  791. \def\sv@readenv#1{%
  792. \expandafter\expandafter\expandafter%
  793. #1\expandafter\sv@readenv@i\@currenvir\@@%
  794. }
  795. \def\sv@readenv@i#1\@@{{|end<#1>}{\end{#1}}}
  796. }
  797. % \end{macrocode}
  798. %
  799. % \end{macro}
  800. %
  801. % \begin{macro}{\sv@verbline}
  802. %
  803. % This macro typesets a line in a verbatim way, so you can construct a real
  804. % verbatim environment from it. It's a bit tricky in the way that it catches
  805. % the last line. Don't worry about this: it's easy really. Note the
  806. % |\relax| after the |\par| -- this is because \package{doc} tries to do
  807. % clever things with |\par| to strip `|%|' signs out.
  808. %
  809. % \begin{macrocode}
  810. \def\sv@verbline#1{%
  811. \setbox\z@\hbox{#1\sv@stripspc}%
  812. \ifdim\wd\z@=\z@%
  813. \if@matched\ifhmode\par\relax\fi\else\leavevmode\par\relax\fi%
  814. \else%
  815. \leavevmode\box\z@\par\relax%
  816. \fi%
  817. }
  818. % \end{macrocode}
  819. %
  820. % \end{macro}
  821. %
  822. % \subsection{Listing environments}
  823. %
  824. % The \env{listing} environment is our equivalent of the standard
  825. % \env{verbatim} environment. We do some slightly cleverer things, though,
  826. % to make sure (for example) that even text which contains |\end{listing}|
  827. % can be typeset.
  828. %
  829. % \begin{macro}{\listinglist}
  830. % \begin{environment}{listinglist}
  831. %
  832. % This defines the layout for the \env{listing} environment. It starts a
  833. % list with the appropriate shape. It's also made into an environment, so
  834. % that the end-paragraph-environment bits work correctly.
  835. %
  836. % The |\listingindent| length parameter sets up the indentation of the
  837. % listings. If there's a |\parindent| setting, I'll line listings up with
  838. % that; otherwise I'll just choose something which looks right.
  839. %
  840. % \begin{macrocode}
  841. \newdimen\listingindent
  842. \AtBeginDocument{%
  843. \ifdim\parindent=\z@\listingindent1em\else\listingindent\parindent\fi%
  844. }
  845. % \end{macrocode}
  846. %
  847. % Now to define a size hook for the environment. This is fairly simple
  848. % stuff.
  849. %
  850. % \begin{macrocode}
  851. \ifx\listingsize\@@undefined
  852. \let\listingsize\small
  853. \fi
  854. % \end{macrocode}
  855. %
  856. % Now to define the environment itself. Suppress the indentation if we're
  857. % first thing on a new list item, so that the listing lines up with
  858. % everything else.
  859. %
  860. % \begin{macrocode}
  861. \def\listinglist{%
  862. \list{}{%
  863. \if@inlabel%
  864. \leftmargin\z@%
  865. \else%
  866. \leftmargin\listingindent%
  867. \fi%
  868. \rightmargin\z@%
  869. \labelwidth\z@%
  870. \labelsep\z@%
  871. \itemindent\z@%
  872. \listparindent\z@%
  873. \let\makelabel\relax%
  874. \parsep\z@skip%
  875. }%
  876. \parfillskip\@flushglue%
  877. \item\relax%
  878. }
  879. \let\endlistinglist\endlist
  880. % \end{macrocode}
  881. %
  882. % \end{environment}
  883. % \end{macro}
  884. %
  885. % \begin{environment}{listing}
  886. %
  887. % The \env{listing} environment is the only real verbatim-like environment we
  888. % create will all this kit, although it does the job very nicely.
  889. %
  890. % The environment indents its contents slightly, unlike \env{verbatim}, and
  891. % uses a smaller typeface in an attempt to fit 77-column text on an A5~page.
  892. % There is also a $*$-variant, which allows you to specify the terminating
  893. % text. This enables you to include absolutely any text in the environment,
  894. % including |\end{listing}|.
  895. %
  896. % First, we must define the |\listing| command.
  897. %
  898. % \begin{macrocode}
  899. \def\listing{%
  900. \listinglist%
  901. \listingsize%
  902. \sv@readenv\sv@listing%
  903. }
  904. % \end{macrocode}
  905. %
  906. % Now we define the |\@listing| command, which does most of the work. We
  907. % base the \env{listing} environment on a \env{list}.
  908. %
  909. % \begin{macrocode}
  910. \def\sv@listing#1#2{%
  911. \sv@startlisting%
  912. \sv@read{#1}\sv@verbline{\endlistinglist#2}%
  913. }
  914. % \end{macrocode}
  915. %
  916. % Now we define the starred version. The command name needs to include the
  917. % `|*|' character, so we must use |\csname|. There's some hacking here to
  918. % allow us to read the name using the appropriate catcodes for otherwise
  919. % normal characters: \LaTeX\ activates some characters and makes them typeset
  920. % themselves to suppress some ligaturing.
  921. %
  922. % \begin{macrocode}
  923. \expandafter\def\csname listing*\endcsname{%
  924. \listinglist%
  925. \listingsize%
  926. \begingroup%
  927. \@noligs%
  928. \def\@tempa##1{\endgroup\sv@listing{##1}{\end{listing*}}}%
  929. \@tempa%
  930. }
  931. % \end{macrocode}
  932. %
  933. % \end{environment}
  934. %
  935. % \begin{environment}{ignore}
  936. %
  937. % The \env{ignore} environment entirely ignores its contents. Anything at
  938. % all may be put into the environment: it is discarded utterly.
  939. %
  940. % We define some macros for defining ignoring environments, because this can
  941. % be useful for version control, possibly.
  942. %
  943. % \begin{macrocode}
  944. \def\sv@ignore#1#2{%
  945. \@bsphack%
  946. \let\do\@makeother\dospecials%
  947. \sv@read{#1}\@gobble{\@esphack#2}%
  948. }
  949. \def\ignore{\sv@readenv\sv@ignore}
  950. \def\ignoreenv#1{%
  951. \expandafter\let\csname #1\endcsname\ignore%
  952. }
  953. \def\unignoreenv#1{%
  954. \expandafter\def\csname #1\endcsname{\endgroup}%
  955. \expandafter\def\csname end#1\endcsname%
  956. {\begingroup\def\@currenvir{#1}}%
  957. }
  958. % \end{macrocode}
  959. %
  960. % \end{environment}
  961. %
  962. % \subsection{The \env{verbwrite} environment}
  963. %
  964. % The \env{verbwrite} environment allows text to be written to a file in a
  965. % verbatim way. Note that tab characters don't work, because \TeX\ refuses
  966. % to be nice.
  967. %
  968. % \begin{macro}{\sv@write}
  969. %
  970. % As seems to be traditional now, we first define a general hookable macro
  971. % which allows a caller to specify the end-text and what to do afterwards.
  972. %
  973. % \begin{macrocode}
  974. \newwrite\sv@writefile
  975. \def\sv@write#1#2{%
  976. \begingroup%
  977. \@bsphack%
  978. \let\do\@makeother\dospecials%
  979. \sv@safespc%
  980. \sv@read{#1}\sv@writeline{\sv@endwrite#2}%
  981. }
  982. \def\sv@writeline#1{%
  983. \immediate\write\sv@writefile{#1}%
  984. }
  985. \def\sv@endwrite{%
  986. \@esphack%
  987. \endgroup%
  988. }
  989. % \end{macrocode}
  990. %
  991. % \end{macro}
  992. %
  993. % \begin{environment}{verbwrite}
  994. %
  995. % Now we can define the actual environment. We define a $*$-variant which
  996. % allows the user to specify the end-text, just to make sure.
  997. %
  998. % \begin{macrocode}
  999. \def\verbwrite#1{%
  1000. \immediate\openout\sv@writefile#1\relax%
  1001. \sv@readenv\sv@write%
  1002. }
  1003. \def\endverbwrite{\immediate\closeout\sv@writefile}
  1004. \expandafter\def\csname verbwrite*\endcsname#1#2{%
  1005. \immediate\openout\sv@writefile#2\relax%
  1006. \sv@write{#1}{\immediate\closeout\sv@writefile\end{verbwrite*}}%
  1007. }
  1008. % \end{macrocode}
  1009. %
  1010. % \end{environment}
  1011. %
  1012. % \subsection{The \env{demo} environment}
  1013. %
  1014. % By way of tying all of this together, I present an environment for
  1015. % displaying demonstrations of \LaTeX\ markup. We read the contents of the
  1016. % environment, write it to a temporary file, and read it back twice,
  1017. % typesetting it the first time and displaying it verbatim the second time.
  1018. %
  1019. % \begin{macro}{\sv@demoname}
  1020. %
  1021. % This macro expands to the filename to use for the temporary data. To
  1022. % allow the package documentation to demonstrate the \env{demo} environment
  1023. % itself, we need to keep a nesting count. This avoids too much hackery,
  1024. % which unfortunately appears to plague all of my \TeX\ code.
  1025. %
  1026. % \begin{macrocode}
  1027. \newcount\sv@nestcount
  1028. \def\sv@demoname{demo\number\[email protected]}
  1029. % \end{macrocode}
  1030. %
  1031. % \end{macro}
  1032. %
  1033. % \begin{macro}{\sv@demo}
  1034. %
  1035. % As for listing, we do all the business through a private macro. This is
  1036. % good because it means we can leave the main macro readable. The argument
  1037. % is the end-text to spot.
  1038. %
  1039. % \begin{macrocode}
  1040. \def\sv@demo#1#2{%
  1041. \@ifnextchar[{\sv@demo@i{#1}{#2}}{\sv@demo@i{#1}{#2}[n]}%
  1042. }
  1043. \def\sv@demo@i#1#2[#3]#4{%
  1044. \advance\sv@nestcount by\@ne%
  1045. \immediate\openout\sv@writefile\sv@demoname\relax%
  1046. \sv@write{#1}{%
  1047. \immediate\closeout\sv@writefile%
  1048. \sv@dodemo{#2}{#3}{#4}%
  1049. }%
  1050. }
  1051. % \end{macrocode}
  1052. %
  1053. % \end{macro}
  1054. %
  1055. % \begin{environment}{demo}
  1056. %
  1057. % This is the real environment. We provide \env{demo$*$} too, to allow the
  1058. % user to choose the end-text.
  1059. %
  1060. % \begin{macrocode}
  1061. \def\demo{\sv@readenv\sv@demo}
  1062. \expandafter\def\csname demo*\endcsname#1{\sv@demo{#1}{\end{demo*}}}
  1063. % \end{macrocode}
  1064. %
  1065. % \end{environment}
  1066. %
  1067. % \begin{macro}{\sv@dodemo}
  1068. %
  1069. % First, let's define some common bits of code in the stuff below. The
  1070. % minipages used to typeset the material has some clever stuff to avoid
  1071. % strange spacing in the output.
  1072. %
  1073. % \begin{macrocode}
  1074. \def\sv@demosmp{%
  1075. \begin{minipage}[t]{\@tempdima}%
  1076. \vskip8\p@%
  1077. \hrule\@height\z@%
  1078. \raggedright%
  1079. \vbox\bgroup%
  1080. }
  1081. \def\sv@demoemp{%
  1082. \par\unpenalty\unskip%
  1083. \egroup%
  1084. \vskip8\p@%
  1085. \hrule\@height\z@%
  1086. \end{minipage}%
  1087. }
  1088. % \end{macrocode}
  1089. %
  1090. % This is the macro which actually typesets the demonstration.
  1091. %
  1092. % \begin{macrocode}
  1093. \def\sv@dodemo#1#2#3{%
  1094. % \end{macrocode}
  1095. %
  1096. % Now work out some values. We set |\hsize| to the line width leaving 2\,em
  1097. % of space on either side. The size of the minipages is calculated depending
  1098. % on the shape of the demonstration. This is all fairly simple.
  1099. %
  1100. % \begin{macrocode}
  1101. \begingroup%
  1102. \@tempdima\linewidth%
  1103. \advance\@tempdima-2em%
  1104. \hsize\@tempdima%
  1105. \if#2w%
  1106. \advance\@tempdima-2em%
  1107. \else%
  1108. \advance\@tempdima-3em%
  1109. \divide\@tempdima2%
  1110. \fi%
  1111. % \end{macrocode}
  1112. %
  1113. % Now we open a big vertical box, and put in a header to mark off the
  1114. % demonstration.
  1115. %
  1116. % \begin{macrocode}
  1117. \par%
  1118. \setbox\z@\hbox{\strut\enspace#3\enspace\strut}%
  1119. \@tempdimb.5\dp\z@%
  1120. \advance\@tempdimb-.5\ht\z@%
  1121. \ht\z@\@tempdimb\dp\z@\@tempdimb%
  1122. \noindent\hskip1em\vtop{%
  1123. \hb@xt@\hsize{%
  1124. \hrulefill%
  1125. \raise\@tempdimb\box\z@%
  1126. \hrulefill%
  1127. }%
  1128. \nointerlineskip%
  1129. \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
  1130. \nointerlineskip%
  1131. % \end{macrocode}
  1132. %
  1133. % Now we insert the output text in the first minipage. I'll force `|%|'
  1134. % to be a comment character, in case something like \package{doc} has had its
  1135. % wicked way.
  1136. %
  1137. % \begin{macrocode}
  1138. \vskip-\parskip%
  1139. \noindent\hbox{}\hskip1em%
  1140. \sv@demosmp%
  1141. \catcode`\%14\relax%
  1142. \input{\sv@demoname}%
  1143. \sv@demoemp%
  1144. % \end{macrocode}
  1145. %
  1146. % Insert some kind of separation between the two. In `wide' format, we start
  1147. % a new line, and put a ruleoff between the two. In `narrow' format, we just
  1148. % leave some space.
  1149. %
  1150. % \begin{macrocode}
  1151. \if#2w%
  1152. \vskip8\p@\hrule\vskip8\p@%
  1153. \noindent\hbox{}%
  1154. \fi%
  1155. \hskip1em%
  1156. % \end{macrocode}
  1157. %
  1158. % Now we put the verbatim copy of the text in the other minipage.
  1159. %
  1160. % \begin{macrocode}
  1161. \sv@demosmp%
  1162. \listingindent\z@%
  1163. \verbinput\sv@demoname%
  1164. \sv@demoemp%
  1165. \par%
  1166. \nointerlineskip%
  1167. \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
  1168. \hrule%
  1169. }%
  1170. \endgroup%
  1171. \par%
  1172. \vskip\baselineskip%
  1173. #1%
  1174. }
  1175. % \end{macrocode}
  1176. %
  1177. % \end{macro}
  1178. %
  1179. % That's all there is. Have fun.
  1180. %
  1181. % \begin{macrocode}
  1182. %</package>
  1183. % \end{macrocode}
  1184. %
  1185. % \hfill Mark Wooding, \today
  1186. %
  1187. % \Finale
  1188. %
  1189. \endinput