% dolines.doc --- version 1.0 (15 April 1991) % This is the documentation for dolines.tex. % To read this file, process it with (plain) TeX: tex dolines.doc % (To do that, you need manmac.tex, which has % the macros for typesetting the TeXbook, as explained in appendix E. % It comes free with the standard distribution of TeX.) % % NOTE: Processing this file with TeX will create empty files % index.tex and answers.tex in your directory. And if you % have a file pages.tex in your directory, TeX will probably % get very confused. % The manmac format will try to load a font called cmman; if % TeX complains that it cannot find that font you can savely % ignore that, since the font is not actually used. % % This file: copyright (c) 1991 Marcel van der Goot. % You may redistribute this file and printed versions of it. % % original: csvax.cs.caltech.edu [131.215.131.131] in pub/tex % (use anonymous ftp). Also in various archives. % % Marcel van der Goot % marcel@cs.caltech.edu % Caltech 256--80 % Pasadena, CA 91125 % (818) 356--4603 % ------ definitions for manual pages: % The documentation is typeset using Knuth's ``manmac'' macros, with a % few additional things defined here. You are free to use or adapt these % extra definitions. \input manmac % the macros used for typesetting The TeXbook (appendix E) \catcode`^=7 % manmac makes ^ active for creating an index % we don't make an index, and we need ^ to be non-active {\catcode`\^^M=12 \endlinechar=-1 % 12 = other \long\gdef\manpagehead#1^^M#2^^M#3^^M^^M% tex-file, description, version {\egroup % matches \bgroup in \manpage \par\vfill\eject \edef\rhead{\manualname: #1\unskip}% \setbox1=\hbox{\titlefont #1\quad}% \setbox3=\vtop{\advance\hsize by-\wd1 \parindent=0pt \raggedright #2\par #3\par \cnotice }% \line{\box1\box3}% \bigskip\bigskip\bigskip\noindent }% } % restore \catcode`\^^M \outer\def\manpage {\bgroup\catcode`\^^M=12 \manpagehead } \hsize=6.5in\vsize=8.9in % default plain TeX values \pagewidth=\hsize \pageheight=\vsize \def\cnotice{Copyright \copyright\ 1991 Marcel R. van der Goot} \def\manualname{Midnight Macros} % LaTeX logo, from latex.tex (except for the capital `A': manmac % doesn't have a real smallcaps font) \def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc A}\kern-.15em T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} \tenpoint % (end of extra definitions) % -------------------- dolines.doc: \pageno=9 % follows loop.doc \manpage dolines.tex Meta-macros to separate arguments by newlines and by empty lines. Version: 1.0 (15 April 1991) (doc: 15 Apr 1991) The macros in dolines.tex are intended to help you write your own macros, rather than to typeset text directly. Consequently, it is assumed that you have some experience writing macros; in other words, assume that this whole section is preceded by a ``dangerous bend'' symbol. Dolines.tex\footnote*{To use dolines.tex you also need Midnight/loop.tex, which will be |\input| when you |\input dolines|.} helps to write macros for which line breaks inserted by the user are important. When the definitions from dolines.tex are in effect, text consists of paragraphs separated by one or more empty lines (as usual). Each paragraph consist of one or more lines, where a line is terminated by a normal newline character, `|^^M|' (normally, \TeX\ treats newlines as if they are spaces). Note that, as far as dolines.tex is concerned, a paragraph can only be terminated by an empty line, not by, e.g., |\par| or |\vskip|. To use dolines.tex, you have to define three macros, |\beforelines|, |\everyline#1|, and |\afterlines|. When dolines.tex detects the beginning of a paragraph, |\beforelines| is called. Next, for every line, |\everyline| is called with as argument a single macro. That macro has as its expansion the line that was read. (Usually, this is almost the same as saying that |\everyline| is called with the line as argument.) After the last line of the paragraph, |\afterlines| is called. No output is generated, other than what is produced by your own macros. {\def\fnm{\<\rm file name>} There are two ways of using dolines.tex. One is to read lines from a file, the other is to take the lines from the current input file. If you say \begintt \filedolines{|fnm} \endtt dolines.tex will attempt to read the file, calling |\beforelines|, |\everyline|, and |\afterlines| as described above. The file is read inside a group, so you may need to use |\global| if you do assignments within, e.g., |\everyline|. }% \fnm As an example, we define a ``poetry environment'' which reads a poem from a file, preserving the poet's line breaks. We draw horizontal lines around the poem, and put every stanza in a vbox to prevent page breaks. (It is certainly possible to write better poetry environments, we are just illustrating dolines.tex.) \beginlines |\input dolines| \nobreak\smallskip\nobreak |\def\readpoem#1{\medskip \hrule \filedolines{#1}\hrule \medskip}| \smallbreak |\def\beforelines{\medskip \vbox\bgroup}| |\def\everyline#1{\hbox{\kern\parindent \it #1}}| |\def\afterlines{\egroup \medskip} % end of the vbox| \endlines If file ``epic.tex'' contains a poem, we can typeset it with |\readpoem{epic}|. However, if you are typesetting several short rhymes, it is somewhat inconvenient to have each of them in a separate file. This is where the second method of using dolines.tex is useful. You have to define a macro |\enddolines|, the expansion of which should be the text you want to use to terminate dolines.tex's effect. You also have to define a macro |\finishdolines|. When you say |\begindolines|, dolines.tex starts reading lines, calling |\everyline| etc. This continues until dolines.tex reads a line equal to the (top level) expansion of |\enddolines|. Then your macro |\finishdolines| is called, and \TeX\ resumes normal processing. |\begindolines| and the line equal to |\enddolines| form a group (as with |\filedolines|); |\finishdolines| is called {\sl outside} this group. Here is how we can extend the poetry environment with two control sequences |\beginpoem| and |\endpoem|. We keep the above definitions of |\beforelines| etc. \beginlines |\def\beginpoem{\medskip \hrule \begindolines}| |\def\enddolines{\endpoem}| |\def\finishdolines{\hrule \medskip}| \endlines Now we can typeset a poem as follows (the English stanza is from The \TeX book): \beginlines |\beginpoem| \nobreak\medskip\nobreak |Roses are red,| |\quad Violets are blue;| |Rhymes can be typeset| |\quad With boxes and glue.| \nobreak\medskip\nobreak |Blauw de viooltjes,| |\quad Rood zijn de rozen;| |Een rijm kan gezet| |\quad Met plaksel en dozen.| \nobreak |\endpoem| \endlines Note that we never defined |\endpoem|, as it is never expanded. In fact, there is no reason to terminate the poem with a control sequence. If we define |\def\enddolines{***}|, three stars on a single line will play the r\^ole of |\endpoem| above. \danger There are a few things to be careful about. First, a line must have properly nested |{...}| groups. (Because a line is read as an argument delimited by a \ character.) You should not use this to fold long lines, because that will insert an explicit \ character with catcode 12 in the line. Second, spaces at the beginning of a line are skipped, unless you change the catcode of `\]'. This means that, for instance, there can be spaces in front of |\endpoem|. (Spaces are skipped at the beginning of a line because at that point \TeX\ is in ``state N'' --- see Chapter 8 of The \TeX book.) Third, when |\everyline| is called, the line that is its argument is already tokenized. This means that a catcode change within |\everyline| cannot effect this line. Furthermore, when |\beforelines| is called, the first line is already read and tokenized. \danger |\filedolines| and |\begindolines| treat lines in pretty much the same way. There is however a significant difference in the way comments are treated. If a line has a comment (i.e., it ends with `|%...|'), |\begindolines| will miss the \ at the end of the line. This is normal for \TeX, it can be used to fold long lines. However, if you are using |\filedolines|, comments will be skipped, but lines are not concatenated: |\filedolines| will not miss the \! (This is because |\filedolines| uses \TeX's |\read| primitive.) A rather obscure difference is that a line consisting of just `|\par|' is read as an empty line by |\filedolines|, whereas it is read as a non-empty line by |\begindolines|. If you want to use |\begindolines| to read from a file, you can say |\expandafter\begindolines\input ...|. It is possible for |\finishdolines| to take arguments, but they have to appear on the line following the line with the expansion of |\enddolines|. Suppose we change the poem environment by defining |\finishdolines| as \begintt \def\finishdolines#1% {\line{\strut \hss --- #1\hss\hss}\hrule \medskip} \endtt Hence, |\finishdolines| will print the author's name under the poem. The argument should be written on the line following |\endpoem|: \begintt \beginpoem ... \endpoem {A.U. Thor} \endtt Sometimes we want to use dolines.tex to read just one paragraph by making |\enddolines| equal to an empty line. For instance, a macro |\address| which reads an address terminated by an empty line. The problem with defining |\def\enddolines{}| is that if there is an empty line before the address (or even if the rest of the line after |\address| is empty), no lines will be read at all. To ensure that at least one paragraph is read, we use |\beforelines| to define |\enddolines|: \begintt \def\beforelines{\normalbeforelines\def\enddolines{}} \let\enddolines=\relax \endtt Here, |\normalbeforelines| denotes whatever must be done at the beginning of the address. Initially |\enddolines| is equal to |\relax|, but as soon as the first non-empty line is found, |\enddolines| is redefined as an empty line. Following that, an empty line causes calls of |\afterlines| and |\finishdolines|. (A way to include an empty line in the address is to write a tie (`|~|') on a line of its own.) \danger As a more complicated example, we design a simple verbatim environment. The verbatim environment treats horizontal tabs as spaces, and considers multiple empty lines equal to a single empty line. We first write macros |\setupverbatim| and |\finishverbatim|. The first sets up the character codes for verbatim printing, the second resets those character codes. \beginlines |\def\setupverbatim| \nobreak | {\medskip \hrule \bgroup| | \def\do##1{\catcode`##1=12 }\dospecials| | \obeyspaces \tt| | }| \medskip |\def\finishverbatim{\egroup \hrule \medskip}| \medskip |{\obeyspaces\global\let|\]|=\|\]|}| \endlines Grouping is used to keep the catcode changes local. Plain \TeX's |\dospecials| macro applies the macro |\do| to all special characters (`|\|', `|$|', etc.), which, in this case, gives them all catcode 12 (``other''). But we don't want catcode 12 for spaces, because the |\tt| font has a visible space character `\]'. Therefore, spaces are made active with |\obeyspaces|, and in the last line we make an active space equal to \hbox{|\|\]}. To start setting verbatim text, we use |\beginverbatim|; |\readverbatim| is used to typeset a whole file in verbatim mode. The macros for typesetting lines and paragraphs are very straightforward. \beginlines |\def\beginverbatim{\setupverbatim\begindolines}| |\let\finishdolines=\finishverbatim| \medbreak |\def\readverbatim#1{\setupverbatim\filedolines{#1}\finishverbatim}| \medbreak |\def\beforelines{\smallskip}| |\def\everyline#1{\hbox{\strut #1}}| \nobreak |\def\afterlines{\smallskip}| \endlines Finally, we have to define |\enddolines|. We want to match |\beginverbatim| with |\endverbatim|, so we would like to do \begintt \def\enddolines{\endverbatim} \endtt The problem is that this makes |\enddolines| expand to the {\sl control sequence} |\endverbatim|. But while we are in verbatim mode, no control sequences are recognized, because `|\|' is not an escape character. What we really want is to make the expansion of |\enddolines| equal to the {\sl string} ``$\backslash$endverbatim''. This is done by temporarily making `|\|' a normal character and `|/|' an escape character: \beginlines |{\catcode`\/=0 /catcode`/\=12| | /gdef/enddolines{\endverbatim}| \nobreak |}| \endlines This completes the verbatim environment. Note that |\endverbatim| is only recognized if it appears on a line by its own and is not preceded by spaces. If you are not afraid of confusion, you can change the name |\finishverbatim| to |\endverbatim|. \bye