diff options
Diffstat (limited to 'macros/plain/contrib/chbar')
-rw-r--r-- | macros/plain/contrib/chbar/a4-9.doc | 304 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/a4-9.sty | 324 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/a4-marg.chf | 34 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/chbars.doc | 738 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/chbars.tex | 758 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/copying | 249 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/progltx.sty | 759 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/readme | 116 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/test1.tex | 60 | ||||
-rw-r--r-- | macros/plain/contrib/chbar/test2.tex | 70 |
10 files changed, 3412 insertions, 0 deletions
diff --git a/macros/plain/contrib/chbar/a4-9.doc b/macros/plain/contrib/chbar/a4-9.doc new file mode 100644 index 0000000000..d15ce6113d --- /dev/null +++ b/macros/plain/contrib/chbar/a4-9.doc @@ -0,0 +1,304 @@ +% This is A4-9.DOC as of 10 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for a non-arbitrary A4 page layout +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +\documentstyle[progltx,a4-9]{article} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% local macros +% + +\let\mc=\ninrm % for names like GNU + +\def\WEB{{\tt WEB\/}} +\def\DVI{{\tt DVI\/}} +\def\GNU{{\mc GNU}} + +\chardef\bs=`\\ + +\def\fract#1/#2.{% % fraction a/b within text + \leavevmode % borrowed from D. Knuth's manmac + \kern .1em + \raise .5ex \hbox{\the\scriptfont0 #1}% + \kern -.1em/\kern -.15em + \lower .25ex \hbox{\the\scriptfont0 #2}% + } + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\begin{document} + + +\title{ + A non-arbitrary A4 page layout\\ + The {\tt a4-9\/} style option + } +\author{\sc Joachim Schrod} + +\maketitle + + + +\sect This macro file is the |a4-9| document style option for \LaTeX{} +that produces a {\it well designed\/} A4 page layout. This style +option works with all standard \LaTeX{} styles and should work with +all other well written ones, too. It should not be used with an +underlined headings page style (see below for an explanation). + +But what does this mean: ``a {\it well designed\/} page layout''? +Mostly it means that the design is not chosen by accident but +within a {\it non-arbitrary process}. To my knowledge this theme +has first been covered by Jan Tschichold in his famous article of +1962: ``Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und +des Satzspiegels'' (look for references at the end). This style +option implements his design (I'm no designer\,\dots) + +If you are interested in typography and you do not know anything of +Jan Tschichold, you should---he and Stanley Morrison were probably the +two most important typographers in this century. He received as one +of very few Europeans the gold medal of the American Institute of +Graphic Arts, was a honorary member of the Double Crown Club, London, +and of the Soci\'et\'e typographique de France. Furthermore he was +appointed as Honorary Royal Designer for Industry by the Royal Society +of Arts, London. In 1965 he got the Gutenberg-Preis of the city +Leipzig (which celebrated its 800th~birthday in this year), the most +important typographic award in Europe. + + +\sect This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~1, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +%You should have received a copy of the \GNU{} General Public License +%along with this program; if not, write to the Free Software Foundation, +If you have not received a copy of the \GNU{} General Public License +along with this program, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\sect This style option implements the partition by nine of the A4 +page as explained by Tschichold. The proportion for a two-sided +layout is shown in Figure~\ref{fig:layout} (the picture is not true to +scale due to the limited features of the \LaTeX{}-{\tt +picture\/}-environment). +% +\begin{figure} +\unitlength=.3mm +\begin{center} +\begin{picture}(420,315) % 420,297 + +% double page (dashed lines) +\multiput(0,0)(210,0){2}{\dashbox{5}(210,315){}} % 210,297 + +% help lines for construction (thin lines) +\put( 0, 0){\line( 4, 3){420}} +\put( 0, 0){\line( 2, 3){210}} +\put( 0,315){\line( 4,-3){420}} +\put(210,315){\line( 2,-3){210}} + +\put(280,315){\line( 0,-1){105}} +\put(140,210){\line( 4, 3){140}} + +% resulting pages (thick lines) +\thicklines +\multiput(46.66666,70)(186.66666,0){2}{\framebox(140,210){}} % 140,198 + +\end{picture} +\end{center} +\caption{Partition by nine of the A4 page according to Tschichold} +\label{fig:layout} +\end{figure} +% +The important fact is that the proportions of the type area and the +margins repeat the proportion of the whole page. The above +construction yields margins with a ratio of $ \sqrt{2} : 1 : 2 : +2\sqrt{2} $, where 1 is the ninth of the page width, i.e.\ $\rm +23\fract 1/3. \,mm$. But we do not use this exact value because +the margin will be shortened by bookbinding or filing. We assume a +total need of 8\,mm for such purposes which results in 4\,mm for +each page. This 4\,mm will first be subtracted from the total +margin width of 70\,mm and the remaining 66\,mm will be divided +into one third for the inner margin and two third for the outer +margin. The resulting approximate values are therefore: +% +\begin{center} +\begin{tabular}{lr} +\multicolumn1{c}{\sc Dimension}& \multicolumn1{c}{\sc Value}\\[2pt] +page width& 210\,mm\\ +width of type area& 140\,mm\\ +inner margin& 26\,mm\\ +outer margin& 44\,mm\\[1pt] +page height& 297\,mm\\ +height of type area& 198\,mm\\ +top margin& 33\,mm\\ +bottom margin& 66\,mm\\ +\end{tabular} +\end{center} +% +The value for the inner margin consists of 4\,mm for binding and +filing purposes and 22\,mm ``real'' margin. Of course, all values +are measured from the paper edge. + +If the page layout is not for two-sided printing, it can be still +assumed that a margin of c\`a.~4\,mm will be needed for filing. +This remaining margin space of 66\,mm is distributed evenly on the +left and on the right side. Precisely spoken, we use 37\,mm for +the left margin ($\rm = 33\,mm + 4\,mm$) and 33\,mm for the right +margin. The resulting margins have a ratio of $1 : 1 : 1 : +2\sqrt{2}$. + + +\sect The height of the type area needs a special remark: Usually this +height does neither include the headline nor the footline. But if the +headline is underlined the headline should be taken into +account---that's the reason why this style option cannot be used with +underlined headings. + +The values in the above table are only approximations to the one +we will use in reality. An approximation because the height of the +type area must be a multiple of a line height, i.e.\ it must equal +$ (n-1)|\baselineskip| + |\topskip| $ where $n$ is the number of lines +on one page. If we have to choose we will prefer the longer type area. + + +\sect We assume a starting position of $\rm (2\,cm, 2\,cm)$, i.e., the +\DVI{} driver shall leave a top and a left margin of 2\,cm by his own. This is +different from the usual 1\,in margin---but the usual margin was made +for legal paper ($\rm 8\,in \times 11.5\,in$). I hope that this +driver margin value---which was presented by Klaus Guntermann and +me at the Euro\TeX88 conference in Exeter---will be accepted +by the \DVI{} driver standards commitee of TUG. + +|\hoffset| and |\voffset| are set to 0\,mm, so that we can proceed on +the assumption of the above margin. If you use a driver which leaves a +margin of 1\,in you should use the changefile |a4-marg.chf|. + +\beginprog +\hoffset=0mm +\voffset=0mm +\endprog + + +\sect To get the precise value of |\textheight| we first calculate the +number of lines which may be on the page in full. Then we add another +line and recalculate the value of |\textheight|. + +\beginprog +\normalsize % this sets \baselineskip + +\dimen@=198mm +\count@=\dimen@ % value in sp +\advance \count@ by -\topskip % \topskip and \baselineskip will be +\divide \count@ by \baselineskip % coerced to integer, value is in sp + +\textheight=\count@\baselineskip % \count@ equals the number of lines - 1 +\advance \textheight by \topskip +\endprog + + +\sect Because we have altered the original value of |\textheight| +(198\,mm) we must alter the value of the top margin, too. It will be +just a third of the remaining place on the page. Please note that the +place for the top margin consists of the four values driver +margin, |\topmargin|, |\headheight|, and |\headsep|. + +\beginprog +\topmargin=297mm + \advance \topmargin by -\textheight % place for top and bottom margin + \divide \topmargin by 3 % place for top margin + \advance \topmargin by -20mm % driver margin + \advance \topmargin by -\headheight + \advance \topmargin by -\headsep + +\textwidth=140.1mm +\if@twoside + \oddsidemargin=6mm % 26mm - 20mm (driver margin) + \evensidemargin=24mm % 44mm - 20mm (driver margin) + \marginparwidth=33mm % half of total vertical margin +\else + \oddsidemargin=17mm % 37mm - 20mm (driver margin) + \marginparwidth=22mm % third of total vertical margin + \evensidemargin=\maxdimen % usage should result in an error message +\fi +\endprog + + +\sect We finish the macro file so that garbage (e.g.\ of exchanges +between systems) can come afterwards. + +\beginprog +\endinput +\endprog + + +%%% +\newpage +%%% + +\sect It remains to give a few pointers to the article where the +design which was implemented here has been described: +% +\begin{itemize} + +\item {\sc Jan Tschichold}: +Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und des Satzspiegels. +In {\it Typographische Monatsbl\"atter}. +February 1964. + +\item {\sc Jan Tschichold}: +Non-arbitrary proportions of page and type area. +In {\it Print in Britain}. +London: September 1963. + +\item {\sc Jan Tschichold}: +Proportions rationelles du format du livre et de la page imprim\'ee. +In {\it Revue suisse d'imprimerie}, 4. +St-Gall 1964. + +\end{itemize} +% +The original paper is a private edition which can not be bought, it +was published in 1962. It appeared in seven different publications +in german language, three times in french, two times in dutch. +Besides being translated to english, it was translated to danish, +norwegian, finn, italian, and hungarian. + + + +\end{document} diff --git a/macros/plain/contrib/chbar/a4-9.sty b/macros/plain/contrib/chbar/a4-9.sty new file mode 100644 index 0000000000..2614968909 --- /dev/null +++ b/macros/plain/contrib/chbar/a4-9.sty @@ -0,0 +1,324 @@ +% This is A4-9.DOC as of 10 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for a non-arbitrary A4 page layout +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\ninrm % for names like GNU + +%%% \def\WEB{{\tt WEB\/}} +%%% \def\DVI{{\tt DVI\/}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% \def\fract#1/#2.{% % fraction a/b within text +%%% \leavevmode % borrowed from D. Knuth's manmac +%%% \kern .1em +%%% \raise .5ex \hbox{\the\scriptfont0 #1}% +%%% \kern -.1em/\kern -.15em +%%% \lower .25ex \hbox{\the\scriptfont0 #2}% +%%% } + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%% \begin{document} + + +%%% \title{ +%%% A non-arbitrary A4 page layout\\ +%%% The {\tt a4-9\/} style option +%%% } +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + + +%%% \sect This macro file is the |a4-9| document style option for \LaTeX{} +%%% that produces a {\it well designed\/} A4 page layout. This style +%%% option works with all standard \LaTeX{} styles and should work with +%%% all other well written ones, too. It should not be used with an +%%% underlined headings page style (see below for an explanation). + +%%% But what does this mean: ``a {\it well designed\/} page layout''? +%%% Mostly it means that the design is not chosen by accident but +%%% within a {\it non-arbitrary process}. To my knowledge this theme +%%% has first been covered by Jan Tschichold in his famous article of +%%% 1962: ``Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und +%%% des Satzspiegels'' (look for references at the end). This style +%%% option implements his design (I'm no designer\,\dots) + +%%% If you are interested in typography and you do not know anything of +%%% Jan Tschichold, you should---he and Stanley Morrison were probably the +%%% two most important typographers in this century. He received as one +%%% of very few Europeans the gold medal of the American Institute of +%%% Graphic Arts, was a honorary member of the Double Crown Club, London, +%%% and of the Soci\'et\'e typographique de France. Furthermore he was +%%% appointed as Honorary Royal Designer for Industry by the Royal Society +%%% of Arts, London. In 1965 he got the Gutenberg-Preis of the city +%%% Leipzig (which celebrated its 800th~birthday in this year), the most +%%% important typographic award in Europe. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% %You should have received a copy of the \GNU{} General Public License +%%% %along with this program; if not, write to the Free Software Foundation, +%%% If you have not received a copy of the \GNU{} General Public License +%%% along with this program, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect This style option implements the partition by nine of the A4 +%%% page as explained by Tschichold. The proportion for a two-sided +%%% layout is shown in Figure~\ref{fig:layout} (the picture is not true to +%%% scale due to the limited features of the \LaTeX{}-{\tt +%%% picture\/}-environment). +%%% % +%%% \begin{figure} +%%% \unitlength=.3mm +%%% \begin{center} +%%% \begin{picture}(420,315) % 420,297 + +%%% % double page (dashed lines) +%%% \multiput(0,0)(210,0){2}{\dashbox{5}(210,315){}} % 210,297 + +%%% % help lines for construction (thin lines) +%%% \put( 0, 0){\line( 4, 3){420}} +%%% \put( 0, 0){\line( 2, 3){210}} +%%% \put( 0,315){\line( 4,-3){420}} +%%% \put(210,315){\line( 2,-3){210}} + +%%% \put(280,315){\line( 0,-1){105}} +%%% \put(140,210){\line( 4, 3){140}} + +%%% % resulting pages (thick lines) +%%% \thicklines +%%% \multiput(46.66666,70)(186.66666,0){2}{\framebox(140,210){}} % 140,198 + +%%% \end{picture} +%%% \end{center} +%%% \caption{Partition by nine of the A4 page according to Tschichold} +%%% \label{fig:layout} +%%% \end{figure} +%%% % +%%% The important fact is that the proportions of the type area and the +%%% margins repeat the proportion of the whole page. The above +%%% construction yields margins with a ratio of $ \sqrt{2} : 1 : 2 : +%%% 2\sqrt{2} $, where 1 is the ninth of the page width, i.e.\ $\rm +%%% 23\fract 1/3. \,mm$. But we do not use this exact value because +%%% the margin will be shortened by bookbinding or filing. We assume a +%%% total need of 8\,mm for such purposes which results in 4\,mm for +%%% each page. This 4\,mm will first be subtracted from the total +%%% margin width of 70\,mm and the remaining 66\,mm will be divided +%%% into one third for the inner margin and two third for the outer +%%% margin. The resulting approximate values are therefore: +%%% % +%%% \begin{center} +%%% \begin{tabular}{lr} +%%% \multicolumn1{c}{\sc Dimension}& \multicolumn1{c}{\sc Value}\\[2pt] +%%% page width& 210\,mm\\ +%%% width of type area& 140\,mm\\ +%%% inner margin& 26\,mm\\ +%%% outer margin& 44\,mm\\[1pt] +%%% page height& 297\,mm\\ +%%% height of type area& 198\,mm\\ +%%% top margin& 33\,mm\\ +%%% bottom margin& 66\,mm\\ +%%% \end{tabular} +%%% \end{center} +%%% % +%%% The value for the inner margin consists of 4\,mm for binding and +%%% filing purposes and 22\,mm ``real'' margin. Of course, all values +%%% are measured from the paper edge. + +%%% If the page layout is not for two-sided printing, it can be still +%%% assumed that a margin of c\`a.~4\,mm will be needed for filing. +%%% This remaining margin space of 66\,mm is distributed evenly on the +%%% left and on the right side. Precisely spoken, we use 37\,mm for +%%% the left margin ($\rm = 33\,mm + 4\,mm$) and 33\,mm for the right +%%% margin. The resulting margins have a ratio of $1 : 1 : 1 : +%%% 2\sqrt{2}$. + + +%%% \sect The height of the type area needs a special remark: Usually this +%%% height does neither include the headline nor the footline. But if the +%%% headline is underlined the headline should be taken into +%%% account---that's the reason why this style option cannot be used with +%%% underlined headings. + +%%% The values in the above table are only approximations to the one +%%% we will use in reality. An approximation because the height of the +%%% type area must be a multiple of a line height, i.e.\ it must equal +%%% $ (n-1)|\baselineskip| + |\topskip| $ where $n$ is the number of lines +%%% on one page. If we have to choose we will prefer the longer type area. + + +%%% \sect We assume a starting position of $\rm (2\,cm, 2\,cm)$, i.e., the +%%% \DVI{} driver shall leave a top and a left margin of 2\,cm by his own. This is +%%% different from the usual 1\,in margin---but the usual margin was made +%%% for legal paper ($\rm 8\,in \times 11.5\,in$). I hope that this +%%% driver margin value---which was presented by Klaus Guntermann and +%%% me at the Euro\TeX88 conference in Exeter---will be accepted +%%% by the \DVI{} driver standards commitee of TUG. + +%%% |\hoffset| and |\voffset| are set to 0\,mm, so that we can proceed on +%%% the assumption of the above margin. If you use a driver which leaves a +%%% margin of 1\,in you should use the changefile |a4-marg.chf|. + +%%% \beginprog +\hoffset=2cm \advance\hoffset by -1in +\voffset=2cm \advance\voffset by -1in +%%% \endprog + + +%%% \sect To get the precise value of |\textheight| we first calculate the +%%% number of lines which may be on the page in full. Then we add another +%%% line and recalculate the value of |\textheight|. + +%%% \beginprog +\normalsize % this sets \baselineskip + +\dimen@=198mm +\count@=\dimen@ % value in sp +\advance \count@ by -\topskip % \topskip and \baselineskip will be +\divide \count@ by \baselineskip % coerced to integer, value is in sp + +\textheight=\count@\baselineskip % \count@ equals the number of lines - 1 +\advance \textheight by \topskip +%%% \endprog + + +%%% \sect Because we have altered the original value of |\textheight| +%%% (198\,mm) we must alter the value of the top margin, too. It will be +%%% just a third of the remaining place on the page. Please note that the +%%% place for the top margin consists of the four values driver +%%% margin, |\topmargin|, |\headheight|, and |\headsep|. + +%%% \beginprog +\topmargin=297mm + \advance \topmargin by -\textheight % place for top and bottom margin + \divide \topmargin by 3 % place for top margin + \advance \topmargin by -20mm % driver margin + \advance \topmargin by -\headheight + \advance \topmargin by -\headsep + +\textwidth=140.1mm +\if@twoside + \oddsidemargin=6mm % 26mm - 20mm (driver margin) + \evensidemargin=24mm % 44mm - 20mm (driver margin) + \marginparwidth=33mm % half of total vertical margin +\else + \oddsidemargin=17mm % 37mm - 20mm (driver margin) + \marginparwidth=22mm % third of total vertical margin + \evensidemargin=\maxdimen % usage should result in an error message +\fi +%%% \endprog + + +%%% \sect We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\endinput +%%% \endprog + + +%%% %%% +%%% \newpage +%%% %%% + +%%% \sect It remains to give a few pointers to the article where the +%%% design which was implemented here has been described: +%%% % +%%% \begin{itemize} + +%%% \item {\sc Jan Tschichold}: +%%% Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und des Satzspiegels. +%%% In {\it Typographische Monatsbl\"atter}. +%%% February 1964. + +%%% \item {\sc Jan Tschichold}: +%%% Non-arbitrary proportions of page and type area. +%%% In {\it Print in Britain}. +%%% London: September 1963. + +%%% \item {\sc Jan Tschichold}: +%%% Proportions rationelles du format du livre et de la page imprim\'ee. +%%% In {\it Revue suisse d'imprimerie}, 4. +%%% St-Gall 1964. + +%%% \end{itemize} +%%% % +%%% The original paper is a private edition which can not be bought, it +%%% was published in 1962. It appeared in seven different publications +%%% in german language, three times in french, two times in dutch. +%%% Besides being translated to english, it was translated to danish, +%%% norwegian, finn, italian, and hungarian. + + + +%%% \end{document} diff --git a/macros/plain/contrib/chbar/a4-marg.chf b/macros/plain/contrib/chbar/a4-marg.chf new file mode 100644 index 0000000000..c5aba1d7a4 --- /dev/null +++ b/macros/plain/contrib/chbar/a4-marg.chf @@ -0,0 +1,34 @@ +% This is A4-MARG.CHF as of 08 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. + +% +% changefile for A4-9.DOC or A4-12.DOC +% for DVI drivers with 1in margin +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + +@x +\hoffset=0mm +\voffset=0mm +@y +\hoffset=2cm \advance\hoffset by -1in +\voffset=2cm \advance\voffset by -1in +@z diff --git a/macros/plain/contrib/chbar/chbars.doc b/macros/plain/contrib/chbar/chbars.doc new file mode 100644 index 0000000000..77610d2db3 --- /dev/null +++ b/macros/plain/contrib/chbar/chbars.doc @@ -0,0 +1,738 @@ +% This is CHBARS.DOC as of 09 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in Plain TeX +% MAKEPROG is needed +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +\documentstyle[progltx,a4-9]{article} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% local macros +% + +\let\mc=\small % for names like GNU + +\def\PS{{\sc PostScript}} +\def\DVI{{\tt DVI}} +\def\GNU{{\mc GNU}} + +\chardef\bs=`\\ + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +\begin{document} + + +\title{Changebars without {\tt \bs{}special}'s} +\author{\sc Joachim Schrod} + +\maketitle + + + +\begin{abstract} +It is common practice to use vertical bars in the margins of a +document to mark pieces of text which have changed since the last +version(s) of this document. Such vertical bars are usually +called {\em changebars}. It has often been said that it is +impossible to produce changebars with \TeX{} without the usage of +|\special| commands (driver directives), which extend the +primitives of \TeX{}. This paper presents a \TeX{} macro file +which implements changebars without such a usage. The macro file +is written for the usage with Plain~\TeX{} but the implementation +strategy can be used with \LaTeX{}, too. +\end{abstract} + + + +\chap Introduction. + +Changebars are used to mark modified parts in existing documents. For +the usage in \TeX{} documents, there exist only solutions that use +driver/printer features by the way of inserting |\special| commands in +the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +that are no longer as freely interchangeable as the \DVI{} concept would +allow---device dependency is problematic especially for this application +that is useful for multi-authoring or standards development. + +This macro package offers a pure \TeX{} solution. Nevertheless, it has +its restrictions, too. The page break will no longer be optimal, +because no strechability or shrinkability on a page on top of the last +mark of a change is supported. But this seems to be acceptable, +especially as the change bar feature often will be used for proof +reading and not in the final document. This restriction is the reason +why no change marks can be used on titlepages or for similar +constructions. Changes in floating insertions (footnotes, figures) are +not discovered. + +The demonstrated solution is written in Plain \TeX{}, because it was +easier and could be presented better at the Euro\TeX89 conference in +Karlsruhe. An adaption to \LaTeX{} is possible, but would require +modifications to the \LaTeX{} kernel, i.e.\ the output routine and the +layout parameters of the standard styles. + + +\sect This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~1, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +%You should have received a copy of the \GNU{} General Public License +%along with this program; if not, write to the Free Software Foundation, +If you have not received a copy of the \GNU{} General Public License +along with this program, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\sect A changed area is described by two marks, |\beginchange| and +|\endchange|. The method for writing a change bar consists of three +parts: First, it will be indicated to the output routine that a change +has occured. Next, the position of the changed area will be found out +and fixed. A list of all changed areas is built, that can at last be +marked by the output routine using vertical rules at the right margin. + +But before we start we declare some shorthands for category codes. By +declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +letters we can use them in our macros. (I agree with D.~Knuth that +|\identifier_several_words_long| is more readable than +|\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +With the at sign we can use the ``private'' Plain macros and with the +underscore we can make our own macros more readable. But as we have to +restore these category codes at the end of this macro file we store +their former values in the control sequences |\atcode| and |\uscode|. +This method is better than to use a group because not all macros have to +be defined global this way. + +\beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter +\endprog + + + + +\chap Triggering the Output Routine. + +\begin{sloppypar} +First, the output routine must know that changes occured. This is done +by the macros |\beginchange| and |\endchange| that append a reserved +penalty value |\break_penalty| to the current list that is below +$-10\,000$. The penalty will be in the range $|\change_penalty_group| +\cdot 100 - 99 \ldots |\change_penalty_group| \cdot 100$. +For the output it must be differentiated if the mark indicates +begin or end of the changed area. This is done with the values +|\change_penalty_begin| and |\change_penalty_end| that are used as the +second-to-last digit of the change penalty. +\end{sloppypar} + +It must also be differentiated between the beginning of a mark being in +horizontal or vertical mode. In horizontal mode, the change bar must +not begin at the baseline of the actual text position, but on top of the +actual line. This is marked in the last digit, an odd digit will be +used in horizontal mode. + +Note that the values mentioned above are used as digits here that can be +concatenated. If they are not followed by an other digit they should be +terminated by |\space| to stop the look-ahead for digits. + +These interactions with the output routine adds a lot of dead cycles; we +must therefore increase |\maxdeadcycles| to prevent \TeX{} from grumbling. + +\beginprog +\def\change_penalty_group{-101} +\def\change_penalty_begin{0} +\def\change_penalty_end{1} + +\maxdeadcycles=100 +\endprog + + +\sect The marks set the change penalty value (including the indication +of begin or end of mark). The rest (|\trigger_output|) is the same action +for both. An end change mark in horizontal mode can be preceeded by +glue that could cause a line break, thus including the following line to +the change area as well. To avoid this unwanted behaviour, the space is +saved in |\save_space|, discarded in front of the mark and restored +afterwards. + +\beginprog +\newcount\break_penalty +\newskip\save_space + +\def\beginchange{% + \break_penalty=\change_penalty_group\change_penalty_begin0 + \trigger_output + } +\def\endchange{% + \ifhmode \save_space=\lastskip \unskip \fi + \break_penalty=\change_penalty_group\change_penalty_end0 + \trigger_output + \ifhmode \hskip\save_space \fi + } +\endprog + + +\sect In |\trigger_output| the real output trigger is done. We must consider +that an |\output|-invocation by our |\break_penalty| can be discarded at +the beginning of a page. So we trigger the output routine twice, first +with a special penalty value that is 2~less than the correct value +(including the code for horizontal or vertical mode). After the first +page break it is asserted that the current list is empty. The output +routine has to save the former page contents if necessary. + +Now we set the penalty to the correct value. The second page break does +the real work, restores the page contents and handles the split +insertions (footnotes, figures,~\dots) + +In horizontal mode |\spacefactor| must not be destroyed. + +\beginprog +\newcount\save_space_factor + +\def\trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else + \ifvmode \let\do_in_vmode=\relax + \advance \break_penalty by -2 + \else \save_space_factor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\break_penalty + \null + \advance \break_penalty by 2 \penalty\break_penalty + }% + \ifhmode \spacefactor\save_space_factor \fi + \fi + } +\endprog + + +\sect The usage of the output routine as an information passing system +has always it's difficulties. One of the real hard parts is the +handling of the page marks, special token lists that are handled by +\TeX{}. These token lists provide informations about text on a page, +they are usually used to create head lines etc. The user may access +these token lists with three control sequences: |\botmark| is the +last page mark given, |\topmark| is the |\botmark| of the previous +page, and |\firstmark| is the first page mark on the actual page or +|\topmark| if none was given. Here ``page'' is used in the \TeX{} +sense, i.e.\ as the material which has been collected between two +|\output| invocations. Of course, the page marks must not be +destroyed---and that means they must be reinserted after each +special use of the output routine. + +But we have luck: A ``special use'' consists of two |\output| +invocations, so we can insert |\topmark| again as a page mark after +the first invocation where it will be the only page mark on that +\TeX{} page. The second invocation will automatically transform this +page mark into the ``last page mark on the previous page,'' i.e.\ in +|\topmark|---that's what we need! Furthermore |\firstmark| and +|\botmark| are saved in control sequences during the first invocation, +they will be inserted again, too. + +There's one situation where this approach doesn't work: In front of +the first page mark |\topmark|, |\firstmark|, and |\botmark| expand +to an empty token list. If we save them then and insert their old +values we have inserted empty page marks. If other page marks follow +on the same ``real'' page |\firstmark| will be empty instead of +expanding to the token list of the first page mark. To prevent this +we must not save and restore page marks before the first |\mark| has +been added to the main vertical list. + +Well, that can be controlled with a switch---but this switch must be +set very carefully. If it is set immediately by the first |\mark| +this may be in horizontal mode and special output invocations can +occur above this page mark (i.e., there may be a |\beginchange| in the +same paragraph in front of the |\mark|). Therefore the setting of the +switch must be delayed until the vertical position of the |\mark| +(precisely: the position of the |\mark| in the current list) is +reached. In horizontal mode this can be done with a |\vadjust| and +the output routine! Voil\`a, this is another command group for the +output routine with only one command. + +\beginprog +\newif\if@save_mark@ \@save_mark@false + +\def\mark_penalty_group{-102} +\endprog + + +\sect We will redefine |\mark| so that the first page mark either sets +the switch to true (in vertical mode all possible special page breaks +are already handled) or forces the |\output| routine to do this at an +appropriate place. In the last case we can use |\trigger_output| +again. Afterwards we restore the original meaning of |\mark| again to +reduce the processing overhead (and the dead cycles). + +This change of |\mark| has the consequence that the first |\mark| in a +document cannot be used anymore in horizontal mode inside a vertical +box that shall be split afterwards. But this is only sensible if this +mark shall be used as |\splitfirstmark| because it will almost never +migrate to the outer list---really a rare case! + +\beginprog +\let\@@mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\@save_mark@true \fi % split marks! + \else \break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \trigger_output + \fi + \global\let\mark=\@@mark + \@@mark + } +\endprog + + +\sect +\begin{sloppypar} +If the output routine is triggered with the mark penalty value +it will call |\start_saving_page_marks|. +\end{sloppypar} + +\beginprog +\def\start_saving_page_marks{% % this may be executed twice + \unvbox255 + \global\@save_mark@true + } +\endprog + + +\sect To finish the treatment of page marks we can formulate the two +macros which are used at the first resp.\ second invocation of a +``special output,'' the principles have already been explained. + +\beginprog +\def\backup_page_marks{% + \if@save_mark@ + \mark{\topmark}% + \xdef\save_firstmark{\firstmark}% + \xdef\save_botmark{\botmark}% + \fi + } + +\def\restore_page_marks{% + \if@save_mark@ + \mark{\save_firstmark}\mark{\save_botmark}% + \fi + } +\endprog + + + + + +\chap Positioning the Change Marks. + +Now we must handle the positions of the bars. |\change_pos| will hold +the position of the actual mark, i.e.\ the distance between top of page +and actual mark. |\top_change_pos| will hold the beginning of a changed +area; a value of |\maxdimen| indicates that no change is in effect. If +a changed area is completed, it is appended to the list |\bar_list| as +an element |\bar(\top_change_pos,\change_pos)|. This list contains all +changed areas within the current page so that bars can be written later +on. A single bar will be produced by |\write_bar|. + +\noindent The definition of |\bar| to |\relax| allows the concatenation +of new elements to |\bar_list| with |\xdef|. + +\beginprog +\newdimen\change_pos +\newdimen\top_change_pos \top_change_pos=\maxdimen + +\let\bar_list=\empty + +\let\bar=\relax +\def\write_bar(#1,#2){% + \setbox0=\hbox{\vrule height -#1 depth #2}% + \dp0=0pt \ht0=0pt + \box0 + } +\endprog + + +\sect If the output routine was activated by a |\outputpenalty| value +within the range of our reserved penalties, the change handling will +occur, otherwise standard plain output can be done. + +\beginprog +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\change_penalty_group\space \change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \start_saving_page_marks + \else \plainoutput + \fi + \fi + } +\endprog + + +\sect As explained before, the change handling must differentiate +between the kind of the change command (beginning is indicated by +$|\change_cmd|=0$, end by~1) and between the mode (horizontal indicated +by an odd |\change_mode| value, vertical by an even). A change mode +higher than one indicates that we are doing the first page break that +has to backup the page as far as it exists already and results in an +empty current list of page elements. + +\beginprog +\newcount\change_cmd +\newcount\change_mode + +\def\change_handling{% + \change_cmd=-\outputpenalty % ==> absolute value + \advance \change_cmd by \change_penalty_group00 % subtraction + \change_mode=\change_cmd + \divide \change_cmd by 10 % second-to-last digit + \advance \change_mode by -\number\change_cmd0 % last digit + \ifnum \change_mode>1 \backup_page + \else + \ifcase \change_cmd \begin_change + \or \end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +\endprog + + +\sect Processing a mark during the second trigger of the output routine +means restoring the page and storing the positions. At the beginning, +the begin of the change is saved, at the end, we know the bar already +and put it into the bar list. Then the positioning values are +reinitialized. + +As within every output invocation, the box 255 must be unboxed. As we +are here in the second invocation of the output routine the |\box255| +consists only of the empty |\vbox| we have inserted in +|\trigger_output|. We can therefore throw it away. + +\beginprog +\def\begin_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \global\top_change_pos=\change_pos \global\change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\end_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=\maxdimen \global\change_pos=0pt + \fi + } +\endprog + + + + +\chap Handling the Page Contents. + +We handle the part of the page that was collected up to now by putting +it into a box. This fixes the position of the change mark so that +|\change_pos| can be set and stored later on in |\top_change_pos| or as +the lower end of a bar in |\bar_list|. + +To save the page contents in the first output invocation, we have to +save the page in |\save_page|. Before that, we store the size of the +box (which equals |\pagegoal|!)\ in |\page_goal|. If the unboxing +caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +we eject the page up to the change mark. Now we have to compute the +current position of our mark in |\change_pos|. It is fixed by the size +of the |\save_page|, but in case of a begin mark in horizontal mode we +must decrease it from the baseline position to the top of the last line. +Finally, we must save the values for the allowed insertions and change +them to the maximal value so that a rest that is split from an insertion +will be appended to the insertion box at the second invocation in every +case. + +The |\vsize| is initialized to |\maxdimen|. This allows to control +whether this first output invocation ocurred or if it was discarded. +For the same reason |\change_pos| is initialized to~0pt. + +\beginprog +\newbox\save_page + +\newdimen\page_goal +\newdimen\save_vsize \save_vsize=\maxdimen +\newdimen\save_dimen_topins +\newdimen\save_dimen_footins + +\def\backup_page{% + \global\page_goal=\ht255 + \global\setbox\save_page=\vbox{\unvbox255}% + \ifdim \ht\save_page>\page_goal \eject_page_so_far \fi + \change_pos=\ht\save_page \global\advance \change_pos by \dp\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode \higher_change_pos \fi + \fi + \global\save_vsize=\vsize \global\vsize=\maxdimen + \global\save_dimen_topins=\dimen\topins \global\dimen\topins=\maxdimen + \global\save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \backup_page_marks + } + +\change_pos=0pt +\endprog + + +\sect To eject a page as far as it is we restore it from the +|\save_page| back to box~255. In horizontal mode and at a begin mark +the last line contains the mark and must not be output. So we remove it +and the preceding glue from the stored rest, just leaving a single hbox +to be on top of the actual page (in |\save_page|) now. Then normal +output can be done with box~255. + +\beginprog +\def\eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox255=\vbox to \page_goal{% + \unvbox\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode + \global\setbox\save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \plainoutput + } +\endprog + + +\sect +\begin{sloppypar} +In horizontal mode and at a begin mark, we need the position of +the mark (|\change_pos|) on the upper boundary of the last line in +|\save_page|. If there is just one line left from a recent eject, the +height is given by the topskip decreased by the height of this hbox. If +the height of the box is larger than |\topskip| the skip will not be +inserted and the change position results to~0pt. Otherwise, +|\save_page| is a vbox whose last hbox we delete temporarily using +box~0. Height and depth of the rest are the actual position on the page. +\end{sloppypar} + +The double of the page we have constructed this way will immediately be +fed back to the garbage collector because it could have become +reasonably large. + +\beginprog +\def\higher_change_pos{% + \ifhbox \save_page % rest of page from \eject_page_so_far + \change_pos=\topskip \global\advance \change_pos by -\ht\save_page + \ifdim \change_pos<0pt \global\change_pos=0pt \fi + \else + \setbox0=\vbox{% + \unvcopy\save_page + \setbox0=\lastbox % delete last line + }% + \change_pos=\ht0 \global\advance \change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +\endprog + + +\sect To restore a page during the second output invocation, we first +restore the saved values, but only if they were really changed (this can +be discovered by the value of |\save_vsize|). Now the |\save_page| is +appended to the current list as a box, which stops later usage of its +stretch- and shrinkability! Then the collected insertions can be +inserted again. The page marks have to be inserted, too. + +\beginprog +\def\restore_page{% + \ifdim \save_vsize=\maxdimen + \else \global\vsize=\save_vsize + \global\dimen\topins=\save_dimen_topins + \global\dimen\footins=\save_dimen_footins + \global\save_vsize=\maxdimen + \restore_page_marks + \fi + \box\save_page % discards stretch- and shrinkability! + \ifvoid \topins + \else \insert\topins{\floatingpenalty=0 \unvbox\topins}% + \fi + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +\endprog + + +\sect {\em Please note, that there is still a problem with this concept +of handling the output trigger:} + +\bigskip + +If the first output trigger is discarded because a page break has occured +just in front, footnote parts may be juggled around. I.e., if a +footnote is split in three parts, the first part was just been shipped +out, the second part is inserted back into the recent contributions by +the output routine but {\em behind\/} the third part which is saved in +the ``special place'' (according to the \TeX{}book, p.~125). A solution to +this problem might be to insert a |\do_change| again within the second +output trigger and finishing the treatmend afterwards. Afterwards a +full triggering process (two output invocations) is executed again and +alle insertion parts will be accessible in the insertion box. + +By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +\LaTeX{} this can happen every time because at the first output invocation +the |\dimen|-values of the footnote insertion is not increased. I leave +the problem open to the reader\,\dots + + + + + +\chap Writing the Stuff. + +The positions of the bars which mark the changed areas are relative to +the top of the text, i.e.\ the height of the top insertion is not +included. Therefore it is best to write them just after the top +insertions before the page text---but to do this we have to change the +Plain macro |\pagecontents|. + +Below is the new definition, I have just rearranged it a little bit so +that it is more legible. The line I have inserted is marked with +`|%%%%|'. |\insert_current_bar| inserts a last element in |\bar_list| +if a changed area is not yet finished, afterwards all bars can be +written. + +\beginprog +\def\pagecontents{% + \ifvoid \topins \else \unvbox\topins \fi + \insert_current_bar \write_all_bars %%%% + \dimen@=\dp\@cclv \unvbox\@cclv % open up \box255 + \ifvoid \footins + \else % footnote info is present + \vskip\skip\footins + \footnoterule + \unvbox\footins + \fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi + } +\endprog + + +\sect If $|\top_change_pos|=|\maxdimen|$ no change is active. Otherwise +the current change reaches from the begin mark (|\top_change_pos|) to +the end of the page, i.e.\ we insert a virtual end mark. Because the +change continues on the next page we insert a virtual begin mark on the +top of the page, too. + +\beginprog +\def\insert_current_bar{% + \ifdim \top_change_pos=\maxdimen + \else + \change_pos=\ht255 \advance\change_pos by \dp255 + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=0pt + \fi + } +\endprog + + +\sect Now we can write all bars---if they exist anyway. It's rather +easy, we just have to define |\bar| to |\write_bar| and execute +|\bar_list|. The resulting output must not use vertical place. We must +not forget to delete the list, or we will get the same bars on the next +page again. + +\noindent |\BarDistance| is the amount of place between the text margin +and the change bars. + +\beginprog +\newbox\@bars +\newdimen\BarDistance \BarDistance=2cc + +\def\write_all_bars{% + \ifx \bar_list\empty + \else % changes exist + \setbox\@bars=\hbox to \hsize{% + \hskip\hsize \hskip\BarDistance + \vbox to 0pt{\offinterlineskip + \let\bar=\write_bar \bar_list + }% + \hss + }% + \ht\@bars=0pt \dp\@bars=0pt \box\@bars + \global\let\bar_list=\empty + \fi + } +\endprog + + +\sect We finish the macro file so that garbage (e.g.\ of exchanges +between systems) can come afterwards. + +\beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +\endprog + + + +\end{document} diff --git a/macros/plain/contrib/chbar/chbars.tex b/macros/plain/contrib/chbar/chbars.tex new file mode 100644 index 0000000000..83801dd7a3 --- /dev/null +++ b/macros/plain/contrib/chbar/chbars.tex @@ -0,0 +1,758 @@ +% This is CHBARS.DOC as of 09 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in Plain TeX +% MAKEPROG is needed +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\PS{{\sc PostScript}} +%%% \def\DVI{{\tt DVI}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +%%% \begin{document} + + +%%% \title{Changebars without {\tt \bs{}special}'s} +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + + +%%% \begin{abstract} +%%% It is common practice to use vertical bars in the margins of a +%%% document to mark pieces of text which have changed since the last +%%% version(s) of this document. Such vertical bars are usually +%%% called {\em changebars}. It has often been said that it is +%%% impossible to produce changebars with \TeX{} without the usage of +%%% |\special| commands (driver directives), which extend the +%%% primitives of \TeX{}. This paper presents a \TeX{} macro file +%%% which implements changebars without such a usage. The macro file +%%% is written for the usage with Plain~\TeX{} but the implementation +%%% strategy can be used with \LaTeX{}, too. +%%% \end{abstract} + + + +%%% \chap Introduction. + +%%% Changebars are used to mark modified parts in existing documents. For +%%% the usage in \TeX{} documents, there exist only solutions that use +%%% driver/printer features by the way of inserting |\special| commands in +%%% the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +%%% that are no longer as freely interchangeable as the \DVI{} concept would +%%% allow---device dependency is problematic especially for this application +%%% that is useful for multi-authoring or standards development. + +%%% This macro package offers a pure \TeX{} solution. Nevertheless, it has +%%% its restrictions, too. The page break will no longer be optimal, +%%% because no strechability or shrinkability on a page on top of the last +%%% mark of a change is supported. But this seems to be acceptable, +%%% especially as the change bar feature often will be used for proof +%%% reading and not in the final document. This restriction is the reason +%%% why no change marks can be used on titlepages or for similar +%%% constructions. Changes in floating insertions (footnotes, figures) are +%%% not discovered. + +%%% The demonstrated solution is written in Plain \TeX{}, because it was +%%% easier and could be presented better at the Euro\TeX89 conference in +%%% Karlsruhe. An adaption to \LaTeX{} is possible, but would require +%%% modifications to the \LaTeX{} kernel, i.e.\ the output routine and the +%%% layout parameters of the standard styles. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% %You should have received a copy of the \GNU{} General Public License +%%% %along with this program; if not, write to the Free Software Foundation, +%%% If you have not received a copy of the \GNU{} General Public License +%%% along with this program, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect A changed area is described by two marks, |\beginchange| and +%%% |\endchange|. The method for writing a change bar consists of three +%%% parts: First, it will be indicated to the output routine that a change +%%% has occured. Next, the position of the changed area will be found out +%%% and fixed. A list of all changed areas is built, that can at last be +%%% marked by the output routine using vertical rules at the right margin. + +%%% But before we start we declare some shorthands for category codes. By +%%% declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +%%% letters we can use them in our macros. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +%%% With the at sign we can use the ``private'' Plain macros and with the +%%% underscore we can make our own macros more readable. But as we have to +%%% restore these category codes at the end of this macro file we store +%%% their former values in the control sequences |\atcode| and |\uscode|. +%%% This method is better than to use a group because not all macros have to +%%% be defined global this way. + +%%% \beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter +%%% \endprog + + + + +%%% \chap Triggering the Output Routine. + +%%% \begin{sloppypar} +%%% First, the output routine must know that changes occured. This is done +%%% by the macros |\beginchange| and |\endchange| that append a reserved +%%% penalty value |\break_penalty| to the current list that is below +%%% $-10\,000$. The penalty will be in the range $|\change_penalty_group| +%%% \cdot 100 - 99 \ldots |\change_penalty_group| \cdot 100$. +%%% For the output it must be differentiated if the mark indicates +%%% begin or end of the changed area. This is done with the values +%%% |\change_penalty_begin| and |\change_penalty_end| that are used as the +%%% second-to-last digit of the change penalty. +%%% \end{sloppypar} + +%%% It must also be differentiated between the beginning of a mark being in +%%% horizontal or vertical mode. In horizontal mode, the change bar must +%%% not begin at the baseline of the actual text position, but on top of the +%%% actual line. This is marked in the last digit, an odd digit will be +%%% used in horizontal mode. + +%%% Note that the values mentioned above are used as digits here that can be +%%% concatenated. If they are not followed by an other digit they should be +%%% terminated by |\space| to stop the look-ahead for digits. + +%%% These interactions with the output routine adds a lot of dead cycles; we +%%% must therefore increase |\maxdeadcycles| to prevent \TeX{} from grumbling. + +%%% \beginprog +\def\change_penalty_group{-101} +\def\change_penalty_begin{0} +\def\change_penalty_end{1} + +\maxdeadcycles=100 +%%% \endprog + + +%%% \sect The marks set the change penalty value (including the indication +%%% of begin or end of mark). The rest (|\trigger_output|) is the same action +%%% for both. An end change mark in horizontal mode can be preceeded by +%%% glue that could cause a line break, thus including the following line to +%%% the change area as well. To avoid this unwanted behaviour, the space is +%%% saved in |\save_space|, discarded in front of the mark and restored +%%% afterwards. + +%%% \beginprog +\newcount\break_penalty +\newskip\save_space + +\def\beginchange{% + \break_penalty=\change_penalty_group\change_penalty_begin0 + \trigger_output + } +\def\endchange{% + \ifhmode \save_space=\lastskip \unskip \fi + \break_penalty=\change_penalty_group\change_penalty_end0 + \trigger_output + \ifhmode \hskip\save_space \fi + } +%%% \endprog + + +%%% \sect In |\trigger_output| the real output trigger is done. We must consider +%%% that an |\output|-invocation by our |\break_penalty| can be discarded at +%%% the beginning of a page. So we trigger the output routine twice, first +%%% with a special penalty value that is 2~less than the correct value +%%% (including the code for horizontal or vertical mode). After the first +%%% page break it is asserted that the current list is empty. The output +%%% routine has to save the former page contents if necessary. + +%%% Now we set the penalty to the correct value. The second page break does +%%% the real work, restores the page contents and handles the split +%%% insertions (footnotes, figures,~\dots) + +%%% In horizontal mode |\spacefactor| must not be destroyed. + +%%% \beginprog +\newcount\save_space_factor + +\def\trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else + \ifvmode \let\do_in_vmode=\relax + \advance \break_penalty by -2 + \else \save_space_factor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\break_penalty + \null + \advance \break_penalty by 2 \penalty\break_penalty + }% + \ifhmode \spacefactor\save_space_factor \fi + \fi + } +%%% \endprog + + +%%% \sect The usage of the output routine as an information passing system +%%% has always it's difficulties. One of the real hard parts is the +%%% handling of the page marks, special token lists that are handled by +%%% \TeX{}. These token lists provide informations about text on a page, +%%% they are usually used to create head lines etc. The user may access +%%% these token lists with three control sequences: |\botmark| is the +%%% last page mark given, |\topmark| is the |\botmark| of the previous +%%% page, and |\firstmark| is the first page mark on the actual page or +%%% |\topmark| if none was given. Here ``page'' is used in the \TeX{} +%%% sense, i.e.\ as the material which has been collected between two +%%% |\output| invocations. Of course, the page marks must not be +%%% destroyed---and that means they must be reinserted after each +%%% special use of the output routine. + +%%% But we have luck: A ``special use'' consists of two |\output| +%%% invocations, so we can insert |\topmark| again as a page mark after +%%% the first invocation where it will be the only page mark on that +%%% \TeX{} page. The second invocation will automatically transform this +%%% page mark into the ``last page mark on the previous page,'' i.e.\ in +%%% |\topmark|---that's what we need! Furthermore |\firstmark| and +%%% |\botmark| are saved in control sequences during the first invocation, +%%% they will be inserted again, too. + +%%% There's one situation where this approach doesn't work: In front of +%%% the first page mark |\topmark|, |\firstmark|, and |\botmark| expand +%%% to an empty token list. If we save them then and insert their old +%%% values we have inserted empty page marks. If other page marks follow +%%% on the same ``real'' page |\firstmark| will be empty instead of +%%% expanding to the token list of the first page mark. To prevent this +%%% we must not save and restore page marks before the first |\mark| has +%%% been added to the main vertical list. + +%%% Well, that can be controlled with a switch---but this switch must be +%%% set very carefully. If it is set immediately by the first |\mark| +%%% this may be in horizontal mode and special output invocations can +%%% occur above this page mark (i.e., there may be a |\beginchange| in the +%%% same paragraph in front of the |\mark|). Therefore the setting of the +%%% switch must be delayed until the vertical position of the |\mark| +%%% (precisely: the position of the |\mark| in the current list) is +%%% reached. In horizontal mode this can be done with a |\vadjust| and +%%% the output routine! Voil\`a, this is another command group for the +%%% output routine with only one command. + +%%% \beginprog +\newif\if@save_mark@ \@save_mark@false + +\def\mark_penalty_group{-102} +%%% \endprog + + +%%% \sect We will redefine |\mark| so that the first page mark either sets +%%% the switch to true (in vertical mode all possible special page breaks +%%% are already handled) or forces the |\output| routine to do this at an +%%% appropriate place. In the last case we can use |\trigger_output| +%%% again. Afterwards we restore the original meaning of |\mark| again to +%%% reduce the processing overhead (and the dead cycles). + +%%% This change of |\mark| has the consequence that the first |\mark| in a +%%% document cannot be used anymore in horizontal mode inside a vertical +%%% box that shall be split afterwards. But this is only sensible if this +%%% mark shall be used as |\splitfirstmark| because it will almost never +%%% migrate to the outer list---really a rare case! + +%%% \beginprog +\let\@@mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\@save_mark@true \fi % split marks! + \else \break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \trigger_output + \fi + \global\let\mark=\@@mark + \@@mark + } +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% If the output routine is triggered with the mark penalty value +%%% it will call |\start_saving_page_marks|. +%%% \end{sloppypar} + +%%% \beginprog +\def\start_saving_page_marks{% % this may be executed twice + \unvbox255 + \global\@save_mark@true + } +%%% \endprog + + +%%% \sect To finish the treatment of page marks we can formulate the two +%%% macros which are used at the first resp.\ second invocation of a +%%% ``special output,'' the principles have already been explained. + +%%% \beginprog +\def\backup_page_marks{% + \if@save_mark@ + \mark{\topmark}% + \xdef\save_firstmark{\firstmark}% + \xdef\save_botmark{\botmark}% + \fi + } + +\def\restore_page_marks{% + \if@save_mark@ + \mark{\save_firstmark}\mark{\save_botmark}% + \fi + } +%%% \endprog + + + + + +%%% \chap Positioning the Change Marks. + +%%% Now we must handle the positions of the bars. |\change_pos| will hold +%%% the position of the actual mark, i.e.\ the distance between top of page +%%% and actual mark. |\top_change_pos| will hold the beginning of a changed +%%% area; a value of |\maxdimen| indicates that no change is in effect. If +%%% a changed area is completed, it is appended to the list |\bar_list| as +%%% an element |\bar(\top_change_pos,\change_pos)|. This list contains all +%%% changed areas within the current page so that bars can be written later +%%% on. A single bar will be produced by |\write_bar|. + +%%% \noindent The definition of |\bar| to |\relax| allows the concatenation +%%% of new elements to |\bar_list| with |\xdef|. + +%%% \beginprog +\newdimen\change_pos +\newdimen\top_change_pos \top_change_pos=\maxdimen + +\let\bar_list=\empty + +\let\bar=\relax +\def\write_bar(#1,#2){% + \setbox0=\hbox{\vrule height -#1 depth #2}% + \dp0=0pt \ht0=0pt + \box0 + } +%%% \endprog + + +%%% \sect If the output routine was activated by a |\outputpenalty| value +%%% within the range of our reserved penalties, the change handling will +%%% occur, otherwise standard plain output can be done. + +%%% \beginprog +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\change_penalty_group\space \change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \start_saving_page_marks + \else \plainoutput + \fi + \fi + } +%%% \endprog + + +%%% \sect As explained before, the change handling must differentiate +%%% between the kind of the change command (beginning is indicated by +%%% $|\change_cmd|=0$, end by~1) and between the mode (horizontal indicated +%%% by an odd |\change_mode| value, vertical by an even). A change mode +%%% higher than one indicates that we are doing the first page break that +%%% has to backup the page as far as it exists already and results in an +%%% empty current list of page elements. + +%%% \beginprog +\newcount\change_cmd +\newcount\change_mode + +\def\change_handling{% + \change_cmd=-\outputpenalty % ==> absolute value + \advance \change_cmd by \change_penalty_group00 % subtraction + \change_mode=\change_cmd + \divide \change_cmd by 10 % second-to-last digit + \advance \change_mode by -\number\change_cmd0 % last digit + \ifnum \change_mode>1 \backup_page + \else + \ifcase \change_cmd \begin_change + \or \end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +%%% \endprog + + +%%% \sect Processing a mark during the second trigger of the output routine +%%% means restoring the page and storing the positions. At the beginning, +%%% the begin of the change is saved, at the end, we know the bar already +%%% and put it into the bar list. Then the positioning values are +%%% reinitialized. + +%%% As within every output invocation, the box 255 must be unboxed. As we +%%% are here in the second invocation of the output routine the |\box255| +%%% consists only of the empty |\vbox| we have inserted in +%%% |\trigger_output|. We can therefore throw it away. + +%%% \beginprog +\def\begin_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \global\top_change_pos=\change_pos \global\change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\end_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=\maxdimen \global\change_pos=0pt + \fi + } +%%% \endprog + + + + +%%% \chap Handling the Page Contents. + +%%% We handle the part of the page that was collected up to now by putting +%%% it into a box. This fixes the position of the change mark so that +%%% |\change_pos| can be set and stored later on in |\top_change_pos| or as +%%% the lower end of a bar in |\bar_list|. + +%%% To save the page contents in the first output invocation, we have to +%%% save the page in |\save_page|. Before that, we store the size of the +%%% box (which equals |\pagegoal|!)\ in |\page_goal|. If the unboxing +%%% caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +%%% we eject the page up to the change mark. Now we have to compute the +%%% current position of our mark in |\change_pos|. It is fixed by the size +%%% of the |\save_page|, but in case of a begin mark in horizontal mode we +%%% must decrease it from the baseline position to the top of the last line. +%%% Finally, we must save the values for the allowed insertions and change +%%% them to the maximal value so that a rest that is split from an insertion +%%% will be appended to the insertion box at the second invocation in every +%%% case. + +%%% The |\vsize| is initialized to |\maxdimen|. This allows to control +%%% whether this first output invocation ocurred or if it was discarded. +%%% For the same reason |\change_pos| is initialized to~0pt. + +%%% \beginprog +\newbox\save_page + +\newdimen\page_goal +\newdimen\save_vsize \save_vsize=\maxdimen +\newdimen\save_dimen_topins +\newdimen\save_dimen_footins + +\def\backup_page{% + \global\page_goal=\ht255 + \global\setbox\save_page=\vbox{\unvbox255}% + \ifdim \ht\save_page>\page_goal \eject_page_so_far \fi + \change_pos=\ht\save_page \global\advance \change_pos by \dp\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode \higher_change_pos \fi + \fi + \global\save_vsize=\vsize \global\vsize=\maxdimen + \global\save_dimen_topins=\dimen\topins \global\dimen\topins=\maxdimen + \global\save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \backup_page_marks + } + +\change_pos=0pt +%%% \endprog + + +%%% \sect To eject a page as far as it is we restore it from the +%%% |\save_page| back to box~255. In horizontal mode and at a begin mark +%%% the last line contains the mark and must not be output. So we remove it +%%% and the preceding glue from the stored rest, just leaving a single hbox +%%% to be on top of the actual page (in |\save_page|) now. Then normal +%%% output can be done with box~255. + +%%% \beginprog +\def\eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox255=\vbox to \page_goal{% + \unvbox\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode + \global\setbox\save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \plainoutput + } +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% In horizontal mode and at a begin mark, we need the position of +%%% the mark (|\change_pos|) on the upper boundary of the last line in +%%% |\save_page|. If there is just one line left from a recent eject, the +%%% height is given by the topskip decreased by the height of this hbox. If +%%% the height of the box is larger than |\topskip| the skip will not be +%%% inserted and the change position results to~0pt. Otherwise, +%%% |\save_page| is a vbox whose last hbox we delete temporarily using +%%% box~0. Height and depth of the rest are the actual position on the page. +%%% \end{sloppypar} + +%%% The double of the page we have constructed this way will immediately be +%%% fed back to the garbage collector because it could have become +%%% reasonably large. + +%%% \beginprog +\def\higher_change_pos{% + \ifhbox \save_page % rest of page from \eject_page_so_far + \change_pos=\topskip \global\advance \change_pos by -\ht\save_page + \ifdim \change_pos<0pt \global\change_pos=0pt \fi + \else + \setbox0=\vbox{% + \unvcopy\save_page + \setbox0=\lastbox % delete last line + }% + \change_pos=\ht0 \global\advance \change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +%%% \endprog + + +%%% \sect To restore a page during the second output invocation, we first +%%% restore the saved values, but only if they were really changed (this can +%%% be discovered by the value of |\save_vsize|). Now the |\save_page| is +%%% appended to the current list as a box, which stops later usage of its +%%% stretch- and shrinkability! Then the collected insertions can be +%%% inserted again. The page marks have to be inserted, too. + +%%% \beginprog +\def\restore_page{% + \ifdim \save_vsize=\maxdimen + \else \global\vsize=\save_vsize + \global\dimen\topins=\save_dimen_topins + \global\dimen\footins=\save_dimen_footins + \global\save_vsize=\maxdimen + \restore_page_marks + \fi + \box\save_page % discards stretch- and shrinkability! + \ifvoid \topins + \else \insert\topins{\floatingpenalty=0 \unvbox\topins}% + \fi + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +%%% \endprog + + +%%% \sect {\em Please note, that there is still a problem with this concept +%%% of handling the output trigger:} + +%%% \bigskip + +%%% If the first output trigger is discarded because a page break has occured +%%% just in front, footnote parts may be juggled around. I.e., if a +%%% footnote is split in three parts, the first part was just been shipped +%%% out, the second part is inserted back into the recent contributions by +%%% the output routine but {\em behind\/} the third part which is saved in +%%% the ``special place'' (according to the \TeX{}book, p.~125). A solution to +%%% this problem might be to insert a |\do_change| again within the second +%%% output trigger and finishing the treatmend afterwards. Afterwards a +%%% full triggering process (two output invocations) is executed again and +%%% alle insertion parts will be accessible in the insertion box. + +%%% By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +%%% \LaTeX{} this can happen every time because at the first output invocation +%%% the |\dimen|-values of the footnote insertion is not increased. I leave +%%% the problem open to the reader\,\dots + + + + + +%%% \chap Writing the Stuff. + +%%% The positions of the bars which mark the changed areas are relative to +%%% the top of the text, i.e.\ the height of the top insertion is not +%%% included. Therefore it is best to write them just after the top +%%% insertions before the page text---but to do this we have to change the +%%% Plain macro |\pagecontents|. + +%%% Below is the new definition, I have just rearranged it a little bit so +%%% that it is more legible. The line I have inserted is marked with +%%% `|%%%%|'. |\insert_current_bar| inserts a last element in |\bar_list| +%%% if a changed area is not yet finished, afterwards all bars can be +%%% written. + +%%% \beginprog +\def\pagecontents{% + \ifvoid \topins \else \unvbox\topins \fi + \insert_current_bar \write_all_bars %%%% + \dimen@=\dp\@cclv \unvbox\@cclv % open up \box255 + \ifvoid \footins + \else % footnote info is present + \vskip\skip\footins + \footnoterule + \unvbox\footins + \fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi + } +%%% \endprog + + +%%% \sect If $|\top_change_pos|=|\maxdimen|$ no change is active. Otherwise +%%% the current change reaches from the begin mark (|\top_change_pos|) to +%%% the end of the page, i.e.\ we insert a virtual end mark. Because the +%%% change continues on the next page we insert a virtual begin mark on the +%%% top of the page, too. + +%%% \beginprog +\def\insert_current_bar{% + \ifdim \top_change_pos=\maxdimen + \else + \change_pos=\ht255 \advance\change_pos by \dp255 + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=0pt + \fi + } +%%% \endprog + + +%%% \sect Now we can write all bars---if they exist anyway. It's rather +%%% easy, we just have to define |\bar| to |\write_bar| and execute +%%% |\bar_list|. The resulting output must not use vertical place. We must +%%% not forget to delete the list, or we will get the same bars on the next +%%% page again. + +%%% \noindent |\BarDistance| is the amount of place between the text margin +%%% and the change bars. + +%%% \beginprog +\newbox\@bars +\newdimen\BarDistance \BarDistance=2cc + +\def\write_all_bars{% + \ifx \bar_list\empty + \else % changes exist + \setbox\@bars=\hbox to \hsize{% + \hskip\hsize \hskip\BarDistance + \vbox to 0pt{\offinterlineskip + \let\bar=\write_bar \bar_list + }% + \hss + }% + \ht\@bars=0pt \dp\@bars=0pt \box\@bars + \global\let\bar_list=\empty + \fi + } +%%% \endprog + + +%%% \sect We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + +%%% \end{document} diff --git a/macros/plain/contrib/chbar/copying b/macros/plain/contrib/chbar/copying new file mode 100644 index 0000000000..9a17037581 --- /dev/null +++ b/macros/plain/contrib/chbar/copying @@ -0,0 +1,249 @@ + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/macros/plain/contrib/chbar/progltx.sty b/macros/plain/contrib/chbar/progltx.sty new file mode 100644 index 0000000000..c59f986fc4 --- /dev/null +++ b/macros/plain/contrib/chbar/progltx.sty @@ -0,0 +1,759 @@ +% This is PROGLTX.DOC as of 25 May 90 +%--------------------------------------------------------- +% (c) 1989,1990 by J.Schrod. copy conditions see below + +% +% Macro package for the documentation of programs +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 89-11-18 js repaired the handling of `|' (verbatim and \index). +% 89-10-05 js first version (for TeX89) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% documented with itself... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\WEB{{\tt WEB\/}} +%%% \def\GNU{{\mc GNU}} + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%% \begin{document} + + +%%% \title{ +%%% Documenting programs in a \WEB{} style\\ +%%% The {\tt progltx\/} style option +%%% } +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + +%%% \chap Introduction. + +%%% \WEB{} systems allow the documentation of programs by supporting the +%%% separation in program fragments which can be collected and rearranged +%%% afterwards. This allows {\it top-down\/} programming as well as the +%%% {\it bottom-up\/} design of programs. Each program fragment can be +%%% documented, usually with \TeX{}\@. A disadvantadge is that \WEB{} +%%% actually exists only for a few programming languages (Pascal, C, +%%% Modula-2). Besides, building up \WEB{} systems for ``exotic'' +%%% programming languages like \TeX{} is very difficult. + +%%% This macro package was built to allow good documentation for programs +%%% in languages for which \WEB{} doesn't exist. It separates a program +%%% text in sections that can be documented. All sections, collected +%%% sequentially, will result in the complete program. In every section +%%% begin and end of the program part are marked with |\beginprog| and +%%% |\endprog|, this program part will be formatted as it is input +%%% (``verbatim''). + +%%% Originally these macros were written for the usage with Plain \TeX{} +%%% resp.\ on top of the \WEB{} macro package |webmac.tex|. But often the +%%% requirement has been told to me that a \LaTeX{} version would be +%%% useful, too---well, here it is. But even with \LaTeX{} I have decided +%%% that still |\beginprog| and |\endprog| must be used for the markup of +%%% the program parts, not |\begin{prog}| or |\end{prog}| which would be +%%% more ``\LaTeX{}-like.'' The reason behind this is that I didn't want +%%% to maintain two versions of the {\mc MAKEPROG\/} processor---but {\mc +%%% MAKEPROG\/} wants to see the non-\LaTeX{}-like macros. But everybody +%%% is encouraged to change it by themselves (it is {\it very\/} easy). + +%%% The user of these macros may use the usual sectioning macros of +%%% \LaTeX{} for structuring his documentation. Additionally we provide a +%%% |progdoc|-compatible (i.e.\ \WEB{}-like) markup with the two macros +%%% |\chap| and |\sect|. + +%%% In the documentation part of a section text pieces, e.g.\ names of +%%% variables, can be inserted verbatim to demonstrate the connection to +%%% the program text. These parts are included in vertical bars +%%% (`{\tt\vbar}') This makes this style option extremely useful if your +%%% identifiers (or your file names) include characters which would be +%%% special characters for \TeX{} otherwise. (One example of these +%%% program languages is \TeX{} itself, but just enclose the macro names +%%% in vertical bars and {\tt \vbar|\relax|\vbar}.) + +%%% The macros |\makevertother| and |\makevertactive| are available to +%%% activate and deactivate the special behaviour of the vertical bar but +%%% these macros should be needed seldom because the usual cases as the +%%% usage within |verbatim| and |tabular| environments or |\index| macros +%%% etc.\ are handled. + +%%% If a vertical bar must be used in the original fashion you can use two +%%% command sequences: |\origvert| holds the meaning of the vertical bar +%%% at the time this macro file was read in and |\vbar| is the character +%%% with the {\mc ASCII\/} code of the vertical bar (i.e.~|"EC|) in the +%%% current font. + +%%% The new notion of |\verb| must not be used within parameters of +%%% macros, e.g.\ in the argument of |\section| etc.---it will result in +%%% an error message by \TeX{}\@. Furthermore within the preamble of a +%%% |tabular|, an |array| environment, or the |\multicolumn| command the +%%% vertical bar has the same meaning as before. (That means within +%%% |@{|\ldots|}| it is an ordinary character and otherwise it specifies a +%%% vertical rule between the columns. + +%%% This macro package does not offer the automatic creation of an index +%%% because it is not known which syntactical tokens the language has that +%%% should be mentioned in an index. But of course all \LaTeX{} stuff like +%%% |\index|, |\tableofcontents|, etc.\ may be used. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% You should have received a copy of the \GNU{} General Public License +%%% along with this program; if not, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect We have to realize three parts: (1)~the formatting of rather +%%% small verbatim texts in a line, (2)~the formatting of larger parts of +%%% program and (3)~the document structuring elements for the separation +%%% of the sections. + +%%% \begin{sloppypar} +%%% Before we start we declare some shorthands for category codes. By +%%% declaring the underscore~`(|_|)' as a letter we can use it in our +%%% macros names. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than +%%% |\p@@@s|.) But as we have to restore the category codes at the end +%%% of this macro file we store its former value in the control +%%% sequence |\uscode|. This method is better than the usage of a +%%% group because not all macros have to be defined global this way. +%%% \end{sloppypar} + +%%% \beginprog +\chardef\escape=0 +\chardef\open=1 +\chardef\close=2 +\chardef\letter=11 +\chardef\other=12 +%\chardef\active=13 % is defined in Plain already + +\chardef\uscode=\catcode`\_ + +\catcode`\_=\letter +%%% \endprog + + + + +%%% \chap Local Verbatim Formatting. + +%%% The main point of every verbatim formatting is the switching of the +%%% character codes of all characters that have a special \TeX{} meaning. +%%% This can be done with the control sequence |\dospecials| that applies +%%% the control sequence |\do| to all special characters. Additionally, +%%% every line is regarded as a paragraph without indentation. Between +%%% two paragraphs, i.e.\ between two lines, no extra space is set. +%%% Finally all blanks and tabular characters shall be obeyed and the +%%% inter word space after sentence terminators shall not be enlarged. +%%% The activation of the tabular characters with |\obeytabs| is +%%% equivalent to |\obeyspaces| in {\tt plain.tex}. + +%%% \begin{sl} +%%% As a matter of fact, I would like to use the character set with the +%%% extended {\mc ASCII} (like in\/ \WEB{}) for setting the verbatim texts +%%% in monospace. But then I must code many\/ |\@getfont|'s\,\dots +%%% \end{sl} + +%%% \beginprog +%\font\tentex=cmtex10 % typewriter extended ASCII 10pt +%\let\ttex=\tentex % only with base size 10pt +\def\ttex{\tt} % as a substitute + +\def\setup_verbatim{% + \def\do##1{\catcode`##1\other}\dospecials + \parskip\z@skip \parindent\z@ + \catcode`\`\active \@noligs + \obeylines \@vobeyspaces \obeytabs \frenchspacing + \ttex + } + +\let\tab=\space +\begingroup + \catcode`\^^I=\active% % Attention: no tabs! + \gdef\obeytabs{\catcode`\^^I=\active\def^^I{\tab}} + \global\let^^I=\tab% % if an active tab appears in a \write +\endgroup +%%% \endprog + + +%%% \sect After having saved the old meaning of `{\tt\vbar}' in +%%% |\origvert| and after declaring |\vbar| as a synonym for the character +%%% that has the code of a vertical bar in the actual font, the vertical +%%% bar can be made active. Then we call |\setup_verbatim|. But the +%%% newline characters shall not be processed, they shall be regarded like +%%% blank space. This can be reached by defining |\par| as |\space|. + +%%% The next vertical bar in the input closes the group which becomes an +%%% (unbreakable) |\hbox| then. The old meanings of the special +%%% characters and of the vertical bar are restored and \TeX{} is in +%%% normal (horizontal) mode again. + +%%% \beginprog +\let\origvert=| +\chardef\vbar=`\| + +\def\makebaractive{\catcode`\|\active} +\def\makebarother{\catcode`\|\other} +\makebaractive + +\def|{% + \leavevmode + \hbox\bgroup + \let\par\space \setup_verbatim + \let|\egroup + } +%%% \endprog + + +%%% \sect A problem with this definition of the vertical bar is that +%%% the bar is not a normal character any more but there exists situations +%%% where the \LaTeX{} macros assumes this: +%%% % +%%% \begin{itemize} + +%%% \item In a |verbatim| environment a vertical bar must be typeset if it +%%% occurs in the input. + +%%% \item In a |tabular| or an |array| environment a vertical bar is used +%%% to denote rules between columns in the table. These environments must +%%% be started with a parameter which is a ``preamble,'' the same preamble +%%% construction is used to specify the format of multi-column entries. + +%%% \item In an output of an index entry the vertical bar must not result +%%% in an error message. Usually index entries are typeset in a seperate +%%% \TeX{} run where |idverb| is not used as a style option and the +%%% vertical bar is therefore useful. This is no problem in section +%%% headings or captions etc. Because they take their argument as a +%%% parameter in every case the vertical bar can never be used there. But +%%% |\origvert| resp.\ |\vbar| may be used there. + +%%% \end{itemize} +%%% % +%%% In the next sections we handle each of these problems. + + +%%% \sect Before we start a |verbatim| environment we just redefine the +%%% vertical bar as an ordinary character. Because this is within the +%%% environment grouping the end of the environment will reestablish the +%%% special meaning. + +%%% \beginprog +\let\@@verbatim=\@verbatim +\def\@verbatim{% + \makebarother + \@@verbatim + } +%%% \endprog + + +%%% \sect Special care is needed in the |tabular| and the |array| +%%% environment. Both environments are begun by one macro (|\@tabarray|), +%%% we redefine it so that the bar can be used in the preamble +%%% specification. The same problem occurs in |\multicolumn|, it is +%%% solved the same way. After the preamble construction (with +%%% |\@mkpream|) the special meaning of the bar can be switched on +%%% again---this allows the usage of the new meaning in the body of a +%%% table. + +%%% Of course this mean that the ``verbatim identifier'' facility can +%%% not be used within a preamble of a table. Furthermore it can not +%%% be used within the |\multicolumn| statement, neither in the +%%% preamble part (the second parameter) nor within the text part (the +%%% third parameter). + +%%% \beginprog +\let\@@tabarray=\@tabarray +\def\@tabarray{% + \makebarother + \@@tabarray + } + +\def\multicolumn#1{% + \multispan{#1}% + \begingroup + \makebarother + \restof_multicolumn + } +\def\restof_multicolumn#1#2{% + \@mkpream{#1}% + \def\@sharp{#2}% + \let\protect\relax + \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox + \@arstrut \@preamble + \endgroup + \ignorespaces + } + +\let\@@mkpream=\@mkpream +\def\@mkpream#1{% + \@@mkpream{#1}% + \makebaractive + } +%%% \endprog + + +%%% \sect Before an index entry is scanned almost all special characters +%%% are transformed into ordinary characters. The only exceptions are the +%%% opening and the closing brace because they are needed to delimit the +%%% argument. This transformation is done with |\@sanitize|, this macro +%%% must be called within a group. We just append the transformation of +%%% the vertical bar. + +%%% \beginprog +\begingroup + \def\@makeother{\noexpand\@makeother\noexpand} + \xdef\@sanitize{\@sanitize\@makeother\|} +\endgroup +%%% \endprog + + + + +%%% \chap Fragments in Verbatim. + +%%% We need macros to format the program fragments without any +%%% linebreaking. Such a text area shall start with the macro +%%% |\beginprog| and end with |\endprog|, i.e.\ as a kind of a +%%% |prog|-environment. The macro |\endprog| must stand at the very +%%% beginning of a line and must be followed by white space (blank, tab or +%%% newline character). After |\beginprog| as well as after +%%% |\endprog| the rest of the line is ignored. + +%%% Two demands must be regarded: There should be no length restrictions +%%% for the processed text, and the tabular characters should be expanded +%%% so that this macro works on PC's and on VAXes etc., too. + + +%%% \sect The implementation method is quite simple: We read the next +%%% line, test, wether the end is reached (by comparing with the end line) +%%% and otherwise set the line actually read. Every character is +%%% inspected and tabular characters are expanded. + +%%% The verbatim text is started with |\begin_verbatim| which will be +%%% either called by |\beginprog| or by |\beginverbatim|. These macros +%%% will also define the contents of the end line. + +%%% Whether a line is set or whether the end of the processed area is +%%% reached is indicated by the switch |\if@print|. At the beginning of +%%% the |\begin_verbatim| macro most settings are done with +%%% |\setup_verbatim| (the vertical bar must be handled separately) +%%% and the rest of the line is ignored. As everything is done within +%%% a group, the end of the verbatim text can be processed by simply +%%% closing this group. + +%%% For the user it looks as if |\endprog| or |\endverbatim| +%%% terminates the processing, but it just serves for the +%%% identification of the end, the true processing is done with the +%%% internal macro |\end_verbatim|. + +%%% \beginprog +\newif\if@print + +\def\begin_verbatim{% + \endgraf + \bigbreak + \begingroup + \setup_verbatim \makebarother + \@printtrue + \ignore_rest_line + } +\let\end_verbatim=\endgroup % internal command ! +%%% \endprog + + +%%% \sect {\sloppy +%%% The first line is ignored, all the other lines are identified with +%%% |\set_next_line| and processed with |\do_set|. This separation in +%%% identification and processing allows that the line end character is +%%% active in the definition only for a short time. +%%% \par} + +%%% When a line is to be formatted, we first check with |\check_print| +%%% wether it contains the end line, otherwise it is printed with +%%% |\print_char|. The printing must be done for every character +%%% individually because we want to check for tabular characters; the +%%% exact algorithm is described below. Here we just have to note that +%%% |\print_char| is used with two parameters of which the second one is +%%% finished with the token |\end_line|. The first parameter is the first +%%% character of the line, the second parameter is the rest of the line. +%%% If the line is empty, the argument of |\do_set| is empty, too; so the +%%% activation of |\print_char| must be finished with two |\end_line|. +%%% Then the first |\end_line| is the first argument for |\print_char| and +%%% the second argument is empty. But if the line did contain something, +%%% the second |\end_line| is evaluated, for this case it is defined as +%%% |\relax|. + +%%% At last we call |\set_next_line| again to format the next line. If +%%% the end is reached, i.e.\ if the sample line was found, +%%% |\set_next_line| will be redefined as |\relax|. This can be done +%%% because the original meaning is restored while closing the group +%%% with |\end_verbatim|. + +%%% \beginprog +\begingroup + \obeylines% % ^^M is active! ==> every line must end with % + \gdef\ignore_rest_line#1^^M{\set_next_line}% + \gdef\set_next_line#1^^M{\do_set{#1}}% +\endgroup + +\def\do_set#1{% + \endgraf + \check_print{#1}% + \if@print \indent \print_char#1\end_line\end_line + \else \let\set_next_line\end_verbatim + \fi + \set_next_line + } +\let\end_line=\relax +%%% \endprog + + +%%% \sect {\sloppy +%%% Before we look at the problem of formatting a line, we declare +%%% |\check_print| that checks the end of the verbatim mode. We have to +%%% do two things: we must split everything in front of the first blank +%%% or tabular character and compare for identity with |\endprog|. The +%%% splitting is easy because the line which is our first argument +%%% contains blanks and tabulators as active characters. First we call +%%% |\cut_at_tab| that demands a tabular character as separator for its +%%% two pramenters so that everything in the line in front of the first +%%% tabulator is part of the first parameter. If there is no tabular +%%% character in the line, we append one so that the second parameter is +%%% empty. The same trick is used to separate the part in front of the +%%% first blank character from the resulting first part. +%%% \par} + +%%% The check is done with |\do_check|. We use a separate macro here so +%%% that we can indent it (in the following definition blanks are active!) + +%%% \beginprog +\begingroup +\obeyspaces\obeytabs +\gdef\check_print#1{\cut_at_tab#1^^I\end_line} +\gdef\cut_at_tab#1^^I#2\end_line{\check_first_part#1 \end_line}% blank ! +\gdef\check_first_part#1 #2\end_line{\do_check{#1}} +\endgroup +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% |\do_check| compares the line with a sample line that is +%%% available in |\end_verbatim_line|. This macro will be defined later. +%%% \end{sloppypar} + +%%% \beginprog +\def\do_check#1{% + \def\@line{#1}% + \ifx \@line\end_verbatim_line \@printfalse + \fi + } +%%% \endprog + + +%%% \sect Now we can set a line: we start with the first character, +%%% followed by the rest of the line. Each character is counted in +%%% |\char_count|. At the beginning of a line |\char_count| is~0, this +%%% is reset at the end of the line. + +%%% \beginprog +\newcount\char_count \char_count\z@ + +\def\print_char#1#2\end_line{% + \print_first_char{#1}% + \print_rest_of_line{#2}% + } +%%% \endprog + + +%%% \sect For each character that is set |\char_count| is incremented. +%%% If a character is a tabulator, we set with |\print_tab| the fitting +%%% amount of blank characters, otherwise the character itself. We must +%%% compare the character that is stored in |\@char| with a macro of which +%%% the ``first-level'' expansion is an active tabulator. For this case +%%% we declare |\@tab|. + +%%% \beginprog +{\obeytabs\gdef\@tab{^^I}} + +\def\print_first_char#1{% + \def\@char{#1}% + \advance \char_count\@ne + \ifx \@char\@tab \print_tab + \else \@char + \fi + } +%%% \endprog + + +%%% \sect If we want to fill the line with blank spaces up to the next +%%% column with a number that can be divided by~8, we must be able to +%%% compute the column number modulo~8, but \TeX{} has no modulo operator. +%%% So we define the macro |\mod_viii| that computes its argument modulo~8 +%%% and returns the result in the counter |\count_mod_viii|. For the +%%% computation we need the temporary counter |\count@|. + +%%% \beginprog +\newcount\count_mod_viii +\def\mod_viii#1{% + \count@ #1\relax \count_mod_viii\count@ + \divide \count@ 8\relax + \multiply \count@ 8\relax + \advance \count_mod_viii -\count@ + } +%%% \endprog + + +%%% \sect Now we can declare |\print_tab|. We must remember that +%%% |\char_count| was incremented already, if we set only one blank +%%% character the counter keeps untouched. + +%%% \beginprog +\def\print_tab{% + \loop \space \mod_viii\char_count + \ifnum \count_mod_viii>\z@ + \advance \char_count\@ne + \repeat + } +%%% \endprog + + +%%% \sect If the rest of the line is empty, we are ready. |\char_count| +%%% is reset to~0 for the next line. + +%%% Inside the |\else| part of |\ifx| |\print_char| should not be used +%%% directly because this costs too much storage of \TeX{}\@. Instead we +%%% set a control sequence |\next| that is processed afterwards, depending +%%% on the result of the comparison. (This tail recursion will be +%%% discovered by \TeX{} and handled appropriately.) If there is still +%%% something to set, we use |\print_char| again, otherwise a +%%% syntactically similar macro that expands to |\relax|. + +%%% \beginprog +\def\print_rest_of_line#1{% + \def\@line{#1}% + \ifx \@line\empty \char_count\z@ + \def\next##1\end_line{\relax}% + \else \let\next\print_char + \fi + \next#1\end_line + } +%%% \endprog + + +%%% \sect {\sloppy +%%% Now we are ready to define the two ``user accessible'' macros +%%% |\beginprog| and |\beginverbatim|. They must define the prototyp end +%%% line |\end_verbatim_line| which will be compared against every line +%%% in the verbatim text. During the definition of +%%% |\end_verbatim_line| it must be cared for that the escape character~`|\|' +%%% is a printable character: A comparison with |\ifx| demands identical +%%% category codes. As a temporary escape character we use the slash. +%%% \par} + +%%% \beginprog +{\catcode`\/=\escape % / is temporary escape char + \catcode`\\=\other + /gdef/beginprog{% + /gdef/end_verbatim_line{\endprog}% + /begin_verbatim + } + /gdef/beginverbatim{% + /gdef/end_verbatim_line{\endverbatim}% + /begin_verbatim + } +} % here \endgroup can't be used +%%% \endprog + + + + +%%% \chap Document Structuring. + +%%% In addition to the normal \LaTeX{} structuring markups we will +%%% provide a markup for a layout of the document that is like in +%%% \WEB{}. This can be done easily. All sections are numbered, the +%%% number of the next section is stored in the counter |section|. We +%%% distinguish between main sections which start a group of sections +%%% and between normal sections within a group. + +%%% The main sections are started with the macro |\chap|. It has one +%%% parameter, the title of the section group. This parameter must be +%%% terminated by a dot. We start a new page, typeset the title in +%%% bold face and separate it from the section text with a |\medskip|. +%%% This text, the documentation part of the section, is formatted +%%% without paragraph indentation. + +%%% If the \WEB{}-like macros are used every section number should be +%%% output with a following dot. We want to establish this when we use the +%%% |\chap| or the |\sect| macro the first time. Furthermore the new page +%%% at the begin of a main section should not be started at the first +%%% |\chap| because a title may precede it (and the title should not +%%% be on a seperate page unless explicitely requested). Instead a +%%% skip of (approximately) 2~pica should be set. To achieve +%%% both goals a macro |\chap_intro| is defined that defines |\thesection| +%%% appropriately, skips the 2~pica, and redefines itself to +%%% |\newpage|---we then just have to call |\chap_intro| at the beginning +%%% of |\chap|. The same applies to |\sect_intro|. + +%%% \beginprog +\newskip\pre_sect_skip \pre_sect_skip=2pc plus 1pc minus 6pt + +\def\chap_intro{% + \gdef\thesection{\arabic{section}.}% + \gdef\chap_intro{\newpage}% + \addvspace{\pre_sect_skip}% + } + +\def\sect_intro{% + \gdef\thesection{\arabic{section}.}% + \global\let\sect_intro\relax + } +%%% \endprog + + +%%% \sect Now we will have a look at the {\it wonderful\/} internal +%%% interface of \LaTeX{}\@. With ``wonderful'' I mean that I'm always +%%% full of wonder why it was designed in this way. E.g., if anybody +%%% can explain to me why the coding of the non-indentation of the first +%%% line in the following paragraph was combined with the coding of +%%% the skip which will come in front of the section---I will be thankful +%%% for the rest of my life. Such different things should be kept +%%% different, i.e., the suppression of the indentation should not be +%%% hidden in the sign of a skip! The same comment applies to the combined +%%% coding of the skip below the section heading resp.\ to the right +%%% of a run-in heading. + +%%% \begin{quote} \it +%%% I want the following layout: no indentation in the following +%%% paragraph\/ {\rm but no} space in front of the section heading. +%%% How do I code a value of\/ $\sl -0 pt$? +%%% \end{quote} +%%% % +%%% Well, a work-around is to use a value of $\rm -1\,sp$ because the +%%% reader will not see this distance---but in my opinions this is no +%%% good programming style. In this special case I have luck, too: +%%% the skip is not set anyway, either it is discarded by the preceding +%%% |\newpage| or it is not added by |\addvspace| because of the preceding +%%% |\pre_sect_skip|. + +%%% \beginprog +\def\chap#1.{% + \chap_intro + \@startsection{section}{1}% + {\z@}% + {\m@ne sp}% + {\medskipamount}% + {\normalsize\bf}% + {#1.}% + } +%%% \endprog + + +%%% \sect Normal sections are started with |\sect|. This macro has no +%%% parameter. Between two paragraphs we skip |\pre_sect_skip|. +%%% Between the section number and the text one quad of space is set. +%%% We have to take care for empty documentation parts where the +%%% program part (i.e.\ |\beginprog|) will follow immediately. Then +%%% the program part should begin on a new line and not behind the +%%% section number. So we provide |\null| as an empty documentation +%%% part in every case. + +%%% Now again the design of |\@startsection| comes in hand: \LaTeX{} +%%% always leaves a quad after the section number (by the way, +%%% this is not mentioned in the documentation---you have to look +%%% in the macros to figure this out). Because our section header +%%% consists only of the number we have to code a value of $\rm +%%% -0\,pt$\,\dots + +%%% \begin{quote} +%%% Again: {\it non-orthogonal design is bad design}. +%%% \end{quote} + +%%% \beginprog +\def\sect{% + \sect_intro + \@startsection{section}{1}% + {\z@}% + {\pre_sect_skip}% + {\m@ne sp}% + {\normalsize\bf}% + {\null}% + } +%%% \endprog + + +%%% \sect We are finished and just have to restore the category code. + +%%% \beginprog +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + + + +%%% \end{document} diff --git a/macros/plain/contrib/chbar/readme b/macros/plain/contrib/chbar/readme new file mode 100644 index 0000000000..9053be7938 --- /dev/null +++ b/macros/plain/contrib/chbar/readme @@ -0,0 +1,116 @@ +% README for changebar macros 09 Apr 91 +%------------------------------------------------------------ + + +GENERAL NOTES + +These are my macros for producing changebars with Plain TeX. Please +note that (1) these macros will not produce an optimal page breaking +(i.e. vertical glue will disappear in many places) and (2) that there +is still a problem with these macros: it is described in the last +section of the chapter `Handling the Page Contents.' By the way, this +problem is within the current LaTeX, too. + The macros were written for TeX 2. In the meantime TeX 3 became +available; new features (i.e., \holdinginsert) would now allow a +better implementation. + +The macros are written for the usage with Plain TeX. I will not do +the LaTeX adaption because I neither use LaTeX in my own documents +nor do I need changebars... For me it was just a nice play to show +what can be done with the \output routine of TeX. Therefore I will +not put further work in these macros. But I will happily redistribute +enhancements and will make them available on the usual TeX servers. + +So: If you enhance the macros, or if you adapt them to LaTeX, or if +you incorporate the new features of TeX 3, send them to me so that +others can share your work. + + +NOTES ON THE DISTRIBUTED FILES + +The macro file chbars.doc can be LaTeXed (the result is not as +readable as it should be---but this is due to the inflexibility of +the \@startsection macro of LaTeX). The needed style files are +included. Furthermore two test files (test1.tex and test2.tex) for +the usage of change bars in vertical and horizontal mode are +included, too. + +These macros are documented with my MAKEPROG processor. Perhaps I +should mention why I don't use the doc-option of Frank Mittelbach: +MAKEPROG has been written by me before I have heard of the existence +of doc. But even then I would have written it: doc is a special +documentation tool for TeX macros which heavily depends on LaTeX and +the LaTeX coding conventions. It is not very easy to use it for the +documentation of other stuff than LaTeX macros. In contrary, MAKEPROG +is a {\it general documentation facility\/} which I use for all things +where WEB is not available. (In fact, it was created to document lex +and yacc programs...) Especially the changefile possibility I need +very hardly. MAKEPROG has the disadvantage that a special care of the +TeX environment (e.g. the indexing of macro names) can not be +implemented. I'm still working on MAKEPROG, the next version 2.0 will +have a code rearrangement ability like TANGLE. + +MAKEPROG may be fetched from LISTSERV@DHDURZ1 (for the Bitnet folks) +and per ftp from Washington (where it is in the UNIX distribution). I +would prefer if you get it from there so that I don't have to mail out +so much stuff. If you have no access contact me. If you are working +on an IBM(-compatible) PC you should nevertheless contact me: I have +changefiles for Turbo Pascal available. + +I'm not really satisfied that I have not found the time to update the +documentation of MAKEPROG to mention that progltx, the +progdoc-equivalent LaTeX style option, exists. To get a +documentation you must run LaTeX over progltx.doc and print the +result. Because I print the whole stuff usually on A4 paper I have +included a style option for A4 page layout, too. The macro file +a4-9.sty assumes that the driver leaves a margin of 1 in. Please +note, that this is not just ``one other'' A4 page layout -- it was +designed by a typographer and I have only done the LaTeX +realization---have a look at a4-9.doc! + +Perhaps it is of interest for you how the verbatim typesetting in +progltx is done---the scheme is robuster than the one LaTeX uses, it +works with tabs (are you working on a VAX or a PC?), but it's slower, +too. In the last sections of the files you can have a look at the +`great' internal design of the current LaTeX, too. + + + +Well, I hope that you will enjoy the macros + + Greetings + Joachim Schrod + + +current address: + Technical University of Darmstadt + Department of Computer Science + Joachim Schrod + Alexanderstr. 10 + + D-6100 Darmstadt + FR Germany + + Email: xitijsch@ddathd21.bitnet + + +============================================================================== + +The following files are in the distribution: + +COPYING copy conditions, i.e. the GNU General Public License +README this file you are reading + +chbars.doc The documented macro source (with MAKEPROG!) +progltx.sty Style files needed to print it. +a4-9.sty + +chbars.tex the macro version of chbars.doc +test1.tex Test files for chbars.tex +test2.tex + +a4-9.doc a non-arbitrary A4 page layout style option +a4-marg.chf changefile for a4-9.doc, adaption to 1in driver margin + + +-- diff --git a/macros/plain/contrib/chbar/test1.tex b/macros/plain/contrib/chbar/test1.tex new file mode 100644 index 0000000000..92d2839ef8 --- /dev/null +++ b/macros/plain/contrib/chbar/test1.tex @@ -0,0 +1,60 @@ +\input chbars + +\catcode`\@=\letter +\catcode`\_=\letter +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +Zeile 1 +\beginchange +Zeile 2 +\mark{Mark 1}% +\write 16{Ausgabe 1}% +Zeile 3 +\endchange +Zeile 4% +\mark{Mark 2}% +\mark{Mark 3} +\beginchange +Zeile 5 +\write 16{Ausgabe 2}% +Zeile 6 +\endchange +Zeile 7 +\beginchange +Zeile 8 +\write 16{Ausgabe 3}% +Zeile 9 +\endchange +Zeile 10 +\beginchange +Zeile 11 +\write 16{Ausgabe 4}% +Zeile 12 +\endchange +Zeile 13 +\beginchange +Zeile 14 +\write 16{Ausgabe 5}% +Zeile 15 +\endchange +Zeile 16 +\beginchange +Zeile 17 +\write 16{Ausgabe 6}% +Zeile 18 +\endchange +Zeile 19 + + +\bye diff --git a/macros/plain/contrib/chbar/test2.tex b/macros/plain/contrib/chbar/test2.tex new file mode 100644 index 0000000000..5dbdd4a17a --- /dev/null +++ b/macros/plain/contrib/chbar/test2.tex @@ -0,0 +1,70 @@ +\input chbars + +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +Zeile 1 + +\beginchange + +Zeile 2 + +\mark{Mark 1}% +\write 16{Ausgabe 1}% + +Zeile 3 + +\endchange + +Zeile 4 + +\mark{Mark 2}% + +\mark{Mark 3}% + +\beginchange + +Zeile 5 + +\write 16{Ausgabe 2}% + +Zeile 6 + +\endchange + +Zeile 7 + + +\beginchange + +Zeile 8 + +\write 16{Ausgabe 3}% + +Zeile 9 + +\endchange + +Zeile 10 + +\beginchange + +Zeile 11 + +\write 16{Ausgabe 4}% + +Zeile 12 + +\endchange + +\bye |