[tex-eplain] \doublecolumns bug

Stepan Kasal kasal at ucw.cz
Sun Jan 11 18:25:01 CET 2004


Hello,
  attached is a solution to the \doublecolumns bug described 3 years
ago.  The other file attached is a test file which exhibits the bug.

Enjoy,
	Stepan Kasal
-------------- next part --------------
2003-12-27  Stepan Kasal  <kasal at ucw.cz>

	* xeplain.tex (\@column): Make sure there is enough space before
	  we start columned output.
	  (\@col at minlines, \@ejectpartialpenalty): New constants.
	  (\@columnhsize): Removed.
	  (\@setuplisting, \@endcolumns): Use \break instead of \eject,
	  when we are sure TeX is in vertical mode.

--- xeplain.tex.a0	2003-12-17 13:58:56.000000000 +0100
+++ xeplain.tex	2004-01-11 10:14:27.000000000 +0100
@@ -1182,7 +1182,7 @@
    \obeywhitespace
    \makeactive\`
    \makeactive\^^I
-   \def^^L{\vfill\eject}%
+   \def^^L{\vfill\break}%
    \parskip = 0pt
    \listingfont
 }%
@@ -2604,7 +2604,6 @@
 %
 % These registers are needed for dealing with switching back and forth.
 \newbox\@partialpage
-\newdimen\@columnhsize
 \newdimen\@normalhsize
 \newdimen\@normalvsize  % The original (before multi-columns) \vsize.
 \newtoks\previousoutput
@@ -2621,47 +2620,78 @@
 % Set this by default so \vfootnote can unconditionally inspect it.
 \chardef\@numcolumns = 1
 %
-% Start typesetting with #1 columns.
+\mathchardef\@ejectpartialpenalty = 10141
+%
+%
+% \@columns:  Start typesetting with #1 columns.
+%
+% Before we actually start, we have to make sure that there are at least
+\chardef\@col at minlines = 3
+% free lines.
+% (It could be 2, or even 1, but it might give ugly results; at least one
+% line is absolutely necessary, or the output routine might get confused.)
+% We have to be careful, so that eg.
+%	\hbox{TITLE}
+%	\nobreak
+%	\doublecolumns
+% won't break between the title and the start of the columned output.
+%
+% To achieve this, we add vskip of fixed size equal to
+%	@col at minlines * baselineskip
+% and then eject the page.
+% The output routine then catches the pages ejected:
+%  1) if it's a normal page, it is processed by previous output routine;
+%  2) if it's the last one, it is saved and the added skip is removed.
+%
+% When the box is processed according to 1), an underfull vbox can appear,
+% but it's not our problem, the manuscript (or it's macros) has to be fixed.
+%
+% Another note: all assignments are global; it is not possible to call
+% \doublecolumns in a group.
+%
 \def\@columns#1{%
   \@ndcolumns
   %
-  \let\@ndcolumns = \@endcolumns
-  \chardef\@numcolumns = #1
+  \global\let\@ndcolumns = \@endcolumns
+  \global\chardef\@numcolumns = #1
+  \global\previousoutput = \expandafter{\the\output}%
+  %
+  % Grab the page so far (i.e., the material BEFORE \@columns was called)
+  % and save it in \@partialpage.
+  \global\output = {%
+    \ifnum\outputpenalty = -\@ejectpartialpenalty
+      \dimen@ = \vsize
+      \advance\dimen@ by \@col at minlines\baselineskip
+      \global\setbox\@partialpage =
+        \vbox  \ifdim \pagetotal > \vsize  to \dimen@  \fi  {%
+	  \unvbox255 \unskip
+	}%
+    \else
+      \the\previousoutput
+    \fi
+  }%
+  %
+  \vskip \abovecolumnskip
+  \vskip \@col at minlines\baselineskip
+  % now execute the output routine:
+  \penalty -\@ejectpartialpenalty
   %
-  \par                     % Shouldn't start in horizontal mode.
-  \previousoutput = \expandafter{\the\output}%
+  % Reset \output to prepare for the first real page break.
+  \global\output = {\@columnoutput}%
+  %
+  \global\@normalhsize = \hsize
+  \global\@normalvsize = \vsize
   %
   % Figure out how wide the columns should be -- for n columns,
   % decrement by n - 1 gutters.
-  \@columnhsize = \hsize
   \count@ = \@numcolumns
   \advance\count@ by -1
-  \advance\@columnhsize by -\count@\gutter
-  \divide\@columnhsize by \@numcolumns
-  %
-  % Set up to grab the page so far (i.e., the material BEFORE
-  % \@columns was called) and save it in \@partialpage.
-  \output = {\global\setbox\@partialpage =
-    \vbox{\unvbox255\vskip\abovecolumnskip}%
-  }%
-  %
-  % \pagegoal is the size that TeX will make \box255.  We want a box
-  % exactly the size of the current height of the page, i.e., \pagetotal.
-  \pagegoal = \pagetotal
-  %
-  % Expand the \output we just defined. Thus, the previous text is
-  % stored in \@partialpage. After this, we start setting multiple
-  % columns in earnest.
-  \eject
-  %
-  % Reset \output to prepare for the first real page break.
-  \output = {\@columnoutput}%
-  \@normalhsize = \hsize
-  \@normalvsize = \vsize
-  \hsize = \@columnhsize
+  \global\advance\hsize by -\count@\gutter
+  \global\divide\hsize by \@numcolumns
   %
   % Compute \vsize based on what's already on the page
   % and the number of columns. Also change the mag factor for insertions.
+  %
   \advance\vsize by -\ht\@partialpage
   %
   \advance\vsize by -\ht\footins
@@ -2810,7 +2840,7 @@
   %
   \global\output = {\global\setbox1 = \box255}%
   \pagegoal = \pagetotal
-  \eject                     % Exercise the page builder, i.e., \output.
+  \break                     % Exercise the page builder, i.e., \output.
   \setbox2 = \box1           % Save material in box2 in case of overflow.
   \global\setbox255 = \copy2 % Retrieve what the fake \output set.
   %
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testdouble.tex
Type: application/x-tex
Size: 602 bytes
Desc: not available
Url : http://tug.org/pipermail/tex-eplain/attachments/20040111/c88381ac/testdouble.tex


More information about the tex-eplain mailing list