% This file is public domain. % %Date: Thu, 16 May 91 14:59 PDT %From: David Guichard %Subject: Re: eplain %To: karl@cs % %Karl-- % %Here are my multi-column macros and a rewrite of the double columns section %of eplain.texinfo. I included a \quadcolumns because this seems potentially %useful on landscape pages. % %I ran into a couple of problems/bugs/features of the original macros that I %think I've fixed. % %First, if I started double columns and then returned to single column before %the output routine was invoked, but there was too much text in the columns to %fit on the current page, then all of the text was put on the next page, leaving %lots of blank space on the first page. I think I've fixed this by changing how %\vsize is defined. % %Next, unless I'm doing something screwy, it looks to me like eplain goofs up on %footnotes and topinserts issued in multicolumn mode. I think I've got things %changed around so they work. % %I also discovered that the "\vskip\interfootnoteskip" in the vfootnote macro %will produce a parskip even if the interfootnoteskip is 0---was this %intentional? If not, perhaps you'd like to add \parskip=0pt to vfootnote. %(I have already added it to the modified vfootnote in the columns macro). \newskip\abovecolumnskip \abovecolumnskip = \bigskipamount \newskip\belowcolumnskip \belowcolumnskip = \bigskipamount \newdimen\gutter \gutter = 2pc \newdimen\c@lumnhsize \newtoks\previousoutput \newcount\number@fcolumns \newbox\@partialpage \newdimen\singlec@lumnhsize \newdimen\singlec@lumnvsize \newtoks\previousoutput \let\@ndcolumns=\relax % % We have a few synonymous ways to refer to multiple column modes. % \def\doublecolumns{\@columns2} \def\triplecolumns{\@columns3} \def\quadcolumns{\@columns4} \def\begincolumns#1{\ifcase#1\relax \or \singlecolumn \or \@columns2 \or% \@columns3 \or \@columns4 \else \relax \fi} \def\singlecolumn{\@ndcolumns\vskip\belowcolumnskip\nointerlineskip} \let\endcolumns=\singlecolumn % \def\@columns#1{% \@ndcolumns% \begingroup % % We redefine the main footnote macro so footnotes will extend across % the whole page, not just the width of a column. Likewise for @ins, % the insertion macro. % \def\vfootnote##1{\insert\footins\bgroup\hsize=\singlec@lumnhsize \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \advance\splittopskip by \interfootnoteskip \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \everypar = {}% \parskip0pt \the\everyfootnote \vskip\interfootnoteskip \indent\llap{##1\kern\footnotemarkseparation}\footstrut\futurelet\next\fo@t} % \def\@ins{\par\begingroup\setbox\z@\vbox\bgroup\hsize=\singlec@lumnhsize} \global\let\@ndcolumns=\@@endcolumns \global\number@fcolumns=#1 \global\c@lumnhsize = \hsize % If \hsize changed, get the new value. \par % Shouldn't start in horizontal mode. \global\previousoutput = \expandafter{\the\output}% \global\advance\c@lumnhsize by -#1\gutter \global\divide\c@lumnhsize by #1 \global\output = {% \global\setbox\@partialpage = \vbox{\unvbox255\vskip\abovecolumnskip}% }% \pagegoal = \pagetotal \eject % Now expand the \output just above. \global\output = {\c@lumnoutput}% \global\singlec@lumnhsize = \hsize \global\singlec@lumnvsize = \vsize \hsize = \c@lumnhsize % % Compute the proper vsize based on what's already on the page % and the number of columns. Also change the mag factor for insertions. % \global\advance\vsize by -\ht\@partialpage \global\advance\vsize by -\ht\footins \ifvoid\footins\else \global\advance\vsize by -\skip\footins \fi \global\advance\vsize by -\ht\topins \ifvoid\topins\else \global\advance\vsize by -\skip\topins \fi \global\vsize = #1\vsize \multiply\count\footins by #1 \multiply\count\topins by #1 }% % % When this is invoked box 255 should contain just the right amount of % material, whether triggered by an output routine or a change in the % number of columns. Because columns have to contain a whole number of % lines of type, we take a bit of care with balancing the heights of the % columns to prevent either losing material or having a very short last % column. % % Note: when a page ends due to \bye or \eject, box 255 will contain lotsa % white space, so the columns will not look balanced. To fix this use % \singlecolumn before ending the page. % \def\@columnsplit{% \splittopskip = \topskip \splitmaxdepth = \baselineskip \dimen0 = \ht255 \divide\dimen0 by \number@fcolumns \begingroup % the balancing act \vbadness = 10000 \loop \setbox8=\copy255 \global\setbox1 = \vsplit8 to \dimen0 \global\wd1 = \hsize \global\setbox3 = \vsplit8 to \dimen0 \global\wd3 = \hsize \ifnum\number@fcolumns>2% \global\setbox5 = \vsplit8 to \dimen0 \global\wd5 = \hsize \fi \ifnum\number@fcolumns>3% \global\setbox7 = \vsplit8 to \dimen0 \global\wd7 = \hsize \fi \ifdim\ht8>0pt \advance\dimen0 by 1pt \repeat \endgroup \global\setbox255 = \vbox{% \unvbox\@partialpage \ifcase\number@fcolumns \relax\or\relax\or% \hbox to \singlec@lumnhsize{\box1\hfil\box3}\or% \hbox to\singlec@lumnhsize{\box1\hfil\box3\hfil\box5}\or% \hbox to\singlec@lumnhsize{\box1\hfil\box3\hfil\box5\hfil\box7}\or% \else\relax\fi% }% }% \def\c@lumnoutput{% \@columnsplit \hsize = \singlec@lumnhsize % Local to the \output group. \vsize = \singlec@lumnvsize \the\previousoutput % % Now the correct vsize is the original vsize times the % number of columns. % \global\vsize=\number@fcolumns\singlec@lumnvsize }% \def\@@endcolumns{% \global\let\@ndcolumns=\relax% \par % Shouldn't start in horizontal mode. \global\output = {\global\setbox1 = \box255}% \pagegoal = \pagetotal \eject \global\setbox255 = \box1 \@columnsplit \global\vsize = \singlec@lumnvsize \global\output = \expandafter{\the\previousoutput}% \endgroup \ifvoid\topins\else\topinsert\unvbox\topins\endinsert\fi \unvbox255 }% \endinput @node Multiple columns, Footnotes, Margins, User definitions @section Multiple columns @cindex double column output @cindex triple column output @cindex quadruple column output @cindex multiple column output Eplain provides for double, triple and quadruple column output: you just say @code{\doublecolumns}, @findex doublecolumns @code{\triplecolumns} @findex triplecolumns or @code{\quadcolumns} @findex quadcolumns and from that point on, the manuscript will be set in columns. If you want to go back to one column, say @code{\singlecolumn}. @findex singlecolumn The columns macros insert the value of the glue parameter @code{\abovecolumnskip} @findex abovecolumnskip before the multi-column text, and the value of the glue parameter @code{\belowcolumnskip} @findex belowcolumnskip after it. The default value for both of these parameters is @code{\bigskipamount}, i.e., one linespace. The columns are separated by the value of the dimen parameter @code{\gutter}. @findex gutter The default value for @code{\gutter} is two picas. The macros take into account only the insertion classes @cindex insertion classes defined by plain @TeX{}, namely, footnotes and @code{\topinsert}s. If you have defined additional insertion classes, you will need to change the macros which implement multi-column mode. Furthermore, the insertions do not respect the column widths; if you want them to, you have to change the way your output routine works. (Eplain uses whatever the current output routine is; it is not tied to @code{\plainoutput}.) @findex plainoutput @xx: \columnfill @xx: \singlecolumn to balance columns @xx: footnote/topinsert width of whole page @xx: \vfootnote resets \parskip