% pdcoput.tex 4.1.6 1994/07/20 -- output routines for Stomping Scene % Copyright 1994 P. Damian Cugley %%% @TeX-macro-file { %%% filename = "pdcoput.tex", %%% version = "4.1.6", %%% date = "1994/07/20", %%% package = "Malvern 1.1", %%% author = "P. Damian Cugley", %%% email = "damian.cugley@comlab.ox.ac.uk", %%% address = "Oxford University Computing Laboratory, %%% Parks Road, Oxford OX1 3QD, UK", %%% codetable = "USASCII", %%% keywords = "TeX, plain TeX, output routine", %%% supported = "Maybe", %%% abstract = "An output routine for Plain TeX docs.", %%% dependencies = "pdcutil.tex", %%% } % See the Malvern Handbook (maman.tex) for more info about Malvern. % This software is available freely but without warranty. % See the file COPYING for details. %{{{ pdcoput.tex %{{{ preamble \ifx\utilsversion\UNDEFINED \input pdcutil \fi \begingroup\catcode`\%=12 \toks0={\endgroup \def\pdcoputversion{4.1.6 } }\the\toks0 \message{\pdcoputversion} %}}} preamble %{{{ parameters \newdimen\paperwd \newdimen\paperht % Size of paper \newdimen\bodywd \newdimen\bodyht % size of page body (text etc.) \newdimen\gridwd \newdimen\gridht % size of grid slots \newdimen\colwd \newdimen\colht % width & height of text columns \newdimen\topmarge \topmarge=20mm \newdimen\outmarge \outmarge=20mm \newdimen\innmarge \innmarge=20mm \newdimen\botmarge \botmarge=27mm % Size of top, bottom, inner and outer margins between paper edge and % edge of page body. % botmarge is an approximation -- the margin at bottom will be % increased slightly in order to make \bodyht a good value wrt % \baselineskip. \newskip\headlineskip % distance betw baselines of headline & 1st body line \newskip\footlineskip % ditto for footline \headlineskip=10mm \footlineskip=10mm \newdimen\outputrule \outputrule=0.1mm % default thickness for rules \newdimen\caprule \caprule=\outputrule \newskip\capsep \capsep=5mm % rule and separation between caption and body text \newdimen\colrule \colrule=\outputrule \newdimen\colsep \colsep=5mm % ditto for between columns \newcount\ncols \ncols=1 % Number of columns \newbox\partialpage % stores partial pages when balancing columns \newbox\topbox \newbox\botbox % vboxes placed around body \newbox\leftbox \newbox\rightbox % hboxes placed around body \chardef\pagebox=255 \let\collist\empty % list macro of \makecolumns \let\pagelist\empty % list macro of \makepages \newtoks\everypage % expanded at start of vbox being shipped out \newtoks\everycaption % expanded at start of every caption %}}} parameters %{{{ make a column (vbox) \newdimen\toptotal \newdimen\bottotal % Helper macro -- calculate total size of space + caption for % top/bot of a column % #1 caculate total into here % #2 <8-bit number> place cap in this box % #3 space to be left % #4 text text of caption, or empty \def\calctotal#1#2#3#4% {% \setbox#2=\vbox{\the\everycaption#4}% #1=\ht#2% \advance#1\baselineskip \advance#1-1sp \divide#1\baselineskip \multiply#1\baselineskip \advance#1#3% \ifdim#1>0pt \advance#1\capsep \fi } % Create one column of stuff of height \colht, as a vbox % If \capsep=\baselineskip and captions done in fonts of same % baselineskip as body, then baselines should all line up neatly % (this takes some doing!). % #1 space at top of col % #2 text text of top caption, or empty % #3 <8-bit number> box to make middle out of % #4 text text of bot cap, or empty % #5 space at bottom of col \def\makecolumn#1#2#3#4#5% {% \vbox to \colht { \calctotal\toptotal0{#1}{#2}% \calctotal\bottotal2{#5}{#4}% % % Chop off enough text to fill in gap: % \dimen0=\colht \ifvoid\footins\else % allow space for footnotes \advance\dimen0-\ht\footins \advance\dimen0-\skip\footins \fi \ifvoid\topins\else % allow for a \topinsert as well \advance\dimen0-\ht\topins \advance\dimen0-\skip\topins \fi \advance\dimen0-\toptotal \advance\dimen0-\bottotal % \splittopskip=\topskip \splitmaxdepth=\maxdepth \setbox1=\vsplit#3to\dimen0 % % Sandwich it all together: \kern\toptotal \ifdim \toptotal>0pt \vbox to 0pt { \vss \box0 %%%% \kern-\dp\strutbox \capseprule \kern-\dp\strutbox \kern\baselineskip \kern-\topskip } \fi \ifvoid\topins\else \unvbox\topins \vskip\skip\topins \fi \dimen0=\dp1 % this will be prevdepth for bot caption \ifvoid1 \vfil \else \unvbox1 \fi \ifvoid\footins \else \vskip\skip\footins \footnoterule \dimen0=\dp\footins % revise prevdepth-to-be \unvbox\footins \fi \ifdim \bottotal>0pt \vbox to 0pt { \prevdepth=\dimen0 \capseprule \vtop{\unvbox2 } \vss } \kern\bottotal \fi \kern-\dimen0 }% } \def\capseprule {% \hbox to \colwd {% \dimen0=0.5ex \advance\dimen0-0.5\caprule \dimen1=\dimen0 \advance\dimen1\caprule \strut \vrule height \dimen1 depth-\dimen0 width\colwd }% } %}}} make a column %{{{ make body part of page (hbox) % Generate a column of text to be put in the current page body \def\makecolumnfromcollist#1% {% \ifx\collist\empty \makecolumn{0pt}{}{#1}{}{0pt}% \else \glop\temp\collist \temp \fi } \def\makebody#1% {% \hbox to \bodywd {% \ifvoid\leftbox\else \box\leftbox \hfil \vrule width \colrule \hfil \fi \counta=\ncols \makecolumnfromcollist{#1}% \loop \ifnum\counta>1 \hfil \vrule width \colrule depth 0pt \hfil \makecolumnfromcollist{#1}% \advance\counta -1 \repeat \ifvoid\rightbox\else \hfil \vrule width \colrule \hfil \box\rightbox \fi }% } %}}} make insides of page (hbox) %{{{ make a page (vbox) % Generate a box to be shipped out as the current page. Used in \output. \def\makepage {% \vbox { \special{papersize=\the\paperwd,\the\paperht}% \colht=\bodyht \advance\colht-\ht\partialpage \advance\colht-\ht\topbox \advance\colht-\ht\botbox \the\everypage \makeheadline \nointerlineskip \box\partialpage \box\topbox \ifx\pagelist\empty \makebody\pagebox \else \glop\temp\pagelist \temp \fi \unvbox\botbox \makefootline }% } % Generate vertical meterial with zero height to produce the headline. % Expanded at very top of vbox being shipped out, % immediately after the \everypage tokens have been read. % Used in \makepage. \def\makeheadline { \vbox to 0pt { \skip0=\topskip \advance\skip0-2\ht\strutbox \advance\skip0-\headlineskip \vskip\skip0 \hbox to \bodywd{\strut\the\headline} \vss } } % Generate vertical material that gives the footline of the page. % Expanded immediately after the botbox, as the last thing in the % box that is shipped out. (Does not need to be zero-height). \def\makefootline {{ \baselineskip=\footlineskip \hbox to \bodywd{\the\footline} }} %}}} make a page (vbox) %{{{ output \def\ssoutput {% \ifodd\pageno \hoffset=\innmarge \else \hoffset=\outmarge \fi \advance\hoffset-1 true in \voffset=\topmarge \advance\voffset-1truein \shipout\makepage \advancepageno \ifnum\outputpenalty>-20000 \else \dosupereject \fi \unvbox\pagebox } \output={\ssoutput} %}}} output %{{{ automated column setting % User macro -- set paper size and other corresponding dimens % Use when body font + baselineskip have already been selected. % #1 width % #2 height \def\setpaper#1#2% {% \paperwd=#1% \paperht=#2% \calcbodywdht \calctopskip } % helper macro -- set bodywd, bodyht \def\calcbodywdht { \bodywd=\paperwd \advance\bodywd-\outmarge \advance\bodywd-\innmarge \bodyht=\paperht \advance\bodyht-\topmarge \advance\bodyht-\botmarge \calctopskip } % set topskip to suit current font % bodyht is munged to be of the form N*baselineskip + topskip \def\calctopskip { \setbox0=\hbox{Xbl()!gyJQ,} \topskip=\ht0 \maxdepth=\dp0 \advance\bodyht-\topskip \divide\bodyht \baselineskip \multiply\bodyht \baselineskip \advance\bodyht\topskip } % helper macro % set hsize and vsize appropriate to current #cols, topskip, bodyht, % and bodywd % if bodyht = N * baselineskip + topskip, for some N, then set % vsize to ncols * (N + 1) * baselineskip - baselineskip + topskip \def\sethsizevsize { \hsize=\colwd \vsize=\bodyht \advance\vsize-\topskip \advance\vsize\baselineskip \multiply\vsize\ncols \advance\vsize-\baselineskip \advance\vsize\topskip } % User macro % divide into grid of n, with k grid widths making 1 column of body % #1 number of grid slots making up body width % #2 number of grid slots making up one column % so there will be floor(#1/#2) body columns per page \def\setnkgrid#1#2% {% \gridwd=\bodywd \advance\gridwd-#1\colsep \advance\gridwd\colsep \divide\gridwd by #1 \colwd=#2\gridwd \advance\colwd#2\colsep \advance\colwd-\colsep \ncols=#1 \divide\ncols#2 \gridht=\baselineskip \capsep=\gridht \sethsizevsize } % User macro % divide into n columns % #1 number of columns per page \def\setncolumns#1% {% \colwd=\bodywd \advance\colwd-#1\colsep \advance\colwd\colsep \divide\colwd by #1 \gridwd=\colwd \ncols=#1 \sethsizevsize } \def\setpaperA#1% { \ifcase#1 \setpaper{841mm}{1189mm}\or % A0 \setpaper{594mm}{841mm}\or % A1 \setpaper{420mm}{594mm}\or % A2 \setpaper{297mm}{420mm}\or % A3 \setpaper{210mm}{297mm}\or % A4 \setpaper{148mm}{210mm} % A5 \else \errmessage{Dunno how big DIN A#1 paper is, sorry.} \fi } % default settings (using default font): \setpaperA4 \setncolumns1 %}}} automated column setting %{{{ balancing columns % Knuth's rigid balancing routine TeXbook App. D Sec. 7 (p. 396--397) \newcount\RGDncols \newdimen\RGDtopskip \newif\ifRGDfirstcol \newtoks\RGDsep % Take a rigid, regular box, and split into several approx equal % columns. Produces assignments followed by a box -- this can be % retrieved using \lastbox. % #1 <8-bit number> box to chop % #2 #columns to make % #3 value of \topskip for box % #4 width of the whole shebang % #5 TeX code what goes between columns (e.g., \hfil) \def\rigidbalance#1#2#3#4#5% {% \setbox0=\box#1\relax \RGDncols=#2\relax \RGDtopskip=#3\relax \RGDsep={#5}% \hbox to #4\relax {% \splittopskip=\RGDtopskip \vbadness=10000 \RGDfirstcoltrue \valign{##\vfil\cr \doRGDsplits}% }% } % recursive helper function for above - produces the valign's body \def\doRGDsplits {% \ifnum\RGDncols>0 % if not first folumn, put in separator \ifRGDfirstcol \global\RGDfirstcolfalse \else \noalign{\the\RGDsep}% \fi % split off one column (see TeXbook for justification % for this value of \dimen0): \dimen0=\ht0 \divide\dimen0 \RGDncols \advance\dimen0 \RGDtopskip \setbox1=\vsplit0 to \dimen0 \unvbox1 % \global\advance\RGDncols-1 \cr \doRGDsplits \fi } %}}} balancing columns %}}} pdcoput.tex %Local variables: %fold-folded-p: t %tex-macros-p: t %End: