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