summaryrefslogtreecommitdiff
path: root/usergrps/uktug/baskervi/6_1/bv61rus.tex
blob: 4bd937d25fe03960fbaeeed0b3d2becf25e16f4d (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

\title{Russian Paragraph Shapes}
\author{Based on \texttt{comp.text.tex} article of Peter Schmitt\\
        with extra commentary by David Carlisle.}

\begin{Article}

\section{The problem}

\catcode`\<=12
\let\Par\par
\parfillskip0pt
\parindent1cm
\def\russianpar{\ifhmode \unskip
         \hskip-2\parindent minus-2\parindent \hskip\hsize minus\hsize
         \hbox{\hskip\parindent}\hskip0pt
         \hbox{\strut}\hskip-\parindent\hskip\hsize plus\parindent
         \vadjust{\nobreak\vskip-\baselineskip}\Par
         \fi}
\let\par\russianpar

Recently on the \texttt{comp.text.tex} newsgroup The following
question was asked (as an aside in a thread that was originally about
``My Life with \TeX''.


\begin{itshape}
\textbf{Related problem:} the last line of a paragraph must be \textbf{either}
longer than \verb|\parindent| and shorter than 
$(\verb|\hsize|-\verb|\parindent|)$, \textbf{or}
it must reach the right margin (exactly \verb|\hsize| long).

How can I implement this with the existing continuous
\verb|\parfillskip| glue? This is my publisher's demand, based on
traditional Russian typography rules.
\end{itshape}


In fact it is clear that this requirement cannot be satisfied
by any setting of the pargraph parameters alone, however the question
produced two  deceptively simple solutions from two `regulars' on that
newsgroup, Peter  Schmitt and Donald Arseneau. In a couple of followup
articles these methods were refined. This article is based
on Peter's summary as posted to the newsgroup and typeset with the
requested paragraph style.

The ideas here may be
of use to anyone wishing to implement non-standard paragraph shapes,
not just the particular requirements of this question.

\section{The first solution}

You can do this by ending each paragraph by \mbox{glue $+$ hbox $+$ glue}
 where the (empty) hbox spans \verb|\parindent|,
 \mbox{glue $+$ hbox} together range from 
 \verb|\parindent| to \verb|\hsize|~$-$~\verb|\parindent|,
 and \hbox{hbox $+$ glue} range from
\verb|\hsize|~$-$~\verb|\parindent|
 to \verb|\hsize|,
 such that a break may occur either before \mbox{glue $+$ hbox}
 (such that glue disappears) or just after hbox.
In both cases the paragraph will end in an empty line.
Therefore you have to back up one line.

\begin{verbatim}
\parfillskip0pt

\def\russianpar{%
  \hskip2\parindent plus\hsize
  \hskip-2\parindent
  \hbox{\hskip\parindent}%
  \hskip0pt
  \hbox{}%
  \hskip-\parindent
  \hskip\hsize plus\parindent
  \vadjust{\vskip-\baselineskip}%
  \endgraf} 
\end{verbatim}

\section{The second solution}
Donald Arseneau's solution is similar, but rather than always forcing
a blank row at the end of the paragraph, a rule of a special (small)
depth is inserted together with glue items. If the line breaks leaving
this rule on its own on the last line, then this can be detected by 
inspecting \verb|\prevdepth|, and a suitable negative skip can be
added to compensate for the `blank' line.

\begin{verbatim}
\def\par{%
  \ifhmode
    \unskip
    \strut
    \hskip-\parindent 
    \vadjust{}%
    \nobreak
    \hskip2\parindent 
    \vrule depth 54321sp 
           height \ht \strutbox width 0sp
    \endgraf
    \ifdim\prevdepth=54321sp
      \nobreak
      \vskip-2\baselineskip
      \hbox{\strut}%
    \fi
  \fi}

\parfillskip=\hsize minus\hsize 
\advance\parfillskip 
           -2\parindent minus-2\parindent

\end{verbatim}

\section{Comments}

Donald Arseneau commented on one problem with the first solution:
Unfortunately, \verb|plus \hsize| does not set a firm limit on the stretch
the same way that \verb|minus\hsize| sets a limit on the shrink.  Inserting
the settings  \verb|\tolerance=100| \verb|\pretolerance=100| may fix
this, but I doubt that such low tolerances would be practical when
building a paragraph under such ``Russian'' constraints to the line
breaking.

To which the reply was:
One might, however, wish to take advantage of this effect
by setting a higher (than  \verb|\parindent|) limit for the last line
where the length is chosen such that a tolerable line would
still meet the \verb|\parindent| requirement.
On average, this should prefer longer last lines and this is
is certainly aesthetically better.

Some more remarks:
calculating the \verb|\parskip| has the advantage (over setting
\verb|\parskip| to a calculated value) that one may change
\verb|\hsize| and \verb|\parindent| without needing to adapt other values.
If one does not mind this, using fixed values (calculated once)
is certainly more efficient.
In this case one should also think of using prepared boxes
(\verb|\setbox| and \verb|\copybox|) instead of producing these boxes
each time when a paragraph is set.

The trick of passing information via the depth of a special strut is
well known, but relies on the fact that no other macro package is
using the same value. Donald Knuth remarks in the \TeX{}Book\ ``\emph{A
distance of~$1000\,$sp is invisible to the naked eye, so a variety of
messages can be passed in this way.}''
However if there is a chance that several
macro packages really are using this trick, it would be wise to define
an allocation mechanism  (cf.\ \verb|\newcount|) that allocates a
unique `special depth' each time it is called. Similar comments could
apply to allocating penalty values over 10000 which are also often
used to flag special actions to be taken.

As all these methods require a redefinition of \verb|\par| (which is
inserted by \TeX\ automatically for each blank line in the input file)
they may need some further work to work in conjunction with other
macros that redefine \verb|\par|, probably the most common such case
are the \LaTeX\ list environments.

\section{Final versions}
After considering the points raised in the discussion Peter Schmitt
posted the following two variants, which take more care over inserting
the glue, and an original use of \verb|\discretionary|. This article
is set with \verb|\par| defined by the first of these methods, and with
paragraph indent of 1\,cm.

\noindent1)
\begin{verbatim} 
\parfillskip0pt

\def\russianpar{%
  \ifhmode
    \unskip
    \hskip-2\parindent minus-2\parindent 
    \hskip\hsize minus\hsize
    \hbox{\hskip\parindent}%
    \hskip0pt
    \hbox{\strut}%
    \hskip-\parindent
    \hskip\hsize plus\parindent
    \vadjust{\nobreak\vskip-\baselineskip}%
    \endgraf
  \fi}

\end{verbatim}

\noindent2)
\begin{verbatim} 
\parfillskip0pt

\def\Russianpar{%
  \ifhmode
    \unskip
    \strut\vadjust{}%
    \nobreak
    \discretionary
      {}%
      {\hbox{\hskip2\parindent
             \vrule depth 123sp
                    width 0sp 
                    height \ht \strutbox}}
      {\hbox{\hskip\parindent}}%
    \hskip-2\parindent minus2\parindent
    \hskip\hsize minus\hsize
    \kern0pt
    \endgraf
    \ifdim\prevdepth=123sp
      \nobreak
      \vskip-2\baselineskip
      \hbox{\strut}%
    \fi
  \fi}

\end{verbatim}

\mbox{}

\end{Article}