sverb.dtx 35 KB

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