% Save file as: NEWSLETR.TEX Source: FILESERV@SHSU.BITNET \def\IDENT{01-014} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright 1989--1991 by Hunter Goatley. This code may be freely % % distributed and modified for non-commercial purposes as long as this % % copyright notice is retained. Please notify the author of any fixes or % % improvements you make. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % File: NEWSLETTER_FORMAT.TEX % % Abstract: % % This file defines TeX control sequences required to produce a % newsletter. It assumes plain.tex has been loaded. % % Author: Hunter Goatley % VAX Systems Programmer % Western Kentucky University % Academic Computing, STH 226 % Bowling Green, KY 42101 % Voice: 502-745-5251 % E-mail: goathunter@WKUVX1.BITNET % % Partially based on examples from _The TeXbook_, by % Donald E. Knuth, and various other sources. Virtually % all of the macros from other sources have been rewritten % or at least modified. % % Date: June 3, 1989 % % Modified by: % % 01-014 Hunter Goatley 21-AUG-1991 10:47 % Rewrote double-quote macros (they work now!). Cleaned up % a little bit. Added \slant and \ital. % % 01-013 Hunter Goatley 25-JAN-1991 08:23 % Added \newpage. Added \tt definitions to \*point macros. % Fixed problem with \quotee (quotee name was getting split). % Added setting of \hyphenpenalty and \emergencystretch to % \newspage macro. % % 01-012 Hunter Goatley 15-JAN-1991 07:03 % Added macro \round to help with keeping page & figure heights % even. It helps some. Re-worked \beginquote and \endquote. % Add \Quote and \quotee. Added \listindent and dimens. % Modified \coltitle to include \noindent; changed amount of % \vglue. Modified \beginlist and \endlist to check for % a \parskip of 0pt; if 0, skip .5\baselineskip. Fixed % \centerbox (was \vbox, now \hbox). % % 01-011 Hunter Goatley 5-JAN-1991 23:40 % Changed \ednote macro so that \sl is redefined as \rm, not \ss. % Changed \say macro to look like LaTeX's \typeout macro. % % 01-010 Hunter Goatley 6-OCT-1990 02:55 % Commented out \ss calls at end of font macros. % Placed newsletter hsize commands in a macro (\newspage) % so that NEWTEX can be used like TeX normally is. % % 01-009 Hunter Goatley 10-MAR-1990 16:05 % Added \par to the beginning of definition of \endlist. % % 01-008 Hunter Goatley 7-DEC-1989 22:07 % Added \farright (place hbox flush right or on next line if it % won't fit). Modified definition of \eoa to call \farright. % Added \pmb -- "poor man's bold." Added font cmssxb. Added % \eldots and \edots. % % 01-007 Hunter Goatley 1-OCT-1989 03:41 % Added figure support for multiple column environment. % Added \centerbox. % % 01-006 Hunter Goatley 17-AUG-1989 10:11 % Modified so that "@" is an active character throughout the % format file. Added new header/footer commands that are more % flexible. Improved appearance of shadow box created by % \leftshadowbox. % % 01-005 Hunter Goatley 10-AUG-1989 22:09 % Modified \onepageout output routine so that it does not % disable interline skip (commented out \offinterlineskip). % This was causing the header and footer to appear flush % with the main body of text on the page. Added routine % \checkdqbalsub. Modified \include to automatically call % \checkdqbalsub after the file has been read in. % % 01-004 Hunter Goatley 30-JUL-1989 03:10 % Added macros to handle font size changes. Added code to % let " be used. % % 01-003 Hunter Goatley 29-JUL-1989 19:26 % Modified double column routines so that the number of columns % can be specified. The routines now work for 2 to 6 columns % of output. % % 01-002 Hunter Goatley 23-JUL-1989 22:21 % Added more comments. Fixed double column routines so that % page sizes are handled properly. % % 01-001 Hunter Goatley 2-JUL-1989 21:28 % Added macros to handle bibliographies. % % 01-000 Hunter Goatley 3-JUN-1989 14:56 % Original version. % \def\say#1{{\let\protect\string\immediate\write10{#1}}} \say{TeX Input file for Newsletter format - version \IDENT} \say{Copyright 1989-1991, Hunter Goatley} \everyjob{\say{TeX Newsletter version \IDENT. Copyright 1989-1991, Hunter Goatley}} % % The \catcode command below lets us use "@" as a letter. It can therefore % be used in command and variable names. PLAIN TeX uses this to avoid % conflicts with user code, so we'll do it, too. % \catcode`@=11 % borrow the private macros of PLAIN (with care) \say{Loading fonts...} % % Load fonts and define commands to switch between fonts % \font\twelverm=cmr12 \font\tenrm=cmr10 \font\ninerm=cmr9 \font\eightrm=cmr8 \font\twelvei=cmmi12 \font\teni=cmmi10 \font\ninei=cmmi9 \font\eighti=cmmi8 %\font\twelvesy=cmsy12 \font\tensy=cmsy10 \font\ninesy=cmsy9 \font\eightsy=cmsy8 \font\twelvebf=cmbx12 \font\tenbf=cmbx10 \font\ninebf=cmbx9 \font\eightbf=cmbx8 \font\twelvett=cmtt12 \font\tentt=cmtt10 \font\ninett=cmtt9 \font\eighttt=cmtt8 \font\twelveit=cmti12 \font\tenit=cmti10 \font\nineit=cmti9 \font\eightit=cmti8 \font\twelvesl=cmsl12 \font\tensl=cmsl10 \font\ninesl=cmsl9 \font\eightsl=cmsl8 \font\twelvess=cmss12 \font\tenss=cmss10 \font\niness=cmss9 \font\eightss=cmss8 \font\twelvessi=cmssi12 \font\tenssi=cmssi10 \font\ninessi=cmssi9 \font\eightssi=cmssi8 \font\tenssb=cmssbx10 % % 11-point font is scaled 10pt % \font\elevenrm=cmr10 scaled\magstephalf \font\eleveni=cmmi10 scaled\magstephalf \font\elevenbf=cmbx10 scaled\magstephalf \font\eleventt=cmtt10 scaled\magstephalf \font\elevenit=cmti10 scaled\magstephalf \font\elevensl=cmsl10 scaled\magstephalf \font\elevenss=cmss10 scaled\magstephalf \font\elevenssi=cmssi10 scaled\magstephalf \font\seventeenrm=cmr17 \font\seventeenss=cmss17 \font\seventeenssi=cmssi17 \def\seventeenpoint{% \def\sl{\seventeenssi}\def\it{\seventeenssi}\def\bf{\seventeenss}% \def\rm{\seventeenrm}\def\ss{\seventeenss}\def\ssi{\seventeenssi}% \baselineskip=19pt% % Change baselineskip \rm% % By default, use sans serif } \def\twelvepoint{% \def\sl{\twelvesl}\def\it{\twelveit}\def\bf{\twelvebf}% \def\rm{\twelverm\let\sl=\twelvesl}\def\ss{\twelvess\let\sl=\ssi}% \def\ssi{\twelvessi}\def\tt{\twelvett}% \baselineskip=14pt% % Change baselineskip \rm% % By default, use sans serif } \def\elevenpoint{% \def\sl{\elevensl}\def\it{\elevenit}\def\bf{\elevenbf}% \def\rm{\elevenrm\let\sl=\elevensl}\def\ss{\elevenss\let\sl=\ssi}% \def\ssi{\elevenssi}% \def\tt{\eleventt}% \baselineskip=13pt% % Change baselineskip \rm% % By default, use sans serif } \def\tenpoint{% \def\sl{\tensl}\def\it{\tenit}\def\bf{\tenbf}% \def\ssb{\tenssb}% \def\rm{\tenrm\let\sl=\tensl}\def\ss{\tenss\let\sl=\ssi}% \def\ssi{\tenssi}% \def\tt{\tentt}% \baselineskip=12pt% % Change baselineskip \rm% % By default, use sans serif } \def\ninepoint{% \def\sl{\ninesl}\def\it{\nineit}\def\bf{\ninebf}% \def\rm{\ninerm\let\sl=\ninesl}\def\ss{\niness\let\sl=\ssi}% \def\ssi{\ninessi}% \def\tt{\ninett}% \baselineskip=11pt% % Change baselineskip \rm% % By default, use sans serif } \def\eightpoint{% \def\sl{\eightsl}\def\it{\eightit}\def\bf{\eightbf}% \def\rm{\eightrm\let\sl=\eightsl}\def\ss{\eightss\let\sl=\ssi}% \def\ssi{\eightssi}% \def\tt{\eighttt}% \baselineskip=10pt% % Change baselineskip \rm% % By default, use sans serif } \font\HUGE=cmr17 %scaled\magstep2 \font\verysmallrm=cmr5 % Used to make small copyright "C" \font\smallsy=cmsy7 % Used to make small copyright circle \def\tiny{\eightpoint\ss} % Equate \tiny to \eightpoint \let\em=\eightssi \font\quotefont=cmss12 at 14.4truept % Quotation font \font\quoteefont=cmcsc10 % Font for quotee \say{Defining macros...} \newdimen\normalhsize % Create a new dimension \newdimen\normalvsize % Create a new dimension \normalhsize=\hsize % % \newspage % % Set up the page for a newsletter (7" by 9" of text, higher tolerance). % \def\newspage{% \global\topskip=0pt % Set 1 inch top margin \global\hoffset=-.25 true in % Move output .25 in to the left \global\pretolerance=1000 % Set tolerance up (before hyphenation) \global\tolerance=1500 % ... (after hyphenation) \global\hyphenpenalty=500 % Discourage hyphenation \global\emergencystretch=30pt \global\normalhsize=7in \global\hsize=\normalhsize % Pages are 7 inches wide \global\vsize=9in % ... and 9 inches tall \global\abovedisplayskip=\baselineskip \global\belowdisplayskip=\baselineskip \global\pagewidth=\hsize \global\pageheight=\vsize } \clubpenalty=500 %-1000 % Set penalties for club and widow lines \widowpenalty=1000 % ... % %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= % Multiple Column Output %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= % % Define macros to handle multiple column output % % These macros support figures, but the figures must be defined inside % the multiple-column environment. Each column can have up to 3 figures % of varying sizes; the figures are referred to as "top", "middle", and % "bottom". Figures are identified via page number, column number, and % the position. In addition, two special figures that span all columns % can be specified using column 0 with "top" and "bottom". % % For example, {3}{2}{middle} refers to the middle figure in column 2 % of output page 3. % % The figures are stored as temporary inserts (the inserts are freed % after \endcolumns). The inserts are treated as an array whose first % entry is \c@lfigstart. % % Note: column figures are not handled on the last page of column output. % \balancecolumns does not understand how to deal with them. % % While in X column mode, the text is arranged as one column % \columnwidth wide and \pageheight*X tall. This narrow column is % then split into X boxes of equal height. % %*************************************** % % Allocate a bunch of dimens, boxes, and counts for use in multiple-column % macros. % \newdimen\columnwidth % Width of a column \newdimen\columnseprule % Width of rule between columns \newdimen\columnsep % Width of whitespace between columns \newdimen\pagewidth % Total width of page \newdimen\pageheight % Total height of page \newdimen\pageheightkeep % Total height of page \newdimen\ruleht % Height of \hrules \newif\ifcolfigs % Create a new \if (true if figures) \newbox\partialpage % Box to hold partial page before cols. \newbox\partialpagetop % Box to hold figure for top of page \newbox\partialpagebottom % Box to hold figure for bottom of page \newcount\mulc@lbegin % Allocate a counter \newcount\mulc@lpart % Allocate a counter \newcount\numberofcols % Number of columns \newcount\c@lpageno % Current page # for column environment \newcount\maxcolfigs % Maximum # of figures \newcount\c@lfigstart % Starting array slot # for inserts \newcount\c@lslot % Work counter to hold current slot # \newcount\maxfigp@ges % Maximum # of pages of column output \newcount\figsperp@ge % Number of figures on each page % % Allocate multi-column work counters and dimens. % \newdimen\tmp@ % Dimen used to calculate pageheights, etc. \newdimen\tmp@one % Dimen used to calculate pageheights, etc. \newcount\tmp@two % Usually # of cols * 2 \newcount\tmp@three \newcount\tmp@four \newcount\tmp@five \newcount\tmp@six \newcount\tmp@seven \newdimen\rtmp@ % Dimen used in rounding % % Initialize the \column* dimens. If \columnwidth is still 0pt when % \begincolumns is called, the correct \columnwidth will be % calculated from the current \hsize. This lets the user set a column % width, without requiring that it be done. % \columnsep=20pt % Space between columns \columnseprule=.4pt % Width of rule between columns \columnwidth=0pt % Initialize columnwidth to 0pt % % Initialize pagewidth, pageheight, and ruleht % \pagewidth=\hsize \pageheight=\vsize \ruleht=.5pt % % Define constant values used to indicate type of figure stored in % figure boxes. Probably inefficient to store them as macros, but it's % easier that way (and they're not hardcoded in the macros below). % \def\TopFig@{500} % Figure is at top of page \def\BotFig@{600} % Figure is at bottom of page \def\RegFig@{321} % Figure is a corner figure \def\topc@lpos{1} % The top figure position (1) \def\middlec@lpos{2} % The middle figure position (2) \def\bottomc@lpos{3} % The bottom figure position (3) % % Macro \onepageout % % Output routine used to actually shipout pages to the DVI file. % \def\onepageout#1{\shipout\vbox{ % here we define one page of output {\hsize=\pagewidth\makeheadline} % Do normal width headline %\offinterlineskip % butt the boxes together \vbox to \pageheightkeep{ % Create a vbox big enough \boxmaxdepth=\maxdepth % Set boxmaxdepth #1 % Now insert the information } % \vbox to \pageheight {\hsize=\pagewidth\makefootline} % Do normal width footline } % End of \vbox \advancepageno % Advance current page number } % End of \def\onepageout %\output{\onepageout{\unvbox255}} % Send out any current output % % When \begincolumns is called: % % \output is set to perform the following functions: % Store the current vbox in the partialpage box (with some vskip) % Eject the page (executing \output - page is not really ejected) % Set new definition of output: % Call \multiplecolumnout to output the columns % Set \hsize = \columnwidth % Set \vsize = (\pageheight * X) - (\ht\partialpage * X) --- each column will % now be just as tall as the space below \partialpage % % Sometimes the first \output was executed twice in a row, which caused the % first \partialpage to be lost. The code below includes a counter that is % used to determine if the output routine is called a second time. If it % is, the routine ships the previously stored partial page and then creates % a new \partialpage. % % Originally, \begincolumns set \vsize = X * \pageheight (it did not % take the height of the \partialpage into account). If the complete text % would fit in the full \vsize, the balancing routine would have problems % balancing and you'd end up with lots of whitespace on a page and the % multiple columns would show up on the next page. Make sense? If not, % just trust me; it caused problems. % % The solution to the problem was to set % % \vsize = (\pageheight * X) - (\ht\partialpage * X) % % and then set \vsize back to (X*\pageheight) after the first page had been % ejected. This worked fine and dandy except for the fact that grouping was % causing the changes to not hold. The solution (and it is a little % dangerous) was to use \global\vsize so that the \vsize changes were never % local to the group. \endcolumns then resets \vsize = \pageheight. % Again, trust me; it seems to work OK. % \def\begincolumns#1{ \ifnum#1<2 \errmessage{Invalid number of columns -- #1; must be 1 < X < 7}\fi \ifnum#1>6 \errmessage{Invalid number of columns -- #1; must be 1 < X < 7}\fi \begingroup % Begin a new group \global\mulc@lbegin=1 % Set "first time" output counter \global\mulc@lpart=1 % Set "first time" outputting dbl cols. \global\pageheightkeep=\vsize % Initialize \pageheight \global\pageheight=\vsize % Initialize \pageheight \round{\pageheight}{\baselineskip}{<} % Round the pageheight down \global\pagewidth=\hsize % Initialize \pagewidth \global\tmp@two=#1 \global\advance\tmp@two by-1 \global\numberofcols=#1 % Initialize number of columns % Calculate column width unless user set a value \ifdim\columnwidth=0pt % If user did not set \columnwidth \columnwidth=\hsize % Set columnwidth = normal page width \tmp@=-\columnsep % Copy neg. amount of columnsep to tmp@ \multiply\tmp@ by\tmp@two % Multiply by X (total amount of colsep) \advance\columnwidth by\tmp@ % Subtract width space between columns \divide\columnwidth by\numberofcols % Divide by X to get X column output \fi % End of \columnwidth calculation \output={ \ifnum\mulc@lbegin=1 % 1st time through? \global\setbox\partialpage=\vbox{\unvbox255\bigskip} % Store partial \global\mulc@lbegin=2 % Increment counter \else % 2nd time through... \onepageout{\vbox{\unvbox\partialpage}} % Ship previous partial \global\setbox\partialpage=\vbox{\unvbox255\bigskip} % Make a new \fi % ... partial }\eject % Force the output routine to execute \output={\multiplecolumnout} % Output X columns \hsize=\columnwidth % Set hsize = col. width % Set \vsize = (\pageheight * X) - (\ht\partialpage * X) \global\vsize=\pageheight % Set \vsize=X*\pageht \global\multiply\vsize by\numberofcols % Multiply by X \tmp@=-\ht\partialpage \multiply\tmp@ by\numberofcols % Subtract (height of \global\advance\vsize by\tmp@ % ... partial page * X) \round{\vsize}{\baselineskip}{>} % Round it up } % End of \begincolumns % % \endcolumns performs the following functions: % % Sets \output to call \balancecolumns % \vfills page and ejects it % Terminates the group % Resets vsize to original size % Resets pagegoal = to original \vsize % Skips parskip vertical space % Signals that this is a good place for a break, if necessary % \def\endcolumns{\output={\balancecolumns} \eject \endgroup \global\vsize=\pageheightkeep \pagegoal=\vsize \bigskip \goodbreak} % % \multiplecolumnout % % Sets splittopskip = topskip % Sets splitmaxdepth = maxdepth % Sets TeX register \dimen@ = to height of the page % Subtracts the height of the partial page from \dimen@ % Subtracts the heights of the top & bottom figures from \dimen@ % Splits up the current output box into X boxes of size \dimen@, handling % figures, if present % Calls \onepageout to dump the new boxes % Resets \vsize = (X * \pageheight) if first time through macro % Frees up current output vbox (255) % \def\multiplecolumnout{\splittopskip=\topskip \splitmaxdepth=\maxdepth \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage \advance\dimen@ by-\ht\partialpagetop % Subtract height of top figure \advance\dimen@ by-\ht\partialpagebottom % Subtract height of bottom fig. \tmp@four=\numberofcols \multiply\tmp@four by2 % Calculate upper box # \tmp@five=0 % Start boxes with box 0 \ifcolfigs % Are there figures defined? \splitfigc@ls % Yes - go handle text & figures \else % No - split \box255 into X cols % % Split box255 into a box of dimen@ height. Loop until X boxes created. % {\loop \global\setbox\tmp@five=\vsplit255 to\dimen@ \advance\tmp@five by2 \ifnum\tmp@five<\tmp@four \repeat} % Loop if not done \fi % \ifcolfigs \onepageout\pagesofar % Send this page to DVI file \ifnum\mulc@lpart=1 % Does vsize need to be reset? \global\mulc@lpart=2 % Yes - change counter \global\vsize=\pageheight % Set \vsize = X * \pageheight \global\multiply\vsize by\numberofcols % ... \fi % ... \ifcolfigs % If figures defined... \global\advance\c@lpageno by\@ne % Bump column output page no. \handlefigures % Handle next page's figures \fi % \ifcolfigs \unvbox255 \penalty\outputpenalty % Free current output vbox } % End of \multiplcolumnout % % \splitfigc@ls % % This macro splits \box255 into X columns, handling the figures. % % Get figure array slot number for figure 1, column 1 on current page % Loop for each column (starting with column in \tmp@five) % Make a copy of \dimen@ -> \tmp@ % If a figure is defined for top of column % Decrease \tmp@ by the height of the figure % Set box 1 = the figure % Else % Set box 1 = null vbox % Bump figure array slot number - now points to slot for middle figure % If a figure is defined for middle of column % Decrease \tmp@ by the height of the figure % Set box 5 = the figure % Else % Set box 5 = null vbox % Bump figure array slot number - now points to slot for bottom figure % If a figure is defined for bottom of column % Decrease \tmp@ by the height of the figure % Set box 9 = the figure % Else % Set box 9 = null vbox % Bump figure array slot number - now points to slot for next top figure % Split \box255 into 1 or 2 pieces (2 if there is a middle figure) % Set \box\tmp@five = \box1 + \box3 + \box5 + \box7 + \box9 % Advance \tmp@five by 2 and loop until X "columns" created % \def\splitfigc@ls{ % % Split box255 into a box of dimen@ height. Loop until X boxes created. % \tmp@two=1 % Figure counter \calcc@lslot{\c@lpageno}{1}{\tmp@two} % Get slot for figure 2 on current page {\loop % Start loop \tmp@=\dimen@ % Make a working copy of dimen@ % % Handle top figure % \ifnum\count\c@lslot=\RegFig@ % If this slot holds a single-column fig \advance\tmp@ by-\ht\c@lslot % Subtract figure's height from \tmp@ \setbox1=\vbox{\unvbox\c@lslot} % Copy figure to \box1 \say{Figure \the\tmp@two\space on page \the\c@lpageno, document page \folio} \else \setbox1=\vbox{} % Else set box 1 = null page \fi % \ifnum % % Handle middle figure % \advance\c@lslot by\@ne % Point to next figure \advance\tmp@two by\@ne % Advance figure counter \ifnum\count\c@lslot=\RegFig@ % If this slot holds a single-column fig \advance\tmp@ by-\ht\c@lslot % Subtract figure's height from \tmp@ \setbox5=\vbox{\unvbox\c@lslot} % Copy figure to \box3 \say{Figure \the\tmp@two\space on page \the\c@lpageno, document page \folio} \else \setbox5=\vbox{} % Else set box 3 = null page \fi % \ifnum % % Handle bottom figure % \advance\c@lslot by\@ne % Point to next figure \advance\tmp@two by\@ne % Advance figure counter \ifnum\count\c@lslot=\RegFig@ % If this slot holds a single-column fig \advance\tmp@ by-\ht\c@lslot % Subtract figure's height from \tmp@ \setbox9=\vbox{\unvbox\c@lslot} % Copy figure to \box3 \say{Figure \the\tmp@two\space on page \the\c@lpageno, document page \folio} \else \setbox9=\vbox{} % Else set box 3 = null page \fi % \ifnum \advance\c@lslot by\@ne % Point to next figure in array \advance\tmp@two by\@ne % Advance figure counter % % Here, top figure is in \box1, middle figure is in \box5, and bottom % figure is in \box9. % Split \box255 to fill the remaining column space, splitting in % half if there is a middle figure. % Special case: if height of \box1 = \pageheight, \box\tmp@five=null % \ifdim\ht1=\pageheight % Is top = whole column? \global\setbox3=\vbox{} % Yes - set \box3 to null \global\setbox7=\vbox{} % Yes - set \box7 to null \else % No - go ahead and do split \ifdim\ht5>0pt % Is there a middle figure? \divide\tmp@ by2 % Yes - break text to 2 pieces \global\setbox3=\vsplit255 to\tmp@ % Set \box3 = 1st piece \global\setbox7=\vsplit255 to\tmp@ % Set \box7 = 2nd piece \else % No middle column... \global\setbox3=\vsplit255 to\tmp@ % Put all text in \box3 \global\setbox7=\vbox{} % Set \box7 to null \fi % \ifdim\ht5... \fi % \ifdim % % Now put the 5 pieces together as one vbox in \box\tmp@five % \global\setbox\tmp@five=\vbox to\dimen@{\offinterlineskip% \ifdim\ht1=0pt\else\vbox{\unvbox1}\fi \ifdim\ht3=0pt\else\vbox{\unvbox3}\fi \ifdim\ht5=0pt\else\vbox{\unvbox5}\fi \ifdim\ht7=0pt\else\vbox{\unvbox7}\fi \ifdim\ht9=0pt\else\vbox{\unvbox9}\fi \vfil\vfilneg % Cancels spurious vglue ???? (it works) } \advance\tmp@five by2 % Bump column box # \ifnum\tmp@five<\tmp@four \repeat} % Loop if not done } % End of \splitc@lfigs % % \pagesofar % % Releases \partialpage box % Sets width of X boxes (from box 0 to box X) = to \columnwidth % Creates an hbox = pagewidth that consists of box0 + separator rule + box 2 % + separator rule + box X % This new hbox is \box255 and can be used to \shipout % \def\pagesofar{\unvbox\partialpage \unvbox\partialpagetop % Include top figure \tmp@four=\numberofcols \multiply\tmp@four by2 % Loop boundary number \tmp@five=0 % Start with box 0 % % For each box, set the width equal to the column width % {\loop \wd\tmp@five=\columnwidth \advance\tmp@five by2 \ifnum\tmp@five<\tmp@four \repeat} % Loop until X done % % Now put all the boxes together like this: % % box | box | ... | box % \tmp@five=0 % Start with box 0 again \hbox to\pagewidth{\box\tmp@five\advance\tmp@five by2% Do the left column \loop \hfil\vrule width\columnseprule \hfil \box\tmp@five% \advance\tmp@five by2 % Bump box counter \ifnum\tmp@five<\tmp@four \repeat % Loop if not done } % End of hbox \unvbox\partialpagebottom % Include bottom figure } % End of \pagesofar % % \balancecolumns - Balance both columns at end of X column page % % Sets box 0 = current page % Sets dimen@ = height of the vbox in box 0 % Adds topskip value to dimen@ % Subtracts X * \baselineskip from dimen@ % Divides dimen@ by X -- dimen@ now has target height of each column % Sets splittopskip = to topskip so it can be added to all columns % Loops % Copies box 0 to box 3 % Splits box 3 to dimen@ and stores in box 1 & 3 % Increments dimen@ by 1pt and loops if column in box 3 exceeds dimen@ % Note: Splitting of box is actually implemented as a loop that creates % X boxes % Moves columns in odd-numbered boxes to corresponding even-numbered boxes % Calls pagesofar to make the hbox for it % \def\balancecolumns{\setbox0=\vbox{\unvbox255} \dimen@=\ht0 % % Subtract X * \baselineskip from dimen@ and divide dimen@ by X % \tmp@two=\numberofcols \advance\tmp@two by-1 \tmp@=-\baselineskip \multiply\tmp@ by\tmp@two \advance\dimen@ by\tmp@ \divide\dimen@ by\numberofcols \splittopskip=\topskip % Dimen@/X % % Split the column X times so we have X columns of equal height. If our % last column is > dimen@, bump dimen@ by one and loop. % \tmp@four=\numberofcols \multiply\tmp@four by2 % X * 2 \tmp@seven=\tmp@four \advance\tmp@seven by-1 % Work box: (X*2)-1 {\vbadness=10000 \loop \global\setbox\tmp@seven=\copy0 \tmp@five=0 \tmp@six=1 % Work box starts with 1 {\loop % Loop for X boxes \global\setbox\tmp@six=\vsplit\tmp@seven to\dimen@ % Vsplit box \advance\tmp@six by2 % Bump box counter \ifnum\tmp@six<\tmp@seven \repeat} % Loop if not done \ifdim\ht\tmp@seven>\dimen@ \global\advance\dimen@ by1pt \repeat} % % Here we have X columns of equal height. Note that the last column may % not be equal to the others. % % Copy the columns to the even-numbered boxes in preparation for \pagesofar % \tmp@five=0 \tmp@six=1 {\loop \global\setbox\tmp@five=\vbox to\dimen@{\unvbox\tmp@six} \advance\tmp@five by2 \advance\tmp@six by2 \ifnum\tmp@five<\tmp@four \repeat} \pagesofar} % Call \pagesofar to build page % % \c@lnewinsert % % This macro is used to perform a \newinsert for temporary usage (inside a grp) % \def\c@lnewinsert{\advance\insc@unt by\m@ne % Decrement insert counter \ch@ck0\insc@unt\count % Make sure count is available \ch@ck1\insc@unt\dimen % Make sure dimen is available \ch@ck2\insc@unt\skip % Make sure skip is available \ch@ck4\insc@unt\box % Make sure box is available % NEED TO EMPTY BOX!!! \count\insc@unt=0 % Set the count to 0 \allocationnumber=\insc@unt % Set the allocation number } % End of \c@lnewinsert % % \definefigs % % This macro is called to establish the figure environment inside of the % multiple-column environment. It allocates (until \endcolumns) an array % of inserts (boxes, counts, dimens, and skips) to handle all of the % figures per page for the given number of pages. When the figures % are defined using \definefig, the proper box is filled with the figure. % % Inputs: % % #1 - Number of pages of multiple-column output (should be as large % as the total number of pages between \begincolumns and % \endcolumns) % \def\definefigs#1{ \colfigstrue % Set column figure flag \global\c@lpageno=1 % Get current page number \maxfigp@ges=#1 % Set maximum # of pages with figures \figsperp@ge=\numberofcols % Calculate # of figures per page \multiply\figsperp@ge by3 % Figs/Page = 2 + (3 * number of cols) \advance\figsperp@ge by2 % ... \maxcolfigs=\maxfigp@ges % Figure out how many inserts are needed \multiply\maxcolfigs by\figsperp@ge % ... for all of the figures \tmp@two=\maxcolfigs % Start there and work down to first box \loop \c@lnewinsert \advance\tmp@two by\m@ne \ifnum\tmp@two>0 \repeat \c@lfigstart=\insc@unt % Save starting array slot # % We've allocated all boxes now } % End of \definefigs % % \definefig % % This macro stores figure information in the appropriate slot in the insert % array. After calculating the proper slot number for the figure, it stores % the figure in the corresponding box and sets the corresponding \count to % a code identifying the box as holding a figure. % % Inputs: % % #1 Output page number % #2 Column Number % #3 Position (top, middle, bottom) % #4 The vbox for the figure % \def\definefig#1#2#3#4{ \ifcolfigs % Has \definefigs been called? \else \errmessage{Illegal use of \string\definefig\space before \string\definefigs} \fi % \ifnum \ifnum#2>\numberofcols % Illegal column number? \errmessage{Column number #2 exceeds number of columns} \fi % \ifnum \calcc@lslot{#1}{#2}{\csname #3c@lpos\endcsname} % Calculate slot # \ifcase\csname #3c@lpos\endcsname \or\setbox\c@lslot=\vbox{#4\vskip\belowdisplayskip} \or\setbox\c@lslot=\vbox{\vskip\abovedisplayskip#4% \vskip\belowdisplayskip} \or\setbox\c@lslot=\vbox{\vskip\abovedisplayskip#4} \tmp@=\ht\c@lslot % Round up the size \round{\tmp@}{\baselineskip}{>} % ... \tmp@one=\tmp@ \advance\tmp@one by-\ht\c@lslot \setbox\c@lslot=\vbox to\tmp@{\box\c@lslot} \fi \ifnum#2=0 % If column # is 0, special fig. \ifnum\csname #3c@lpos\endcsname=1\count\c@lslot=\TopFig@ \else\count\c@lslot=\BotFig@\fi % Top or Bottom figure that \else % ... spans all columns \count\c@lslot=\RegFig@ % Otherwise, identify the box \fi % ... as containing a figure \say{Processed #3 figure for column #2\space on page #1\space - slot \the\c@lslot} \say{The height is \the\ht\c@lslot} } % % \calcc@lslot % % This macro is called to calculate the array slot number for a figure. % The formula for normal figures is: % % ((column# - 1) * 3figs/column) + Position % % This macro assumes there can be 3 figures per column (top, middle, & bottom) % % Inputs: % % #1 - Page number % #2 - Column number (0 = special figure that spans all columns) % #3 - Figure number (1 = top, 2 = middle, 3 = bottom) % % Returns: % % \c@lslot - Slot number for given figure. This slot number % identifies the allocated insert for the figure. % \def\calcc@lslot#1#2#3{ \tmp@seven=#1 % Start with page # \advance\tmp@seven by\m@ne % (Page - 1) \multiply\tmp@seven by\figsperp@ge % (Page - 1) * # of figs \ifnum#2=0 % If column is 0, special one \ifnum#3=1\tmp@six=1\else\tmp@six=\figsperp@ge\fi \advance\tmp@six by\m@ne % Decrement for slot # \else \tmp@six=#2 % Column # \advance\tmp@six by\m@ne % (Column# - 1) \multiply\tmp@six by3 % (Column# - 1) * 3 \advance\tmp@six by#3 % (Column# - 1) * 3 + Position \fi % Really + 1, but -1 negates it \advance\tmp@seven by\tmp@six % Add figure # to page # \advance\tmp@seven by\c@lfigstart % Figure slot number \global\c@lslot=\tmp@seven % Set the slot number } % End of \calcc@lslot % % \handlefigures % % This macro is called to step through all of the figures for the current % page and subtract the height of each from the total \vsize. % % The two special figures (top (1) and bottom (\figsperp@ge)) are handled % differently; because each spans all of the columns on the page, the height % of each is multiplied by the number of columns before subtracting it from % \vsize. The top figure is then placed in \partialpagetop and the bottom % figure is placed in \partialpagebottom. % % Returns: Adjusted \vsize. % \def\handlefigures{ \global\vsize=\pageheight % \vsize to pageheight \global\multiply\vsize by\numberofcols % Multiply by # of columns \tmp@three=\figsperp@ge % Start with figure X \calcc@lslot{\c@lpageno}{0}{3} % Start with last figure box {\loop \ifnum\count\c@lslot=\TopFig@ % If box is top section of page \global\setbox\partialpagetop=\vbox{\unvbox\c@lslot} % Copy it \tmp@=\ht\partialpagetop % Get the height \multiply\tmp@ by\numberofcols % Multiply by number of columns \global\advance\vsize by-\tmp@ % (vsize - figure size) \else % Else \ifnum\count\c@lslot=\BotFig@ % If box is bottom section \global\setbox\partialpagebottom=\vbox{\unvbox\c@lslot} \tmp@=\ht\partialpagebottom \multiply\tmp@ by\numberofcols \global\advance\vsize by-\tmp@ % (vsize - figure size) \else % Else, see if regular figure \ifdim\ht\c@lslot>0pt\all@wfigure{\ht\c@lslot}\fi % \vsize \fi % End \ifnum \fi % End \ifnum \advance\tmp@three by\m@ne % Point to next box \advance\c@lslot by\m@ne % Point to next box \ifnum\tmp@three>0 \repeat} % Loop until done } % End of \handlefigures \def\all@wfigure#1{ \tmp@=#1 % Height of figure \global\advance\vsize by-\tmp@ % Subtract figure size from vsize } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Macro: \round#1#2#3 % % Purpose: Round a dimen parameter (#1) to the nearest even multiple of % parameter #2. Primarily used to ensure that the page height % or a figure height is an even multiple of the baselineskip. % % NOTE: this macro assumes there is no stretch or shrink to #2. % % Inputs: % #1 Dimen variable to change (e.g., \pageheight) % #2 Dimen variable to use as multiple (e.g., \baselineskip) % #3 Symbol indicating round up (>) or round down (<) % \tmp@ Work dimen (saved and restored) % % Example: % \pageheight=598.213pt \baselineskip=12pt % \round{\pageheight}{\baselineskip}{<} %yields \pageheight=588.0pt % \round{\pageheight}{\baselineskip}{>} %yields \pageheight=600.0pt % \def\round#1#2#3{\bgroup% %Keep \tmp@ changes local \rtmp@=0pt %Initialize \tmp@ \loop %Begin a loop \advance\rtmp@ by #2 %Bump \tmp@ by #2 \ifdim#1>\rtmp@ \repeat %Loop until \tmp@ > #1 \ifx<#3 %If #3 = "<" then \advance\rtmp@ by-#2 %... subtract #2 from \tmp@ \fi %... \global#1=\rtmp@ %Reset parameter #1 \egroup %End the group } %End of macro %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Define list macros % % Dimens: % % \llistindent - Amount of left indent (0pt by default) % \rlistindent - Amount of right indent (0pt by default) % % Macros: % % \beginlist - Begin list (skips space, sets indent) % \endlist - Terminates a list % \beginlistt - Begin list with glue (used for list headers) % \endlistt - Terminates a \beginlistt % \dotitem - Itemize with a dot "o" % \newdimen\llistindent \llistindent=0pt \newdimen\rlistindent \rlistindent=0pt \def\listindent#1{\llistindent=#1\rlistindent=#1} \def\beginlist{\begingroup% \ifdim\parskip=0pt \vskip.5\baselineskip % Skip 1/2 line \else \vskip\parskip % or the \parskip \fi % \parindent=10pt\parskip=0pt% % Reset parindent \leftskip=\llistindent \rightskip=\rlistindent} % Indent margins \def\endlist{\par\endgroup% \ifdim\parskip=0pt \vskip.5\baselineskip \else \vskip\parskip\fi} \def\dotitem#1\par{\item{$\bullet$} #1 \par} \def\beginlistt#1{#1\vglue0pt\begingroup% \divide\parskip by2\vskip\parskip\parindent=10pt\parskip=0pt% \leftskip=\llistindent \rightskip=\rlistindent} \def\endlistt{\par\endgroup} %\vskip\parskip} % % Define a small copyright (for use with 8-point type). % \def\smallcir{\smallsy\char13} \def\smallcopyright{\leavevmode\raise.25ex\hbox{ \ooalign{\hfil\raise.03ex\hbox{\kern .16em\verysmallrm C} \hfil\crcr\smallcir}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Define macros to manipulate boxes % % Dimens: % % \boxitrule=Xpt - Width of rules used to draw boxes % \boxitspace=Xpt - Space between box rules and box contents % \boxshadowsize=Xpt - Width of shadow boxes % % Macros: % % \articletitle{Title}{byline} - Do article title in double box % \coltitle{Title} - Do a title box in a column % \shadowbox{some_box} - Draw a shadow box around an hbox or vbox % \leftshadowbox{somebox} - Draw a left-hand shadow box around a box % \centerbox{somebox} - Center a \vbox on a page % \boxit{some_box} - Draw a box around an hbox or vbox % \ednote - Do editor's note in a box % \newdimen\boxitspace \newdimen\boxitrule \newdimen\boxitwidth \boxitspace=3pt \boxitrule=1.2pt \boxitwidth=\boxitspace \advance\boxitwidth by\boxitspace \advance\boxitwidth by\boxitrule \advance\boxitwidth by\boxitrule % % Define macro to write an article title inside a double box % % Parameters: % % #1 - Title of article % #2 - Byline % % For both \articletitle and \coltitle, the width of the box(es) must be % subtracted from the current hsize in order for centering and justification % to work right (otherwise the letters will run into the lines of the box). % \def\articletitle#1#2{ \bestbreak{ % Say that this is best break \advance\hsize by -\boxitwidth % Bring margin in before \center \advance\hsize by -\boxitwidth % Do for both boxes! \vskip 10pt plus 5pt % Skip some space \boxit{ % Box the box \divide\boxitrule by 2 % Make inside box lines thinner \boxit{ % Box the text \vbox{\noindent % Create a box \centerline{\seventeenpoint\ss #1} % Print title of article \centerline{\ninepoint\ss #2} % Print article byline }}}}} % Create the text box \def\coltitle#1\par{{% % Swallow next paragraph \advance\hsize by -\boxitwidth % Bring margins in \boxit{% % Draw a box around the text \vbox{\ss\noindent #1}}}% % Create a vbox that contains \vglue.5\baselineskip% % Skip some non-breakable space \noindent} % Don't indent next paragraph \def\ednote#1{{ \sl % Switch to slanted font \def\sl{\/\rm} % Redefine \sl \advance\hsize by -\boxitwidth % Bring margins in \boxit{ % Draw a box around the text \vbox{\noindent Editor's note: #1}}} % Create a vbox that contains \vglue 0pt} % Finish it up \def\boxit#1{\vbox{\tithrule\hbox{\titvrule\kern\boxitspace% \vbox{\kern\boxitspace #1 \kern\boxitspace}% \kern\boxitspace\titvrule}\tithrule}} \def\tithrule{\hrule height\boxitrule} \def\titvrule{\vrule width\boxitrule} % % \centerbox % % Create a \vbox that contains a centered \hbox. The centering is relative % to the current \hsize. % % Inputs: % % #1 - \vbox to center -> \centerbox{\shadowbox{...}} % \def\centerbox#1{\hbox{\hfil#1\hfil}} % Create a \vbox containing a centered \newdimen\oboxht \newdimen\oboxwd \newdimen\boxshadowsize \boxshadowsize=4pt % Shadow box size is 4pt % % Draw a righthand shadow box. This is accomplished by building a vbox % containing an hbox that is the boxed text and an hbox that is the right % hand shadow. This vbox is then joined with a vbox that forms % the bottom shadow. % \def\shadowbox#1{{ \setbox0=\vbox{\boxit{#1}} % Set box after \boxit \oboxht=\ht0 \oboxwd=\wd0 % Store the dimensions \advance\oboxwd by-\boxshadowsize % Subtract shadow size from wd \vbox{ % Put it all in one vbox \offinterlineskip % Butt \vboxes together \vbox{ % Create a vbox of whole thing \hbox{\vbox{\unvbox0} % Create box with text box + \hskip-\fontdimen2\font \lower\boxshadowsize % Draw the right-hand boxshadowsize \hbox{\vrule width\boxshadowsize height\oboxht}} % ... Finish off \hbox } % End of the \vbox \advance\boxshadowsize by\boxitrule \vskip-\boxshadowsize % Back up to bottom of \vbox \vbox{ % Start a new \vbox \hbox{\kern\boxshadowsize\vbox{ % Create \hbox that is shadow \hrule height\boxshadowsize width\oboxwd}} % ... } % End of the \vbox } % End of \vbox }} % End of \shadowbox % % Draw a lefthand shadow box. This is accomplished by building a lowered % vbox containing an hbox that is the left hand shadow and an hbox that % contains the boxed text. This vbox is then joined with a vbox that forms % the bottom shadow. % \def\leftshadowbox#1{{ \setbox0=\vbox{\boxit{#1}} % Set box after \boxit \oboxht=\ht0 \oboxwd=\wd0 % Store the dimensions \advance\oboxwd by-\boxshadowsize % Subtract shadow size from wd \vbox{ \offinterlineskip % Butt \vboxes together \vbox{ % Create a vbox of whole thing \hbox{ % Create an hbox \hskip-\fontdimen2\font % Move left one character width \hskip-\boxshadowsize % Move left = size of shadow box \advance\boxitrule by\boxshadowsize % Make shadow a tad bit wider \lower\boxshadowsize % Move down the same amount \hbox{\vrule width\boxitrule height\oboxht} % Draw the left box } % ... Finish off \hbox \vskip-\oboxht\vskip-\boxshadowsize % Move back up to top of box \hbox{\vbox{\unvbox0} % Create box with text inside it }} % End of vboxes \advance\boxshadowsize by\boxitrule % Make box a little thicker % ... so it overlaps bottom line \vskip-\boxitrule % Move up height of bottom line \vbox{ % Start a new \vbox \hbox{\vbox{ % Create \hbox that is shadow \hrule height\boxshadowsize width\oboxwd}} % ... } % End of the \vbox } % End of \vbox }} % End of \shadowbox \def\bestbreak{\par\penalty-1000} % % Begin a quotation. The quote is separated from the main text by two % hrules and is indented from the normal text. % \def\beginquote{ \begingroup % Define beginning of a group \quotefont\baselineskip=16.8pt \hrule height2pt % Draw a line \parindent 5pt % Indent paragraphs by 5pt \vglue\medskipamount % Use some glue so rule sticks \narrower\narrower % Bring margins in (10pt) \noindent % Don't indent } % End of macro % % End a quotation. % \def\endquote{ \vglue\medskipamount % Use some glue so rule sticks \hrule height2pt % Draw a line \endgroup % End the quote group } \def\quotee#1{{\hfill\break\hbox{}\nobreak\hfill\hbox{\quoteefont #1} \finalhyphendemerits=0}} \def\Quote#1#2{\vbox{\vskip1.2pt\beginquote #1% \quotee{#2}\endquote\vskip1.20003pt}} % % Insert current month and year % \def\DATE{\ifcase\month\or January\or February\or March\or April\or May \or June\or July\or August\or September\or October\or November \or December\fi\space\number\year} % % Include a TeX file. % \def\include#1{\immediate\write10{Including TeX file #1} \input #1 % Read the file in % Things to do after formatting the file } % % Separate articles with some vskip and an \hrule % \def\articlesep{ % Rule to separate articles \vglue 10pt plus2pt minus4pt % Use vglue \hrule %height.4pt % Draw a rule equal to \hsize \vskip 10pt plus2pt minus2pt % Skip some vertical space } % Put release flush right. If it won't fit, put it on the next line. % From TeXbook, Chapter 14. \def\farright#1{{\unskip\nobreak\hfill\penalty50\hskip2em \hbox{}\nobreak\hfill \hbox{#1}\finalhyphendemerits=0}} % % Define end-of-article marker. % \def\eoa{\farright{\vrule height1.5ex width1.5ex depth0pt}} % % Generate a blank page and a blank line. % \def\nullpage{\eject\line{}\vfil\eject} % Define an empty page \def\nullline{\break\hbox{}\hfil\break} % Define an empty line % % Start on a new page. % \def\newpage{\vfill\eject} % % Get rid of underfill errors % \def\ignoreunderfill{\vbadness=10000\hbadness=10000\tolerance=2000} %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= % Macros for bibliography entries %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= % % Sample usage: % % \beginbibliography % \bibbook{The Wolf's Hour} % \ENUM New York: Pocket Books, March 1989 (paperback) % \endbibliography % \newcount\enumno % New counter - item # % % \beginbibliography - Begin a bibliography % \def\beginbibliography{\begingroup\global\enumno=1 \tiny % Use 8pt font \parskip=1pt plus 1pt % Skip up to 2 points } % End of \beginbibliography \def\endbibliography{\par\endbiblist\endgroup} % End of bibliography % % \beginbiblist - Begin a list of bibliographic references % \def\beginbiblist{\begingroup \vglue0pt\parindent=30pt\parskip=0pt} % % \beginanotherlist - Begin a list inside a list of bibliographic references % \def\beginanotherlist{\begingroup \divide\parskip by 2 \vglue\parskip\advance\parindent by10pt\parskip=0pt} \def\endbiblist{\par\endgroup\vskip4pt} % ENUM - Number items in a list % ENum - No number, but spaced as if number was present % NoENUM - Only one reference is present. Start reference where number would % normally start (hanging into left column). % % Examples: % % \ENUM First one 1. First one % \ENUM Second one Yields 2. Second one % \ENum Third one Third one % \NoENUM Fourth one Fourth one % \def\ENUM#1\par{\item{\the\enumno.}\advance\enumno by 1 #1 \par } \def\ENum#1\par{\item{}\advance\enumno by 1 #1 \par } \def\NoENUM#1\par{\advance\enumno by 1\par\hang\hskip-10pt #1 \par } % % \bibshort, \bibbook, \bibview % % Macros to begin a new bibliography entry for a short story, a book, and % and interviews. These macros will terminate the previous bibliography % entry (if there is one) and begin a new entry. % \def\bibshort#1{\ifnum\enumno>1 \bestbreak\endbiblist\fi % Short story \noindent{\story{#1}}\beginbiblist } \def\bibbook#1{\ifnum\enumno>1 \endbiblist\fi % Book \noindent{\sl #1}\beginbiblist } \def\bibview#1{\ifnum\enumno>1 \endbiblist\fi % Interview \noindent{#1}\beginbiblist } \def\subbib#1{\hskip-20pt #1\hfill} %Subheading for a bib entry \def\bibsectitle#1{ %Title of bib section (BOOKS...) \vskip 8pt plus1pt minus1pt % Skip some space \hrule % Draw an hrule {\tenss #1} % Add text in 10pt font \vglue 10pt plus1pt minus1pt % Skip some more space } %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= % % File: QUOTE.TEX % % Author: Hunter Goatley % % Date: August 14, 1991 % % Abstract: % % This file defines the macros \begindoublequotes and \enddoublequotes, % which let TeX replace the double-quote character (") with TeX's % left double-quote and right double-quote. For example: % % "This is a test." ---> ``This is a test.'' % % The double-quote character is still available via \dq. (\" is still % treated as the umlaut accent.) % % This macro makes a couple of assumptions about the double-quotes: % % 1. Double-quotes are assumed to come in pairs. When replacing % double-quotes, the macro alternates between `` and ''. The only % exception to this is noted in (2) below. % 2. A double-quote at the beginning of a paragraph is always treated % as ``. This correctly handles the case where a quotation is % continued into a second paragraph: % % "This is the first paragraph.\par % "This is the second paragraph of the same quote." % % Normal TeX spacing after `` and '' is maintained by saving and % restoring the \spacefactor. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % HOW IT WORKS: % % The double-quote character (") is made active by \begindoublequotes. % The " macro keeps track of left-quote/right-quote pairs and inserts % the appropriate `` and '' in its place. % % Each character has a \spacefactor associated with it, which specifies % the amount of stretch or shrink that a space following the character % can have. Most characters have a factor of 1000, but some punctuation % marks have higher spacefactors, most notably the period, which has a % \spacefactor of 3000. This means the space following a period can % stretch up to 3 times more than the space after a regular character, % accounting for the increased space at the end of sentences. % % The `` and '' ligatures are assigned \spacefactor's of 0, so that the % \spacefactor that is applied to the next character is the same as that % of the character preceding the quotes. Because " has been redefined as % a macro, any spaces following " are swallowed by TeX. It was necessary % to have this macro re-insert any needed space so that the following % cases worked correctly: % % "This is a test," she said. --> ``This is a test,'' she said. % "This is in a list"; etc. --> ``This is in a list''; etc. % % Without the added space, the first example becomes: % % ``This is a test,''she said. % % The solution was to save the current \spacefactor before inserting a % right double-quote, then resetting the \spacefactor after the % insertion. The net effect was that the " macro has a \spacefactor % of 0, which matches the way TeX treats `` and ''. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% {% % Begin a group for which " is active \catcode`\"=\active % Make " an active character \catcode`\@=11 % Make @ an active character % % \begindoublequotes % % This macro makes " an active character, resets the control sequence % \dblqu@te to L (left), and defines \dq as a replacement for ". % \gdef\begindoublequotes{% % \begindoublequotes enables " \global\catcode`\"=\active % Make " an active character \global\chardef\dq=`\" % Double-quote char. via \dq \global\let\dblqu@te=L % Always start with a left double-quote } % End of macro % % Define the macro that will be executed whenever " is encountered. % \gdef"{% % If the double-quote is the first character in a new paragraph, % make sure it becomes a left double-quote. This case can be % detected by checking to see if TeX is currently in vertical mode. % If so, the double-quote is at the beginning of the paragraph % (since " hasn't actually generated any horizontal mode tokens % yet, TeX is still in vertical mode). If the mode is vertical, % set \dblqu@te equal to L. % \ifinner\else\ifvmode\let\dblqu@te=L\fi\fi % % Now insert the appropriate left or right double-quote. % % If \dblqu@te is L, insert a `` and set \dblqu@te to R. % \if L\dblqu@te``\global\let\dblqu@te=R% % % Otherwise, save the current \spacefactor, insert '', set \dblqu@te % to L, and reset the original \spacefactor. % \else \let\xxx=\spacefactor % Save the \spacefactor ''\global\let\dblqu@te=L% % Insert '' and reset \dblqu@te \spacefactor\xxx % Reset the \spacefactor \fi % End of \if L\dblqu@te... } % End of " macro } % End of group \gdef\enddoublequotes{% \catcode`\"=12 %Set " back to other } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Header & Footer Macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % These macros implement the headers and footers for the newsletter format. % The macros accept three parameters: text that is to appear flush-left on % the line, text that should be centered, and text that should be flush-right % on the line. Parameters can be omitted by specifying empty braces ({}). % % The following macros are defined for headers and footers: % % \evenpageheader{LEFT}{CENTER}{RIGHT} % \oddpageheader{LEFT}{CENTER}{RIGHT} % \evenpagefooter{LEFT}{CENTER}{RIGHT} % \oddpagefooter{LEFT}{CENTER}{RIGHT} % % If the headers/footers are the same for even & odd pages, the following % macros can be used instead of the four above: % % \pageheader{LEFT}{CENTER}{RIGHT} % \pagefooter{LEFT}{CENTER}{RIGHT} % % Additional header/footer definitions: % % \pageheaderlinetrue - A line should extend below header text % \pageheaderlinefalse - Header does NOT have a line % \pagefooterlinetrue - A line should extend above footer text % \pagefooterlinefalse - Footer does NOT have a line % \headfootrule=Xpt - Thickness of header/footer lines % \pageheaderskip=Xpt - \vskip between header and line % \pagefooterskip=Xpt - \vskip between footer and line % \headfont=\fontname - Font to use for header text % \footfont=\fontname - Font to use for footer text % % Example: % % \pageheader{}{My Newsletter}{} % \pagefooter{October 1989}{}{\pageno} % \newif\ifpageheaderline \pageheaderlinefalse % By default, no header line \newif\ifpagefooterline \pagefooterlinefalse % By default, no footer line \newdimen\headfootrule \headfootrule=0.50pt % Height of header & footer rule \newdimen\pageheaderskip \pageheaderskip=4pt % Space between header and rule \newdimen\pagefooterskip \pagefooterskip=4pt % Space between rule and footer \let\headfont=\twelverm \let\footfont=\twelverm % Assign fonts for head/foot \def\@pageheader#1#2#3{% \ifpageheaderline % If headerline \vbox{\hbox to\normalhsize{{\headfont\rlap{#1}\hss{#2}\hss\llap{#3}}}% \vskip\pageheaderskip\hrule height\headfootrule}% Do hbox and hrule \else {\headfont\rlap{#1}\hss{#2}\hss\llap{#3}} \fi } \def\@pagefooter#1#2#3{% \ifpagefooterline \vbox{\hrule height\headfootrule\vskip\pagefooterskip \hbox to\normalhsize{\footfont\rlap{#1}\hss{#2}\hss\llap{#3}}}% \else {\footfont\rlap{#1}\hss{#2}\hss\llap{#3}} \fi } % % Define default headers and footers - null lines of text % \def\@oddhead{\nullline} \def\@evenhead{\nullline} \def\@oddfoot{\nullline} \def\@evenfoot{\nullline} \def\@newhead{\headline{\ifodd\pageno\@oddhead\else\@evenhead\fi}} \def\@newfoot{\footline{\ifodd\pageno\@oddfoot\else\@evenfoot\fi}} \def\oddpageheader#1#2#3{\@newhead\def\@oddhead{\@pageheader{#1}{#2}{#3}}} \def\evenpageheader#1#2#3{\@newhead\def\@evenhead{\@pageheader{#1}{#2}{#3}}} \def\oddpagefooter#1#2#3{\@newfoot\def\@oddfoot{\@pagefooter{#1}{#2}{#3}}} \def\evenpagefooter#1#2#3{\@newfoot\def\@evenfoot{\@pagefooter{#1}{#2}{#3}}} % % If no difference between even and odd pages, just define both to be the same. % \def\pageheader#1#2#3{\evenpageheader{#1}{#2}{#3}\oddpageheader{#1}{#2}{#3}} \def\pagefooter#1#2#3{\evenpagefooter{#1}{#2}{#3}\oddpagefooter{#1}{#2}{#3}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Command for "poor man's bold": \pmb (use sparingly) % \def\pmb#1{\setbox0=\hbox{#1}% % Copy box to box0 \leavevmode\hbox{% % Make an hbox that holds \kern-.025em\copy0\kern-\wd0% % Move left 1/4 em and copy box0 \kern.05em\copy0\kern-\wd0% % Move right 1/4 em and copy it \kern-.025em\raise.0433em\box0 }} % Raise a little and copy again % % Define dots for ending sentences (4 dots instead of 3) % \def\eldots{\mathinner{\ldotp\ldotp\ldotp\ldotp}} \def\edots{\relax\ifmmode\eldots\else$\m@th\eldots\,$\fi} \def\ellip{\hskip.2em\ifmmode\ldots\else$\ldots$\fi\hskip.25em} % % Define macros \ital and \slant to switch to italic (\it) and slanted (\sl) % respectively. These macros automatically insert the italic correction % unless the next character is a period or a comma. Based on the % \predict macro presented in _TeX for the Impatient_, p. 233. % % These macros use \toks0 as a temporary. % % The \futurelet\it@next in \ital and \slant defines \it@next to be whatever % the character following the parameter is. \d@slant checks to see if % \it@next is a comma or period; if it is neither, the italic correction % (\/) is included. % \def\ital#1{\toks0={#1}\let\slf@nt=\it\futurelet\it@next\d@slant} \def\slant#1{\toks0={#1}\let\slf@nt=\sl\futurelet\it@next\d@slant} \def\d@slant{{\slf@nt\the\toks0}% \ifx\it@next,% % If \it@next not a comma \else\ifx\it@next.% % ... and is not a period \else\/% % ... insert the correction (\/) \fi\fi% % ... \let\it@next=\relax% % "Undefine" \it@next } \def\book#1{\ital{#1}} %For ease, define \book too % % Important - make "@" a valid alphanumeric character again % \catcode`\@=12 % Follow TeX's lead on variable names \tenpoint % Default point size is 10pt