chiark / gitweb /
slowbox.dtx: Mention that `\newslowboxenv' handles optional args correctly.
[mdwtools] / poetry.dtx
1 % \begin{meta-comment}
2 %
3 % poetry.dtx
4 %
5 % Sophisticated typesetting of poetry
6 %
7 % (c) 1996 Mark Wooding
8 %
9 % \end{meta-comment}
10 %
11 % \begin{meta-comment} <general public licence>
12 %%
13 %% poetry package -- sophisticated typesetting of poetry
14 %% Copyright (c) 1996 Mark Wooding
15 %%
16 %% This program is free software; you can redistribute it and/or modify
17 %% it under the terms of the GNU General Public License as published by
18 %% the Free Software Foundation; either version 2 of the License, or
19 %% (at your option) any later version.
20 %%
21 %% This program is distributed in the hope that it will be useful,
22 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
23 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 %% GNU General Public License for more details.
25 %%
26 %% You should have received a copy of the GNU General Public License
27 %% along with this program; if not, write to the Free Software
28 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 %%
30 % \end{meta-comment}
31 %
32 % \begin{meta-comment} <Package preambles>
33 %<+package>\NeedsTeXFormat{LaTeX2e}
34 %<+package>\ProvidesPackage{poetry}
35 %<+package>                [1996/05/28 1.00 Poetry typesetting]
36 % \end{meta-comment}
37 %
38 % \CheckSum{593}
39 %% \CharacterTable
40 %%  {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
41 %%   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
42 %%   Digits        \0\1\2\3\4\5\6\7\8\9
43 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
44 %%   Dollar        \$     Percent       \%     Ampersand     \&
45 %%   Acute accent  \'     Left paren    \(     Right paren   \)
46 %%   Asterisk      \*     Plus          \+     Comma         \,
47 %%   Minus         \-     Point         \.     Solidus       \/
48 %%   Colon         \:     Semicolon     \;     Less than     \<
49 %%   Equals        \=     Greater than  \>     Question mark \?
50 %%   Commercial at \@     Left bracket  \[     Backslash     \\
51 %%   Right bracket \]     Circumflex    \^     Underscore    \_
52 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
53 %%   Right brace   \}     Tilde         \~}
54 %%
55 %
56 % \begin{meta-comment}
57 %
58 %<*driver>
59 \input{mdwtools}
60 \describespackage{poetry}
61 \def\todo#1{%
62   \par\bigskip\noindent%
63   \fbox{\dimen0\hsize\advance\dimen0-2\fboxsep%
64         \parbox{\dimen0}%
65                {\vskip5pt\centerline{\bfseries TO DO}\vskip 12pt#1}}%
66   \par\bigskip}%
67 \mdwdoc
68 %</driver>
69 %
70 % \end{meta-comment}
71 %
72 % \section{User guide}
73 %
74 % The \package{poem} package is designed to provide appropriate typesetting
75 % for all manner of `sensible' poems, by which I mean not to exclude the
76 % works of such great poets as Spike Milligan, but more those who lay out
77 % their words to form pretty patterns: such works must be dealt with on
78 % an individual basis, I'm afraid.
79 %
80 % An overview of the features provided wouldn't go amiss, I think.
81 % \begin{itemize}
82 %
83 % \item Poems are normally centred on the page based on the length of
84 %       the longest line.  This package handles this requirement, but
85 %       allows poems to be left or right aligned if desired.
86 %
87 % \item Lines of poems are numbered, and may be labelled and referenced
88 %       using the normal |\label| and |\ref| commands of \LaTeX.  Numbers
89 %       are by default printed every 5 lines, on the right hand side, but
90 %       this is fully configurable, as is the style of the numbers.
91 %
92 % \item Stanzas can be numbered, titled, either, neither or both.  Stanza
93 %       numbers can be labelled and referenced.
94 %
95 % \end{itemize}
96 %
97 %
98 % \subsection{Typesetting simple poems}
99 %
100 % \DescribeEnv{poem}
101 % You can typeset a poem using the \env{poem} environment.  The lines of
102 % the poem are separated by |\\| commands as usual.  Use the |\stanza*|
103 % command to start new stanzas.  Something like this would do the job:
104 %
105 % \todo{There should be a demo here}
106 %
107 % Lines of a poem will be broken if they get too long.  However, a
108 % `logical' line of a poem will never be broken between pages.\footnote{
109 %   This is an artifact of the way I've implemented the poems.  I don't
110 %   think it's a terribly nasty restriction.}
111 % Continued lines are indented from the left margin by a fair distance,
112 % so that they don't get confused with the starts of new lines.
113 %
114 % \DescribeMacro{\poemline}
115 % You've probably noticed that the poem lines are numbered down the right
116 % hand side.  This happens automatically, although you can turn it off if
117 % it's inappropriate.  All the line numbers are generated by the command
118 % |\poemline|, which you can define however you like.  Saying
119 % \begin{listing}
120 %\renewcommand{\poemline}{}
121 % \end{listing}
122 % will cause nothing to be printed for the line numbers, turning them off.
123 %
124 % \todo{A command to disable numbering?}
125 %
126 % \DescribeMacro{\title}
127 % You can use the |\title| command to typeset a title for your poem.  The
128 % title is inserted right there and then, so watch out.  It's conventional
129 % to put the title at the top of the poem, although this is art we're talking
130 % about, so who knows?  Just say \syntax{"\\title{"<title>"}"}.
131 %
132 % \DescribeMacro{\author}
133 % Similarly, the author of a poem can be credited with the |\author| command.
134 % Just put the author's name in the argument.  Authors usually go at the
135 % bottom of poems.
136 %
137 % \DescribeMacro{\poemtitle} \DescribeMacro{\poemauthor}
138 % The |\title| and |\author| commands are implemented internally by the
139 % commands |\poemtitle| and |\poemauthor|, which you can redefine if you
140 % like.  You should probably have a look at the default definitions before
141 % you do this: they use some little features which haven't been described
142 % yet.  Don't be intimidated, though: I'll get to them later!
143 %
144 %
145 % \subsection{Playing with stanzas}
146 %
147 % \DescribeMacro{\stanza}
148 % The |\stanza| command is actually fairly complicated.  It always starts
149 % a new stanza, leaving a gap if necessary after the previous line.
150 % Also, the stanza will be numbered, unless you use the |\stanza*| command.
151 % You can also give the stanza a title by saying
152 % \syntax{"\\stanza["<title>"]"} (or |\stanza*|\dots\ if you don't want the
153 % number).  The title and number are printed above the new stanza.
154 %
155 % \DescribeMacro{\labelstanza}
156 % The stanza numbers are typeset by the command |\labelstanza| which you
157 % can define however you like.  To disable them entirely, say
158 % \begin{listing}
159 %\renewcommand{\labelstanza}{}
160 % \end{listing}
161 %
162 % There are a collection of other style parameters for stanza titles.  These
163 % are described below (if you're not interested in this sort of thing, skip
164 % to the next section).
165 %
166 % \begin{description} \setdescriptionlabel{\ttfamily\string#1}
167 % \item [stanza] is a \LaTeX\ counter which contains the current stanza
168 %       number.
169 % \item [\thestanza] typesets the value of the |stanza| counter in normal
170 %       text.
171 % \item [\labelstanza] typesets the value of the |stanza| counter specially
172 %       for use as a stanza title.  (The default style uses small caps here,
173 %       which is generally inappropriate in running text.)
174 % \item [\stanzaname] is a command with one argument which typesets a stanza
175 %       title string, as passed to the |\stanza| command (not including the
176 %       number).
177 % \item [\stanzacombine] is given two arguments: a title (built by
178 %       |\labelstanza|) and a title (formatted by |\stanzaname|).  It
179 %       should format and space these two arguments.  It \emph{can't}
180 %       change the font of this text -- it's too late for that now.
181 %       This command is only used when both a number and a stanza title
182 %       are given.
183 % \item [\stanzaspace] is called with no arguments.  It should somehow
184 %       separate the previous stanza (if any) from the new one.  Look at the
185 %       counter value to find out whether this is the first stanza, if it
186 %       matters (e.g., you're drawing little rows of stars or something).
187 % \item [\stanzatitle] is given one argument: a `combined' title.  It should
188 %       typeset the title as a line in LR mode.  Again, it's too late to
189 %       play with fonts now.
190 % \end{description}
191 %
192 % All of the commands described above are given fairly simple definitions
193 % by default: you should be able to customise these without difficulty.
194 %
195 %
196 % \subsection{Starting new lines}
197 %
198 % \DescribeMacro{\\}
199 % New lines within a stanza are started with the |\\| command.  This always
200 % starts a new line.  The |\\*| command (which forbids a following page
201 % break) and the optional argument (which adds vertical space) are
202 % fully supported.
203 %
204 % \DescribeMacro{\nl}
205 % However, there's also a command |\nl| which works like |\\| (it has a
206 % $*$-version and so on) except that it won't start a new line unless
207 % there's something already on the current one.  This is useful in commands
208 % like |\poemauthor| which want to typeset their text on a new line without
209 % possibly leaving an ugly looking gap.
210 %
211 % For example, the definition of |\poemauthor| is:
212 % \begin{listing}
213 %\providecommand{\poemauthor}[1]{%
214 %  \nl*[\smallskipamount]%
215 %  \nonumber%
216 %  \hfill\normalfont\itshape#1%
217 %  \\%
218 %}
219 % \end{listing}
220 % The important part to us is that |\nl*[\smallskipamount]| at the
221 % beginning.  This starts a new line, making sure that there's no page
222 % break between it and the previous line, and adds a little extra space
223 % before the author's name.  The |\nonumber| command just prevents this line
224 % from being numbered, since it's not actually part of the poem itself:
225 % numbering is dealt with in detail in the next section.
226 %
227 %
228 % \subsection{Line numbering}
229 %
230 % \DescribeMacro{\poemline}
231 % I skimmed over line numbering earlier, because it's a bit complex.  I'll
232 % start with the default definition of the |\poemline| command, which will
233 % give me something specific to talk about.  The command is used to generate
234 % the line number for the line which has \emph{just finished}.
235 %
236 % \begin{listing}
237 %\providecommand{\poemline}{%
238 %  \ifmultipleof{5}{\value{poemline}}%
239 %    {\poemlineposition[r]{\scriptsize\thepoemline}}%
240 %    {}%
241 %  \refstepcounter{poemline}%
242 %}
243 % \end{listing}
244 %
245 % \DescribeMacro{\ifmultipleof}
246 % The |\ifmultipleof{5}{\value{poemline}}|\dots\ construction restricts the
247 % printed numbers to every fifth line (|\value{poemline}| is the value of
248 % the |poemline| counter).  Saying
249 % \syntax{"\\ifmultipleof{"$n$"}{"$x$"}{"<true>"}{"<false>"}"} will do
250 % \<true> if~$x$ is a multiple of~$n$; otherwise it does \<false>.
251 %
252 % \DescribeMacro{\poemlineposition}
253 % The |\poemlineposition| command positions its text to the right or
254 % left of the poem, according to whether its optional argument is \lit{l}
255 % or \lit{r}.
256 %
257 % So, the code up there just prints the poem line in small numbers on the
258 % right hand side of every fifth line of the poem.  (Phew!)  It then steps
259 % the counter so it'll be all right for cross-references in the next line
260 % down.  Got that?
261 %
262 % \DescribeMacro{\nonumber}
263 % Something a little simpler now: saying |\nonumber| in a line of poetry will
264 % suppress the line number on that line.  The counter won't be stepped, and
265 % no number is printed.  This is mainly useful in titles and other
266 % adornments in poems.
267 %
268 %
269 % \subsection{Other little extras}
270 %
271 % \DescribeEnv{xpoem}
272 % The \env{poem} environment doesn't actually do a lot by itself.  If you
273 % look at its definition, you'll see that it just starts a standard \LaTeX\
274 % \env{verse} environment and then calls the \env{xpoem} environment to
275 % do the actual work.  The idea is that you can then redefine \env{poem}
276 % to do whatever setting up you want and then use \env{xpoem} to do
277 % its typesetting magic.  For example, the definitions
278 % \begin{listing}
279 %\newcommand{\poemend}{}
280 %\renewenvironment{poem}[2]{%
281 %  \begin{verse}%
282 %  \renewcommand{\poemend}{\author{#2}}%
283 %  \begin{xpoem}%
284 %  \title{#1}%
285 %}{%
286 %  \poemend%
287 %  \end{xpoem}%
288 %  \end{verse}%
289 %}
290 % \end{listing}
291 % modifies the environment so that it takes two arguments, the title and
292 % the author, and sets them at the beginning and end of the poem
293 % respectively.
294 %
295 % \TeX\ hackers who know about such things could make a \env{poem}
296 % environment which `obeys' line breaks in the input file by making active
297 % newlines do an |\nl| command.  The possibilities are endless.
298 %
299 % \DescribeMacro{\splitline}
300 % The |\splitline| command should be used at the start of a new line (it
301 % starts a new line all by itself otherwise).  It shunts all the text of
302 % the line to the right so that it starts where the previous line finished.
303 %
304 % \todo{Come up with an example for this}
305 %
306 %
307 % \implementation
308 %
309 % \section{Implementation}
310 %
311 % \subsection{Various allocations}
312 %
313 % I need a shocking number of allocations for this package to work.  I'll
314 % start with the counters, because they're probably the most reasonable.
315 %
316 % |poem@count| keeps track of which poem this is, so I can look up the
317 % width in my magic list (I'll describe width handling later in detail).
318 % |poemline| is a user-level counter which keeps track of the current line
319 % number.  |stanza| keeps track of the current stanza number.
320 %
321 % The |\poemchunksize| counter (which is also faked as a \LaTeX\ counter)
322 % tells me how big a chunk should be.  The final counter, |\poem@linesleft|
323 % tells me how many more lines I can do in this chunk.
324 %
325 % All the counters are assigned globally, or at least they should be.
326 %
327 %    \begin{macrocode}
328 \newcounter{poem@count}
329 \newcounter{poemline}
330 \newcount\poemchunksize
331 \let\c@poemchunksize\poemchunksize
332 \newcount\poem@linesleft
333 \poemchunksize=30
334 %    \end{macrocode}
335 %
336 % Now for some length registers.  |\poem@width| contains the width of the
337 % poem as read from the |.aux| file; |\poem@thiswidth| contains the width
338 % of the longest line read so far.  Both of these are updated as I go through
339 % the poem.  The final value of |\poem@thiswidth| is written back to the
340 % list when all's finished.
341 %
342 % |\poem@lastwidth| contains the width of the last line -- it's used in
343 % handling |\splitline|s.  |\poem@prevdepth| is used to fiddle |\prevdepth|
344 % when handling long lines.
345 %
346 % All of these length parameters should be modified globally at all times.
347 %
348 %    \begin{macrocode}
349 \newdimen\poem@width
350 \newdimen\poem@thiswidth
351 \newdimen\poem@lastwidth
352 \newdimen\poem@prevdepth
353 %    \end{macrocode}
354 %
355 % The switch |\ifpoem@long| is used to decide whether we need to save the
356 % poem width in the aux file.
357 %
358 %    \begin{macrocode}
359 \newif\ifpoem@long
360 %    \end{macrocode}
361 %
362 % Lastly, a skip register.  This is the glue on the left hand side of a
363 % poem.  It should be |\@centering| to center the poem horizontally, or
364 % something rigid and nonzero to left-align.
365 %
366 %    \begin{macrocode}
367 \newskip\poemleftskip
368 \poemleftskip\@centering
369 %    \end{macrocode}
370 %
371 %
372 % \subsection{Handling poem widths}
373 %
374 % Poems are horizontally centred, based on the width of their longest line.
375 % This can be done without too many problems using an |\halign|.  However,
376 % this would require \TeX\ to read in the whole poem before being able to lay
377 % out the first line; this is clearly impractical for something like
378 % \emph{The Rime of the Ancient Mariner}.
379 %
380 % The solution is fairly similar to that used by the \package{longtable}
381 % package.  I'll divide a poem up into chunks, centring each chunk
382 % horizontally.  I'll also keep track of the longest line so far, and make
383 % sure that it affects each chunk, so as to prevent the chunks looking odd.
384 % When all's finished, I'll write a list containing the widths of all the
385 % poems to the |.aux| file so that next time everything will look nice.
386 %
387 % The list is held in just one macro, which contains entries of the form
388 % \syntax{"["<poem-number>"]{"<width>"}"}.  I build the new updated
389 % list in another macro as I go -- this version will be written to the
390 % |.aux| file at the very end, to ensure that inserted or removed poems
391 % don't mess anything up permanently.  It also avoids problems to do with
392 % poem widths decreasing, which gives \package{longtable} a bit of a
393 % headache.
394 %
395 % These two macros are always assigned globally.
396 %
397 %    \begin{macrocode}
398 \def\poem@widths{}
399 \def\poem@savedwidths{}
400 %    \end{macrocode}
401 %
402 % \begin{macro}{\poem@getwidth}
403 %
404 % The width of the current poem can be read using this macro.  It assigns
405 % the width to the |\poem@width| register; it gets the value 0\,pt if no
406 % value for this poem actually exists.
407 %
408 %    \begin{macrocode}
409 \def\poem@getwidth#1{%
410   \def\@tempa##1[#1]##2##3\@@{##2}%
411   \global\poem@width\expandafter\@tempa\poem@savedwidths[#1]\z@\@@%
412   \relax%
413 }
414 %    \end{macrocode}
415 %
416 % \end{macro}
417 %
418 % \begin{macro}{\poem@setwidth}
419 %
420 % I can also write the width of the current poem using this macro.  It
421 % updates the new improved list with the value of |\poem@thiswidth|.
422 %
423 %    \begin{macrocode}
424 \def\poem@setwidth#1{%
425   \def\@tempb##1[#1]\z@{##1}%
426   \def\@tempa##1[#1]##2##3\@@{%
427     \xdef\poem@widths{%
428       ##1%
429       [#1]{\the\poem@thiswidth}%
430       \ifdim##2=\z@\else\expandafter\@tempb\fi##3%
431     }%
432   }%
433   \expandafter\@tempa\poem@widths[#1]\z@\@@%
434 }
435 %    \end{macrocode}
436 %
437 % \end{macro}
438 %
439 % At the very end of the document, I want to write the poem widths to the
440 % |.aux| file.  The following code will do the job nicely.
441 %
442 %    \begin{macrocode}
443 \AtEndDocument{%
444   \if@filesw%
445     \immediate\write\@auxout%
446       {\gdef\noexpand\poem@savedwidths{\poem@widths}}%
447   \fi%
448 }
449 %    \end{macrocode}
450 %
451 %
452 % \subsection{Some little details}
453 %
454 % \begin{macro}{\@maybe@unskip}
455 %
456 % This macro solves a little problem.  In an alignment (and in other places)
457 % it's desirable to suppress trailing space.  The usual method, to say
458 % |\unskip|, is a little hamfisted, because it removes perfectly reasonable
459 % aligning spaces like |\hfil|s.  While as a package writer I can deal with
460 % this sort of thing by saying |\kern\z@| in appropriate places, it can
461 % annoy users who are trying to use |\hfill| to override alignment in funny
462 % places.
463 %
464 % My current solution seems to be acceptable.  I'll remove the natural width
465 % of the last glue item, so that it can still stretch and shrink if
466 % necessary.  The implementation makes use of the fact that multiplying
467 % a \<skip> by a \<number> kills off the stretch.
468 %
469 %    \begin{macrocode}
470 \def\@maybe@unskip{\ifhmode\hskip\m@ne\lastskip\relax\fi}
471 %    \end{macrocode}
472 %
473 % \end{macro}
474 %
475 %
476 % \subsection{Line numbering}
477 %
478 % Poem lines are numbered in a fairly sensible and normal way.  However, it's
479 % not normal to number every single line.  The macro |\poemline| below will
480 % decide whether and how to number a line.
481 %
482 % \begin{macro}{\ifmultipleof}
483 %
484 % This macro is called as
485 % \syntax{"\\ifmultipleof{"$n$"}{"$x$"}{"<true>"}{"<false>"}"}.  If the
486 % number~$x$ is a multiple of~$n$, then the whole lot expands to \<true>;
487 % otherwise it expands to \<false>.  The test here relies on \TeX\ doing
488 % integer division (which it does).
489 %
490 %    \begin{macrocode}
491 \def\ifmultipleof#1#2{%
492   \count@#2%
493   \divide\count@#1%
494   \multiply\count@#1%
495   \relax%
496   \ifnum#2=\count@%
497     \expandafter\@firstoftwo%
498   \else%
499     \expandafter\@secondoftwo%
500   \fi%
501 }
502 %    \end{macrocode}
503 %
504 % \end{macro}
505 %
506 % \begin{macro}{\poemlineposition}
507 %
508 % This macro typesets its argument relative to the poem in some neat way.
509 % It's called as \syntax{"\\poemlineposition["<posn>"]{"<text>"}"}.  The
510 % \<posn> may be \lit{l} or \lit{r}, where `l' and `r' mean left and right
511 % respectively.
512 %
513 % This command only produces at all sensible results when typesetting poem
514 % line numbers.
515 %
516 %    \begin{macrocode}
517 \def\poemlineposition{\@ifnextchar[\poem@lp@i{\poem@lp@i[l]}}
518 %    \end{macrocode}
519 %
520 % Now there's some sorting out to do.  If the number is to go on the
521 % right, then there's no problem: it can just be typeset as it is.
522 % Positioning on the left isn't too hard either -- I just need to shift the
523 % number to the left by |\linewidth| plus a bit for niceness.
524 %
525 %    \begin{macrocode}
526 \def\poem@lp@i[#1]#2{%
527   \if#1r%
528     \hfil\kern8\p@#2%
529   \else\if#1l%
530     \llap{#2\kern8\p@\kern\linewidth}%
531   \fi\fi%
532 }
533 %    \end{macrocode}
534 %
535 % \end{macro}
536 %
537 % \begin{macro}{\poemline}
538 %
539 % The default definition of |\poemline| will put a line number in script
540 % size (so as not to appear too obvious) on every fifth line.
541 %
542 %    \begin{macrocode}
543 \providecommand{\poemline}{%
544   \ifmultipleof{5}{\value{poemline}}%
545     {\poemlineposition[r]{\scriptsize\thepoemline}}%
546     {}%
547   \refstepcounter{poemline}%
548 }
549 %    \end{macrocode}
550 %
551 % \end{macro}
552 %
553 %
554 % \subsection{The main environment}
555 %
556 % \begin{environment}{xpoem}
557 %
558 % The \env{xpoem} environment is where the nastiness really starts.
559 % Actually, the early bit is simple enough.
560 %
561 % This environment has a funny name, so that users and style designers can
562 % define a usable `poem' environment the way they want.  Typically this
563 % will involve playing with some parameters, maybe setting up some active
564 % characters in a funny way, and probably adding a list environment to
565 % provide appropriate indentation on the left and right sides.
566 %
567 %    \begin{macrocode}
568 \def\xpoem{%
569 %    \end{macrocode}
570 %
571 % The first thing to do is to reset the line number counter.
572 %
573 %    \begin{macrocode}
574   \global\c@poemline\z@%
575 %    \end{macrocode}
576 %
577 % Now for some hookery -- the internal |\poem@printline| command will do
578 % the job of deciding whether to print a line number or not on the current
579 % line.  Unless otherwise disabled, this will be equal to |\poemline|.
580 %
581 %    \begin{macrocode}
582   \global\let\poem@printline\poemline%
583 %    \end{macrocode}
584 %
585 % The |\nonumber| command, which is also used by \env{eqnarray},\footnote{^^A
586 %   Just a plug: check out the improved \env{eqnarray} environment in the
587 %   \package{mathenv} package!}
588 % suppresses numbering of the current line by changing |\poem@printline|.
589 % It will be reset by the next line end, so it only applies to a single line.
590 %
591 %    \begin{macrocode}
592   \def\nonumber{\global\let\poem@printline\@empty}%
593 %    \end{macrocode}
594 %
595 % The |\title| and |\author| commands need redefining.  I'll set these
596 % equal to some user-configurable commands below.
597 %
598 %    \begin{macrocode}
599   \let\title\poemtitle%
600   \let\author\poemauthor%
601 %    \end{macrocode}
602 %
603 % Do some nasty things to make lists work properly.
604 %
605 %    \begin{macrocode}
606   \global\@inlabelfalse%
607   \global\@newlistfalse%
608 %    \end{macrocode}
609 %
610 % Now it's time to start the alignment.  I'll clear the |\everycr| tokens,
611 % and set up the |\\| command.  I'll make |\par| expand to nothing exciting,
612 % so that blank lines in poems won't mess anything up, and set up the
613 % `outside' meaning of |\nl|.
614 %
615 %    \begin{macrocode}
616   \everycr{}%
617   \let\\\poem@cr%
618   \def\nl{\poem@nl}%
619   \global\let\poem@nl\poem@donl%
620   \let\par\@empty%
621 %    \end{macrocode}
622 %
623 % Now to set the widths of the poem.  |\poem@width| is read from the |.aux|
624 % file from the \emph{last} time the poem was typeset, and is used to set
625 % the width \emph{this} time, while |\poem@thiswidth| is initially zero,
626 % and is set up as we go through \emph{this} time, and will be used to
627 % set the actual poem width \emph{next} time.  Is that clear?  No?  Oh, well.
628 %
629 %    \begin{macrocode}
630   \expandafter\poem@getwidth\expandafter{\the\c@poem@count}%
631   \global\poem@thiswidth\z@%
632   \global\poem@longfalse
633 %    \end{macrocode}
634 %
635 % Now some hacking to position the poem horizontally.  I need to inspect the
636 % current list margins, so as to make it look right.  I'll set |\dimen@| to
637 % be the size of the right hand margin.
638 %
639 %    \begin{macrocode}
640   \dimen@\hsize%
641   \advance\dimen@-\@totalleftmargin%
642   \advance\dimen@-\linewidth%
643 %    \end{macrocode}
644 %
645 % Now for some silly little things before I really get going.  Leave some
646 % vertical space, and step the counter ready for the first line.
647 %
648 %    \begin{macrocode}
649   \bigskip%
650   \stepcounter{poemline}%
651   \def\@currentlabel{\p@poemline\thepoemline}%
652 %    \end{macrocode}
653 %
654 % Other things may want to add their declarations here.  I'll provide a hook.
655 %
656 %    \begin{macrocode}
657   \poem@hook%
658 %    \end{macrocode}
659 %
660 % Now start the first poem chunk and give control to the user.
661 %
662 %    \begin{macrocode}
663   \poem@startchunk%
664 }
665 %    \end{macrocode}
666 %
667 % That's the start of the environment done; what happens at the end?  Well,
668 % some fairly simple things, actually.
669 %
670 %    \begin{macrocode}
671 \def\endxpoem{%
672 %    \end{macrocode}
673 %
674 % First of all, I forcibly truncate this chunk of poem.
675 %
676 %    \begin{macrocode}
677   \nl%
678   \poem@endchunk%
679 %    \end{macrocode}
680 %
681 % Now, if the poem is longer than the chunk size, I'll add it to the new
682 % width list.  If it's shorter than the chunk size, there's no need to do
683 % this, since \TeX\ will always work out the correct width `in time'.
684 %
685 %    \begin{macrocode}
686   \ifnum\c@poemline>\poemchunksize\poem@longtrue\fi%
687   \ifpoem@long%
688     \expandafter\poem@setwidth\expandafter{\the\c@poem@count}%
689   \fi%
690 %    \end{macrocode}
691 %
692 % Now I'll step the poem counter, leave a little gap, and end the
693 % environment.
694 %
695 %    \begin{macrocode}
696   \global\advance\c@poem@count\@ne%
697   \bigskip%
698 }
699 %    \end{macrocode}
700 %
701 % \end{environment}
702 %
703 % \begin{macro}{\poem@hook}
704 %
705 % The hook used above in |\poem| starts off empty.  Macro packages can add
706 % to it later.
707 %
708 %    \begin{macrocode}
709 \def\poem@hook{}
710 %    \end{macrocode}
711 %
712 % \end{macro}
713 %
714 % \begin{macro}{\poem@addtohook}
715 %
716 % Packages add to that hook by saying
717 % \syntax{"\\poem@addtohook{"<declarations>"}"}.  This is truly trivial.
718 %
719 %    \begin{macrocode}
720 \def\poem@addtohook#1{%
721   \expandafter\def\expandafter\poem@hook\expandafter{\poem@hook#1}%
722 }
723 %    \end{macrocode}
724 %
725 % \end{macro}
726 %
727 % I'll take a break from the deep hacking for a while, and implement some
728 % style things.  These commands should be redefined to alter the style of
729 % the poems.  (I've tried hard to make them as simple as possible.)
730 %
731 % \begin{macro}{\poemtitle}
732 %
733 % Poem titles are large, bold, and centred.  The |\nl| command starts a new
734 % row if necessary.  I want to avoid a page break after the title, for
735 % obvious reasons.
736 %
737 %    \begin{macrocode}
738 \providecommand{\poemtitle}[1]{%
739   \nl%
740   \nonumber%
741   \hfill\normalfont\large\bfseries#1\hfill%
742   \\*[\bigskipamount]%
743 }
744 %    \end{macrocode}
745 %
746 % \end{macro}
747 %
748 % \begin{macro}{\poemauthor}
749 %
750 % Authors are typeset in italics, right aligned.
751 %
752 %    \begin{macrocode}
753 \providecommand{\poemauthor}[1]{%
754   \nl*[\smallskipamount]%
755   \nonumber%
756   \hfill\normalfont\itshape#1%
757   \\%
758 }
759 %    \end{macrocode}
760 %
761 % \end{macro}
762 %
763 %
764 % \subsection{Poem chunk handling}
765 %
766 % Poems are divided into chunks to save \TeX's memory.  Chunks are started
767 % like this:
768 %
769 % \begin{macro}{\poem@startchunk}
770 %
771 %    \begin{macrocode}
772 \def\poem@startchunk{%
773 %    \end{macrocode}
774 %
775 % Reset the `lines left' counter.  When this hits zero, I end the chunk and
776 % start another one.
777 %
778 %    \begin{macrocode}
779   \global\poem@linesleft\poemchunksize%
780 %    \end{macrocode}
781 %
782 % Now for the alignment itself.  The poem is centred by tabskip glue around
783 % its first column.  There are an infinite number of zero-width columns off
784 % to the right, in which the line numbers are typeset (this avoids problems
785 % if users accidentally tab over to the next column).
786 %
787 % The `main' column is a bit odd.  It reads the text into a box, which is
788 % global to preserve save stack space, and then calls a macro |\poem@doline|
789 % to typeset the text in the box correctly.
790 %
791 %    \begin{macrocode}
792   \skip@\@totalleftmargin%
793   \advance\skip@\poemleftskip%
794   \tabskip\skip@%
795   \halign to\hsize\bgroup%
796     \global\let\poem@nl\poem@cr%
797     \global\setbox\@ne\hbox{{\ignorespaces##\@maybe@unskip}}\poem@doline%
798     \tabskip\@centering&&%
799     \poem@rightcolumn\hbox{{##}}\tabskip\dimen@\cr%
800 }
801 %    \end{macrocode}
802 %
803 % \end{macro}
804 %
805 % \begin{macro}{\poem@endchunk}
806 %
807 % This is really easy.  I end the line, in case it hasn't been ended already
808 % (although it should have been), and end the alignment.
809 %
810 %    \begin{macrocode}
811 \def\poem@endchunk{%
812   \crcr%
813   \noalign{\global\dimen@i\prevdepth\nointerlineskip}%
814   \omit\hb@xt@\poem@width{}\cr%
815   \egroup%
816   \prevdepth\dimen@i%
817 }
818 %    \end{macrocode}
819 %
820 % \end{macro}
821 %
822 %
823 % \subsection{Typesetting poem lines}
824 %
825 % \begin{macro}{\poem@doline}
826 %
827 % This is where most of the real mess lies.  Given a line of doggerel in
828 % box~1, I must typeset it beautifully.
829 %
830 %    \begin{macrocode}
831 \def\poem@doline{%
832 %    \end{macrocode}
833 %
834 % In order to know whether I need to split the line, I must know how wide
835 % the line number is.  (Judging from the books I've seen, lines are allowed
836 % to encroach on the space allocated to line numbers, as long as there isn't
837 % a number on this line.  Maybe as a future extension, I could decide whether
838 % it might be better to suppress this line, and maybe force a number for
839 % the next one since it won't fit here.)
840 %
841 % Anyway, I'll do this the easy way.  I'll work out the width of the line
842 % number, and subtract it from the basic line width.
843 %
844 %    \begin{macrocode}
845   \dimen@\linewidth%
846   \global\setbox\@labels\hbox{\poem@printline}%
847   \advance\dimen@-\wd\@labels%
848 %    \end{macrocode}
849 %
850 % If the width of the doggerel is wider than |\dimen@|, I must split the
851 % text over more than one line, or at least I must try to.  (\TeX\ may
852 % be able to squeeze the text onto one line by shrinking the glue, so I've
853 % got to watch out for this possibility.)
854 %
855 %    \begin{macrocode}
856   \ifdim\wd\@ne>\dimen@%
857 %    \end{macrocode}
858 %
859 % I'll now put the text in a vbox, so I can play with it.  The parshape
860 % is set up so that the first line misses the line number (if there is
861 % one), while subsequent lines are indented, but take up the full available
862 % width of the page.  The text is not indented (just to make sure).
863 %
864 % The messing with |\leftskip| and the initial kern provides the indentation,
865 % and saves a little arithmetic.  There is a more plausible historical reason
866 % for it too.
867 %
868 %    \begin{macrocode}
869     \global\setbox\@ne\vtop{%
870       \parshape\tw@ \z@\dimen@ \z@\linewidth%
871       \leftskip3em%
872       \noindent%
873       \kern-3em%
874       \unhbox\@ne%
875       \@@par%
876     }%
877 %    \end{macrocode}
878 %
879 % Since table cells are set in LR mode, the baselineskip glue will be set
880 % all wrong underneath this line.  I also need to set |\poem@lastwidth|
881 % correctly.  I'll copy the box to another box, and pick off the bottom line
882 % so I can peek inside.
883 %
884 % I'll set |\poem@prevdepth| from the depth of the box (this will be set
885 % properly at the end of the line).  I'll also rip that box apart, remove
886 % the |\parfillskip| glue, and rebox it in an attempt to calculate
887 % |\poem@lastwidth|.  This isn't perfect, since the line might actually be
888 % shrinking instead of stretching.  This is unlikely, though.
889 %
890 %    \begin{macrocode}
891     \global\setbox\thr@@\vbox{%
892       \unvcopy\@ne%
893       \global\setbox\thr@@\lastbox%
894       \global\poem@prevdepth\dp\thr@@%
895       \global\setbox\thr@@\hbox{\unhbox\thr@@\unskip}%
896       \global\poem@lastwidth\wd\thr@@%
897     }%
898 %    \end{macrocode}
899 %
900 % Now that's done, I can output the box.  I'll clear box~3, which I
901 % vandalised above.  I also know that the line was too long, so I can
902 % set the poem widths to |\linewidth| with impunity.
903 %
904 %    \begin{macrocode}
905     \box\@ne%
906     \global\setbox\thr@@\box\voidb@x%
907     \global\poem@width\linewidth%
908     \global\poem@thiswidth\linewidth%
909   \else%
910 %    \end{macrocode}
911 %
912 % If it fits, I can update the widths if necessary, set |\poem@lastwidth|,
913 % and spew out the text.  Finally, I'll set |\poem@prevdepth| to a sentinel
914 % value meaning `don't change'.
915 %
916 %    \begin{macrocode}
917     \ifdim\wd\@ne>\poem@width\global\poem@width\wd\@ne\fi%
918     \ifdim\wd\@ne>\poem@thiswidth\global\poem@thiswidth\wd\@ne\fi%
919     \global\poem@lastwidth\wd\@ne%
920     \unhbox\@ne\hfil%
921     \global\poem@prevdepth\maxdimen%
922   \fi%
923 }
924 %    \end{macrocode}
925 %
926 % \end{macro}
927 %
928 %
929 % \subsection{Starting a new line}
930 %
931 % There are two different routes to starting new lines.  The |\\| command
932 % always starts a new line.  The command |\nl| will work out if
933 % the current line hasn't been started yet, and behaves appropriately.
934 %
935 % \begin{macro}{\poem@cr}
936 %
937 % The |\poem@cr| macro implements the |\\| command and the |\nl|
938 % command once a new line has been started.
939 %
940 % First, I need to pick out the optional arguments.  All the standard hacking
941 % for doing newlines in alignments appears here.  If you want detailed
942 % commentary, look somewhere else -- this is humdrum stuff now.
943 %
944 %    \begin{macrocode}
945 \def\poem@cr{%
946   \relax%
947   \global\let\poem@nl\poem@donl%
948   \iffalse{\fi\ifnum0=`}\fi%
949   \@ifstar{\poem@cr@i\@M}{\poem@cr@i\z@}%
950 }
951 \def\poem@cr@i#1{\@ifnextchar[{\poem@cr@ii{#1}}{\poem@cr@ii{#1}[\z@]}}
952 %    \end{macrocode}
953 %
954 % That's the standard hacking over.  Here's the tricky bit.
955 %
956 %    \begin{macrocode}
957 \def\poem@cr@ii#1[#2]{%
958   \ifnum0=`{}\fi%
959 %    \end{macrocode}
960 %
961 % First of all, I must clear the command which raises an error in the right
962 % hand column.  Then I'll enter the column and insert the line number (which
963 % was stored in |\@labels| for safekeeping).
964 %
965 %    \begin{macrocode}
966   \global\let\poem@rightcolumn\relax%
967   &\relax%
968   \llap{\unhbox\@labels}%
969 %    \end{macrocode}
970 %
971 % Now I'll reset the various hooks and things ready for the next like.
972 %
973 %    \begin{macrocode}
974   \global\let\poem@printline\poemline%
975   \global\let\poem@rightcolumn\poem@@rightcolumn%
976 %    \end{macrocode}
977 %
978 % Now to decide whether to start a new chunk.  I'll decrement the counter,
979 % and if it reaches zero, I'll end that chunk and start a new one.
980 %
981 %    \begin{macrocode}
982   \global\advance\poem@linesleft\m@ne%
983   \ifnum\poem@linesleft=\z@%
984     \poem@endchunk%
985     \expandafter\poem@startchunk%
986   \else%
987     \expandafter\cr%
988   \fi%
989 %    \end{macrocode}
990 %
991 % Finally, if I had a split line, I must change the |\prevdepth| setting to
992 % keep everyone happy.
993 %
994 %    \begin{macrocode}
995   \noalign{%
996     \addpenalty{#1}%
997     \vskip#2%
998     \ifdim\poem@prevdepth=\maxdimen\else\prevdepth\poem@prevdepth\fi%
999   }%
1000 }
1001 %    \end{macrocode}
1002 %
1003 % \end{macro}
1004 %
1005 % \begin{macro}{\poem@donl}
1006 %
1007 % The |\poem@nl| macro implements |\nl| during those `in-between' times
1008 % outside of a line of doggerel.  This is actually spectacularly easy.
1009 %
1010 %    \begin{macrocode}
1011 \def\poem@donl{%
1012   \noalign{\ifnum0=`}\fi%
1013   \@ifstar{\poem@donl@i{\addpenalty\@M}}{\poem@donl@i{}}%
1014 }
1015 \def\poem@donl@i#1{%
1016   \@ifnextchar[{\poem@donl@ii{#1}}{\poem@donl@ii{#1}[\z@]}%
1017 }
1018 \def\poem@donl@ii#1[#2]{%
1019   #1%
1020   \addvspace{#2}%
1021   \ifnum0=`{\fi}%
1022 }
1023 %    \end{macrocode}
1024 %
1025 % \end{macro}
1026 %
1027 %
1028 % \subsection{Other things}
1029 %
1030 % Well, that's all that I actually need to supply; everything else can be
1031 % added over the top.
1032 %
1033 % \begin{macro}{\splitline}
1034 %
1035 % Some books appear to split lines, starting the second where the first
1036 % ends.  This is easy to handle with the |\splitline| command.
1037 %
1038 %    \begin{macrocode}
1039 \def\splitline{\nl\nonumber\kern\poem@lastwidth\ }
1040 %    \end{macrocode}
1041 %
1042 % \end{macro}
1043 %
1044 % \begin{macro}{\stanza}
1045 %
1046 % New stanzas are started using the |\stanza| command, oddly enough.  There's
1047 % a problem, though: to number, or not to number?  Following the example of
1048 % \LaTeX's sectioning commands, I'll not number if there's a following $*$.
1049 % I don't really think that this is the right thing to do, since unnumbered
1050 % stanzas are much more common than numbered ones.  This is actually a real
1051 % pain.
1052 %
1053 % Anyway, if I'm going to handle numbered stanzas, I'll need a counter.
1054 %
1055 %    \begin{macrocode}
1056 \newcounter{stanza}
1057 %    \end{macrocode}
1058 %
1059 % Whatever happens, I'll start by adding in some vertical space above the
1060 % stanza.  Then I'll see if there's a following $*$.  If so, step the counter
1061 % and typeset the number; otherwise do nothing.  However, there's a snaglet
1062 % here: |\@ifstar| will do assignments and things, and start the next row of
1063 % the alignment prematurely.  I'll do the work in a |\noalign| to avoid
1064 % problems.  (Yuk.)
1065 %
1066 %    \begin{macrocode}
1067 \def\stanza{%
1068   \nl%
1069   \noalign{\ifnum0=`}\fi%
1070   \@ifstar{%
1071     \stanza@i{}%
1072   }{%
1073     \stanza@i{\global\advance\c@stanza\@ne\labelstanza}%
1074   }%
1075 }
1076 %    \end{macrocode}
1077 %
1078 % OK\@.  Now I have to see if there's an optional argument.  I'm still safely
1079 % inside that |\noalign|, remember.
1080 %
1081 %    \begin{macrocode}
1082 \def\stanza@i#1{\@ifnextchar[{\stanza@ii{#1}}{\stanza@ii{#1}[]}}
1083 %    \end{macrocode}
1084 %
1085 % I can now read the argument, and decide what actually needs to be done.
1086 %
1087 %    \begin{macrocode}
1088 \def\stanza@ii#1[#2]{%
1089 %    \end{macrocode}
1090 %
1091 % I want to be able to allow |\label|s inside the optional argument.
1092 % However, I also want to be able to see whether the number and/or title
1093 % is `empty', bearing in mind that the title may contain just a |\label|,
1094 % which shouldn't alter the spacing; which means really that I ought to put
1095 % them into boxes and measure them.  But this stops |\refstepcounter|'s
1096 % setting of |\@currentlabel| (in the `number' box) being noticed by the
1097 % possible |\label| command in the other box.  I \emph{could} say something
1098 % like
1099 % \begin{listing}
1100 %\refstepcounter{stanza}
1101 %\addtocounter{stanza}{-1}
1102 % \end{listing}
1103 % which will do what I want, but defining |\@currentlabel| by hand is
1104 % considerably easier, and more efficient.
1105 %
1106 %    \begin{macrocode}
1107   \def\@currentlabel{\p@stanza\thestanza}%
1108   \sbox\z@{#1}%
1109   \sbox\tw@{\stanzaname{#2}}%
1110 %    \end{macrocode}
1111 %
1112 % There are essentially four possibilities:
1113 % \begin{itemize}
1114 % \item There's nothing to typeset at all.  This is easy: don't typeset
1115 %       anything.
1116 % \item There's a number, but no title.
1117 % \item There's a title, but no number.
1118 % \item There's both a title \emph{and} a number.
1119 % \end{itemize}
1120 % The tricky bit is the last possibility, since I don't know how the two
1121 % will be separated.  Oh, well: I'll just have to use a load of user macros.
1122 %
1123 % As a first attempt, I'll put the thing to typeset into box~0.  This is
1124 % fairly simple.  If there's a title, then I check if there's a number too:
1125 % if so, I'll combine them both into box~0; otherwise I can just copy the
1126 % box over.  If there's anything to typeset at this point, it'll be in
1127 % box~0.  However, I'm currently in a |\noalign|, and that introduces a
1128 % level of grouping.  So I'll then move the box into box~1, which is global.
1129 %
1130 %    \begin{macrocode}
1131   \ifdim\wd\tw@>\z@%
1132     \ifdim\wd\z@>\z@%
1133       \global\setbox\@ne\hbox{\stanzacombine{\unhbox\z@}{\unhbox\tw@}}%
1134     \else%
1135       \global\setbox\@ne\box\tw@%
1136     \fi%
1137   \else%
1138     \global\setbox\@ne\hbox{\unhbox\z@\unhbox\tw@}%
1139   \fi%
1140 %    \end{macrocode}
1141 %
1142 % That's all the messy processing done.  Now I can just typeset the
1143 % title.
1144 %
1145 %    \begin{macrocode}
1146   \ifnum0=`{\fi}%
1147   \stanzaspace%
1148   \ifdim\wd\@ne>\z@%
1149     \nonumber%
1150     \stanzatitle{\unhbox\@ne}%
1151   \else
1152   \fi%
1153 %    \end{macrocode}
1154 %
1155 % That's it!  I'm done.
1156 %
1157 %    \begin{macrocode}
1158 }
1159 %    \end{macrocode}
1160 %
1161 % \end{macro}
1162 %
1163 % The |stanza| counter must be reset at the beginning of the poem.
1164 %
1165 %    \begin{macrocode}
1166 \poem@addtohook{\global\c@stanza\z@}
1167 %    \end{macrocode}
1168 %
1169 % Now for some formatting defaults.  This is easy stuff.
1170 %
1171 %
1172 % \begin{macro}{\thestanza}
1173 %
1174 % Obviously, this is the default way to typeset a stanza number.
1175 %
1176 %    \begin{macrocode}
1177 \renewcommand{\thestanza}{\Roman{stanza}}
1178 %    \end{macrocode}
1179 %
1180 % \end{macro}
1181 %
1182 % \begin{macro}{\labelstanza}
1183 %
1184 % This macro is responsible for giving the stanza number to be typeset in
1185 % the title line.
1186 %
1187 %    \begin{macrocode}
1188 \providecommand{\labelstanza}{\textsc{\roman{stanza}}}
1189 %    \end{macrocode}
1190 %
1191 % \end{macro}
1192 %
1193 % \begin{macro}{\stanzaname}
1194 %
1195 % This is responsible for typesetting the stanza's name.  This is easy.
1196 %
1197 %    \begin{macrocode}
1198 \providecommand{\stanzaname}[1]{\textsc{#1}}
1199 %    \end{macrocode}
1200 %
1201 % \end{macro}
1202 %
1203 % \begin{macro}{\stanzacombine}
1204 %
1205 % This is how to combine stanza numbers and names.  I'll just leave a space.
1206 %
1207 %    \begin{macrocode}
1208 \providecommand{\stanzacombine}[2]{#1\quad#2}
1209 %    \end{macrocode}
1210 %
1211 % \end{macro}
1212 %
1213 % \begin{macro}{\stanzaspace}
1214 %
1215 % Separate the previous stanza from a new one.  This isn't done in
1216 % |\stanzatitle| because there may not be a title.
1217 %
1218 %    \begin{macrocode}
1219 \providecommand{\stanzaspace}{\nl[\medskipamount]}
1220 %    \end{macrocode}
1221 %
1222 % \end{macro}
1223 %
1224 % \begin{macro}{\stanzatitle}
1225 %
1226 % Finally, this is the typesetting of the stanza title in its entirety.
1227 %
1228 %    \begin{macrocode}
1229 \providecommand{\stanzatitle}[1]{%
1230   \hfill#1\hfill\\%
1231 }
1232 %    \end{macrocode}
1233 %
1234 % \end{macro}
1235 %
1236 %
1237 % \hfill Mark Wooding, \today
1238 %
1239 % \Finale
1240 %
1241 \endinput