summaryrefslogtreecommitdiff
path: root/macros/plain/contrib/chbar
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/plain/contrib/chbar
Initial commit
Diffstat (limited to 'macros/plain/contrib/chbar')
-rw-r--r--macros/plain/contrib/chbar/a4-9.doc304
-rw-r--r--macros/plain/contrib/chbar/a4-9.sty324
-rw-r--r--macros/plain/contrib/chbar/a4-marg.chf34
-rw-r--r--macros/plain/contrib/chbar/chbars.doc738
-rw-r--r--macros/plain/contrib/chbar/chbars.tex758
-rw-r--r--macros/plain/contrib/chbar/copying249
-rw-r--r--macros/plain/contrib/chbar/progltx.sty759
-rw-r--r--macros/plain/contrib/chbar/readme116
-rw-r--r--macros/plain/contrib/chbar/test1.tex60
-rw-r--r--macros/plain/contrib/chbar/test2.tex70
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