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