Date: 27 May 1994 08:19:39 -0400 (EDT) From: Michael Downes 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{|}~