slowbox.dtx: Delete spurious `{'.
[mdwtools] / poetry.dtx
CommitLineData
86f6a31e 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%%
7f306c19
MW
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.
86f6a31e 20%%
7f306c19
MW
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.
86f6a31e 25%%
7f306c19
MW
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.
86f6a31e 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%
85f9f847 38% \CheckSum{593}
86f6a31e 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
a0edbf08 130% about, so who knows? Just say \syntax{"\\title{"<title>"}"}.
86f6a31e 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%
5b071bb2 166% \begin{description} \setdescriptionlabel{\ttfamily\string#1}
86f6a31e 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
eafdddad
MW
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).
86f6a31e 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%
e8e9e5d8 362% Lastly, a skip register. This is the glue on the left hand side of a
86f6a31e 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}
6a1388ae 470\def\@maybe@unskip{\ifhmode\hskip\m@ne\lastskip\relax\fi}
86f6a31e 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%
e8e9e5d8 558% The \env{xpoem} environment is where the nastiness really starts.
86f6a31e 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