summaryrefslogtreecommitdiff
path: root/macros/plain/contrib/misc/varindent.tex
blob: 117eb00c0c50a6a1c2b3268b7904f5d50369b8fa (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
%From: Donald Arseneau <ASND@TRIUMFCL.BITNET>
%Subject: Variable indentation puzzle
%
%The puzzle in TeXmag V4N1 about making indentation match the length of
%the line above is interesting because there are (at least) two very different
%approaches.  One is to set every paragraph in a \vbox in order to measure the
%width of its last line.  I hope someone sends in a solution using that method
%because I chose the method suggested by the question: "(as per what is done
%with displayed equations)."
%                           The width of the line above a displayed equation
%is given with the parameter \predisplaysize, so it would seem trivial to use
%a displayed equation to measure the line width.   However, there are some
%details to keep things interesting:  The vertical spacing must be the same
%as for an ordinary paragraph, including the \parskip; Likewise for the
%penalties; The depths must be preserved, especially if a pagebreak occurs;
%If the indentation gets too wide something must be done to prevent a bad
%linebreak.  The unboxing method has this last problem too, but there it may
%be possible to reset the final line to the full textwidth.  Here I use
%ordinary indentation when the line gets too long.  The advantage the display
%method has over reboxing is that there are things that cannot be pulled
%of a vertical list, so reboxing won't always work.
 
\newdimen \normalparindent
\newdimen \longlinelen
\newdimen \gscratch % used globally
 
% useful little macro: gives absolute value of a number or a dimension (if in
% a dimension register).  Note that this makes use of TeX's confusing habit of
% expanding \if's within a number
 
\def\abs#1{\ifnum#1<0 -\fi#1}
 
% \usevarindent turns on variable indentation.  Use grouping to turn it off.
% (It would be easy to convert this to a LaTeX environment.)
% It is necessary to say \usevarindent before ending the paragraph
% above the first variable indentation.
 
\def\usevarindent{%
% don't try indenting to within 2\parindent of the right margin
 \normalparindent=\parindent
 \longlinelen=\hsize \advance\longlinelen-2\normalparindent
 \displaywidowpenalty=\widowpenalty
 \let\par=\varindent}
 
% \varindent is used to end each paragraph during variable indentation.
 
\def\varindent{\ifhmode\ifinner\else $$ % test for unrestricted horizontal mode
 \lineskiplimit=-999pt % so we get a baselineskip that we can cancel with:
 \abovedisplayskip=-\baselineskip \abovedisplayshortskip=-\baselineskip
 \belowdisplayskip=0pt \belowdisplayshortskip=0pt
 \halign{##\cr\noalign{\global\gscratch=\prevdepth}% get depth of line above
   \hbox{\vrule width0pt depth \gscratch }\cr}% preserve its depth
% now get the width of the last line of the paragraph that just ended,
% If it is too long just use normal indentation:
 \ifdim\abs\predisplaysize>\longlinelen \global\gscratch=\normalparindent
%  otherwise, use the width of the line above (\predisplaysize-2em):
   \else\global\gscratch=\predisplaysize \global\advance\gscratch -2em\fi
$$\parindent=\gscratch
\fi\fi \endgraf}% Plain TeX sets \endgraf=\par; use \@@par in LaTeX