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