summaryrefslogtreecommitdiff
path: root/macros/generic/misc/ragged.sty
blob: 909de8695cefa7d002e7b7d2c6ff906068855206 (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

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%% ragged.sty by Laurent Siebenmann, March 1996 --
  %% beta version of Mar 30, 1996.
  %% Aim: Maintain hyphenation and raggedness control
  %% while providing the following for all formats.
  %% --- to make a paragraph ragged on left and justified   
  %% on right, use the syntax
  %% \raggedL <paragraph> 
  %% --- to make a paragraph ragged on both left and right  
  %% (and symmetric), use the syntax
  %% \raggedC <paragraph>  
  %% \raggedR is essentially equivalent \raggedright of Plain
  %% or to \RaggedRight of raggedri.sty of G. Schr"oder.
  %% All three \raggedX should give the same linebreaks; they 
  %% just provide different horizontal positioning of the lines.
  %% Documentation of options etc. follows \endinput.
  %% Run this file alone to see a demo.
 
 \ifx\undefined\raggedL\else\expandafter\endinput\fi
 
 \chardef\raggedcatAT=\catcode`\@ \catcode`\@=11
 
 %%temporarily suppress Plain's logging of allocations
 \let\R@Gtemp\wlog 
 \def\wlog#1{\relax} 
 
 \newbox\R@Gvbox
 \newbox\R@Ghbox
 \newbox\R@Ghbox@
 
 \newcount\R@Glinect
 
 \newskip\R@Gfillskip
 
 \newdimen\R@Gauxdim
 \newdimen\R@Gindentdim
 \newdimen\R@Ghsize
 \newdimen\raggedStretch
 
 \raggedStretch=10\p@ %% default
 
 \newtoks\raggedEnv
 \newtoks\raggedEnvOnce
 
 \let\wlog\R@Gtemp 
 
 \R@Gfillskip=\z@ plus 1fil
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%% Core macros

 \def\R@Gprep{\ifhmode
  \errmessage{ Do not use 
     \noexpand\raggedX commands in horizontal mode}%
  \expandafter\par\fi}
 
 \def\R@Gcore{%
  \setbox\R@Gvbox=\vbox\bgroup 
   \hsize=\maxdimen \leftskip=\z@
   \hskip\z@skip}
 
 \def\CalcR@GIndent@{%
  %% first set \R@Gindentdim to excess of \R@Ghsize over remainder
  \R@Gindentdim=\hsize
  \advance\R@Gindentdim by -\rightskip
  \advance\R@Gindentdim by -\wd\R@Ghbox@
  %% second convert to hang as l,c,r demand
  \fixR@Ghang@ %% \R@Gindentdim=.5\R@Gindentdim for \raggedC
  }%

 \def\endR@Gcore{\endgraf
  \global\R@Glinect=\prevgraf
  \global\setbox\R@Ghbox=\lastbox
  \egroup %
  \ifcase\R@Glinect\relax %% 0
  \or \endR@Gcore@ %% 1
  \else \errmessage{\noexpand\raggedX is failing. 
    Read about \string\RaggedX}\endR@Gcore@ %% >1
  \fi}
 
 \def\endR@Gcore@{%
  \setbox\R@Gvbox=\vbox{%
    \unhcopy\R@Ghbox\unpenalty\unskip\unskip
    \endgraf\global\R@Glinect=\prevgraf %\showthe\prevgraf
    \global\setbox\R@Ghbox@=\lastbox}%
  \setbox\R@Ghbox@=\hbox{%
    \unhbox\R@Ghbox@\unpenalty\unskip\unskip}%
  \CalcR@GIndent@ %% 
  \ifdim\R@Gindentdim>\z@
    \hangindent=\R@Gindentdim %\showthe\R@Gindentdim
  \else
    \hangindent=\z@ 
    %% Rmk: neg hangindents are from right margin
  \fi
  \advance\R@Glinect by -1\relax
  \hangafter\R@Glinect
  \unhbox\R@Ghbox
  \endgraf}

 \def\endR@@G{\endR@Gcore\let\par\R@Goldpar\endgroup}

 \def\raggedFrac#1{\def\R@GFrac{#1 }}

 \raggedFrac{1} %% default

 \def\R@GEnv@{%
  %\parskip=4pt plus 1pt 
  %\baselineskip=12pt
  %\parfillskip=0pt plus 1fil
  %\emergencystretch=20pt
  \finalhyphendemerits=20000 % 5000 is Plain default
  \parindent=\z@ %% 0
  \pretolerance=\@M %% 10000
  %% end of options easily changeable 
  %% via \raggedEnv{...} and \raggedEnvOnce{...}
  \let\R@Goldpar\par 
  \let\par\endR@@G
  \R@Gauxdim=\hsize 
  \advance\R@Gauxdim by -\leftskip
  \advance\R@Gauxdim by -\rightskip
  \R@Ghsize=\R@GFrac\R@Gauxdim
  \advance\R@Gauxdim by -\R@Ghsize
  \R@GRedefs
  \the\raggedEnv
  \the\raggedEnvOnce\global\raggedEnvOnce{}%
  }%

 \def\R@GRedefs{\let\break\R@Gbreak
  \let\vadjust\R@Gvadjust@
  \everydisplay{\R@Geverydisplaymole@}}

  \def\R@Gnono{ is forbidden with \string\raggedX}
  \def\R@Gbreak{\errmessage{\noexpand\break\R@Gnono}\penalty-\@M}%
  \def\R@Gvadjust@#1{{\tt (USE OF vadjust)}%
        \errmessage{\noexpand\vadjust\R@Gnono.\space See output}}%
  \def\R@Geverydisplaymole@#1$${$${\tt (DISPLAY)}%
        \errmessage{Display math\R@Gnono. See output}}%

  \def\raggedHrule{\unskip\penalty0
        \vrule height0.3\p@ depth-0\p@ width \R@Ghsize \penalty0}%

 %%% \R@GEnv@@ corrects \R@Ghsize if user has modified it 
  %% through \leftskip, \rightskip via \raggedEnv{...}
  %% then does other last minute tasks tasks
 \def\R@GEnv@@{%
   \R@Ghsize=\hsize
   \advance\R@Ghsize by -\leftskip
   \advance\R@Ghsize by -\rightskip
   \parfillskip=\R@Gfillskip
   }

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%% User macros

 %%% \raggedC 
 \def\raggedC{\R@Gprep\begingroup
  \leftskip=1\leftskip \rightskip=1\rightskip 
  \R@GEnv@
  \advance\leftskip by .5\R@Gauxdim plus .5\raggedStretch
  \advance\rightskip by .5\R@Gauxdim plus .5\raggedStretch
  \def\fixR@Ghang@{\R@Gindentdim=.5\R@Gindentdim}%
  \R@GEnv@@ 
  \R@Gcore}

 %%% \RaggedC 
 \def\RaggedC{\R@Gprep\begingroup\let\R@Gcore\relax
  \let\R@GRedefs\relax\raggedC
  \parfillskip=\z@ 
  \def\par{\let\par\R@Goldpar\par\endgroup\endgroup}%
  }

 % %%% \raggedR@ is strict analog of \raggedR@, \raggedC@
 %  %% present for testing only
 % \def\raggedR@{\R@Gprep\begingroup
 %  \R@GEnv@ %% not needed
 %  \advance\rightskip by \R@Gauxdim plus \raggedStretch 
 %  \def\fixR@Ghang@{\R@Gindentdim=0\p@}%
 %  \R@GEnv@@ 
 %  \R@Gcore
 %  }

 %%% \raggedR is more robust then \raggedL, \raggedC as it
  %% it allows $$...$$ and \vadjust, \break etc. in paragraph.
 \def\raggedR{\R@Gprep\begingroup
  \let\R@GRedefs\relax
  \R@GEnv@ %% initial part
  \advance\rightskip by \R@Gauxdim plus \raggedStretch 
  \R@GEnv@@ 
  \def\par{\let\par\R@Goldpar\par\endgroup}%
  }

 %%% \RaggedR 
 \def\RaggedR{\R@Gprep\raggedR
   \parfillskip=\z@\relax}

 \def\raggedL{\R@Gprep\begingroup
  \R@GEnv@
  \advance\leftskip by \R@Gauxdim plus \raggedStretch 
  \def\fixR@Ghang@{}%
  \R@GEnv@@ 
  \R@Gcore}

 %%% \RaggedL 
 \def\RaggedL{\R@Gprep\begingroup\let\R@Gcore\relax
  \let\R@GRedefs\relax\raggedL
  \parfillskip=\z@ 
  \def\par{\let\par\R@Goldpar\par\endgroup\endgroup}%
  }

 \def\gobble#1{}

 \catcode`\@=\raggedcatAT 

 %%%% END INPUT IF THIS IS NOT A DEMO RUN !
 \edef\temp{\csname\jobname\endcsname}%
 \edef\Temp{\csname ragged.sty\endcsname}%
 \ifx\temp\Temp\else
   \expandafter\endinput 
 \fi

 %%%% END OF MACROS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%% BEGINNING OF DEMONSTRATION
  %%% TESTS FOR \raggedX

 \ifx\documentstyle\undefined
   \let\documentstyle\gobble \let\begin\gobble
 \fi
 \documentstyle{article} 
 \begin{document}

 \hsize=400pt

 \raggedStretch=1000pt
 \RaggedC
      THESE ARE TESTS FOR ragged.sty\break
     EXPORT THE TESTS BEFORE PLAYING WITH THEM
 \bigskip

  \widowpenalty=10000
  \leftskip=0\hsize %plus 10pt
  \rightskip=0\hsize %plus 10pt
  \raggedStretch=10pt %% 10pt dafault
  \raggedFrac{.5}
  \raggedEnv{\parskip=4pt plus 3pt
    \emergencystretch=20pt
    %\pretolerance=100
    }
  \parskip=0pt plus 2pt
  \parindent=0pt

\def\TESTTEXT{It is the union of passionate interest in detailed
facts with equal devotion to abstract generalization which forms
the novelty in  \hbox{our present society}. }

 \TESTTEXT

 %\raggedEnvOnce{\raggedStretch=0pt}
 \raggedL\raggedHrule
 % $$dfd$$ %\vadjust{\hrule}% \break
 \TESTTEXT

 \raggedL
 {\sl A.N. Whitehead}

 \raggedC\raggedHrule\TESTTEXT

 %\raggedEnvOnce{\parskip=0pt}
 \raggedC{\sl A.N. Whitehead}


 \raggedR\raggedHrule\TESTTEXT

 \raggedR
{\sl A.N. Whitehead}

 %\end
 %{document}

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%  TESTS FOR \RaggedX
 
  \raggedStretch=1000pt %% default 10pt %% play with this
  \raggedEnv{%
    %\linepenalty=0 %% default 50 %% play with this
    \parskip=4pt plus 3pt
    %\pretolerance=0 %% default 100
    %\hyphenpenalty=0 %% default 50
    }

 \bigskip \hrule \bigskip

 \TESTTEXT

  \RaggedL\raggedHrule\TESTTEXT

 \raggedL
{\sl A.N. Whitehead}

 
 \RaggedC\raggedHrule\TESTTEXT

 %\raggedEnvOnce{\parskip=0pt}
 \raggedC{\sl A.N. Whitehead}


 \RaggedR\raggedHrule\TESTTEXT

 \raggedR
{\sl A.N. Whitehead}

\end
{document}

 %%%% END OF TESTS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


         *****    USER DOCUMENTATION FOR ragged.sty     *****



 *** TYPICAL EXAMPLE

  \input ragged.sty 

  \raggedFrac{.4}
  \raggedEnv{\parskip=4pt plus 3pt}
  \raggedL\raggedHrule 
I was not a Child~Prodigy, because a Child~Prodigy is
a child who knows as much when it is a child as it 
does when it~grows~up.
               
\raggedL
{--- Will Rogers}

The above will produce a quotation that is aligned to the right margin,
ragged on the left and having about .4 the width of a normal line. 

     Just compose this file itself to see to see a more extensive
example instantly composed.



 *** INTENDED USES

(i) For "ragged-left-and-flush-right" formatting of short prose
quotations tradionally placed  at the end  of book chapters.   

(ii) For captions on figures in an artistic page layout.  

(iii) For notes in a left hand margin ragged on the left and aligned
on the right.

 (iv) For "raggedleft" composition of left-hand pages of of narrow
brochures --- matching "raggedright" composition of right hand pages.

     Admittedly, hand specification of linebreaks is often the best
option, and that is how Don Knuth proceeds for use (i) in most of his
books. But in case reformatting for different page sizes or screen sizes
is anticipated, Knuth's alternative should be avoided like the plague;
this should apply to all documents distributed in ".tex" typescript
format.  The last 3 applications seem to demand good control on
raggedness and hyphenation.



 *** NOVELTY 

     It is too early to assert with confidence that ragged.sty offers
genuinely new capabilities in all formats.

     Hopefully \raggedL and \raggedC offer something new even for LaTeX
users. The standard "center" and "flushright" environments of LaTeX do
*roughly* the same thing by a different method.  But the macros
\raggedL and \raggedC seem a necessery innovation in case one wants
control on raggedness and/or hyphenation.

     Outside LaTeX, even the  offer even the more limited LaTeX features
are little known; thus, particularly sturdy macros \RaggedC and  \RaggedL
are also offered by ragged.sty to provide just the  LaTeX features in
other formats --- which means all features except raggedness control and
hyphenation.



 *** USER CONTROL SEQUENCE SUMMARY

The \raggedX trio:
\raggedL <paragraph> %% sets paragraph ragged on left justified on right
\raggedC <paragraph> %% sets paragraph ragged on both left and right
\raggedR <paragraph> %% sets paragraph ragged on right justified on left
See also the companion trio \RaggedX below.

With the default configuration, each of these leaves an arbitrarily
short last line while maintaining some tension on earlier lines
(\raggedStretch=10pt, total raggedness stretch).

Only the following paragraph is affected by each.

 --- \raggedHrule provides a horizontal line of the ragged text width
if put *immediately after* \raggedX.  

 --- \raggedFrac{<decimal fraction>} sets the length of the lines of
the ragged-set paragraphs as a fraction of current line length. 
The  current line length is 

        (\hsize  diminished by  \leftskip  and  \rightskip)

 --- \raggedEnv{...} is to be placed before \raggedX; it allows the user
to redefine parameters for the  line breaking environment of \raggedX. 
Inspect the definition  of the internal macro \R@GEnv@ for hints on
which parameters to change.  Never change the code in ragged.sty;
your modifications belong in \raggedEnv{...} within  your typescripts.

     \raggedEnv{...} and \raggedFrac{...} need not be repeated before
each use of \raggedX. If you want once-only temporary ragged
environment change, you can use grouping or \raggedEnvOnce{...}

     \raggedFrac, \hsize, \leftskip, \rightskip should not appear in the
argument of \raggedEnv; this is roughly because they relate to external
parameters.

     By default, paragraph indentation of the ragged paragraph is
zero.   Hyphenation is by default switched off.  However
\raggedEnv{\parindent=20pt \pretolerance=100}  would change this back
to Plain defaults. 

     You may want to adjust the new dimension \raggedStretch, which is
10pt by default.  Incidentally, if the total stretch in lines falls
below about 20pt, you may have to add, say \emergencystretch=20pt
inside \raggedEnv{...}.

     In tuning stretch and hyphenation, consider also the following:
\fontdimen3\font=<dimension>, \spaceskip=<skip> and \xspaceskip=<skip>.
Cf. Plain's \raggedright.

     A companion trio \RaggedL, \RaggedC, \RaggedR  are simpler,
robuster, and faster macros that perform two services already available
in LaTeX:

 (i) If used with default parameters, they force the last paragraph line
to have roughly the same length as all others.  Results are good if
there are many lines.

 (ii) If used with parameter value \raggedStretch=1000pt, they behave
like the competing LaTeX environments with default parameters: lines are
relaxed and filled in natural order.


 *** INSTALLATION

     For any format,  \input ragged.sty  will install the package.

     For LaTeX (version 2e), place \usepackage{ragged} in the article header
between \documentclass{...} and \begin{document}.



 *** OCCASIONAL PROBLEMS AND THEIR REMEDIES

     \raggedL and \raggedC (not \raggedR and \RaggedX) are only
moderately robust: they work correctly only when the paragraph contents
will form a single line if composed on an "infinitely" long line.
Therefore, they misbehave if they contain *for example* displayed math
or \break or material inserted by \vadjust; and  also if the paragraph
exceeds about a page of typing; error warnings are given.

     The most annoying failing is the unavailability of \break; it can
be replaced  by \hbox{...} and the tie ~ ; indeed without introducing the
inflexibility which \break does.

     Fortunately such limitations do not much interfere with the use
intended. (Indeed the unavailability of \break is a blessing in
disguise.)

    If difficulty is nevertheless encountered, use the *fast* and
*robust* \RaggedL and \RaggedC where necessary (search out "\Ragged"
instructions and tests!).  

    On a given paragraph, all 3 \raggedX should always produce the
*same* linebreaks; any exception is a bug.  Similarly for all three
\RaggedX.

    Please report undocumented bugs to lcs@topo.math.u-psud.fr.



 *** A TRIVIAL SOLUTION WHEN RAGGEDNESS IS NULL

     Donald Arseneau pointed out (Info-TeX, Sat Mar  9, 1996) that if
left and right margins are justified (i.e. \raggedStretch is zero)  then
the last line of paragraphs can be center or right aligned by a simple
"trick" setting as follows:

 *** Center Alignment

   \leftskip=1\leftskip plus 1fil  %% use \setlength in LaTeX
   \rightskip=-\leftskip
   \parfillskip=0pt plus 2fil

 *** Right Alignment

   \leftskip=1\leftskip plus 1fil  %% use \setlength in LaTeX
   \rightskip=-\leftskip
   \parfillskip=0pt plus 1fil

Donald considers this *well known*; he learned of it first from
Barbara Beeton.

    This device will also work in ragged environments IF AND WHEN
*extended* TeX allows skips to have *both* finite and infinite stretch
-- analogous to ordinals of the form integer + \omega.  This is not
yet planned.

    As always in TeX, there may yet be another "deus ex machina"!  Time
will tell.



 *** WHY USE ragged.sty WITH LATEX?

     LaTeX (in all versions) has the environments "flushleft", "center",
and "flushright" that perform very nearly the services of \RaggedL,
\RaggedC, and \RaggedR.  LaTeX also has macros \raggedright and
\raggedleft  roughly equivalent to "flushleft" and "flushright" minus
the grouping that goes along with an environment. 

     These LaTeX environments/macros perform reliably, and like \RaggedX
do *not* suffer the fragility mentioned above for \raggedX. 

      All these LaTeX features are programmed by a mare parameter setting
(cf. programmer documentation below): they simply use the infinite value
1fil  for the stretch component of \leftskip and/or \rightskip, and this
permits quite excessive raggedness -- as testing shows.  If one just
makes this stretch finite and modest, then the last line becomes
excessively stretched and/or all lines tend to become equal. This matter
seems to have been first recorded and remedied by Jan van der Steen and
Martin Schr\"oder who wrote raggedri.sty (1993) (see  CTAN) producing a
macro \RaggedRight more or less  equivalent to Plain's \raggedright --
but no \RaggedCenter nor \RaggedLeft.

     Consequently LaTeX users have reason to use my macros \raggedL and
\raggedC  when controlled raggedness is wanted.  In addition, I suspect
the ragged.sty syntax will prove helpful in adjusting up width's and
margins.

     Since the competing LaTeX environments are deeply imbricated in
the complicated "list" environment apparatus, I have not attempted to
tinker directly with the LaTeX code to make the new ragged.sty features
a well integrated patch for LaTeX; that is a job for those working on
LaTeX3. 



 *** HISTORY

     These macros were initially programmed to respond to a request of 
Laszlo Battha <battha@apollo.ggki.hu>, Mon Mar 4, 1996 on the Info-TeX
list.

     Laurent Siebenmann
             Math'ematique, Bat. 425,
             Univ de Paris-Sud,
             91405-Orsay,
             France







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


     *****   PROGRAMMER DOCUMENTATION FOR ragged.sty   *****

     In essence, \RaggedX is a mere parameter setting; indeed, it sets
the stretch components of \leftskip and \rightskip to total
\raggedStretch.  What is a miracle preordained by Knuth is that as
soon as \raggedStretch is huge (say 1000pt), while \linepenalty
remains substantial (say 50) all lines but the last are as full as
they can be without puting interword spaces under tension. 
Hyphenation occurs only to prevent line length overrun.  LaTeX
operates similarly but using infinite stretch.

     In contrast, \raggedL and \raggedC are hopefully original; they
are more devious than outright difficult; what will be more
difficult is to make them work in absolutely all circumstances where
Plain's \raggedright works. They already give perfect typography 
or else complain.

     Permit me to set the scene with an overstatement. Analogs of all
three \raggedX exist in every competent wordprocessor since 1984 --
beginning with MacWrite. However, in TeX (1982) there was an
unfortunate oversight; there should be not just one \parfillskip but
two: \leftparfillskip and \rightparfillskip=\parfillskip.  These
should be "skip"s (elastic spaces) inserted at the left and right of
the last line of each paragraph.  If these become available (say in
an e-TeX or Omega), one will be able to  program  \raggedL and
\raggedC by merely setting these parameters along with \leftskip,
\rightskip and a few others.

     This makes it clear that the moderately complicated programming
I have used is just a "workaround".  Fortunately it is neither slow
nor bulky.

     Here is the logic of the present programming of \raggedL; it
will be followed by some promising alternatives.



 *** CURRENT METHOD (A)

 --- Sweep the paragraph text into \vbox of huge \hsize so that the
paragraph text fits on one line.  The use of a \vbox instead of an
\hbox; here is the one recent "breakthrough" involved; it surfaced as a
result of investigations of Barbara Beeton, Michael Downes and Don
Knuth -- in this order! -- see TUGboat 11 (Nov 1991), pages 605--612.

 --- Extract the line as an \hbox and \unhbox it into a \vbox with
the "raggedleft" environment as desired, except for \parfillskip=0pt
plus 1fil where we would really want \leftparfillskip=0pt plus 1fil
and  \rightparfillskip=0pt. Here we learn the number of lines in the
paragraph by use of \lastgraph. 

 --- We find out the length of the the last line by using \lastbox to
pick off the last \hbox in the above \vbox, and then \unhbox'ing it
into another \hbox stripping off a penalty10000, \rightskip and
\parfillskip (going right to left).

 --- From this, we can calculate the indentation by which to push the
last box right to make it flush with the right margin.

     But we do *not* do that since it entails unpleasant technical
complications related to vertical placement.  Instead we more
simply:

 --- unhbox onto the current page (essentially) the first \hbox
encountered above, using the last mentioned environment modified only by
a  \hangindent  equal to the measured indent, which is scheduled by 
\hangafter to intervene on the last line of the paragraph.

    In a real sense the current page receives the final paragraph
just like a normal paragraph.  Therefore (hopefully!) no vertical
mode complications will occur.  

    Far *more* complex tricks of this sort, *the last one excepted*, are
exploited in Donald Arseneau's shapepar.sty on CTAN.  Fortunately,
ragged.sty and  shapepar.sty  do not compete on the performance
front.



 *** ALTERNATIVE METHOD (B)

     This is the method I first attempted in a preliminary "hack" posted
on Info-teX Sat Mar 9, 1996.  The raggedleft paragraph can contain
\vadjust and \break since the "one-long-line" requirement of (A) 
disappears.  

 --- first compose the paragraph \vbox with the ultimately desired
\hsize, \leftskip, \rightskip, but use \parfillskip=0pt plus 1fil. 

 --- obtain the relaxed length of the last paragraph line much as 
as above, using \lastbox etc. The last line is thus "deleted".

 --- reconstruct the last line as an \hbox to assure the correct
horizontal location.

 --- restore the last line into the \vbox.  This requires careful
vertical placement, possibly involving \lastskip, \lastdepth,
\lastpenalty,

 --- \unvbox the corrected \vbox onto the current page.  
This again requires careful vertical placement, eg. as regards 
space both above and below, penalties etc.

     The last step requires that one be able to perfectly emulate, by
hand as it were, important parts of TeX's paragraph builder.  It is by
far a more delicate task than the first method.  Donald Arseneau called
it "painful" (Info-TeX, Sat Mar  9, 1996).  

     Indentations above *displayed equations* have not been discussed
(but they are in alternative C below); that would redouble complexity.



 *** ALTERNATIVE METHOD (C)

     This last alternative is my proposed improvement of the first
method by use of an auxiliary file for storing widths between TeX
jobs and by possible use of two passes on each paragraph.  

     This method seems to fully eliminate the failings of \raggedX,
ie. refusal of: displays, \break, \vadjust. Very desirable for a
narrow brochure with left-hand pages composed "raggedleft".   But I
have done only fragmentary prototyping.

     Two passes on a paragraph are executed (when that is necessary)
by taking up the whole paragraph in a macro argument, storing it
temporarily in unexpanded token list form, and then rereading it so
that category assignments are those for normal progressive input. 
This will be done by fast internal primitives in all versions of
e-TeX. But in Knuth's TeX it requires writing the unexpanded token
list out to a file, with help of the the \meaning primitive and
then rereading.
     
     An auxiliary file with indentation widths may indicate that a
preliminary pass is unnecessary; thus, on the average, composition
should be very fast.  

 --- during a possible preliminary composition of a paragraph one
keeps \parfillskip equal 0pt plus 1fil, and merely records, in the
order of occurrence:

 (a) the widths of remainders on the last line before each display,
using \predisplaysize and a temporary addition to the token list
\everydisplay.

 (b) the width of the remainder on the paragraph's last line. This
is gotten using \lastbox much as in methods (A) or (B).

Note that \lastbox operates in internal vertical mode, and not in
vertical mode. Hence all preliminary composition is to be done in a
\vbox. This \vbox is discarded once the necessary indentation
information has been extracted --- just as in method (A) but
contrary to method (B).

 --- during final raggedleft composition of a paragraph, the width
information is applied with help from \lastgraf, \hangindent,
\hangafter much as in method (A).

In this final raggedleft composition of a paragraph, the width
information used may be either from the current job or from a
previous job. But it is always obtained from some preliminary
composition.

     In the case of a paragraph that is composed by \raggedL in a 
single pass, it would be highly desirable to have a check that the
composed paragraph is OK;  it would for example probably *not* be OK
if changes had intervened there since last composition.  The
unavailability of \lastbox in ordinary  vertical mode seems to make
a *sure* check difficult.  Perhaps one must be content  with checks
that are less than sure --- such as variation of the number  of
typescript lines occupied by the paragraph as found via
\inputlineno. The user could also signal changes using a syntax like
\raggedL[changed 1647]. Also,  \raggedTwoPass in the header could
force slow but sure two-pass treatment.


     Incidentally, a simple way to make a brochure with left pages
raggedleft and right pages raggedright and *without* altering the
output routine is to compose the brochure twice,  once raggedleft
and once raggedright; then one can mix the two at the .dvi (or
postscript) level.

     It is clear that, for such brochures, vertical spacing in and
among paragraphs should be perfectly normal, and identical for
raggedleft and raggedright composition.  Method (C)  seems to
promise this without pain.



     I recommend (C) as next method to program. But I could
be wrong.

     Laurent Siebenmann
             Math'ematique, Bat. 425,
             Univ de Paris-Sud,
             91405-Orsay,
             France

             30 March 1996