* texinfo.tex: Rewrite of index stuff to do better column breaking
authorKarl Berry <karl@gnu.org>
Tue, 23 Jun 1998 14:28:30 +0000 (14:28 +0000)
committerKarl Berry <karl@gnu.org>
Tue, 23 Jun 1998 14:28:30 +0000 (14:28 +0000)
and balancing.
The old code failed miserably when the index was just the wrong size,
e.g., the Autoconf manual with @afourpaper.
Bug report from: Wilhelm Mueller <muewi@hb.senbvs43.uni-bremen.de>
Date: Fri, 12 Jun 1998 16:34:49 +0200 (MET DST)
(\initial): Add more glue around the initial, and make it a
multiple of \baselineskip.
(\entry): Add glue before each entry so the columns can always be the
 same height.
(\doublecolumnout): Available space no longer needs to handle
 \partialpage specially.
(\pagesofar): Take \ht\partialpage into account with \vsize.
(\enddoublecolumns): Reset \output to avoid calling
\balancecolumns twice
(\balancecolumns): Format for readability.
(\initialskipamount): No longer needed, remove.

(\hbadness): Increase a bit, boxes that are a little underfull look ok.

texinfo.tex

index 84d6683e2a15e9154dd2eb93c249114433bc7315..6e17548f7e7785dbd7152fc9073ff1d32f52aca0 100644 (file)
@@ -2636,21 +2636,35 @@ width0pt\relax} \fi
 % These macros are used by the sorted index file itself.
 % Change them to control the appearance of the index.
 
-% Same as \bigskipamount except no shrink.
-% \balancecolumns gets confused if there is any shrink.
-\newskip\initialskipamount \initialskipamount 12pt plus4pt
-
-\def\initial #1{%
-{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
-\ifdim\lastskip<\initialskipamount
-\removelastskip \penalty-200 \vskip \initialskipamount\fi
-\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  % 
+  % We like breaks before the index initials, so insert a bonus.
+  \penalty -300
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  % 
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  \vskip .33\baselineskip plus .1\baselineskip
+  %
+  % Do our best not to break after the initial.
+  \nobreak
+}}
 
 % This typesets a paragraph consisting of #1, dot leaders, and then #2
 % flush to the right margin.  It is used for index and table of contents
 % entries.  The paragraph is indented by \leftskip.
 %
-\def\entry #1#2{\begingroup
+\def\entry#1#2{\begingroup
   %
   % Start a new paragraph if necessary, so our assignments below can't
   % affect previous text.
@@ -2673,12 +2687,15 @@ width0pt\relax} \fi
   %
   % \hangafter is reset to 1 (which is the value we want) at the start
   % of each paragraph, so we need not do anything with that.
-  \hangindent=2em
+  \hangindent = 2em
   %
   % When the entry text needs to be broken, just fill out the first line
   % with blank space.
   \rightskip = 0pt plus1fil
   %
+  % A bit of stretch before each entry for the benefit of balancing columns.
+  \vskip 0pt plus1pt
+  %
   % Start a ``paragraph'' for the index entry so the line breaking
   % parameters we've set above will have an effect.
   \noindent
@@ -2777,14 +2794,21 @@ width0pt\relax} \fi
   %
   % Double the \vsize as well.  (We don't need a separate register here,
   % since nobody clobbers \vsize.)
+  \advance\vsize by -\ht\partialpage
   \vsize = 2\vsize
 }
+
+% The double-column output routine for all double-column pages except
+% the last.
+% 
 \def\doublecolumnout{%
   \splittopskip=\topskip \splitmaxdepth=\maxdepth
   % Get the available space for the double columns -- the normal
   % (undoubled) page height minus any material left over from the
   % previous page.
-  \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  %
   % box0 will be the left-hand column, box2 the right.
   \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
   \onepageout\pagesofar
@@ -2793,35 +2817,60 @@ width0pt\relax} \fi
 }
 \def\pagesofar{%
   % Re-output the contents of the output page -- any previous material,
-  % followed by the two boxes we just split.
+  % followed by the two boxes we just split, in box0 and box2.
+  \advance\vsize by \ht\partialpage
   \unvbox\partialpage
+  %
   \hsize = \doublecolumnhsize
-  \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}%
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
 }
 \def\enddoublecolumns{%
-  \output = {\balancecolumns}\eject % split what we have
+  \output = {%
+    % Split the last of the double-column material.  Leave on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+    %
+    % \pagegoal was set to the doubled \vsize above, since we restarted
+    % the current page.  We're now back to normal single-column
+    % typesetting, so reset \pagegoal to the normal \vsize.
+    \pagegoal = \vsize
+  }%
+  \eject
   \endgroup % started in \begindoublecolumns
-  %
-  % Back to normal single-column typesetting, but take account of the
-  % fact that we just accumulated some stuff on the output page.
-  \pagegoal = \vsize
 }
 \def\balancecolumns{%
   % Called at the end of the double column material.
-  \setbox0 = \vbox{\unvbox255}%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
   \dimen@ = \ht0
   \advance\dimen@ by \topskip
   \advance\dimen@ by-\baselineskip
-  \divide\dimen@ by 2
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
   \splittopskip = \topskip
   % Loop until we get a decent breakpoint.
-  {\vbadness=10000 \loop
-    \global\setbox3=\copy0
-    \global\setbox1=\vsplit3 to\dimen@
-    \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt
-   \repeat}%
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
   \setbox0=\vbox to\dimen@{\unvbox1}%
   \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
   \pagesofar
 }
 \catcode`\@ = \other
@@ -4377,6 +4426,7 @@ width0pt\relax} \fi
 
 \def\deftpx #1 {\errmessage{@deftpx in invalid context}}
 
+
 \message{macros,}
 % @macro.
 
@@ -5024,6 +5074,9 @@ width0pt\relax} \fi
 % Prevent underfull vbox error messages.
 \vbadness = 10000
 
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
 % Following George Bush, just get rid of widows and orphans.
 \widowpenalty=10000
 \clubpenalty=10000