Commit | Line | Data |
---|---|---|
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 | |
eafdddad MW |
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). | |
86f6a31e | 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 | % | |
e8e9e5d8 | 363 | % Lastly, a skip register. This is the glue on the left hand side of a |
86f6a31e | 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 | % | |
e8e9e5d8 | 559 | % The \env{xpoem} environment is where the nastiness really starts. |
86f6a31e | 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 |