summaryrefslogtreecommitdiff
path: root/info/challenges/aro-bend/answer.018
blob: f07cb0ff6b4637d0d18b83c02b18fe44d28a30b2 (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
Date: 27 May 1994 08:19:39 -0400 (EDT)
From: Michael Downes <MJD@MATH.AMS.ORG>
Subject: Around the Bend #18, answer
To: info-tex@shsu.edu

I intended to post this sooner but in researching the answer it turned
out that in order to clear up a couple of nagging questions I had to
follow some side trails a long way.

Answer to Around the Bend #18:

Exercise 18 (21 April 1994) pointed out that the output routine

	\output={\unvbox255 \penalty\outputpenalty}

described in the TeXbook p 254 doesn't exactly work as intended: "If
the \vsize hasn't changed, and if no insertions have been held over, the
same page break will be found."

The same pagebreak will be found only if the original page break
occurred at a penalty item. Otherwise (TeXbook, p 125) TeX
sets \outputpenalty=10000 before firing up the user's output
routine. Consequently, the output routine constructs a vertical list in
which the original break point has disappeared.

By an optimization found in section 890 of `TeX: The Program', the
penalty between two paragraph lines---the sum of all applicable
penalties from the set \interlinepenalty, \clubpenalty, \widowpenalty,
\displaywidowpenalty, and \brokenpenalty---is not actually added to
the vertical list unless it is nonzero. Thus when \interlinepenalty =
0 (default from IniTeX/plain TeX) and hyphenated lines are not too
frequent, "most" pairs of lines in a paragraph have no intervening
penalty. And there is usually no penalty between ordinary text
paragraphs. Thus an \outputpenalty value of 10000 will occur fairly
often in practice.

W. E. Baxter (the submitter of this exercise) looked into the
possibility of recompiling TeX without the cited optimization, but found
that the resulting version fails the trip test.

In order for the example to work as intended it would have to be
rewritten as

  \output={\unvbox255
    \ifnum\outputpenalty=10000 \else \penalty\outputpenalty\fi}

For completeness it should be pointed out that the output routine
could come even closer to the goal of `doing nothing' if the parameter
\holdinginserts, added in TeX version 3.0 (circa 1990), were set to
some value greater than 0, so that the state of floating inserts would
be preserved; but that has to be done before the output routine is
entered.

I would have said that such a do-nothing output routine is useless, but
as a matter of fact I wrote something rather close to it as one cycle of
a multi-cycle output routine a couple of years ago. The goal was to look
at the values of \pagetotal, \pagestretch, etc in order to print a
complete survey of the page contents in a marginal note, to help the
person dealing with page break decisions when the automatic breaks
turned out to be inadequate. Unfortunately, the values of \pagetotal etc
reported in the output routine are not exactly the values that are
needed, because if the page break did not occur at a forcing penalty (<=
-10000) then the values include material on the recent contributions
list, yet only the material up to the chosen page break is relevant. So
in order to get accurate values I had to insert a do-almost-nothing
cycle that merely inserted a forcing penalty at the break point after
dumping the contents of box255 back on the main vertical list.

------------------------------------------------------------------------
Some historical research.

If you have an older copy of the TeXbook (pre-1990), as I do, the
above-mentioned section on p 125 about \outputpenalty says that it is
set to 0 (rather than 10000) if the break did not occur at a penalty
item. Thus the output routine example on p 254 seems to be another
case of a well-known phenomenon: documentation failing to keep up with
changes in the software. Make a note of it in your copy!

Excerpt from the TeXbook errata files:

  \bugonpage A125, lines 13--29 (9/23/89)

  \ddanger \looseness=-1
  When the best page break is finally chosen, \TeX\ removes everything after
  the chosen breakpoint from the bottom of the ``current page,'' and puts it
  all back at the top of the ``recent contributions.'' The chosen
  breakpoint itself is placed at the very top of the recent contributions.
  If it is a penalty item, the value of the penalty is recorded in
  ^|\outputpenalty| and the penalty in the contribution list is changed
  to $10000$; otherwise |\outputpenalty| is set to 10000.

It's not clear to me from a cursory examination of tex82.bug,
errata-five.tex, and tex.web when this change occurred in tex.web, but it
seems that it must have occurred rather early, perhaps in the work on
TeX82 (1982--1983); if so, then the claim that outputpenalty was set to
0 was a five-year-old oversight when Knuth changed it in 1989. In
tex82.bug there is no reference to output_penalty or even inf_penalty
near 9/23/89, and tracing backwards from there didn't turn up anything
that seemed relevant to me. Furthermore, a copy of TeX version 2 (circa
1985) that I was able to dig up had outputpenalty 10000 instead of 0,
following the erratum, and my 1986 copy of `TeX: The Program' (i.e.
the woven version of tex.web) agrees with that.

Thanks again to W. E. Baxter for contributing this exercise and
several parts of the answer.

Michael Downes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
mjd@math.ams.org (Internet) ASCII 32--54,55--126: !"#$%&'()*+,-./0123456
789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~