summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/gmverse/gmverse.sty
blob: 51c1140fee1b14b5c1df4a257b47a129f68e10d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
%
% \GetFileInfo{gmverse.sty}
% \title{The \pk{gmverse} Package\thfileinfo}
% \author{Grzegorz Murzynowski}
% \date{\today}
% \maketitle
%%
%% This is (a~documentation of) file \pk{gmverse.sty}, intended to be
%% used with \LaTeXe. % This package redefines \env{verse} environment
%% to optionize |\\| for line ends and gives it a~possibility of
%% optical centering and `right-hanging' alignment of lines
%% broken because of length.
%%
%% \medskip
%%
% \begin{copyrnote}
%
%%   Written by Natror (Grzegorz Murzynowski),
%%   natror at o2 dot pl
%%
%%   \copyright\,2006, 2008 by Natror (Grzegorz Murzynowski).
%%
%%   This program is subject to the \LaTeX\ Project Public License.
%%   See \url{http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html} ^^A
%%   for the details of that license.
%%
%%   LPPL status: "author-maintained".\par
%%
%%   Many thanks to my \TeX\ Guru Marcin Woli\'nski for his \TeX nical ^^A
%%   support.\par
%\end{copyrnote}
%
%
% \chschange{v0.71}{2008/8/6}{825}
% \chschange{v0.72}{2008/8/30}{823}
% \chschange{v0.73}{2008/9/4}{822}
%
%

%\iffalse we skip the driver
\ifnum\catcode`\@=12
\documentclass[countalllines, codespacesgrey, pagella, fontspec=quiet]{gmdocc}
\twocoltoc
 \DeclareSymbolFont{operators}   {T1}{TeXGyrePagella(0)} {m}{n}
% moved from body of text.
\begin{document}
\exhyphenpenalty\hyphenpenalty
\DocInput{\jobname.sty}
\typeout{%
  Produce index with^^J%
  makeindex -r \jobname^^J}
\afterfi{\end{document}

% And for the future, when the changes' history is nonempty
\typeout{%
  Produce change log with^^J%
  makeindex -r -s gmglo.ist -o \jobname.gls \jobname.glo^^J
  (gmglo.ist should be put into some texmf/makeindex directory.)^^J}
}
\fi
%\fi\FileInfo


\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{gmverse}
        [2008/09/04 v0.73 A redefinition of verse env. (GM)]

%
% \tableofcontents
%
%
% \division{Intro, General Usage}
%
% An inspiration for me was the \pk{verse} package by Peter Wilson and
% Herries Press but, as you will see, I~take a~slightly different task.
% The main goal is to make verse typeset long and broken lines flush right
% (i.e., the beginning line flush left as usual and the ending one flush right)
% and optionally gives the ending a~square bracket ([), as sometimes
% practiced in Polish typesetting of poetry.
% This main task is fulfilled by \TextUsage\versehangright\
% declaration executed by 
% default and the |[| option is provided by
% \TextUsage\versehangrightsquare\ declaration, executed if the
% package is loaded with \TextUsage*{squarebr} 
% option.
%
% One more declaration is \TextUsage\verseopticalcenter\ that makes
% \env{verse}s centered due to their baric centre. I~gently deprecate
% this declaration since it requires also another,
% |\defvocgamma[true]| or |[false]|, and what you need most probably
% is \TextUsage\vocweigh|3|---\hskip0spa~declaration of optical  centering due
% to the sum of cubics of the line lengths (it looks best) and
% declares all what's needed. If you type |\vocweigh[]3|, the long
% lines will be broken with [ preceding the lower part. ^^A]
%
%
% \stanza
% My (little) experience is with typesetting great poetry the power of
% which is not in the shape of verses and stanzas but in the words 
% so I~did not pay much attention such things as sophisticated
% indentation. And my opinion is that all verses in one document
% (book) should be typeset as similarly as possible so that the power
% of their words could rather talk not the variety of their
% shapes. That's why my redefinition of \env{verse} is done at the
% beginning and once forever. 
%
% But if someone \emph {really} has to use different versions of
% \env{verse}, I~left \himher\ a~doorway: the \TextUsage*{local}
% option of the package, 
% with which the declarations redefining \env{verse} are not executed (and,
% of course, may be put anywhere the user wishes, with all the scoping
% rules). If |local| option is used, there's no use of |squarebr|
% option and the latter does no harm.
%
% Another task I~set myself was to "preserve'' known commands so that they
% work in a~known way, namely \TextUsage*{\\*}\arg[skip] and blank line.  
% But in these redefined \env{verse}'s one isn't forced to end every line
% with |\\|. Ending a~line with just the |^^M| character will work too.
%
%
% \subdivision{Parameters}
%
% As you can see below, my \env{verse}, unlike the \LaTeX's and \pk{verse}'s ones,
% does not create a~\env{list} environment. It uses the following
% parameters:
% \begin{verse}
%        |\verseskipbefore|
%        |\verseskipafter|
%        |\stanzaskip|
%        |\betweenstanzaspenalty|
%        |\instanzapenalty|
%        |\versegenericlinewidth|
%        |\versemaxlinewidth|
%\end{verse}
% I~suppose their names are self-explaining. Maybe except the last
% two. \TextUsage\versegenericlinewidth\ is a~dimen register intended
% to store an average line width of a~verse. It'll be used to set the
% optical centering. 
%
% What optical centering is? The basic assumption of this package is
% that all the verses are aligned left (ragged right). Optical
% centering of a~verse is such setting the left margin that the verse
% (a~ragged body of text) seems to be balanced at the vertical axis of
% the page. In other words, to human eyes the baric centre of the
% verse seems to lie on the vertical axis of the page.
% 
% \stanza
% The \TextUsage\versemaxlinewidth\ is a~dimen register to store
% a~maximum acceptable line width. The lines exceeding this width will
% be broken and (if the default declaration |\versehangright(square)|
% is in force) the broken ending will be aligned right.
%
% Those two parameters should  only be set with 
% \TextUsage\versecenterdue\arg{generic line (text)} and
% \TextUsage\versemaxline\arg{longest acceptable line (text)}
% commands, which set the dimens \emph{and} switch proper
% switches, \TextUsage\ifcenterverse\ and \TextUsage\ifmaxversewidth\ 
% respectively.
%
% If you have used |\versecenterdue| or |\versemaxline| and since some
% point you don't want center the verse due to generic line width
% (n)or delimit line's width, just write |\centerversefalse| or
% |\maxversewidthfalse| respectively.
%
% |\versecenterdue| takes one argument, which should be any text, rule
% or |\hskip| of desired width. The starred version |\versecenterdue*|
% takes explicit width (dimen) as its argument.
%
% |\versemaxline| works the same way.
% 
% \stanza 
% \TextUsage\betweenstanzaspenalty\ is the penalty put between
% the stanzas, as its name suggests. Its goal is to encourage the
% pagebreaks between two stanzas not in the middle of a~stanza. By
% default, it is set equal |\interlinepenalty| at
% |\begin{document}| but thanks to a~little trick you can set it also
%   in the preamble\footnote{Unless you don't want it to be ^^B
%     \cs{maxdimen}.}.
%
% \stanza
% \TextUsage\instanzapenalty\ is the penalty but between two lines of
% a~stanza. Its goal is to discourage the pagebreaks within
% a~stanza. By default, it's set equal |\clubpenalty| at
% |\begin{document}| and thanks to the same trick as above you can set
% it also in the preamble.
% 
% \stanza
% The default value both of \TextUsage\verseskipbefore\ and
% \TextUsage\verseskipafter\ is |\medskipamount|.
%
% ^^A%% I~found also funny to write a~possibility a~verse has alternately
% ^^A%% indented stanzas (e.g.\ in stanza and refrain case) or just lines.
%
% \subdivision{Four flavours of optical centering}
% The \pk{gmverse} package provides optical centering of verse. By
% `optical centering' I~mean such a~placing of the box containing
% a~verse that it seems be balanced on the vertical axis of the page.
%
% The optical centering may be automatic or manual. The automatic comes
% in four flavours, all of them cases of a~general formula. 
% The idea is to compute some average of the lines' lengths and set the
% rectangle's width to that average. 
%
% The first kind of average one can think of is arithmetical
% mean. That
% \let\mi\mathit \let\mr\mathrm 
% \newcommand*\eq {\mathrel{\hbox{=}}}^^A~to use pagella = not LMR.
% \newcommand*\eqs {\mathrel{\hbox{\scriptsize=}}}
% is the case $W_{1}$. The last kind of average is `only the longest line
% counts', that's $W_\infty$. Between them are $\continuum$
% possibilities: consider a~formula 
%^^A |\EU1/TeXGyrePagella(0)/m/n/11|
%% \[W_\alpha\eq  \sum_{\mi k\eqs \mr1}^{\mi n} 
% {\mi l_{\mi k}}^{\mi\alpha}\Big/\sum_{\mi k\eqs \mr1}^{\mi n} 
% {\mi l_{k^^B\showthe\textfont0
%   }}^{\alpha-\mr1}\]
% where $\mi l_{\mi k}$, $\mi k\eq \mr1\hbox{,}\dots \mi n$ are the lengths of the
% lines\footnote{Assume they all have nonzero length when $\alpha\eq \mr1$.}
% and $\alpha\in\hbox{[}\mr1,\hbox{+}\infty\hbox{)}$.
%
% When $\alpha\eq \mr1$, all the lines have `equal right to decide' about the
% mean. When $\alpha$ grows, the longer lines become `r\'owniejsze'
% (`more equal', a~term from the \acro{PRL} epoch to describe unjust
% privileges of the Party Aparatchiks), which means they mean
% more to the mean.
%
% We define $\mi W_\infty$ most naturally, as the limit:
% \[\mi W_\infty \eq \lim_{\alpha\rightarrow\infty} \mi W_\alpha\]
% and we notice easily that $\mi W_\alpha$ corresponds with taking only the
% longest line into account. 
%
% Me personally like $\mi W_{\mr3}$ most and that's the default 
% when optical centering is on.
%
% If you prefer to set the centering manually, you are given
% two ways to do that: the |\vocpussyhair|
% parameter (dimen) intended for a~slight modifications of the result of
% automatical 
% computation, and the declaration(s) 
% \[|\versecenterdue|\arg{benchmark text}\] or 
% \[|\versecenterdue*|\arg{benchmark dimen}.\]
%
% 
% \subdivision{New environments}
% You can define new verse environments in a~way \TextUsage*{verse0}
% is defined in line \ref{new envs}, that is in such definitions write |\verse| and
% |\endverse| and not |\begin{verse}| \dots\ |\end{verse}|.
%
% \division{The Code}
% \subdivision{Package options}

\newif\ifverseloc@l
\DeclareOption{local}{\verseloc@ltrue}

\newif\ifsqu@rebr
\DeclareOption{squarebr}{\squ@rebrtrue}

\newif\ifv@c
\DeclareOption{voc}{\v@ctrue}

\DeclareOption{vocweigh1}{\v@ctrue\AtEndOfPackage{\vocweigh1 }}
\DeclareOption{vocweigh2}{\v@ctrue\AtEndOfPackage{\vocweigh2 }}
\DeclareOption{vocweigh3}{\v@ctrue\AtEndOfPackage{\vocweigh3 }}
\DeclareOption{vocweigh8}{\v@ctrue\AtEndOfPackage{\vocweigh8 }}
  

\ProcessOptions

% \subdivision{Preliminaries and parameters}
%
\long\def\firstofone#1{#1}
\bgroup\catcode`\^^M=\active%
\firstofone{\egroup%
\def\defobeylines{\catcode`\^^M=\active \def^^M{\par}}}%

\long\def\afterfi#1#2\fi{\fi#1}

\newtoks\everyverse
\everyverse={}
\newdimen\verseleftskip
\verseleftskip=1,5em\relax

\newlength{\versealtleftskip}
\versealtleftskip=1,5em\relax

\newcommand*\begversesquareh@ck{\relax}
\newcommand*\parversesquareh@ck{\relax}
\newcommand*\eversesquareh@ck{\relax}
\newcounter{verselinenum}
\newskip\verseinstanzaparskip


\@ifundefined{stanzaskip}{\newlength\stanzaskip}{}
\stanzaskip=\medskipamount

\newlength\verseskipbefore
\newlength\verseskipafter
\verseskipbefore=\medskipamount
\verseskipafter=\medskipamount

\newcount\instanzapenalty \instanzapenalty=\maxdimen
\AtBeginDocument{%
  \ifnum\instanzapenalty=\maxdimen
    \instanzapenalty=\clubpenalty
  \fi}

\newcount\betweenstanzaspenalty \betweenstanzaspenalty=\maxdimen
\AtBeginDocument{%
  \ifnum\betweenstanzaspenalty=\maxdimen
    \betweenstanzaspenalty=100
  \fi}
% Primarily the five parameters above were set |\AtBeginDocument|
% unconditionally , but it was
% not good, 'cause thus they couldn't be set other way in
% the~preamble. As you see, we use the fact that in some circumstances
% a~|\dimen| register works as a~|\count|.
%
%
%
% \subdivision{Long line rest alignment to the right}

\newcounter{stanzanum}
\newif\ifalterstanzas


\newif\if@linetogether
% \changes{v0.68}{07/04/12}{added to meet ls-R needs}
\@linetogethertrue

\newcommand*\versehangright{%
\renewenvironment{verse}{%
  \par \setcounter{verselinenum}{0}\relax
  % As you'll see, stanza break is done by changing |\parskip| by |\par|
  % in vmode and then by |\everypar|. Below is preliminary---\hskip0spstoring old
  % value of |\parskip|. Idea of this hack comes from Marcin Woli\'nski.
  \verseinstanzaparskip=\parskip\relax
  \if@linetogether\interlinepenalty=\@M\fi
  \clubpenalty=0\relax \widowpenalty=0\relax
  \parindent=0pt\relax%here 'cause later optical centering deals with it.
  \ifcenterverse \parindent=\linewidth
       \advance \parindent by -\versegenericlinewidth
       \advance \parindent by -0.5\parindent
       \verseleftskip=\z@\relax% added 2006-07-15
   \fi% of \cs{ifcenterverse}
  \leftskip=\verseleftskip plus1fill\relax
  \advance\leftskip by\vocpussyhair\relax
   \ifmaxversewidth
       \dimen0=\linewidth
       \advance\dimen0 by -\parindent
       \ifdim\dimen0>\versemaxlinewidth
           \rightskip=\linewidth
           \advance\rightskip by-\parindent
           \advance\rightskip by-\versemaxlinewidth
           \advance\rightskip by0pt plus1fil
           \else\rightskip=0pt plus1fil
       \fi% of \cs{ifdim}
       \else\rightskip=0pt plus1fil\relax
   \fi% of \cs{ifmaxversewidth}
  \parfillskip=0pt plus1fil \hyphenpenalty=100 %
  \newif\ifstanzabreak
  \def\par{%
    \ifvmode %^^A\ifstanzabreak\penalty10000 \vskip\stanzaskip
       \ifnum0<\c@verselinenum\relax% we don't want stanza break before verse
         \ifstanzabreak
           \stepcounter{stanzanum}%
           \penalty10000 \vfil\penalty\betweenstanzaspenalty\vfilneg\relax
           % As announced, we change |\parskip| to make a~stanza break
           \parskip=\stanzaskip\relax \stanzabreakfalse\relax
           \ifalterstanzas
             \ifodd\c@stanzanum
               \ifnum\c@stanzanum>1\advance\leftskip-\versealtleftskip\fi
             \else\advance\leftskip\versealtleftskip
             \fi
           \fi
         \fi% of \cs{ifstanzabreak}
       \else
         \setcounter{stanzanum}{1}%
       \fi%  of \cs{ifnum\bslash c@verselinenum}
    \else
       \penalty\instanzapenalty\relax\stanzabreaktrue\relax
    \fi% of \cs{ifvmode}
    \ifhmode \strut% to make square bracketing case work properly
    % where there'll be |\nointerlineskip|
    \stepcounter{verselinenum}\relax
    \endgraf\parversesquareh@ck\fi}
  \everypar{% At new hmode we restore old value of |\parskip|.
    \parskip=\verseinstanzaparskip\relax
    % and then we hack with stretchability
    \hskip0ptplus-1fill\relax}
  % At the beginning of verse we give some skip
  \addvspace\verseskipbefore% not just |\vskip| 'cause this \LaTeX\
                            % command will check if there's another
                            % skip and 'll use the bigger one, not two.
  \def\br@cketskip [####1]{\vspace{####1}}% four |#|s, indeed!
  \def\\{\@ifstar{\nopagebreak\@ifnextchar{[}{\br@cketskip}{}}%^^A]
    {\@ifnextchar{[}{\br@cketskip}{}}}%^^A]
  \renewcommand*\newpage{\nopagebreak\vfil\pagebreak}%
  % I~redefine |\newpage| because the original one spoils |\leftskip| or
  % |\rightskip|, very important and delicate here.
%
\let\@doendpe\relax% so that |\par| redefing environments don't spoil
                   % verse's redef'ed |\par|
\def\^^M{\ \par}% to make it work as in normal catcodes

\let\@sanitize\gmverse@sanitize% for |\index| macros in active ^^M's
                               % scope (see below)
  \obeylines \the\everyverse \begversesquareh@ck%
}% of begdef{verse}
% enddef of \env{verse}:
{\ifhmode \par \fi \eversesquareh@ck%
  % ^^A\ifstanzabreak\else\vskip-\stanzaskip\fi% hope there'll be no need of
  % ^^A~reverse skip if stanza break is launched by \everypar
  \setbox0=\hbox{12324567890qypf[]gp}\prevdepth=\dp0 %
  % so that \TeX\ deal with usual |\baselineskip| not add |\lineskiplimit|
  \vskip\verseskipafter \relax
  \global\vocpussyhair=\z@\relax
  \@endpetrue
}% of enddef
}% of |\versehangright|

% \subdivision{Long line rest begun with a~[}^^A]
%
% The hacks given below i~wrote with Marcin Woli\'nski's help
% 2006/06/26 
\newcommand*\versehangrightsquare{\versehangright 
  \renewcommand*\begversesquareh@ck{\relax\dimen0=\prevdepth 
    \setbox0=\vbox\bgroup\prevdepth=\dimen0 \strut\e@tlineends}% 
  \renewcommand*\parversesquareh@ck{\relax\ifnum\prevgraf>1
    \setbox0=\lastbox  \nointerlineskip% not |\unskip|---we don't
    % remove interline glue and set new
    % but we assure there'll be a~proper
    % glue afrer first pass (see |\strut|
    % before |\endgraf|) and don't add any
    % new glue with [ pass ^^A]
    \hbox to \hsize{\hfill [\hskip-\leftskip\unhbox0}%^^A]
    \fi\relax}
  \renewcommand*\eversesquareh@ck{\relax\egroup\unvbox0\relax}%
\squ@rebrtrue% so that local calling of |\verseopticalcenter| call
             % this redefinition if called after it
}

% The pair of macros below is used to gobble ^^M's in |\obeylines|'
% scope. It uses the fact that Knuthian |\obeylines| |\let|s not |\def|s.
\def\e@tlineends{\futurelet\tokennotyete@ten\e@tlineend}
\def\e@tlineend{\ifx\par\tokennotyete@ten
  \expandafter\expandafter\expandafter\e@tlineends\expandafter\@gobble
  \fi}


% \subdivision{Centering and optical centering}

\newlength\versegenericlinewidth
\newlength\versemaxlinewidth
\newlength\versepussyhair% for additional correction in case of
                         % automatic optical centering.

\newif\ifcenterverse
\newcommand*\versecenterduest@r[1]{%
  \versegenericlinewidth=#1\relax \centerversetrue}
\newcommand*\versecenterduest@rless[1]{
  \settowidth{\versegenericlinewidth}{#1}%
  \centerversetrue}
\newcommand*\versecenterdue{%
  \@ifstar{\versecenterduest@r}{\versecenterduest@rless}}

\newif\ifmaxversewidth
\newcommand*\versemaxlinest@r[1]{%
  \versemaxlinewidth=#1\relax}
\newcommand*\versemaxlinest@rless[1]{%
  \settowidth{\versemaxlinewidth}{#1}%
  \maxversewidthtrue}
\newcommand*\versemaxline{%
  \@ifstar{\versemaxlinest@r}{\versemaxlinest@rless}}



\newdimen\re@ltextw% to store the real |\textwidth|
\newdimen\vocpussyhair% for a~finishing touch after optical
% centering. The name is owed to A.T. (one of Polish 
% typography Gurus), who used to say 
% ''Ja bym to jeszcze przesun\k a\l\ o~piczny w\l os w~lewo'' (`I'd
% move it left a~pussy hair') As you'll see, this register is cleared
% after each \env{verse} so you don't care about scopes.

\newcount\gmvs@counta
% A~scratch count for global assignments (originally it was |\count1|,
% not a~good idea.

\newcommand*\verseoptic@lcenter{%
  {\ifsqu@rebr\versehangrightsquare%
    \else\versehangright\fi%
    \global\let\inn@verse=\verse%
    \global\let\endinn@verse=\endverse\relax}%
%
  \renewenvironment{verse}{\par%
    \newtoks\verse@contens \verse@contens={}\relax%
    \long\def\per@verse####1\end####2{%
        \addto@hook\verse@contens{####1}\checkifpr@perend{####2}}%
    \def\checkifpr@perend####1{\def\pr@perend@test{####1}%
      \ifx\pr@perend@test\@currenvir%
      \addto@hook\verse@contens{\par}\expandafter\end{####1}%
       \else
       \addto@hook\verse@contens{\end{####1}}\expandafter\per@verse%
     \fi}%
  \defobeylines\per@verse}%of begdef
   % So we have all the environment's contents in the |\verse@contens|
   % tokslist
    {%
      {% we switch off some commands
        \def\br@cketskip [####1]{}% parameters are not allowed in enddef
        \def\\{\@ifstar{\@ifnextchar{[}{\br@cketskip}{}}%^^A]
          {\@ifnextchar{[}{\br@cketskip}{}}}%^^A]
        \renewcommand*\newpage{}%
        % and set |\par| for the first boxing (to measure)
        \def\par{%
          \ifhmode\endgraf%
             \ifnum\prevgraf=1 %
               \setbox0=\lastbox\setbox2=\hbox{\unhbox0}%
             \else
               \setbox2=\hbox to\re@ltextw{}%
             \fi%
% If the last paragraph typeset has only one line, we give it
% the weighing subroutine. If that paragraph has another number of
% lines, which means the respective line of the verse is longer than
% |\textwidth|, then we give a~|\textwidth|-long box the weighing
% subroutine.
%
% The question is still open how to center a~verse with very long
% lines. The solution chosen here seems to be reasonable if the long
% lines are rather seldom. (Note that weighing full-length lines
% |\prevgraf|${}-\mr1$ times and then the last paragraph line isn't
% advisable since the line rest is aligned right so it rather acts as
% a~full-length in perception of the verse.) Note that the weighing
% subroutine always gets a~line not longer than
% |\textwidth|.\label{textW}
             \voc@weighline 2 1 \gmvs@counta %parameters: |#1| box register, |#2| dimen
             % for total length, |#3| count for sum of weights
          \fi% of outermost |\ifhmode| and of |\par|
        }%of |\def\par|
        %
        % the very boxing and weighing
        % preliminaries
        \re@ltextw=\textwidth\relax        
        \ifvoccubic\global\voc@edivs=0\relax\fi% in cubic case we are
        % quite close arithmetics' limitations. This count is for
        % number of emergency divisions to avoid overflow.
        \textwidth=0.5\maxdimen\relax%
        \global\gmvs@counta=0\relax\global\dimen1=\z@\relax%
        % they'll be the number of lines and their scaled total length
        \setbox0=\vbox{%
          \the\verse@contens}% of |\vbox|
        % ^^A       \message{@it should be measured@}%
        % ^^A       \showthe\count1\showthe\dimen1%
        % 
        %
        % And the finale of weighing:
        \voc@weightotal 1 \gmvs@counta% |#1| input/result dimen, |#2| input count.\\
        % If there were emergency divisions just restore original
        % |\voc@scale| and nullize \nlpercent|\voc@edivs|
        \ifnum\voc@edivs>0\global\voc@scale=\@@voc@scale\relax
           \global\voc@edivs=0\relax
        \fi% of \cs{ifnum}\par
        % Common sense's touch:
        \ifdim\dimen1<\z@\global\dimen1=\z@\relax\fi
        \ifdim\dimen1>\re@ltextw\global\dimen1=\re@ltextw\relax\fi
        % ^^A\showthe\dimen1\relax%
    }% of group for first boxing
      \versecenterdue*{\dimen1}%
      \global\dimen1=\z@\relax%
      % and the very verse at last
      \expandafter\inn@verse%
      % \expandafter so that |\inn@verse| could see leading |^^M| signs
        \the\verse@contens%
      \endinn@verse%
  }% of verse's enddef
}% of |\verseoptic@lcenter|


\newif\ifvocgamma% to be able to make longer lines weigh more than
                 % short ones in the average.
\newif\ifvoccubic% switch for cubic weight function.
\voccubictrue
\newif\ifvocmax% switch for max weight function
%
% Two parameters below were experimentally set to given values
% under \pdfeTeX. The trial text was Wis\l awa Szymborska's
% ,,Pod jedn\k a~gwiazdk\k a'' verse typed in one verse environment 11
% times (and the cubic weighing option was taken)
% Chosen verse has many lines and all are long.
% If someone writes text with lines much than those more than 2
% times, \heshe\ should consider if what \heshe\ writes is really
% a~verse and therefore if should it be typeset in a~\env{verse}
% environment. 
\newcount\voc@scale \global\voc@scale="2000 % it'll give us .125pt precision 
\def\@@voc@scale{"2000}
\newdimen\vocunitlength \global\vocunitlength=8pt %
\newcount\voc@edivs% voc emergency divisions

\newcommand*\defvocgamma[1][false]{%
  \csname vocgamma#1\endcsname
  \ifvocgamma
     \def\voc@weighline##1##2##3{%\begin{enumargs}[2]
% \item  box register,
% \item  dimen for total length,
% \item  count for sum of weights
% \end{enumargs}
% 
% \stanza
% The box |##1| is |\re@ltextw|-wide at most, see the remark after
% line \ref{textW}. 
       \dimen0=\wd##1 %
       % we divide the length of a~line by |\vocunitlength|
       \dimen2=\vocunitlength
       %^^A\count2=\dimen2\relax \divide\count2 by \voc@scale\relax
       \count0=\dimen0 %
       \divide\count0 by\dimen2 %^^A\count2\relax
       % and advance |##3| by (square of) it.
       \ifvoccubic\multiply\count0 by \count0 \fi
       \global\advance##3by\count0 %
       % Now we scale the line length and add it's multiple to the
       % total scaled length.
       \divide\dimen0 by\voc@scale
       \multiply\dimen0 by\count0 %
       \global\advance\dimen##2by\dimen0 %
       \ifvoccubic% check if not danger of overflow and maybe emerg.\ divide
          \ifdim\dimen##2>0.875\maxdimen
             \global\divide\dimen##2 by2 %
             \global\multiply\voc@scale by2 %
             \global\advance\voc@edivs by1 %
             \dimen8=\voc@scale sp\relax
             \PackageWarningNoLine{gmverse}{%
               To avoid overflow \on@line\MessageBreak
               I had to diminish precision of optical centering.\MessageBreak
               Current precision is \the\dimen8.\MessageBreak
               (so far I have done \the\voc@edivs\space such emergency
               divisions.)}%
          \fi% of ifdim
       \fi% of \cs{ifvoccubic}
     }% of |\voc@weighline|
% 
   \def\voc@weightotal##1##2{%\begin{enumargs}[2]
     % \item input/result dimen, 
     % \item input count
     % \end{enumargs}
     \ifnum##2>0\global\divide\dimen##1 by##2 \fi%
     \global\multiply\dimen##1 by\voc@scale}%
   % If we wish to use ${}_\infty$ weight function:
   \ifvocmax
     \def\voc@weighline##1##2##3{%\begin{enumargs}[2]
       % \item box register,
       % \item dimen for total length,
       % \item count for sum of weights
       % \end{enumargs}
       % 
       % The box |##1| is |\re@ltextw|-wide at most, see the remark after
       % line \ref{textW}. 
       \dimen0=\wd##1 %
       \divide\dimen0 by\voc@scale
       \ifdim\dimen0>\dimen##2\global\dimen##2=\dimen0 \fi
       \global##3=1\relax
     }% of |\def\voc@weighline|
   \fi% of ifvocmax
 \else% (= |vocgammafalse|)
   \def\voc@weighline##1##2##3{% \begin{enumargs}[2]
     % \item  box register,
     % \item  dimen for total length,
     % \item  count for sum of weights
     % \end{enumargs}
     \global\advance##3by1\relax%
     % The box |##1| is |\re@ltextw|-wide at most, see the remark after
     % line \ref{textW}. 
     \dimen0=\wd##1 %
     \divide\dimen0by\voc@scale
     \global\advance\dimen##2by\dimen0 }%
   \def\voc@weightotal##1##2{%\begin{enumargs}[2]
     %          \item input/result dimen, 
     %          \item input count.
     % \end{enumargs}
     \ifnum\count##1>0\global\divide\dimen##1 by##2 \fi%
     \global\multiply\dimen##1 by\voc@scale}%
\fi%of \cs{ifvocgamma}
}%of |\defvocgamma|



\def\verseopticalcenter{\@ifnextchar{[}{\voce@tbrackets}%^^A]
  {\verseoptic@lcenter}}
\def\voce@tbrackets[#1]{\squ@rebrtrue\verseoptic@lcenter}
% As you see, the
%       |\verseopticalcenter|
% declaration has an optional parameter: if you write (anything in) []
% after it, it shall call squarebracket verse'ion.
% Anyway, if you call it where |\versehangrightsquare| declaration is at
% work, |\verseopticalcenter| will work with square bracket.


% From my personal \pk{gedlyr} package, to make possible put some
% prose into a~\env{verse} i.e., justified paragraphs with no indent,
% separated by |\stanzaskip|:
\newlength{\justrskip}
% |\justrskip| should be assigned in the very document to store value of
% |\rightskip| out of {verse}. We assign nothing, so by default it's |\z@|.
%
\newenvironment*{prosato}{\catcode`\^^M=5\relax%
  \rightskip=\justrskip\relax%
  \dimen0\leftskip\relax%
  \leftskip\dimen0\relax%
  \parfillskip\z@ plus1fil\relax%
  \def\par{\ifhmode\stepcounter{verselinenum}\fi\endgraf}%
  \interlinepenalty=10\relax%
  \linepenalty=10\relax%
  \clubpenalty=10000 \widowpenalty=10000%
  \everypar{\parskip1\stanzaskip%
  \everypar{}%
}%
  \let\itm\relax% back compatibility
  \let\\\newline%
  \let\itl\\% back compatibility
%^^A  \leavevmode\dwaem % in verses1.01.pdf it's not present.
}% of begdef.
{\par}% enddef.
%\nostanza You can still use \cs{prosato} as a~command
%(a~declaration). 

\newcommand*\psalmato{\alterstanzastrue
  \stanzaskip0sp plus0,5ex\relax\ignoreactiveM}



%%%%%%%% last hooking
\ifverseloc@l\else
\ifsqu@rebr\AtBeginDocument{\versehangrightsquare}
  \else\AtBeginDocument{\versehangright}
  \fi%of \cs{ifsqu@rebr}
  \ifv@c\AtBeginDocument{\defvocgamma[true]\centerversetrue\verseoptic@lcenter}\fi
  \fi



\def\gmverse@sanitize{\@makeother\ \@makeother\\\@makeother\$\@makeother\&%
  \@makeother\#\@makeother\^\@makeother\_% |%%\@makeother\%|
% other \% made me some trouble in |\index|ing long texts in
% |\obeyllines|' scope.
\@makeother\~%
\catcode`\^^M=5\relax}


\bgroup\obeylines
\firstofone{\egroup
  \long\def\ignoreactiveM#1{%
    \ifx
    #1\afterfi\ignoreactiveM%
    \else\afterfi#1\fi}}


\newenvironment*{verse0}
% \label{new envs}
{\verseskipbefore\z@skip\verseskipafter\z@skip\verse}
{\endverse}


% For easier declaring the degree of the weighing function:

\newcommand*\vocweigh[2][\newcommand]{%
  \ifx\newcommand#1\relax\afterfi\verseopticalcenter
  \else\afterfi{\verseopticalcenter[]}%
  \fi
  \ifcase#2%
  \or%1
    \afterfi{\voccubicfalse\vocmaxfalse\defvocgamma\relax}%
  \or%2
    \afterfi{\voccubicfalse\vocmaxfalse\defvocgamma[true]}%
  \or%3
    \afterfi{\voccubictrue\vocmaxfalse\defvocgamma[true]}
  \else
    \afterfi{\vocmaxtrue\voccubicfalse\defvocgamma[true]}%
  \fi}


\endinput

% \ChangesGeneral
%
%
%
% \changes{v0.69}{2008/01/15}{Global use of \cs{count1} replaced with
% \cs{gmvs@counta} in \cs{voc@weighline} and \cs{voc@weightotal}}
%
% \changes{v0.73}{2008/09/04}{A~bug fix: obsolete \cs{afterelsefi}
% changed to \cs{afterfi}}

% \PrintChanges
% \NoEOF
%
% removed, first approach to gamma voc
%
%
%        \def\@sixteenth{0.0625}\def\@sixteen{16}%
%
%
%        \dimen0=\re@ltextw\relax% d0 = tw
%        \advance\dimen0 by-\wd2\relax% d0 = tw-wd2
%        \dimen2=\re@ltextw\relax% d2 = tw
%        \divide\dimen2 by\dimen0\relax% d2 = tw/(tw-wd2), the
%        % less the better
%        \count0=17\relax% c0= 16+1
%        \ifnum8>\dimen2\advance\count0 by-\dimen2%
%        \else\advance\count0 by-8\relax\fi
%        % c0= 16-min(8,d2)
%        \dimen0=\@sixteenth\wd2\relax
%        \else% \wd2>=\re@ltextw
%        \count0=16\relax
%        \dimen0=\re@ltextw\relax
%        \fi% of \ifdim
%        \multiply\dimen0 by\count0


% (For my GNU Emacs:)
%%% Local Variables: 
%%% mode: doctex
%%% TeX-master: "../../../../LaTeX/TeXGuru/gmverse/gmverseDoc.tex"
%%% End: