summaryrefslogtreecommitdiff
path: root/language/typingtex/tally.sty
blob: 657eb964e09c9ddb0dd39d05c08adb7008176565 (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
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
%%%% TITLE: TALLY.STY,  Laurent Siebenmann 5-93, alpha version
 %%% --- a portable TeX tool for counting
 %%% paragraphs, lines, words, syllables, letters 
 %%% MASTER POSTING: ftp matups.matups.fr in directory TeX/TeXTyping
 %%% BUGS: To lcs@matups.matups.fr
 %%% DOCUMENTATION: below, with more after \endinput
 %%% 
 %%% SYNTAX : e.g. for word count 
 %%%  \WordCount <text>\endWordCount, OR, for LaTeX (only),
 %%%  \begin{WordCount}<text>\end{WordCount} 
 %%%  
 %%% FUNCTION: Tells number of words (etc) in the <text> by 
 %%% switching to a simple one-syllable-per-page style and 
 %%% counting calls to a degenerate output routine.
 %%% 
 %%% FEATURES
 %%% Hopefully for all formats. 
 %%% Portable:  uses TeX3.xx, nothing more (\LetterCount excepted)
 %%% Extras:
 %%%  \LineCount <text>\endLineCount %% counts lines
 %%%  \SyllableCount <text>\endSyllableCount %% counts syllables
 %%%  \LetterCount <text>\endLetterCount  
 %%%    Counts letters (and digits).
 %%%    It requires special format (see after \endinput).
 %%%  \AllCounts <text>\endLetterCount gives all 4.
 %%%  \AllCounts+ <text>\endLetterCount
 %%%    All 4 with math, punctuation, paragraph suppression
 %%%    plus deductions. Slow. LaTeX syntax is not available.
 %%%  
 %%% ADVICE AND CAUTIONS:
 %%% --- The <text> should contain the whole of 
 %%% any group environment etc. that it meets.
 %%% --- Learn what "word" means in practice.
 %%% "Jean-Pierre" is two words; J.~Bond is one.
 %%% \centerline{Bla bla bla ...} is one, as are
 %%% $<math>$ and $$<display>$$ and \hbox{<text>} 
 %%% and \vbox{<text>}. A texpert can change this somewhat.
 %%% --- \WordCount <text>\endWordCount 
 %%% will crudely rip <text> from your document, so
 %%% comment out "\WordCount" and "\endWordCount" etc.
 %%% in production runs. 
 %%% --- To conserve TeX capacity when counts are not in use
 %%% also comment out the input command for tally.sty.
 
 %%%% Prelims:
 \ifx\undefined\WordCountAt
 \else
    \def\temp{\immediate\write16{}\immediate\write16{%
       tally.sty already loaded\string!}\endinput}
    \expandafter\temp
 \fi
 %
 \chardef\WordCountAt=\catcode`\@
 \catcode`\@=11

 %%temporarily suppress Plain's logging of allocations
 \let\TY@wlog\wlog 
 \def\wlog#1{\relax} 

 %
 %%% \LE for letter counts.
  %% Syntax \begingroup  \LE <text> \endgroup please!
  %% Makes 0--9 and = counted letters. Nearly Pascal convention!
  %% Other punctuation not.
 \def\LE{%
  \ifx\undefined\l@LE
     \immediate\write16{}%
     \immediate\write16{ \string!\string!\string!
     Correct LetterCount requires special patterns.}
     \immediate\write16{ \string!\string!\string!
     See tally.sty internal documentation.}%
   \else
    \language=\l@LE
    \lefthyphenmin=0
    \righthyphenmin=0
     \lccode`0=`0
     \lccode`1=`1
     \lccode`2=`2
     \lccode`3=`3
     \lccode`4=`4
     \lccode`5=`5
     \lccode`6=`6
     \lccode`7=`7
     \lccode`8=`8
     \lccode`9=`9
     \lccode`==`=
   \fi
     }

 \def\QuietCounts{\let\CountPause\relax}
 \let\CountPause\show

  %% Conserve count registers by local use.
 \countdef\TY@cnt=190
 \countdef\TY@lefthyphenmin=195
 \countdef\TY@righthyphenmin=196
 \countdef\TY@cnti=200
 \countdef\TY@cntii=201
 \countdef\TY@accentcnt=202
 \countdef\TY@Lettercnt=203
 \countdef\TY@Syllablecnt=204
 \countdef\TY@Wordcnt=205
 \countdef\TY@Linecnt=206
 \countdef\TY@Parcnt=207
 \countdef\TY@SyllableLen=208
 \countdef\TY@Gaps=209
 \countdef\TY@LLcnt=210

  %% Conserve dimen registers by local use
 \dimendef\TY@hsize=200
 \dimendef\TY@everypar=201 
 \dimendef\TY@baselineskip=202
 \dimendef\TY@lineskiplimit=203
 \dimendef\TY@parskip=204
 \dimendef\TY@ChWd=205

 %%%% Gen@Count: the main macro.
   %% will always be surrounded by grouping
 \def\Gen@Count{%
 %%% Start 
 \vfil\par\break\let\Gen@Count\undefined 
 \let\endGen@Count\endGen@@Count
 %%% Impose a suitable language
 \SetTY@language
 %%% Horizontal changes
 \SetTY@everypar
 \SetTY@hsize
 \hbadness=10000
 \hfuzz=\maxdimen
 %\pretolerance=100000 %% Alas no effect!
 %%% Vertical changes
 \topskip=0pt plus \vsize  
 \baselineskip=\vsize\relax
 %%% Output changes
 \maxdeadcycles=2000000000 %% two billion words at most!
 \csname output\endcsname{\global\setbox255=\box\voidb@x}%
 %%% Initialize
 \deadcycles=0} 

 \def\endGen@@Count{%% defined \endGen@Count in time
  \vfil\par\break
  \errorcontextlines=0
  \immediate\write16{\space
    *** \Count@Mode\space= \the\deadcycles\space\TY@Msg}%
  \CountPause\CountPause %% gives pause
  \global\TY@cnt=\deadcycles
  \deadcycles=0}

 %%% Some defaults
 \def\TY@Msg{(starting at input line \the\inputlineno) ***}%
 \def\SetTY@hsize{\hsize=\z@\relax
                    \let\hsize\TY@hsize} %% uproot!
 \def\SetTY@language{}%
 \def\SetTY@everypar{\everypar\expandafter{\the\everypar\ }
    %% "\ " is glue allowing hyphenation of 1st word
    \let\everypar\TY@everypar %% uproot!
    }

 \def\TY@Safe@Acc#1#2{%
    \if i#2%
        #2\csname @#1@\endcsname \i
    \else
        #2\csname @#1@\endcsname #2\empty
    \fi}

 %\def \TY@CaesarFix{%
 %    \ifx\@Acc\Safe@Acc\let\@Acc\TY@Safe@Acc\fi
 %    \let\Safe@Acc\TY@Safe@Acc
 %    \JDaccents\let\noJDaccents\relax}

 \def \TY@CaesarFix{%
    \ifx\JDaccents\undefined
    \else \DSaccents\fi}

%%% \LetterCount:
 \def\LetterCount{\begingroup
    \TY@CaesarFix %% fixes CaesarXX and HyAcc-CM
    \let\accent\TY@accentcnt %% fixes Knuth
    \def\Count@Mode{LetterCount}%
    \def\SetTY@language{%
      \LE %% then uproot various things in it
      \let\lefthyphenmin\TY@lefthyphenmin 
         %% uproot \lefthyphenmin
      \let\righthyphenmin\TY@righthyphenmin 
         %% uproot \righthyphenmin
      \let\language\TY@language 
       }%
    \Gen@Count}
 %
 \def\endLetterCount{\endGen@Count\endgroup}
      
 %%% \SyllableCount: Simple!
 \def\SyllableCount{\begingroup
      \def\Count@Mode{SyllableCount}%
      \Gen@Count} %% language variation OK!?
 \def\endSyllableCount{\endGen@Count\endgroup}
 
 \newlanguage\l@Unitas
    %% hopefully saves time?
 
 %%% \WordCount: 
 \def\WordCount{\begingroup
    \def\Count@Mode{WordCount}%
    \def\SetTY@language{\language=\l@Unitas 
      \lefthyphenmin=10000 %% enough to stop hyphenation
      \let\lefthyphenmin\TY@lefthyphenmin %% uproot!
      \let\language\TY@language %% uproot!
      }
    \Gen@Count}
 \def\endWordCount{\endGen@Count\endgroup}
  
 %%% \LineCount: Simple!
 \def\LineCount{\begingroup
    \def\Count@Mode{LineCount}%
    \def\SetTY@hsize{}%
    \Gen@Count}
 \def\endLineCount{\endGen@Count\endgroup}
  
 %%% \ParCount:
 \def\ParCount{\begingroup
    \def\Count@Mode{ParCount}%
    \hsize=.5\maxdimen
    \baselineskip=\z@
       \let\baselineskip\TY@baselineskip %% uproot
    \lineskiplimit=-\maxdimen
       \let\lineskiplimit\TY@lineskiplimit %% uproot
    \parskip=2\vsize
       \let\parskip\TY@parskip %% uproot
    \Gen@Count}
 \def\endParCount{\endGen@Count\endgroup}
  
 \def\kill@punct{%
     \catcode`\.=10
     \catcode`\,=10
     \catcode`\;=10
     \catcode`\:=10
     \catcode`\!=10
     \catcode`\?=10
     }
 \def\kill@math#1${$\ignorespaces}
 \def\kill@display#1$${$$}
 \def\kill@par{\catcode"D=10\relax}
 
 %%% \AllCounts

 \def\AllCountsPlus@Extras{%
  %%% Mean syllable length
   \TY@cnti=\TY@Lettercnt
   \multiply\TY@cnti by 10
   \divide\TY@cnti by \TY@Syllablecnt
   \immediate\write16{}% 
   \immediate\write16{ *** 
    Mean syllable length = \the\TY@cnti\space char tenths}%
   \TY@SyllableLen=\TY@cnti
  %%% Mean word length
   \TY@cnti=\TY@Lettercnt
   \multiply\TY@cnti by 10
   \divide\TY@cnti by \TY@Wordcnt
   \immediate\write16{ *** 
    Mean word length = \the\TY@cnti\space  char tenths}%
  %%% Interword spaces per line
   \TY@cnti=\TY@Wordcnt\relax\count255=10
   \multiply\TY@cnti by \count255
   \divide\TY@cnti by \TY@Linecnt
   \multiply \count255 by -1
   \advance\TY@cnti by \count255
   \immediate\write16{ *** 
    Interword spaces per line = \the\TY@cnti\space tenths}%
   \TY@Gaps=\TY@cnti
  %%% Mean line length
   \TY@cnti=\TY@Lettercnt\relax \TY@cntii=\TY@Gaps\relax
   \divide\TY@cnti by \TY@Linecnt
   \TY@cnt=5\relax\advance\TY@cntii by \TY@cnt\relax
   \TY@cnt=10\relax\divide\TY@cntii by \TY@cnt\relax
   \advance\TY@cnti by \TY@cntii\relax\TY@LLcnt=\TY@cnti
   \immediate\write16{ *** 
    Mean line length = \the\TY@LLcnt\space chars}%
  %%% Mean character width
   \TY@cnti=\TY@LLcnt\relax\dimen8=\hsize
   \divide\dimen8 by \TY@cnti\relax\TY@ChWd=\dimen8\relax
   \immediate\write16{ *** 
    Mean character width = \the\TY@ChWd\space (for \string\rm)}%
   \multiply\dimen8 by \TY@SyllableLen\relax
   \TY@cnti=10\relax\divide \dimen8 by \TY@cnti \relax
   \immediate\write16{ ***** Suggested \string\emergencystretch 
        \space= \the\dimen8}%
  %%% Strain per interword space 
   \TY@cnti=\TY@SyllableLen\relax
   \TY@cnt=50
   \multiply \TY@cnti by \TY@cnt
   \ifnum\TY@Gaps>0\relax\divide\TY@cnti by \TY@Gaps\relax
   \else\TY@cnti=10000\relax
   \fi
   \immediate\write16{ *** Strain per interword space = 
      \the\TY@cnti\space char hundredths}%
  %%% Badness of mean interword strain
   \multiply \TY@ChWd by \TY@cnti
   \rm\dimen0=\fontdimen3\font\relax
   \divide\TY@ChWd by \dimen0
   \TY@cnt=\TY@ChWd\relax \TY@cntii=100
   \multiply\TY@cnt by \TY@ChWd\relax\divide\TY@cnt by \TY@cntii
   \multiply\TY@cnt by \TY@ChWd\relax\divide\TY@cnt by \TY@cntii
   \immediate\write16{ *** Badness of mean interword strain
       (for \string\rm) \the\TY@cnt}%
   \TY@cntii=8 \multiply \TY@cnt by \TY@cntii\relax\TY@cnti=100
   \ifnum\TY@cnt<\TY@cnti\relax\TY@cnt=100\fi
   \immediate\write16{ ***** Suggested \string\hbadness \space
        = \the\TY@cnt\space for present \string\hsize=\the\hsize}%
   \immediate\write16{}% 
   }

 \def\AllCountsPlus{\begingroup
   \kill@punct
   \parindent=\z@\kill@par
   \everymath{\kill@math}%
   \everydisplay{\kill@display}%
   \let\AllCounts@Extras\AllCountsPlus@Extras
   \immediate\write16{ **** AllCounts+  starting at 
    input line \the\inputlineno \space ***** }%
  \AllCounts@\gobble
  }

 \def\gobble#1{}
 \def\AllCounts@Extras{} %% default

 \def\AllCounts{\futurelet\next\AllCountsMole}

 \def\AllCountsMole{\ifx\next+\expandafter\AllCountsPlus
         \else\begingroup\expandafter\AllCounts@\fi}

 \long\def\AllCounts@#1\endAllCounts{%
  \def\CountPause{}%
  \def\TY@Msg{***}%
  \immediate\write16{}%  
  \LetterCount#1\endLetterCount
    \TY@Lettercnt=\TY@cnt
  \SyllableCount#1\endSyllableCount
    \TY@Syllablecnt=\TY@cnt
  \WordCount#1\endWordCount
    \TY@Wordcnt=\TY@cnt
  \LineCount#1\endLineCount
    \TY@Linecnt=\TY@cnt
  \ParCount#1\endParCount
    \TY@Parcnt=\TY@cnt
  \AllCounts@Extras
  \endgroup
  \CountPause\CountPause
  }

 \let\wlog\TY@wlog
 \catcode`\@=\WordCountAt

 \endinput

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%  Simple test
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 %\documentstyle{article} %% for LaTeX
 %\begin{document} %% for LaTeX
 %\input tally.sty %% for Plain and her children


 aaaaaaaaaaaaaaaaaaaaaaaa

\def\Hii{Hi! Hi! Hi! Hi!
    %\footnote{*}{Foot foot foot} 
   Hi! Hi! Hi! Hi! Hi! Hi!
   $x=y=z<yt$
Frederico Frederico!\ }

\Hii

\SyllableCount

Jean-Pierre approaches.%\showhyphens{approaches}

$$x=y=z<yt$$

\endSyllableCount

\LetterCount

Jean-Pierre approaches.%\showhyphens{approaches}

$$x=y=z<yt$$

\endLetterCount

\LineCount
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! 
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!
\endLineCount

\AllCounts+
 %\def\insert#1{\ }
 \Hii \Hii \Hii \Hii \Hii
\endAllCounts


zzzzzzzzzzzzzzzzzzzzzzzzzz

 \end{document} %% for LaTeX

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

PUBLICITY FOR tally.sty: revised from TeX-Euro list May 1993
 ---tex-euro@dhdurz1.bitnet of listserv@dhdurz1.bitnet


   **** TEX COUNTS LINES WORDS SYLABLES LETTERS **** 

     Manuel Carriba (M.Carriba@dcs.shef.ac.uk) asked:

  > ... I would like to know if there is a possibility to 
  > count the words in a LaTeX document...

     Philip Taylor, RHBNC <P.Taylor@Vax.Rhbnc.ac.uk> replied:

  > Use DVIspell from the emTeX suite [of E. Mattes], then 
  > count the resulting words using your favourite word counter.

DVIspell is one of the recent miracles of TeX; it requires
careful parsing of the .dvi file.

     Yannis Haralambous <yannis@gat.citilille.fr> suggested
what is potentially an ad hoc simplification:

  > A weird answer (which could very well fit in a Lovecraft
  > novel):...
  > PS. if anyone ever tries this method, let me know please

Yannis' idea is to use <beginning-of-word mark> and
ligature/kerning to insert a tagging character to mark each
beginning-of-word in the .dvi file. 

     As neither solution is very portable, I wish to propose
a completely portable solution tally.sty based on TeX's
line-breaking and \output.  

     tally.sty also provides paragraph counts,  line counts
syllable counts, and letter counts. The syllable counts are 
*not* available via tools based on the ".dvi" file. The full
spectrum of counts help one evaluate and tune hyphenation
performance, so several relevant auxiliary calculations are made.

     I have a feeling this is a genuinely useful gadget. 
Enjoy!  

                 Laurent Siebenmann <lcs@matups.matups.fr>


Notes.

 (i)  tally.sty bore the name wordcnt.sty for the first 
 few weeks of its existence.

 (ii) The present name tally.sty comes from Latin talea for
stick. Notched sticks were used for counting and accounting;
lengthwise splitting of the notched stick provided "carbon"
copies.



 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     **** SPECIAL FORMAT COMPILATION FOR LETTER COUNTING ****

     The letter counting macro

          \LetterCount <text> \endLetterCount
 
requires the special language LE in which each LEtter and
each digit is a syllable. You have to add it at format
compilation  time with INITEX.  Near where other hyphenation
files are \input, it  should suffice to add to your INITEX
script the three lines:

 \newlanguage\l@LE  
 \language=\l@LE
 \input lehyphen.tex %% a very small patterns file
    %% appended to this file

The crudest way is to add these lines to plain.tex after: 

      input hyphen.tex

Since the LE compiled hyphenation patterns are tiny (280
bytes), it is perfectly reasonable to incorporate them into
standard formats. 

     In case the LE patterns are needed but *not* present,
tally.sty will issue a warning message.


 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 **** \AllCounts+ used to evaluate 
       and tune hyphenation performance ****

      There are many hyphenation systems for Euopean languages
freely available on the  CTAN archives,    and there are often
several for the same language. Which is adequate?  Which is
best, all things considered? How can a given one be tuned to a
given task?

      The average length of syllables in a text is a good 
measure of performance of a hyphenation system. Indeed  this
length divided by two is the average stretch that will be
imposed on a justified line --- with the important proviso
that devation from the mean syllable length is negligible.

      The formula to calculate this average is #G/#S where
#G is the number of letters (Glyphs) and #S is the number
of syllables.  

      The quality of the hyphenation is also dependant on the
average word length and this is is chiefly  a function of the
language and of the nature of the text. The reason for this
dependance is that the stretchiness present in a line is 
roughly the interword stretch multiplied by [N-] where N is
the number of words in the line. Here [N-] is the greatest
integer strictly less than N. (This is for a justified text.)

      Thus, the average stretching imposed on a space in a
justified line is roughly proportional to both average
syllable length and average word length but inversely
proportional to the line length.  The product of the first two
is a measure of the expected badness of the text with regards
to line breaking; it is independant of the typesetting and even
of the order of the words.  And this quantity divided by line
length in characters (see below) is approximately the strain
on an a single interword space --- a useful measure of the
expected badness of the linebreaking. A typographer-designer
may wish to calculate these measures of  badness, and contrive
to keep them below some limit values that experience suggests. 
Line length, font, magnification, and hyphenation system  are
the main control paramaters he can vary.

      The above discussion neglects punctuation and the spacing 
around it, hopefully a second order effect.

      The syntax

     \AllCounts <text>\endAllCounts  

shows all four counts. There is a further option

     \AllCounts+ <text>\endAllCounts  

that provides helpful extras.

     Before using \AllCounts+, best clean out unusual material
like titles tables inserts rules from a representative page or two
of prose.   If the paragraph count is then >1 the cleanup has been
less than perfect, but that may not matter.

     \AllCounts+ forgets all math and displays and punctuation
and paragraphs. Only those paragraphs indicated by blank
lines  are successfully suppressed.

     \AllCounts+ calculates mean syllable length in characters,
and the mean number of wordbreaks per line, plus a few other
derived quantities.

     One of them is the number of characters per line.
The space between words is counted as a character; this makes
the calculated value more nearly constant when word length varies.

     Another is Knuth's badness for the strain on interword space
that would occur for syllables of mean size. Knuth normalises this
badness to be 100 when strain equals stretchiness; it then
increases as the third power of the strain (thus eightfold when
strain doubles). A setting for \hbadness is proposed by
\AllCounts+  that will assure that a warning is logged for precisely
those lines in which strain exceeds TWICE the mean stretchiness.

     \emergencystretch is the quantity of stretchiness that TeX
adds to renormalise its linebreak optimisation mechanism in
case the  arithmetic goes off scale. A setting for
\emergencystretch is suggested that is twice the strain that
would be caused by syllables of mean length.

      A major factor in hyphenation has escaped us. Occasional
long syllables have a disproportionate ill effect on
hyphenation. Standard deviation from the mean might evaluate
this; but tally.sty does not provide any measure of this
deviation.  However with the suggested settings of \hbadness
and \emergencystretch one can hope to resort to ad hoc
measures whenever a line creates an underfull \hbox warning.
This is as Knuth intended. The reasonable settings suggested by
tally.sty thus help make Knuth's concepts work.  


Summary for \AllCounts+ :   The quantities calculated are
helpful in choosing a hyphenation system,  and in choosing a
page design parameters (notably \hsize and \magnification). 
They may also help an author keep his manuscript within
prescribed limits. Finally, they should help choose
reasonable values of \emergencystretch and \hbadness to 
facilitate ad hoc improvements in response to underfull
hboxes.


 *** Hyphenation systems for specific tests.  

   HyAcc-CM.tex
   CaesarCM.tex 
   CaesarCK.tex

are tuned to several sorts of font.  You will be able to see
quite different performances depending on both the font and
the macro settings.  The format compilation mechanism
format-dumper-xx (xx=cm or ck) compiles corresponding
formats.  All of these are found on ftp matups.matups.fr
and/or the CTAN archives.


 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     **** LIMITATIONS AND REMEDIES ****

    (A) Boxes: tally.sty messes up counting within boxes: a
whole box of words will usually be counted as one or none.  This
is the case for

   \centerline{My Title}

There are usually ad hoc remedies --- in this case try:

     \let\centerline=\  

     Many cases of this problem are well disguised by macros.
In amsppt.sty bibliographies for example, one gets roughly the
number of entries rather than the count requested. Again there
is an ad hoc fix.

    (B)  Inserts: A somewhat different problem is posed by
inserts, in particular footnotes.  Inserts are excluded from
the count and are stored up and printed after the count is
complete. Try \def\insert#1{\ } to change this.

    (C)  Math: If you do not want each block of math to add
one to the count try

   \def\gobblemath#1${$}
   \everymath{\gobblemath}

Similarly for displays. See \AllCounts+.

   (E)  Initial words (a solved problem!): Normally TeX does
not attempt to hyphenate the first word of a paragraph, since
it looks foreward from glue items to find words to hyphenate,
[TeXBook page 454]. Parindent is, as it turns out, not a
suitable starting point, so the first word of a paragraph is
normally not hyphenated!  Thus the counting macros add some
glue to the right end of of the \everypar token list.  Drastic
measures have been taken to prevent TeX macros from redefining
\everypar and thus destroying this useful glue: the \everypar
syntax is "uprooted", ie  detached from primitive meaning and
temporarily attached  to a "meaningless" token register.

Remark: This "uprooting" device is much used, for example to
protect the typescript from commanding a \language change 
while a \LetterCount is under way. It may be the
source of bugs still to be encountered, notably where applied
to \hsize, and \baselineskip. However \par seems
"non-uprootable", perhaps because it is secretly cited by name
in the execution of other primitives of TeX.

   (F)  The automatic cleanup provided by \AllCounts+ intends
to get rid of everything but words --- in order to evaluate
linebreaking for plain prose; but it is imperfect.

    (a) The punctuation is given category 10 (=space). That
means that  punctuation in predefined macro expansions does
not evaporate.

    (b) The carriage return is also given category 10 (=space).
(Recall that \par cannot  be "uprooted".) Thus paragraphs
implicit in (sub)titles  of various sorts are not eliminated.

Add these to the list of stuctures you may wan to clean out by ad
hoc means.



 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%% lehyphen.tex %% LEtter count hyphenation patterns
   %% for use with word tally.sty
   %% to let \LetterCount<text>\endLetterCount count the letters

 \begingroup
 \catcode`@=11
 
    %%% Globally set high ASCII to 12
  %%
    \count@="80
    \loop
   \global\catcode\the\count@=12
    \ifnum\count@<"FF
   \relax\advance\count@ by 1
    \repeat
 
 %%% Globally set their Cork default lc-uc codes   
  \newcount\Ct@
  \newcount\Ct@@
  \newcount\Ct@@@
  \toks0={% 
  \loop
  \Ct@=\count@\advance\Ct@ by 32 
    %% \count@ is Plain scratch counter \count255
  \global\uccode\the\count@=\the\count@
  \global\lccode\the\count@=\the\Ct@
  \global\uccode\the\Ct@=\the\count@
  \global\lccode\the\Ct@=\the\Ct@
  \ifnum\count@<\Ct@@
  \relax\advance\count@ by 1
  \repeat
  }
 
   \count@="80 \Ct@@="9E \the\toks0 %% segment "80 to "BF
   %% "9F is \S and "BF is pound
   \count@="C0 \Ct@@="DF \the\toks0 %% segment "C0 to "FF
   \lccode"BD=0\uccode"BD=0 %% !!
   \lccode"BD=0\uccode"BD=0 %% ??
 
  %% count figures as letters!?
\lccode`0=`0
\lccode`1=`1
\lccode`2=`2
\lccode`3=`3
\lccode`4=`4
\lccode`5=`5
\lccode`6=`6
\lccode`7=`7
\lccode`8=`8
\lccode`9=`9
\lccode`==`=


 \patterns{%
1^^301
1^^311
1^^321
1^^331
1^^341
1^^351
1^^361
1^^371
1^^381
1^^391
1<1
1=1
1>1
1a1
1b1
1c1
1d1
1e1
1f1
1g1
1h1
1i1
1j1
1k1
1l1
1m1
1n1
1o1
1p1
1q1
1r1
1s1
1t1
1u1
1v1
1w1
1x1
1y1
1z1
 }

 \patterns{%
 %1^^9D1 %% Turkish dot I
 1^^9E1 %% croatian \dj
 %1^^9F1 %% \S
 % 
1^^a01
 1^^a11
 1^^a21
 1^^a31
 1^^a41
 1^^a51
 1^^a61
 1^^a71
 1^^a81
 1^^a91
 1^^aa1
 1^^ab1
 1^^ac1
 1^^ad1
 1^^ae1
 1^^af1
  %
 1^^b01
 1^^b11
 1^^b21
 1^^b31
 1^^b41
 1^^b51
 1^^b61
 1^^b71
 1^^b81
 1^^b91
 1^^ba1
 1^^bb1
 1^^bc1
 %1^^bd1 %% !!
 %1^^be1 %% ??
 %1^^bf1 %% pound
  %
 1^^e01
 1^^e11
 1^^e21
 1^^e31
 1^^e41
 1^^e51
 1^^e61
 1^^e71
 1^^e81
 1^^e91
 1^^ea1
 1^^eb1
 1^^ec1
 1^^ed1
 1^^ee1
 1^^ef1
  %
 1^^f01
 1^^f11
 1^^f21
 1^^f31
 1^^f41
 1^^f51
 1^^f61
 1^^f71
 1^^f81
 1^^f91
 1^^fa1
 1^^fb1
 1^^fc1
 1^^fd1
 1^^fe1
 1^^ff1
 }

 \endgroup

%%% end of lehyphen.tex for tally.sty