% \iffalse meta-comment
%
%% Copyright 1994-2004 (C) Johannes Braams.  All rights reserved.
%
% This file is part of the changebar package.
% -------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2003/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is Johannes Braams.
%
% The list of all files belonging to the changebar package is
% given in the file `manifest.txt.
%
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
% \fi
% \CheckSum{1602}
%
%\iffalse
%    This file is built for \LaTeXe, so we make sure an error is
%    generated when it is used with another format
%    \begin{macrocode}
%<+package>\NeedsTeXFormat{LaTeX2e}
%    \end{macrocode}
%
%    Now announce the package name and its version:
%    \begin{macrocode}
%<*dtx>
\ProvidesFile{changebar.dtx}
%</dtx>
%<+package>\ProvidesPackage{changebar}
           [2004/02/20 v3.4g Indicate changes with marginal bars]
%    \end{macrocode}
%
% \section{A driver for this document}
%
%    The next bit of code contains the documentation driver file for
%    \TeX{}, i.e., the file that will produce the documentation you
%    are currently reading. It will be extracted from this file by the
%    \textsc{docstrip} program.
%
%    \begin{macrocode}
%<*driver>
\documentclass{ltxdoc}
%    \end{macrocode}
%    We do want an index, using linenumbers
%    \begin{macrocode}
\EnableCrossrefs
\CodelineIndex
%    \end{macrocode}
%    This document uses some extra \texttt{doc} style macros.
%    \begin{macrocode}
\makeatletter
\def\DescribeVar#1{\leavevmode\@bsphack
    \marginpar{\raggedleft\PrintDescribeEnv{#1}}%
    \SpecialVarUsageIndex{#1}\@esphack\ignorespaces}
\def\SpecialVarMainIndex#1{\@bsphack
    \index{#1\actualchar\texttt{#1}\encapchar main}%
    \@esphack}
\def\SpecialVarUsageIndex#1{\@bsphack
    \index{#1\actualchar\texttt{#1}\encapchar usage}%
    \@esphack}
\let\@SpecialMainIndex\SpecialMainIndex
\def\Var{\let\SpecialMainIndex\SpecialVarMainIndex\macro}
\def\endVar{\endmacro\let\SpecialMainIndex\@SpecialMainIndex}
\makeatother
%    \end{macrocode}
%    Some commonly used abbreviations
%    \begin{macrocode}
\newcommand{\Lopt}[1]{\textsf {#1}}
\newcommand{\Lenv}[1]{\textsf {#1}}
\newcommand{\file}[1]{\texttt {#1}}
\newcommand{\pkg}[1]{\texttt {#1}}
\newcommand{\Lcount}[1]{\textsl {\small#1}}
\newcommand{\pstyle}[1]{\textsl {#1}}
%    \end{macrocode}
%    We also want the full details.
%    \begin{macrocode}
\begin{document}
\DocInput{changebar.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%\fi
%
% \GetFileInfo{changebar.dtx}
%
% \changes{3.1}{1993/07/02}{Removed a number of typos}
% \changes{3.1a}{1993/08/03}{Uncommented \cs{filedate} and
%    \cs{fileversion}}
% \changes{3.2}{1994/04/21}{Incorporated Robin Fairbairns suggestions
%    for the upgrade for \LaTeX2e}
% \changes{3.2a}{1995/03/20}{Fixed bug about cross-page bars}
% \changes{v3.2b}{1995/06/26}{Removed use of \cs{file...} commands}
% \changes{v3.2b}{1995/06/26}{Use \LaTeX's Warning mechanisms}
% \changes{v3.2c}{1996/03/26}{Reinserted \cs{driver} for compatibility
%    reasons} 
% \changes{v3.4e}{2001/09/14}{Store original definitions using the
%    \texttt{ltx} prefix, define own versions with \texttt{cb} prefix,
%    the use \cmd{let} to replace \LaTeX\ macro.}
%
% \title{The Changebar package
%         \thanks{This file has version number \fileversion,
%                 last revised \filedate.}}
%
% \author{Michael Fine\\Distributed Systems Architecture \and
%         Johannes Braams\\
%         Kersengaarde 33\\
%         2723 BP Zoetermeer\\
%         The Netherlands\\
%         \texttt{texniek at braams.cistron.nl}}
%
% \date{Printed \today}
%
% \maketitle
%
% \begin{multicols}{2}
%  \tableofcontents
% \end{multicols}
%
% \begin{abstract}
%    This package implements a way to indicate
%    modifications in a \LaTeX-document by putting bars in the
%    margin. It realizes this by making use of the |\special|
%    commands supported by `dvi drivers'. Currently six different
%    drivers are supported. More can easily be added.
% \end{abstract}
%
% \section{Introduction}
%
%    \textbf{Important note} Just as with cross references and labels,
%    you usually need to process the document twice (and sometimes
%    three times) to ensure that the changebars come out
%    correctly. However, a warning will be given if another pass is
%    required. 
%
%    \textbf{Features}
%    \begin{itemize}
%    \item Changebars may be nested within each other.  Each level of
%    nesting can be given a different thickness bar. 
%
%    \item Changebars may be nested in other environments including
%    floats and footnotes.
%
%    \item Changebars are applied to all the material within the
%    ``barred'' environment, including floating bodies regardless of
%    where the floats float to.  An exception to this is margin
%    floats.
%
%    \item Changebars may cross page boundaries.
%
%    \item Changebars can appear on the \emph{outside} of the columns
%    of \Lopt{twocolumn} text.
%
%    \item The colour of the changebars can be changed. This has sofar
%      been tested with the \Lopt{dvips} and \Lopt{vtex} drivers, but
%      it may also work with other PostScript based drivers. It will 
%      \emph{not} work for the \texttt{DVItoLN03} and em\TeX\ drivers.
%      For colored changebars to work, make sure that you specify the
%      option \Lopt{color}.
%    \end{itemize}
%
% \section{The user interface}
%
%    This package has options to specify some details of its
%    operation, and also defines several macros.
%
% \subsection{The package options}
% \subsubsection{Specifying the printer driver}
%
%    One set of package options\footnote{For older documents the
%    command \cs{driver} is available in the preamble of the document.
%    It takes the options as defined for \LaTeXe\ as argument.}
%    specify the driver that will be used to print the document can be
%    indicated. The driver may be one of: 
%    \begin{itemize}
%      \item DVItoLN03
%      \item DVItoPS
%      \item DVIps
%      \item em\TeX
%      \item \TeX tures
%      \item V\TeX
%    \end{itemize}
%    The drivers are represented in the normal typewriter method of
%    typing these names, or by the same entirely in lower case.
%    Since version 3.4d the driver can be specified in a configuration
%    file, not surprisingly called \file{changebar.cfg}. If it
%    contains the command |\ExecuteOption{textures}| the
%    \Lopt{textures} option will be used for all documents that are
%    processed while the configuration file is in \TeX's search path.
%
% \subsubsection{Specifying the bar position}
%    The position of the bars may either be on the inner edge of the
%    page (the left column on a recto or single-sided page, the right
%    column of a verso page) by use of the \Lopt{innerbars} package
%    option (the default), or on the outer edge of the page by use of
%    the \Lopt{outerbars} package option.
%
%    Another set of options gives the user the possibility of
%    specifying that the bars should \emph{always} come out on the
%    left side of the text (\Lopt{leftbars}) or on the right side of
%    the text (\Lopt{rightbars}). 
%
%    \emph{Note} that these options only work for \emph{onecolumn}
%    documents and will be ignored for a twocolumn document. 
%
% \subsubsection{Color}
%    For people who want their changebars to be colourfull the option
%    \Lopt{color} is available. It defines the user command
%    |\cbcolor| and loads the \pkg{color} package.
%
%    If a configuration file specifies the \Lopt{color} option and you
%    want to override it for a certain document you can use the
%    \Lopt{grey} option.
%
% \subsubsection{Tracing}
%    The package also implements tracing for its own debugging.  The
%    package options \Lopt{traceon} and \Lopt{traceoff} control
%    tracing. An additional option \Lopt{tracestacks} is available for
%    the die hard who wants to know what goes on in the internal stacks
%     maintained by this package.
%
% \subsection{Macros defined by the package}
%
% \DescribeMacro{\cbstart}
% \DescribeMacro{\cbend}
%    All material between the macros |\cbstart| and |\cbend| is
%    barred.  The nesting of multiple changebars is allowed.  The
%    macro |\cbstart| has an optional parameter that specifies the
%    width of the bar. The syntax is |\cbstart[|\meta{dimension}|]|.
%    If no width is specified, the current value of the parameter
%    |\changebarwidth| is used.  Note that |\cbstart| and |\cbend| can
%    be used anywhere but must be correctly nested with floats and
%    footnotes.  That is, one cannot have one end of the bar inside a
%    floating insertion and the other outside, but that would be a
%    meaningless thing to do anyhow.
%
% \DescribeEnv{changebar}
%    Apart from the macros |\cbstart| and |\cbend| a proper \LaTeX\
%    environment is defined. The advantage of using the environment
%    whenever possible is that \LaTeX\ will do all the work of
%    checking the correct nesting of different environments.
%
% \DescribeMacro{\cbdelete}
%    The macro |\cbdelete| puts a square bar in the margin to indicate
%    that some text was removed from the document. The macro has an
%    optional argument to specify the width of the bar. When no
%    argument is specified the current value of the parameter
%    |\deletebarwidth| will be used.
%
% \DescribeMacro{\nochangebars}
%    The macro |\nochangebars| disables the changebar commands.
%
% \DescribeMacro{\cbcolor}
%    This macro is defined when the \Lopt{color} option is
%    selected. It's syntax is the same as the |\color| command from
%    the \pkg{color} package.
%
% \subsection{Changebar parameters}
%
% \DescribeMacro{\changebarwidth}
%    The width of the changebars is controlled with the \LaTeX\ length
%    parameter |\changebarwidth|.
%    Its value can be changed with the |\setlength| command.
%    Changing the value of |\changebarwidth| affects all subsequent
%    changebars subject to the scoping rules of |\setlength|.
%
% \DescribeMacro{\deletebarwidth}
%    The width of the deletebars is controlled with the \LaTeX\ length
%    parameter |\deletebarwidth|.
%    Its value can be changed with the |\setlength| command.
%    Changing the value of |\deletebarwidth| affects all subsequent
%    deletebars subject to the scoping rules of |\setlength|.
%
% \DescribeMacro{\changebarsep}
%    The separation between the text and the changebars is determined
%    by the value of the \LaTeX\ length parameter |\changebarsep|.
%
% \DescribeVar{changebargrey}
%    When one of the supported dvi to PostScript translators is used
%    the `blackness' of the bars can be controlled. The \LaTeX\
%    counter \texttt{changebargrey} is used for this purpose. Its
%    value can be changed with a command like:
%    \begin{verbatim}
%    \setcounter{changebargrey}{85}
%    \end{verbatim}
%    The value of the counter is a percentage, where the value 0 yields
%    black bars, the value 100 yields white bars.
%
% \DescribeVar{outerbars}
%    The changebars will be printed in the `inside' margin of your
%    document.  This means they appear on the left side of the
%    page. When \Lopt{twoside} is in effect the bars will be printed
%    on the right side of even pages.  This behaviour can be changed
%    by including the command |\outerbarstrue| in your document.
%
%
% \section{Deficiencies and bugs}
%
% \begin{itemize}
% \item The macros blindly use special points |\cb@minpoint| through
%    |\cb@maxpoint|. If this conflicts with another set of macros, the
%    results will be unpredictable.  (What is really needed is a
%    |\newspecialpoint|, analogous to |\newcount| etc.~--- it's not
%    provided because the use of the points is rather rare.)
%
% \item There is a limit of 
%    $(\mbox{\texttt{\bslash cb@maxpoint}}-
%    \mbox{\texttt{\bslash cb@minpoint}}+1)/4$ bars per page
%    (four special points per bar).  Using more than this number yields
%    unpredictable results (but that could be called a feature for a
%    page with so many bars).  This limitation could be increased if
%    desired.
%
% \item Internal macro names are all of the form |\cb@xxxx|.  No
%    checking for conflicts with other macros is done.
%
% \item This implementation does not work with the
%    \texttt{multicolumn} package.
%
% \item The algorithms may fail if a floating insertion is split over
%    multiple pages.  In \LaTeX\ floats are not split but footnotes
%    may be.  The simplest fix to this is to prevent footnotes from
%    being split but this may make \TeX\ very unhappy.
%
% \item The |\cbend| normally gets ``attached'' to the token after it
%    rather than the one before it.  This may lead to a longer bar
%    than intended.  For example, consider the sequence `word1
%    |\cbend| word2'.  If there is a line break between `word1' and
%    `word2' the bar will incorrectly be extended an extra line.  This
%    particular case can be fixed with the incantation
%    `word1|\cbend{}| word2'.
%
% \item The colour support has only been tested with the \Lopt{dvips}
%    driver. 
%  \end{itemize}
%
% \section{The basic algorithm}
%
%    The changebars are implemented using the |\specials| of various
%    \texttt{dvi} interpreting programs like \texttt{DVItoLN03} or
%    \texttt{DVIps}.  In essence, the start of a changebar defines two
%    |\special| points in the margins at the current vertical position
%    on the page.  The end of a changebar defines another set of two
%    points and then joins (using the ``connect'' |\special|) either
%    the two points to the left or the two points to the right of the
%    text, depending on the setting of \Lopt{innerbars},
%    \Lopt{outerbars}, \Lopt{leftbars}, \Lopt{rightbars} and/or
%    \Lopt{twoside}. 
%
%    This works fine as long as the two points being connected lie on
%    the same page.  However, if they don't, the bar must be
%    artificially terminated at the page break and restarted at the
%    top of the next page.  The only way to do this (that I can think
%    of) is to modify the output routine so that it checks if any bar
%    is in progress when it ships out a page and, if so, adds the
%    necessary artificial end and begin.
%
%    The obvious way to indicate to the output routine that a bar is
%    in progress is to set a flag when the bar is begun and to unset
%    this flag when the bar is ended.  This works most of the time
%    but, because of the asynchronous behavior of the output routine,
%    errors occur if the bar begins or ends near a page break.  To
%    illustrate, consider the following scenario.
%
%    \begin{verbatim}
%    blah blah blah          % page n
%    blah blah blah
%    \cbstart                % this does its thing and set the flag
%    more blah
%               <-------------- pagebreak occurs here
%    more blah
%    \cbend                  % does its thing and unsets flag
%    blah blah
%    \end{verbatim}
%
%    Since \TeX\ processes ahead of the page break before invoking the
%    output routine, it is possible that the |\cbend| is
%    processed, and the flag unset, before the output routine is
%    called.  If this happens, special action is required to generate
%    an artificial end and begin to be added to page $n$ and $n+1$
%    respectively, as it is not possible to use a flag to signal
%    the output routine that a bar crosses a page break.
%
%    The method used by these macros is to create a stack of the
%    beginning and end points of each bar in the document together
%    with the page number corresponding to each point.  Then, as a
%    page is completed, a modified output routine checks the stack to
%    determine if any bars begun on or before the current page are
%    terminated on subsequent pages, and handles those bars
%    appropriately.  To build the stack, information about each
%    changebar is written to the \file{.aux} file as bars are processed.
%    This information is re-read when the document is next processed.
%    Thus, to ensure that changebars are correct, the document must
%    be processed twice.  Luckily, this is generally required for
%    \LaTeX\ anyway.
%
%    This approach is sufficiently general to allow nested bars, bars
%    in floating insertions, and bars around floating insertions.
%    Bars inside floats and footnotes are handled in the same way as
%    bars in regular text.  Bars that encompass floats or footnotes
%    are handled by creating an additional bar that floats with the
%    floating material.  Modifications to the appropriate \LaTeX\
%    macros check for this condition and add the extra bar.
%
%\StopEventually{
% \IndexPrologue{\section*{Index}%
%  \markboth{Index}{Index}%
%     Numbers in \emph{italics} indicate the page where the
%     macro is described, the underlined numbers indicate
%     the number of the line of code where the macro is defined,
%     all other numbers indicate where a macro is used.}
%
% \GlossaryPrologue{\section*{History of changes}%
%    \markboth{History of changes}{History of changes}%
%    The numbers behind the changes indicate the page where
%    the macrocode is described.\hfil\null}
%
%  \PrintIndex
%^^AA \PrintChanges
% }
% \section{The implementation}
%
% \subsection{Declarations And Initializations}
%
% \begin{macro}{\cb@maxpoint}
%    The original version of \texttt{changebar.sty} only supported the
%    \texttt{DVItoLN03} specials. The \texttt{LN03} printer has a
%    maximum number of points that can be defined on a page. Also for
%    some PostScript printers the number of points that can be defined
%    can be limited by the amount of memory used. Therefore, the
%    consecutive numbering of points has to be reset when the maximum
%    is reached. This maximum can be adapted to the printers needs.
%    \begin{macrocode}
%<*package>
\def\cb@maxpoint{80}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@minpoint}
%    When resetting the point number we need to know what to reset it
%    to, this is minimum number is stored in |\cb@minpoint|.
%    \textbf{This number has to be \emph{odd}} because the algorithm
%    that decides whether a bar has to be continued on the next page
%    depends on this.
%    \begin{macrocode}
\def\cb@minpoint{1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@nil}
%    Sometimes a void value for a point has to be returned by one
%    of the macros. For this purpose |\cb@nil| is used.
%    \begin{macrocode}
\def\cb@nil{0}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@nextpoint}
%    The number of the next special point is stored in the count
%    register |\cb@nextpoint| and initially equal to
%    |\cb@minpoint|.
%    \begin{macrocode}
\newcount\cb@nextpoint
\cb@nextpoint=\cb@minpoint
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\cb@topleft}
% \changes{v3.3a}{1997/09/26}{Renamed \cs{cb@currentpoint} to
%    \cs{cb@topleft}}
%  \begin{macro}{\cb@topright}
% \changes{v3.3a}{1997/09/26}{New counter}
%  \begin{macro}{\cb@botleft}
% \changes{v3.3a}{1997/09/26}{New counter}
%  \begin{macro}{\cb@botright}
% \changes{v3.3a}{1997/09/26}{New counter}
%    These four counters are used to identify the four special points
%    that specify a changebar. The point defined by |\cb@topleft| is
%    the one used to identify the changebar; the values of the other
%    points are derived from it.
%    \begin{macrocode}
\newcount\cb@topleft
\newcount\cb@topright
\newcount\cb@botleft
\newcount\cb@botright
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\cb@cnta}
% \changes{v3.4f}{2003/10/18}{New temporary storage counter, replaces
%    the use of \cs{@tempcnta}}
%  \begin{macro}{\cb@cntb}
% \changes{v3.4f}{2003/10/18}{New temporary storage counter, replaces
%    the use of \cs{@tempcntb}}
%  \begin{macro}{\cb@dima}
% \changes{v3.4f}{2003/10/18}{New temporary storage dimension}
%    Sometimes we need temporarily store a value. For this purpose two
%    count registers and a dimension register are allocated.
%    \begin{macrocode}
\newcount\cb@cnta
\newcount\cb@cntb
\newdimen\cb@dima
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\cb@curbarwd}
% \changes{v3.3a}{1997/09/26}{Introduced \cs{curbarwd} to eliminate
%    the use of \cs{@tempdima}} 
%    The dimension register |\cb@curbarwd| is used to store the width of
%    the current bar.
%    \begin{macrocode}
\newdimen\cb@curbarwd
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\cb@page}
% \begin{macro}{\cb@pagecount}
%    The macros need to keep track of the number of pages output so
%    far.  To this end the counter |\cb@pagecount| is used.  When a
%    pagenumber is read from the history stack, it is stored in the
%    counter |\cb@page|. The counter |\cb@pagecount| is initially $0$;
%    it gets incremented during the call to |\@makebox| (see
%    section~\ref{pagebreak}).
%    \begin{macrocode}
\newcount\cb@page
\newcount\cb@pagecount
\cb@pagecount=0
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{Var}{outerbars}
%    A switch is provided to control where the changebars will be
%    printed.
%    \begin{macrocode}
\newif\ifouterbars
%    \end{macrocode}
% \end{Var}
%
%  \begin{Var}{@cb@trace}
%    A switch to enable tracing of the actions of this package
%    \begin{macrocode}
\newif\if@cb@trace
%    \end{macrocode}
%  \end{Var}
%
% \begin{macro}{\cb@positions}
%
%    This macro calculates the (horizontal) positions of the
%    changebars.  
%
%  \begin{macro}{\cb@odd@left}
% \changes{v3.3a}{1997/09/26}{Renamed from \cs{b@odd}}
%  \begin{macro}{\cb@odd@right}
% \changes{v3.3a}{1997/09/26}{New dimension register}
%  \begin{macro}{\cb@even@left}
% \changes{v3.3a}{1997/09/26}{Renamed from \cs{b@even}}
%  \begin{macro}{\cb@even@right}
% \changes{v3.3a}{1997/09/26}{New dimension register}
%    Because the margins can differ for even and odd pages and because
%    changebars are sometimes on different sides of the paper we need
%    four dimensions to store the result.
%
%    \begin{macrocode}
\newdimen\cb@odd@left
\newdimen\cb@odd@right
\newdimen\cb@even@left
\newdimen\cb@even@right
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    Since the changebars are drawn with the \textsc{PostScript}
%    command \texttt{lineto} and not as \TeX{}-like rules the
%    reference points lie on the center of the changebar, therefore
%    the calculation has to add or subtract half of the width of the
%    bar to keep |\changebarsep| whitespace between the bar and the
%    body text.
%
%    First the position for odd pages is calculated. I
% \changes{v3.1}{1993/07/02}{Corrected positioning of PostScript bars}
% \changes{v3.3a}{1997/09/26}{calculate horizontal positions
%    independent of options used}
% \changes{v3.3d}{1997/10/28}{Removed bogus offset}
% \changes{v3.3g}{1999/06/11}{Don't use \cs{evensidemargin} when
%    \Lopt{twoside} is \emph{not} in effect}
%    \begin{macrocode}
\def\cb@positions{%
  \global\cb@odd@left=\hoffset
  \global\cb@even@left\cb@odd@left
  \global\advance\cb@odd@left by \oddsidemargin
  \global\cb@odd@right\cb@odd@left
  \global\advance\cb@odd@right by \textwidth
  \global\advance\cb@odd@right by \changebarsep
  \global\advance\cb@odd@right by 0.5\changebarwidth
  \global\advance\cb@odd@left by -\changebarsep
  \global\advance\cb@odd@left by -0.5\changebarwidth
%    \end{macrocode}
%    On even sided pages we need to use |\evensidemargin| in the
%    calculations when \Lopt{twoside} is in effect. 
%    \begin{macrocode}
  \if@twoside
    \global\advance\cb@even@left by \evensidemargin
    \global\cb@even@right\cb@even@left
    \global\advance\cb@even@left by -\changebarsep
    \global\advance\cb@even@left by -0.5\changebarwidth
    \global\advance\cb@even@right by \textwidth
    \global\advance\cb@even@right by \changebarsep
    \global\advance\cb@even@right by 0.5\changebarwidth
  \else
%    \end{macrocode}
%    Otherwise just copy the result for odd pages.
%    \begin{macrocode}
    \global\let\cb@even@left\cb@odd@left
    \global\let\cb@even@right\cb@odd@right
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@removedim}
%    In PostScript code, length specifications are without dimensions.
%    Therefore we need a way to remove the letters `pt' from the
%    result of the operation |\the\|\meta{dimen}.
%    This can be done by defining a command that has a delimited
%    argument like:
%    \begin{verbatim}
%    \def\cb@removedim#1pt{#1}
%    \end{verbatim}
%    We encounter one problem though, the category code of the letters
%    `pt' is 12 when produced as the output from |\the\|\meta{dimen}.
%    Thus the characters that delimit the argument of |\cb@removedim|
%    also have to have category code 12. To keep the changes local
%    the macro |\cb@removedim| is defined in a group.
%    \begin{macrocode}
{\catcode`\p=12\catcode`\t=12 \gdef\cb@removedim#1pt{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Option Processing}
%
%    The user should select the specials that should be used by
%    specifying the driver name as an option to the
%    |\usepackage| call.
%    Possible choices are:
%    \begin{itemize}
%    \item DVItoLN03
%    \item DVItoPS
%    \item DVIps
%    \item em\TeX
%    \item Textures
%    \item V\TeX
%    \end{itemize}
%
%    The intent is that the driver names should be case-insensitive,
%    but the following code doesn't achieve this: it only permits the
%    forms given above and their lower-case equivalents.
% \changes{v3.3e}{1998/02/24}{Added the option \Lopt{textures}}
% \changes{v3.4a}{2001/04/18}{Added the option \Lopt{VTeX}}
%    \begin{macrocode}
\DeclareOption{DVItoLN03}{\global\chardef\cb@driver@setup=0\relax}
\DeclareOption{dvitoln03}{\global\chardef\cb@driver@setup=0\relax}
\DeclareOption{DVItoPS}{\global\chardef\cb@driver@setup=1\relax}
\DeclareOption{dvitops}{\global\chardef\cb@driver@setup=1\relax}
\DeclareOption{DVIps}{\global\chardef\cb@driver@setup=2\relax}
\DeclareOption{dvips}{\global\chardef\cb@driver@setup=2\relax}
\DeclareOption{emTeX}{\global\chardef\cb@driver@setup=3\relax}
\DeclareOption{emtex}{\global\chardef\cb@driver@setup=3\relax}
\DeclareOption{textures}{\global\chardef\cb@driver@setup=4\relax}
\DeclareOption{Textures}{\global\chardef\cb@driver@setup=4\relax}
\DeclareOption{VTeX}{\global\chardef\cb@driver@setup=5\relax}
\DeclareOption{vtex}{\global\chardef\cb@driver@setup=5\relax}
%    \end{macrocode}
%
%    The new features of \LaTeXe\ make it possible to implement the
%    \Lopt{outerbars} option.
%
%    \begin{macrocode}
\DeclareOption{outerbars}{\outerbarstrue}
\DeclareOption{innerbars}{\outerbarsfalse}
%    \end{macrocode}
%
%    It is also possible to specify that the change bars should
%    \emph{always} be printed on either the left or the right side of
%    the text. For this we have the options \Lopt{leftbars} and
%    \Lopt{rightbars}. Specifying \emph{either} of these options will
%    overrule a possible \Lopt{twoside} option at the document level.
% \changes{v3.2b}{1995/06/27}{Added the options\Lopt{leftbars} and
%    \Lopt{rightbars}}
% \changes{v3.3d}{1997/10/28}{Removed bogus offset}
% \changes{v3.3g}{1999/06/11}{take the setting of \Lopt{twoside} into
%    account}
%    \begin{macrocode}
\DeclareOption{leftbars}{%
  \def\cb@positions{%
    \global\cb@odd@left=\hoffset
    \global\cb@even@left\cb@odd@left
    \global\advance\cb@odd@left by \oddsidemargin
    \global\advance\cb@odd@left by -\changebarsep
    \global\advance\cb@odd@left by -0.5\changebarwidth
    \if@twoside
      \global\advance\cb@even@left by \evensidemargin
      \global\advance\cb@even@left by -\changebarsep
      \global\advance\cb@even@left by -0.5\changebarwidth
    \else
      \global\let\cb@even@left\cb@odd@left
    \fi
    \global\let\cb@odd@right\cb@odd@left
    \global\let\cb@even@right\cb@even@left
    }}
\DeclareOption{rightbars}{%
  \def\cb@positions{%
    \global\cb@odd@right=\hoffset
    \global\cb@even@right\cb@odd@right
    \global\advance\cb@odd@right by \oddsidemargin
    \global\advance\cb@odd@right by \textwidth
    \global\advance\cb@odd@right by \changebarsep
    \global\advance\cb@odd@right by 0.5\changebarwidth
    \if@twoside
      \global\advance\cb@even@right by \evensidemargin
      \global\advance\cb@even@right by \textwidth
      \global\advance\cb@even@right by \changebarsep
      \global\advance\cb@even@right by 0.5\changebarwidth
    \else
%    \end{macrocode}
% \changes{v3.3j}{2000/09/26}{\cs{cb@even@right} erroneously wasn't
%    set in the oneside mode with option rightbars}
%    \begin{macrocode}
      \global\let\cb@even@right\cb@odd@right
    \fi
    \global\let\cb@odd@left\cb@odd@right
    \global\let\cb@even@left\cb@even@right
    }}
%    \end{macrocode}
%    A set of options to control tracing.
% \changes{v3.4b}{2001/08/27}{Added tracing of push and pop
%    operations}
%    \begin{macrocode}
\DeclareOption{traceon}{\@cb@tracetrue}
\DeclareOption{traceoff}{\@cb@tracefalse}
\DeclareOption{tracestacks}{%
  \let\cb@trace@stack\cb@@show@stack
  \def\cb@trace@push#1{\cb@trace{%
      Pushed point \the\cb@topleft\space on \noexpand#1: #1}}%
  \def\cb@trace@pop#1{\cb@trace{%
      Popped point \the\cb@topleft\space from \noexpand#1: #1}}%
  }
%    \end{macrocode}
%    Two options are introduced for colour support. The first one,
%    \Lopt{grey}, is activated by default.
% \changes{v3.4b}{2001/08/28}{Added options \Lopt{grey} and
%    \Lopt{color}}
%    \begin{macrocode}
\DeclareOption{grey}{%
  \def\cb@ps@color{\thechangebargrey\space 100 div setgray}}
\DeclareOption{color}{%
  \def\cb@ps@color{\expandafter\c@lor@to@ps\cb@current@color\@@}}
%    \end{macrocode}
%
%    Signal an error if an unknown option was specified.
%    \begin{macrocode}
\DeclareOption*{\OptionNotUsed\PackageError
      {changebar}%
      {Unrecognised option `\CurrentOption'\MessageBreak
        known options are dvitoln03, dvitops, dvips,\MessageBreak
        emtex, textures and vtex, 
        grey, color,\MessageBreak
        outerbars, innerbars, leftbars and rightbars}}
%    \end{macrocode}
%
%    The default is to have grey change bars on the left side of the
%    text on odd pages. When V\TeX\ is used the option \Lopt{dvips} is
%    not the right one, so in that case we have \Lopt{vtex} as the
%    default driver.
% \changes{v3.2c}{1996/03/26}{Added `dvips' to the list of default
%    options} 
% \changes{v3.4b}{2001/08/28}{Added `grey' to the list of default
%    options}
% \changes{v3.4d}{2001/09/04}{Added detection of V\TeX}
%    \begin{macrocode}
\ifx\VTeXversion\undefined
  \ExecuteOptions{innerbars,traceoff,dvips,grey}
\else
  \ExecuteOptions{innerbars,traceoff,vtex,grey}
\fi
%    \end{macrocode}
%
%    A local configuration file may be used to define a site wide
%    default for the driver, by calling |\ExecuteOptions| with the
%    appropriate option. This will override the default specified
%    above.
% \changes{v3.4d}{2001/09/04}{Added the possibility of loading a
%    configuration file}
%    \begin{macrocode}
\InputIfFileExists{changebar.cfg}{}{}
%    \end{macrocode}
%
%  \begin{macro}{\cb@@show@stack}
% \changes{v3.3g}{1999/06/11}{Macro added}
%    When the stack tracing facility is turned on this command is
%    executed. It needs to be defined \emph{before} we call
%    |\ProcessOptions|. This command shows the contents of the stack
%    with currently `open' bars, the stack with pending ends and the
%    history stack. It does \emph{not} show the temporary stack.
% \changes{v3.3h}{1999/06/15}{Added the historystack to the stack
%    tracing}
%    \begin{macrocode}
\def\cb@@show@stack#1{%
  \cb@trace{%
    stack status at #1:\MessageBreak
    current stack: \cb@currentstack\MessageBreak
    \@spaces end stack: \cb@endstack\MessageBreak
    \space\space begin stack: \cb@beginstack\MessageBreak
    history stack: \cb@historystack 
    }}
%    \end{macrocode}
%    The default is to \emph{not} trace the stacks. This is acheived by
%    |\let|ting |\cb@trace@stack| to |\@gobble|.
%    \begin{macrocode}
\let\cb@trace@stack\@gobble
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\cb@trace@push}
%  \begin{macro}{\cb@trace@pop}
% \changes{v3.4b}{2001/08/27}{Added macros for tracing stack push and
%    pop operations} 
%    When stack tracing is turned on, these macros are used to display
%    the push and pop operations that go on. They are defined when the 
%    package option \Lopt{tracestacks} is selected.
%
%    The default is to \emph{not} trace the stacks. 
%    \begin{macrocode}
\let\cb@trace@push\@gobble
\let\cb@trace@pop\@gobble
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%    \begin{macrocode}
\ProcessOptions\relax
%    \end{macrocode}
%
%  \begin{macro}{\cb@trace}
%    A macro that formats the tracing messages.
% \changes{v3.3g}{1999/06/11}{removed line number from tracing
%    messages}
%    \begin{macrocode}
\newcommand{\cb@trace}[1]{%
  \if@cb@trace
    \GenericWarning
      {(changebar)\@spaces\@spaces}%
      {Package changebar: #1\@gobble}%
  \fi
  }
%    \end{macrocode}
%  \end{macro}
%
% \subsection{User Level Commands And Parameters}
%
% \begin{macro}{\driver}
%    The user can select the specials that should be used by calling
%    the command |\driver{|\meta{drivername}|}|.
%    Possible choices are:
%    \begin{itemize}
%    \item DVItoLN03
%    \item DVItoPS
%    \item DVIps
%    \item em\TeX
%    \item \TeX tures
%    \item V\TeX
%    \end{itemize}
%    This command can only be used in the preamble of the document.
%
%    The argument should be case-insensitive, so it is turned into
%    a string containing all uppercase characters. To keep some definitions
%    local, everything is done within a group.
% \changes{v3.1}{1993/07/02}{Removed some spurious spaces}
% \changes{v3.2c}{1996/03/26}{Reintroduced \cs{driver} in
%    compatibility mode} 
% \changes{v3.3e}{1998/02/24}{Added \cs{Textures}}
%    \begin{macrocode}
\if@compatibility
  \def\driver#1{%
    \bgroup\edef\next{\def\noexpand\tempa{#1}}%
      \uppercase\expandafter{\next}%
      \def\LN{DVITOLN03}%
      \def\DVItoPS{DVITOPS}%
      \def\DVIPS{DVIPS}%
      \def\emTeX{EMTEX}%
      \def\Textures{TEXTURES}%
      \def\VTeX{VTEX}%
%    \end{macrocode}
%    The choice has to be communicated to the macro
%    \verb=\cb@setup@specials= that will be called from within
%    \verb=\document=. For this purpose the control sequence
%    \verb=\cb@driver@setup= is used. It receives a numeric value
%    using \verb=\chardef=. 
%    \begin{macrocode}
      \global\chardef\cb@driver@setup=0\relax
      \ifx\tempa\LN       \global\chardef\cb@driver@setup=0\fi
      \ifx\tempa\DVItoPS  \global\chardef\cb@driver@setup=1\fi
      \ifx\tempa\DVIPS    \global\chardef\cb@driver@setup=2\fi
      \ifx\tempa\emTeX    \global\chardef\cb@driver@setup=3\fi
      \ifx\tempa\Textures \global\chardef\cb@driver@setup=4\fi
      \ifx\tempa\VTeX     \global\chardef\cb@driver@setup=5\fi
    \egroup}
%    \end{macrocode}
%    We add \verb+\driver+ to \verb+\@preamblecmds+, which is a
%    list of commands to be used only in the preamble of a document.
%    \begin{macrocode}
  {\def\do{\noexpand\do\noexpand}
    \xdef\@preamblecmds{\@preamblecmds \do\driver}
    }
\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@setup@specials}
%    The macro |\cb@setup@specials| defines macros containing the
%    driver specific |\special| macros. It will be called from
%    within the |\begin{document}| command.
%
%  \begin{macro}{\cb@trace@defpoint}
%    When tracing is on, write information about the point being defined
%    to the log file.
% \changes{v3.3a}{1997/09/26}{use \cs{cb@trace} instead of \cs{wlog}}
%    \begin{macrocode}
\def\cb@trace@defpoint#1#2{%
  \cb@trace{%
    defining point \the#1 at position \the#2
    \MessageBreak
    cb@pagecount: \the\cb@pagecount; page \thepage}}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\cb@trace@connect}
%    When tracing is on, write information about the points being
%    connected to the log file.
% \changes{v3.3a}{1997/09/26}{use \cs{cb@trace} instead of \cs{wlog}}
%    \begin{macrocode}
\def\cb@trace@connect#1#2#3{%
  \cb@trace{%
    connecting points \the#1 and \the#2; barwidth: \the#3
    \MessageBreak
    cb@pagecount: \the\cb@pagecount; page \thepage}}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\cb@defpoint}
%    The macro |\cb@defpoint| is used to define one of the two
%    points of a bar. It has two arguments, the number of the point
%    and the distance from the left side of the paper. Its syntax
%    is:
%    |\cb@defpoint{|\meta{number}|}{|\meta{length}|}|.
% \begin{macro}{\cb@resetpoints}
%    The macro |\cb@resetpoints| can be used to instruct the printer
%    driver that it should send a corresponding instruction to the
%    printer. This is really only used for the \textsf{LN03} printer.
%
% \begin{macro}{\cb@connect}
%    The macro |\cb@connect| is used to instruct the printer driver
%    to connect two points with a bar. The syntax is
%    |\cb@connect{|\meta{number}|}{|\meta{number}|}{|\meta{length}|}|
%    The two \meta{number}s indicate the two points to be connected;
%    the \meta{length} is the width of the bar.
%
%    \begin{macrocode}
\def\cb@setup@specials{%
%    \end{macrocode}
%    The control sequence |\cb@driver@setup| expands to a number which
%    indicates the driver that will be used.  The original
%    \file{changebar.sty} was written with only the |\special|
%    syntax of the program \texttt{DVItoLN03} (actually one of its
%    predecessors, \texttt{ln03dvi}). Therefore this syntax is defined
%    first.
%    \begin{macrocode}
\ifcase\cb@driver@setup
  \def\cb@defpoint##1##2{%
    \special{ln03:defpoint \the##1(\the##2,)}%
    \cb@trace@defpoint##1##2}
  \def\cb@connect##1##2##3{%
    \special{ln03:connect \the##1\space\space \the##2\space \the##3}%
    \cb@trace@connect##1##2##3}
  \def\cb@resetpoints{%
    \special{ln03:resetpoints \cb@minpoint \space\cb@maxpoint}}
%    \end{macrocode}
%    The first extension to the {changebar} option was for the
%    |\special| syntax of the program \texttt{DVItoPS} by James Clark.
%    \begin{macrocode}
\or
  \def\cb@defpoint##1##2{%
    \special{dvitops: inline
                \expandafter\cb@removedim\the##2\space 6.5536 mul\space
                /CBarX\the##1\space exch def currentpoint exch pop
                /CBarY\the##1\space exch def}%
    \cb@trace@defpoint##1##2}
%    \end{macrocode}
% \changes{v3.4b}{2001/08/29}{now use \cs{cb@ps@color} instead of
%    setting the greyness directly}
%    \begin{macrocode}
  \def\cb@connect##1##2##3{%
    \special{dvitops: inline
                gsave \cb@ps@color\space
                \expandafter\cb@removedim\the##3\space 6.5536 mul\space
                CBarX\the##1\space\space CBarY\the##1\space\space moveto
                CBarX\the##2\space\space CBarY\the##2\space\space lineto
                stroke grestore}%
    \cb@trace@connect##1##2##3}
  \let\cb@resetpoints\relax
%    \end{macrocode}
%    The program \texttt{DVIps} by Thomas Rokicki is also
%    supported. The PostScript code is nearly the same as for
%    \texttt{DVItoPS}, but the coordinate space has a different
%    dimension. Also this code has been made resolution independent,
%    whereas the code for \texttt{DVItoPS} might still be resolution
%    dependent.
%
%    So far all the positions have been calculated in \texttt{pt}
%    units.  DVIps uses pixels internally, so we have to convert
%    \texttt{pt}s into pixels which of course is done by dividing by
%    72.27 (\texttt{pt}s per inch) and multiplying by
%    \texttt{Resolution} giving the resolution of the
%    \textsc{PostScript} device in use as a \textsc{PostScript}
%    variable.
%    \begin{macrocode}
\or
  \def\cb@defpoint##1##2{%
     \special{ps:
                \expandafter\cb@removedim\the##2\space
                Resolution\space mul\space 72.27\space div\space
                /CBarX\the##1\space exch def currentpoint exch pop
                /CBarY\the##1\space exch def}%
    \cb@trace@defpoint##1##2}
%    \end{macrocode}
% \changes{v3.4b}{2001/08/29}{now use \cs{cb@ps@color} instead of
%    setting the greyness directly}
%    \begin{macrocode}
  \def\cb@connect##1##2##3{%
    \special{ps:
                gsave \cb@ps@color\space
                \expandafter\cb@removedim\the##3\space
                Resolution\space mul\space 72.27\space div\space
                setlinewidth
                CBarX\the##1\space\space CBarY\the##1\space\space moveto
                CBarX\the##2\space\space CBarY\the##2\space\space lineto
                stroke grestore}%
    \cb@trace@connect##1##2##3}
  \let\cb@resetpoints\relax
%    \end{macrocode}
%    The latest addition is for the drivers written by Eberhard
%    Mattes.  The |\special| syntax used here is supported since
%    version 1.5 of his driver programs.
% \changes{v3.3a}{1997/09/24}{Removed warning about emTeX support from
%    dvidrv 1.5 upwards}  
% \changes{v3.3b}{1997/10/01}{em\TeX{} drivers have their origin in a
%    different position then dvips} 
% \changes{v3.3d}{1997/10/28}{Removed bogus offset}
%    \begin{macrocode}
\or
  \def\cb@defpoint##1##2{%
    \special{em:point \the##1,\the##2}%
    \cb@trace@defpoint##1##2}
  \def\cb@connect##1##2##3{%
    \special{em:line \the##1,\the##2,\the##3}%
    \cb@trace@connect##1##2##3}
  \let\cb@resetpoints\relax
%    \end{macrocode}
%
%    The following definitions are validated with \TeX tures
%    version~1.7.7, but will very likely also work with later
%    releases of \TeX tures. 
%
%    The \cs{cbdelete} command seemed to create degenerate lines
%    (i.e., lines of 0 length). PostScript will not render such lines
%    unless the linecap is set to 1, (semicircular ends) in which case
%    a filled circle is shown for such lines.
% \changes{v3.3e}{1998/02/24}{Added the definitions for textures
%    support}
%    \begin{macrocode}
\or
  \def\cb@defpoint##1##2{%
    \special{rawpostscript
                \expandafter\cb@removedim\the##2\space
                /CBarX\the##1\space exch def currentpoint exch pop
                /CBarY\the##1\space exch def}%
    \if@cb@trace\cb@trace@defpoint##1##2\fi}
%    \end{macrocode}
% \changes{v3.4b}{2001/08/29}{now use \cs{cb@ps@color} instead of
%    setting the greyness directly}
%    \begin{macrocode}
  \def\cb@connect##1##2##3{%
    \special{rawpostscript
                gsave 1 setlinecap \cb@ps@color\space
                \expandafter\cb@removedim\the##3\space
                setlinewidth
                CBarX\the##1\space\space CBarY\the##1\space\space moveto
                CBarX\the##2\space\space CBarY\the##2\space\space lineto
                stroke grestore}%
    \if@cb@trace\cb@trace@connect##1##2##3\fi}
  \let\cb@resetpoints\relax
%    \end{macrocode}
%    The following definitions were kindly provided by Michael Vulis.
% \changes{v3.4a}{2001/04/18}{Added the definitions for V\TeX\
%    support}
%    \begin{macrocode}
\or
  \def\cb@defpoint##1##2{%
    \special{pS:
                \expandafter\cb@removedim\the##2\space
                Resolution\space mul\space 72.27\space div\space
                /CBarX\the##1\space exch def currentpoint exch pop
                /CBarY\the##1\space exch def}%
    \cb@trace@defpoint##1##2}
%    \end{macrocode}
% \changes{v3.4b}{2001/08/29}{now use \cs{cb@ps@color} instead of
%    setting the greyness directly}
%    \begin{macrocode}
  \def\cb@connect##1##2##3{%
    \special{pS:
                gsave \cb@ps@color\space
                \expandafter\cb@removedim\the##3\space
                Resolution\space mul\space 72.27\space div\space
                setlinewidth
                CBarX\the##1\space\space CBarY\the##1\space\space moveto
                CBarX\the##2\space\space CBarY\the##2\space\space lineto
                stroke grestore}%
    \cb@trace@connect##1##2##3}
  \let\cb@resetpoints\relax
%    \end{macrocode}
%    When code for other drivers should be added it can be inserted
%    here.  When someone makes a mistake and somehow selects an
%    unknown driver a warning is issued and the macros are defined to
%    be no-ops.
%    \begin{macrocode}
\or
\else
  \PackageWarning{Changebar}{changebars not supported in unknown setup}
  \def\cb@defpoint##1##2{\cb@trace@defpoint##1##2}
  \def\cb@connect##1##2##3{\cb@trace@connect##1##2##3}
  \let\cb@resetpoints\relax
\fi
%    \end{macrocode}
%    The last thing to do is to forget about |\cb@setup@specials|.
%    \begin{macrocode}
\global\let\cb@setup@specials\relax}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\cbstart}
%    The macro |\cbstart| starts a new changebar. It has an (optional)
%    argument that will be used to determine the width of the bar.
%    The default width is |\changebarwidth|.
% \changes{v3.3i}{1999/06/19}{Use \LaTeX's own mechanism to detect
%    grouping errors.}
% \changes{v3.4e}{2002/10/28}{Reverted the change from version 3.3i} 
%    \begin{macrocode}
\newcommand*{\cbstart}{\@ifnextchar [%]
                        {\cb@start}%
                        {\cb@start[\changebarwidth]}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cbend}
%    The macro |\cbend| (surprisingly) ends a changebar. The macros
%    |\cbstart| and |\cbend| can be used when the use of a
%    proper \LaTeX\ environment is not possible.
%    \begin{macrocode}
\newcommand*{\cbend}{\cb@end}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cbdelete}
%    The macro |\cbdelete| inserts a `deletebar' in the margin.
%    It too has an optional argument to determine the width of the bar.
%    The default width (and length) of it are stored in
%    |\deletebarwidth|.
%    \begin{macrocode}
\newcommand*{\cbdelete}{\@ifnextchar [%]
  {\cb@delete}%
  {\cb@delete[\deletebarwidth]}}
%    \end{macrocode}
%
% \begin{macro}{\cb@delete}
%    Deletebars are implemented as a special `change bar'. The bar
%    is started and immediately ended. It is as long as it is wide.
%    \begin{macrocode}
\def\cb@delete[#1]{\vbox to \z@{\vss\cb@start[#1]\vskip #1\cb@end}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\changebar}
% \begin{macro}{\endchangebar}
%    The macros |\changebar| and |\endchangebar| have the same
%    function as |\cbstart| and |\cbend| but they can be used as a
%    \LaTeX\ environment to enforce correct nesting.  They can
%    \emph{not} be used in the \textsf{tabular} and \textsf{tabbing}
%    environments.
%    \begin{macrocode}
\newenvironment{changebar}%
               {\@ifnextchar [{\cb@start}%
                              {\cb@start[\changebarwidth]}}%
               {\cb@end}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\nochangebars}
%    To disable changebars altogether without having to remove them
%    from the document the macro |\nochangebars| is provided. It makes
%    no-ops of three internal macros.
%    \begin{macrocode}
\newcommand*{\nochangebars}{%
  \def\cb@start[##1]{}%
  \def\cb@delete[##1]{}%
  \let\cb@end\relax}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\changebarwidth}
%    The default width of the changebars is stored in the dimension
%    register |\changebarwidth|.
%    \begin{macrocode}
\newlength{\changebarwidth}
\setlength{\changebarwidth}{2pt}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\deletebarwidth}
%    The default width of the deletebars is stored in the dimension
%    register |\deletebarwidth|.
%    \begin{macrocode}
\newlength{\deletebarwidth}
\setlength{\deletebarwidth}{4pt}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\changebarsep}
%    The default separation between all bars and the text is stored in
%    the dimen register |\changebarsep|.
%    \begin{macrocode}
\newlength{\changebarsep}
\setlength{\changebarsep}{30pt}
%    \end{macrocode}
% \end{macro}
%
% \begin{Var}{changebargrey}
%    When the document is printed using one of the PostScript drivers
%    the bars do not need to be black; with PostScript it is possible
%    to have grey, and colored, bars. The percentage of greyness of the
%    bar is stored in the count register |\changebargrey|. It can
%    have values between $0$ (meaning white) and $100$ (meaning
%    black).
%
%    \begin{macrocode}
\newcounter{changebargrey}
\setcounter{changebargrey}{65}
%    \end{macrocode}
% \end{Var}
%
%    When the option \Lopt{color} was selected we need to load the
%    \pkg{color} package. When we're run by pdf\LaTeX\ we need to pass
%    that information on to the \pkg{color} package.
% \changes{v3.4e}{2001/09/14}{Detect pdf mode}
%    \begin{macrocode}
\@ifpackagewith{changebar}{color}{%
  \ifx\pdfoutput\undefined
    \RequirePackage[dvipsnames]{color}%
  \else
    \RequirePackage[pdftex,dvipsnames]{color}%
  \fi
%    \end{macrocode}
%    Then we need to define the command |\cbcolor| which is a slightly
%    modified copy of the command |\color| from the \pkg{color}
%    package.
%
% \begin{macro}{\cbcolor}
%    |\cbcolor{|\emph{declared-colour}|}| switches the colour of the
%    changebars to \emph{declared-colour}, which must previously have
%    been defined using |\definecolor|. This colour will stay in
%    effect until the end of the current \TeX\ group.
%
%    |\cbcolor[|\emph{model}|]{|\emph{colour-specification}|}| is
%    similar to the above, but uses a colour not declared by
%    |\definecolor|. The allowed \emph{model}'s vary depending on the
%    driver. The syntax of the \emph{colour-specification} argument
%    depends on the model.
%    \begin{macrocode}
  \DeclareRobustCommand\cbcolor{%
    \@ifnextchar[\@undeclaredcbcolor\@declaredcbcolor}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@undeclaredcbcolor}
%    Call the driver-dependent command |\color@|\meta{model} to define
%    |\cb@current@color|.
%    \begin{macrocode}
  \def\@undeclaredcbcolor[#1]#2{%
    \@ifundefined{color@#1}%
      {\c@lor@error{model `#1'}}%
      {\csname color@#1\endcsname\cb@current@color{#2}}%
    \ignorespaces}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\@declaredcbcolor}
%    \begin{macrocode}
  \def\@declaredcbcolor#1{%
    \@ifundefined{\string\color @#1}%
      {\c@lor@error{`#1'}}%
      {\expandafter\let\expandafter\cb@current@color
        \csname\string\color @#1\endcsname}%
    \ignorespaces}%
  }{%
%    \end{macrocode}
%    When the \Lopt{color} option wasn't specified the usage of the
%    |\cbcolor| command results in a warning message.
% \changes{v3.4d}{2001/09/04}{Isue an error when \cmd{cbcolor} is
%    used without specifying the \Lopt{color} option}
% \changes{v3.4e}{2001/09/07}{Made the error message a warning message}
%    \begin{macrocode}
  \def\cbcolor{\@ifnextchar[%]
    \@@cbcolor\@cbcolor}%
  \def\@@cbcolor[#1]#2{\cb@colwarn\def\@@cbcolor[##1]##2{}}%
  \def\@cbcolor#1{\cb@colwarn\def\@cbcolor##1{}}%
  \def\cb@colwarn{\PackageWarning{Changebar}%
    {You didn't specify the option `color';\MessageBreak
      your command \string\cbcolor\space will be ignored}}%
  }
%    \end{macrocode}
%  \end{macro}
%
% \subsection{Macros for beginning and ending bars}
%
% \begin{macro}{\cb@start}
%    This macro starts a change bar.  It assigns a new value to the
%    current point and advances the counter for the next point to be
%    assigned.  It pushes this info onto |\cb@currentstack| and then
%    sets the point by calling |\cb@setBeginPoints| with the point
%    number.  Finally, it writes the \file{.aux} file.
% \changes{v3.3h}{1999/06/15}{Added \cs{cb@checkpage} to find final
%    page from history}
%    \begin{macrocode}
\def\cb@start[#1]{%
  \cb@topleft=\cb@nextpoint
%    \end{macrocode}
%    Store the width of the current bar in |\cb@curbarwd|.
%    \begin{macrocode}
  \cb@curbarwd#1\relax
  \cb@push\cb@currentstack
%    \end{macrocode}
%    Now find out on which page the start of this bar finaly ends up;
%    due to the asynchronous nature of the output routine it might be
%    a different page. The macro |\cb@checkpage| finds the page number
%    on the history stack.
%    \begin{macrocode}
  \cb@checkpage\@ne
%    \end{macrocode}
%    Temporarily assign the page number to |\cb@pagecount| as that
%    register is used by |\cb@setBeginPoints|. Note that it's value is
%    offset by one from the page counter.
%    \begin{macrocode}
  \cb@cnta\cb@pagecount
  \cb@pagecount\cb@page\advance\cb@pagecount\m@ne
  \ifvmode 
    \cb@setBeginPoints
  \else
    \vbox to \z@{%
%    \end{macrocode}
%    When we are in horizontal mode we jump up a line to set the
%    starting point of the changebar.
%    \begin{macrocode}
      \vskip -\ht\strutbox
      \cb@setBeginPoints
      \vskip \ht\strutbox}%
  \fi
%    \end{macrocode}
%    Restore |\cb@pagecount|.
%    \begin{macrocode}
  \cb@pagecount\cb@cnta
  \cb@advancePoint}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@advancePoint}
%    The macro |\cb@advancePoint| advances the count register
%    |\cb@nextpoint|. When the maximum number is reached, the
%    numbering is reset.
%    \begin{macrocode}
\def\cb@advancePoint{%
  \global\advance\cb@nextpoint by 4\relax
  \ifnum\cb@nextpoint>\cb@maxpoint
    \global\cb@nextpoint=\cb@minpoint\relax
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@end}
%    This macro ends a changebar. It pops the current point and
%    nesting level off |\cb@currentstack| and sets the end point by
%    calling |\cb@setEndPoints| with the parameter corresponding to the
%    \emph{beginning} point number. It writes the \file{.aux} file
%    and joins the points.
%
% \changes{v3.3a}{1997/09/26}{Added \cs{ignorespaces}}
% \changes{v3.3g}{1999/06/11}{Added stack tracing}
% \changes{v3.3h}{1999/06/15}{Now check the history stack to find the
%    page on which this point ends up}
%    \begin{macrocode}
\def\cb@end{%
  \cb@trace@stack{end of bar on page \the\c@page}%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
    \PackageWarning{Changebar}%
      {Badly nested changebars; Expect erroneous results}%
  \else
%    \end{macrocode}
%    Call |\cb@checkpage| to find the page this point finally ends up
%    on.
%    \begin{macrocode}
    \cb@checkpage\tw@
%    \end{macrocode}
%    Again, we need to temporarily overwrite |\cb@pagecount|.
%    \begin{macrocode}
    \cb@cnta\cb@pagecount
    \cb@pagecount\cb@page\advance\cb@pagecount\m@ne
    \cb@setEndPoints
    \cb@pagecount\cb@cnta
  \fi
  \ignorespaces}
%    \end{macrocode}
%\end{macro}
%
%  \begin{macro}{\cb@checkpage}
% \changes{v3.3h}{1999/06/15}{Macro added}
%    The macro |\cb@checkpage| checks the history stack in order to
%    find out on which page a set of points finaly ends up.
%
%    We expect the identification of the points in |\cb@topleft| and
%    |\cb@page|. The resulting page will be stored in |\cb@page|.
% \changes{v3.3i}{1999/06/18}{Check for and handle the situation that
%    the history stack is too short due to new bars added to a
%    document}
%    \begin{macrocode}
\def\cb@checkpage#1{%
%    \end{macrocode}
%    First store the identifiers in temporary registers.
%    \begin{macrocode}
  \cb@cnta\cb@topleft\relax
  \cb@cntb\cb@page\relax
  \cb@dima\cb@curbarwd\relax
%    \end{macrocode}
%    Then pop the history stack.
%    \begin{macrocode}
  \cb@pop\cb@historystack
%    \end{macrocode}
%    If it was empty there is nothing to check and we're done.
%    \begin{macrocode}
  \ifnum\cb@topleft=\cb@nil
  \else
%    \end{macrocode}
%    Now keep popping the stack untill |\cb@topleft| is no longer less
%    then the value of |\cb@cnta|. The values popped from the stack
%    are pushed on a temporary stack to be pushed back later. This
%    could perhaps be implemented more efficiently if the stacks had a
%    different design.
%    \begin{macrocode}
    \@whilenum\cb@topleft<\cb@cnta\do{%
      \cb@push\cb@tempstack
      \cb@pop\cb@historystack
%    \end{macrocode}
%    When the user adds changebars to his document we might run out of
%    the history stack before we find a match. This would send \TeX\
%    into an endless loop if it wasn't detected and handled.
%    \begin{macrocode}
      \ifnum\cb@topleft=\cb@nil
        \cb@trace{Ran out of history stack, new changebar?}%
%    \end{macrocode}
%    In this case we give |\cb@topleft| an `impossible value' to
%    remember this special situation.
%    \begin{macrocode}
        \cb@topleft\cb@maxpoint\advance\cb@topleft\@ne
      \fi
      }%
%    \end{macrocode}
%    If we are looking for the start point of a bar we may have found
%    it now, for the end point we need to pop one more value. If
%    |\cb@topleft| has become larger than |\cb@maxpoint| we haven't
%    found what we're looking for and we've run out of the stack.
%    \begin{macrocode}
    \ifnum\cb@topleft>\cb@maxpoint\else
      \ifodd#1\else
        \cb@push\cb@tempstack
        \cb@pop\cb@historystack
      \fi
%    \end{macrocode}
%    Now that we've found it overwrite |\cb@cntb| with the
%    |\cb@page| from the stack.
%    \begin{macrocode}
      \cb@cntb\cb@page
    \fi
%    \end{macrocode}
%    Now we restore the history stack to it's original state.
%    \begin{macrocode}
    \@whilenum\cb@topleft>\cb@nil\do{%
      \cb@push\cb@historystack
      \cb@pop\cb@tempstack}%
  \fi
%    \end{macrocode}
%    Finally return the correct values.
%    \begin{macrocode}
  \cb@topleft\cb@cnta\relax
  \cb@page\cb@cntb\relax
  \cb@curbarwd\cb@dima\relax
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\cb@setBeginPoints}
% \changes{v3.3a}{1997/09/26}{Renamed from \cs{cb@setBeginPoint} and
%    removed parameter; use new dimension register for positioning} 
%    The macro |\cb@setBeginPoints| assigns a position to the top left
%    and top right points. It determines wether the point is on an even
%    or an odd page and uses the right dimension to position the
%    point. Keep in mind that the value of |\cb@pagecount| is one
%    less than the value of |\c@page| unless the latter has been reset
%    by the user. 
%
%    The top left point is used to write an entry on the \file{.aux}
%    file to create the history stack on the next run.
%    \begin{macrocode}
\def\cb@setBeginPoints{%
  \cb@topright=\cb@topleft\advance\cb@topright by\@ne
  \ifodd\cb@pagecount
    \cb@defpoint\cb@topleft\cb@even@left
    \cb@defpoint\cb@topright\cb@even@right
  \else
    \cb@defpoint\cb@topleft\cb@odd@left
    \cb@defpoint\cb@topright\cb@odd@right
  \fi
  \cb@writeAux\cb@topleft
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@setEndPoints}
% \changes{v3.3a}{1997/09/26}{Renamed from \cs{cb@setEndPoint} and
%    removed parameter; use new dimension register for positioning} 
%    The macro |\cb@setEndPoints| assigns positions to the bottom
%    points for a change bar. It then instructs the driver to connect
%    two points with a bar. The macro assumes that the width of the
%    bar is stored in |\cb@curbarwd|. 
%
%    The bottom right point is used to write to the \file{.aux} file
%    to signal the end of the current bar on the history stack.
% \changes{v3.3g}{1999/06/12}{Take the setting of \Lopt{twoside} into
%    account}
%    \begin{macrocode}
\def\cb@setEndPoints{%
  \cb@topright=\cb@topleft\advance\cb@topright by\@ne
  \cb@botleft=\cb@topleft\advance\cb@botleft by\tw@
  \cb@botright=\cb@topleft\advance\cb@botright by\thr@@
  \ifodd\cb@pagecount
    \cb@defpoint\cb@botleft\cb@even@left
    \cb@defpoint\cb@botright\cb@even@right
  \else
    \if@twoside
      \cb@defpoint\cb@botleft\cb@odd@left
      \cb@defpoint\cb@botright\cb@odd@right
    \else
      \cb@defpoint\cb@botleft\cb@even@left
      \cb@defpoint\cb@botright\cb@even@right
    \fi
  \fi
  \cb@writeAux\cb@botright
  \edef\cb@leftbar{%
    \noexpand\cb@connect{\cb@topleft}{\cb@botleft}{\cb@curbarwd}}%
  \edef\cb@rightbar{%
    \noexpand\cb@connect{\cb@topright}{\cb@botright}{\cb@curbarwd}}%
%    \end{macrocode}
% \changes{v3.3a}{1997/09/26}{Added support for typesetting twocolumn
%    text with changebars} 
%    \begin{macrocode}
  \if@twocolumn
    \if@firstcolumn\cb@leftbar\else\cb@rightbar\fi
%    \end{macrocode}
%    
% \changes{v3.4e}{2001/09/07}{The \cs{outerbars} conditional should be
%    inside an \cs{else} clause}
%    \begin{macrocode}
  \else
    \ifouterbars
      \ifodd\cb@pagecount
        \cb@leftbar
      \else
        \if@twoside\cb@rightbar\else\cb@leftbar\fi
      \fi
    \else
      \ifodd\cb@pagecount
        \cb@rightbar
      \else
        \if@twoside\cb@leftbar\else\cb@rightbar\fi
      \fi
    \fi
  \fi
  }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@writeAux}
%    The macro |\cb@writeAux| writes information about a changebar
%    point to the auxiliary file. The number of the point, the
%    pagenumber and the width of the bar are written out as arguments
%    to |\cb@barpoint|. This latter macro will be expanded when the
%    auxiliary file is read in.  The macro assumes that the width of
%    bar is stored in |\cb@curbarwd|.
%
%    The code is only executed when auxiliary files are enabled, as
%    there's no sense in trying to write to an unopened file.
%    \begin{macrocode}
\def\cb@writeAux#1{%
  \if@filesw
    \begingroup
      \edef\point{\the#1}%
      \edef\level{\the\cb@curbarwd}%
      \let\the=\z@
      \edef\cb@temp{\write\@auxout
        {\string\cb@barpoint{\point}{\the\cb@pagecount}{\level}}}%
      \cb@temp
    \endgroup
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Macros for Making It Work Across Page Breaks}
% \label{pagebreak}
%
% \begin{macro}{\@makecol}
% \begin{macro}{\@vtryfc}
%
%    These internal \LaTeX\ macros are modified in order to end the
%    changebars spanning the current page break (if any) and restart
%    them on the next page. The modifications are needed to reset the
%    special points for this page and add begin bars to top of box255.
%    The bars carried over from the previous page, and hence to be
%    restarted on this page, have been saved on the stack
%    |\cb@beginstack|. This stack is used to define new starting
%    points for the change bars, which are added to thetop of box
%    |\@cclv|.  Then the stack |\cb@endstack| is built and 
%    processed by |\cb@processActive|. Finally the original
%    |\@makecol| (saved as |\cb@makecol|) is executed.
%
% \changes{3.2}{1994/04/21}{Added setting of \cs{boxmaxdepth}}
% \changes{v3.3a}{1997/09/26}{Let \cs{cb@writeAux} be \cs{@gobble} to
%    prevent extra entries in the \file{.aux} file}
% \changes{v3.3a}{1997/09/26}{Now use the command
%    \cs{cb@startSpanBars} to define top points for bars spoanning a
%    page break} 
%    \begin{macrocode}
\let\ltx@makecol\@makecol
\def\cb@makecol{%
  \cb@trace@stack{before makecol, page \the\c@page}%
  \let\cb@writeAux\@gobble
  \setbox\@cclv \vbox{%
    \cb@resetpoints
    \cb@startSpanBars
    \unvbox\@cclv
    \boxmaxdepth\maxdepth}%
  \global\advance\cb@pagecount by\@ne
  \cb@buildstack\cb@processActive
  \ltx@makecol
  \cb@trace@stack{after makecol, page \the\c@page}%
  }
\let\@makecol\cb@makecol
%    \end{macrocode}
%   When \LaTeX\ makes a page with only floats it doesn't use
%   |\@makecol|; instead it calls |\@vtryfc|, so we have to modify
%   this macro as well.
% \changes{v3.3a}{1997/09/26}{Let \cs{cb@writeAux} be \cs{@gobble} to
%    prevent extra entries in the \file{.aux} file}
% \changes{v3.3a}{1997/09/26}{Now use the command
%    \cs{cb@startSpanBars} to define top points for bars spoanning a
%    page break} 
%    \begin{macrocode}
\let\ltx@vtryfc\@vtryfc
\def\cb@vtryfc{%
  \let\cb@writeAux\@gobble
  \setbox\@outputbox \vbox{%
    \cb@resetpoints
    \cb@startSpanBars
    \unvbox\@cclv
    \boxmaxdepth\maxdepth}%
  \global\advance\cb@pagecount by \@ne
  \cb@buildstack\cb@processActive
  \ltx@vtryfc}
\let\@vtryfc\cb@vtryfc
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\cb@processActive}
%
%    This macro processes each element on span stack. Each element
%    represents a bar that crosses the page break. There could be more
%    than one if bars are nested. It works as follows:
%
% \begin{verbatim}
%    pop top element of span stack
%    if point null (i.e., stack empty) then done
%    else
%      do an end bar on box255
%      save start for new bar at top of next page in \cb@startSaves
%      push active point back onto history stack (need to reprocess
%         on next page).
% \end{verbatim}
%
%    \begin{macrocode}
\def\cb@processActive{%
  \cb@pop\cb@endstack
  \ifnum\cb@topleft=\cb@nil
  \else
    \setbox\@cclv\vbox{%
      \unvbox\@cclv
      \boxmaxdepth\maxdepth
      \advance\cb@pagecount by -1\relax
      \cb@setEndPoints}%
    \cb@push\cb@historystack
%    \end{macrocode}
%    
% \changes{v3.3a}{1997/09/26}{Now also push points on (new)
%    \cs{cb@beginstack}}
%    \begin{macrocode}
    \cb@push\cb@beginstack
    \expandafter\cb@processActive
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \changes{v3.3a}{1997/09/26}{Removed \cs{cb@saveBeginPoints}}
%
%  \begin{macro}{\cb@startSpanBars}
% \changes{v3.3a}{1997/09/26}{New macro}
%    This macro defines new points for each bar that was pushed on the
%    |\cb@beginstack|. Afterwards |\cb@beginstack| is empty.
% \changes{v3.3g}{1999/06/11}{Added stack tracing; no longer push
%    points on \cs{cb@currenstack}}
%    \begin{macrocode}
\def\cb@startSpanBars{%
  \cb@pop\cb@beginstack
  \ifnum\cb@topleft=\cb@nil
  \else
    \cb@setBeginPoints
    \cb@trace@stack{after StartSpanBars, page \the\c@page}%
    \expandafter\cb@startSpanBars
  \fi
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\cb@buildstack}
% \begin{macro}{\cb@endstack}
%
%    The macro |\cb@buildstack| initializes the stack with open bars
%    and starts populating it.
%    \begin{macrocode}
\def\cb@buildstack{%
  \cb@initstack\cb@endstack
  \cb@pushNextActive}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\cb@pushNextActive}
%    This macro pops the top element off the history stack
%    (|\cb@historystack|).  If the top left point is on a future page,
%    it is pushed back onto the history stack and processing stops.
%    If the point on the current or a previous page and it has an odd
%    number, the point is pushed on the stack with end points
%    |\cb@endstack|); if the point has an even number, it is popped
%    off the stack with end points since the bar to which it belongs
%    has terminated on the current page. 
%    \begin{macrocode}
\def\cb@pushNextActive{%
  \cb@pop\cb@historystack
  \ifnum\cb@topleft=\cb@nil
  \else
    \ifnum\cb@page>\cb@pagecount
      \cb@push\cb@historystack
    \else
      \ifodd\cb@topleft
        \cb@push\cb@endstack
      \else
        \cb@pop\cb@endstack
      \fi
      \expandafter\expandafter\expandafter\cb@pushNextActive
    \fi
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Macros For Managing The Stacks of Bar points}
%
%    The macros make use of four stacks corresponding to |\special|
%    defpoints.  Each stack takes the form \texttt{<element>
%    ... <element>}
%
%    Each element is of the form \texttt{xxxnyyypzzzl} where
%    \texttt{xxx} is the number of the special point, \texttt{yyy} is
%    the page on which this point is set, and \texttt{zzz} is the
%    dimension used when connecting this point.
%
%    The stack |\cb@historystack| is built from the log information
%    and initially lists all the points.  As pages are processed,
%    points are popped off the stack and discarded.
%
%    The stack |\cb@endstack| and |\cb@beginstack| are two temporary
%    stacks used by the output routine and contain the stack with
%    definitions for of all bars crossing the current pagebreak (there
%    may be more than one with nested bars). 
%    They are built by popping elements off the history stack.
%
%    The stack |\cb@currentstack| contains all the current bars.
%    A |\cb@start| pushes an element onto this stack.
%    A |\cb@end| pops the top element off the stack and uses the
%    info to terminate the bar.
%
%    For performance and memory reasons, the history stack, which can
%    be very long, is special cased and a file is used to store this
%    stack rather than an internal macro.  The ``external'' interface
%    to this stack is identical to what is described above.  However,
%    when the history stack is popped, a line from the file is first
%    read and appended to the macro |\cb@historystack|.
%
% \begin{macro}{\cb@initstack}
%    A macro to (globally) initialize a stack.
%    \begin{macrocode}
\def\cb@initstack#1{\xdef#1{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@historystack}
% \begin{macro}{\cb@write}
% \begin{macro}{\cb@read}
%    We need to initialise a stack to store the entries read from the
%    external history file.
%    \begin{macrocode}
\cb@initstack\cb@historystack
%    \end{macrocode}
%    We also need to allocate a read and a write stream for the
%    history file.
%    \begin{macrocode}
\newwrite\cb@write
\newread\cb@read
%    \end{macrocode}
%    And we open the history file for writing (which is done when the
%    \file{.aux} file is read in).
%    \begin{macrocode}
\immediate\openout\cb@write=\jobname.cb\relax
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\cb@endstack}
% \begin{macro}{\cb@beginstack}
%    Allocate two stacks for the bars that span the current page break.
%    \begin{macrocode}
\cb@initstack\cb@endstack
\cb@initstack\cb@beginstack
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\cb@tempstack}
%    Allocate a stack for temporary storage
%    \begin{macrocode}
\cb@initstack\cb@tempstack
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\cb@currentstack}
%    And we allocate an extra stack that is needed to implement nesting
%    without having to rely on \TeX's grouping mechanism.
%    \begin{macrocode}
\cb@initstack\cb@currentstack
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@pop}
%
%    This macro pops the top element off the named stack and puts the
%    point value into |\cb@topleft|, the page value into |\cb@page|
%    and the bar width into |\cb@curbarwd|. If the stack is empty, it
%    returns a void value (|\cb@nil|) in |\cb@topleft| and sets
%    |\cb@page=0|.
%
% \changes{v3.4b}{2001/08/27}{Use global assignments, added more stack
%    tracing info}
%    \begin{macrocode}
\def\cb@pop#1{%
  \ifx #1\cb@historystack
    \ifeof\cb@read
    \else
      {\endlinechar=-1\read\cb@read to\@temp
       \xdef\cb@historystack{\cb@historystack\@temp}%
      }%
    \fi
  \fi
  \ifx#1\@empty
    \global\cb@topleft\cb@nil
    \global\cb@page\z@\relax
  \else
    \expandafter\cb@carcdr#1e#1%
  \fi
  \cb@trace@pop{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@carcdr}
%    This macro is used to `decode' a stack entry.
% \changes{v3.3a}{1997/09/26}{No longer use \cs{@tempdima}}
% \changes{v3.4b}{2001/08/27}{Use global assignments}
%    \begin{macrocode}
\def\cb@carcdr#1n#2p#3l#4e#5{%
  \global\cb@topleft#1\relax
  \global\cb@page#2\relax
  \global\cb@curbarwd#3\relax
  \xdef#5{#4}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@push}
%
%    The macro |\cb@push| Pushes |\cb@topleft|, |\cb@page| and
%    |\cb@curbarwd| onto the top of the named stack.
%
% \changes{v3.4b}{2001/08/27}{Added more stack tracing info}
%    \begin{macrocode}
\def\cb@push#1{%
  \xdef#1{\the\cb@topleft n\the\cb@page p\the\cb@curbarwd l#1}%
  \cb@trace@push{#1}}

%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@barpoint}
%    The macro |\cb@barpoint| populates the history file.  It writes
%    one line to \file{.cb} file which is equivalent to one
%    \meta{element} described above. 
%    \begin{macrocode}
\def\cb@barpoint#1#2#3{\immediate\write\cb@write{#1n#2p#3l}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Macros For Checking That The \file{.aux} File Is Stable}
%
% \begin{macro}{\AtBeginDocument}
%
%    While reading the \file{.aux} file, \LaTeX{} has created the
%    history stack in a separate file. We need to close that file and
%    open it for reading. Also the `initialisation' of the
%    |\special| commands has to take place.  While we are
%    modifying the macro we also include the computation of the
%    possible positions of the changebars
%
%    For these actions we need to add to the \LaTeX\ begin-document
%    hook.
% \changes{3.2}{1994/04/21}{Use the \cs{AtBeginDocument} instead of
%    redefining \cs{document}}
%    \begin{macrocode}
\AtBeginDocument{%
  \cb@setup@specials
%    \end{macrocode}
%    When the document doesn't start with page 1 but with another page
%    set with |\setcounter{page}{...}| the code needs to know about
%    it. Therefore we need to initialize |\cb@pagecount|.
%    \begin{macrocode}
  \global\cb@pagecount\c@page
  \global\advance\cb@pagecount\m@ne
%    \end{macrocode}
%    Compute the left and right positions of the changebars.
% \changes{v3.4g}{2004/01/09}{Added tracing information for the left
%    and right postions} 
%    \begin{macrocode}
  \cb@positions
  \cb@trace{%
    Odd left : \the\cb@odd@left\space
    Odd right : \the\cb@odd@right\MessageBreak
    Even left: \the\cb@even@left\space
    Even right: \the\cb@even@right
    }%
  \immediate\closeout\cb@write
  \immediate\openin\cb@read=\jobname.cb}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\AtEndDocument}
%    We need to issue a |\clearpage| to flush rest of document.  (Note
%    that I believe there is contention in this area: are there in
%    fact situations in which the end-document hooks need to be called
%    \emph{before} the final |\clearpage|? --- the documentation of
%    \LaTeX\ itself implies that there are.)  Then closes the \file{.cb}
%    file and reopens it for checking.  Initialize history stack (to
%    be read from file).  Let |\cb@barpoint=\cb@checkHistory| for
%    checking. 
% \changes{3.2}{1994/04/21}{Use \cs{AtEndDocument} now instead of
%    redefining \cs{enddocument}}
%
%    \begin{macrocode}
\AtEndDocument{%
  \clearpage
  \cb@initstack\cb@historystack
  \immediate\closein\cb@read
  \immediate\openin\cb@read=\jobname.cb%
  \let\cb@barpoint\cb@checkHistory}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@checkHistory}
%
%    Pops the top of the history stack (|\jobname.cb|) and checks to
%    see if the point and page numbers are the same as the arguments
%    $\#1$ and $\#2$ respectively.  Prints a warning message if
%    different.
%
%    \begin{macrocode}
\def\cb@checkHistory#1#2#3{%
  \cb@pop\cb@historystack
  \ifnum #1=\cb@topleft\relax
    \ifnum #2=\cb@page\relax
%    \end{macrocode}
%    Both page and point numbers are equal; do nothing,
%    \begin{macrocode}
    \else
%    \end{macrocode}
%    but generate a warning when page numbers don't match, or
%    \begin{macrocode}
      \cb@error
    \fi
  \else
%    \end{macrocode}
%    when point numbers don't match.
%    \begin{macrocode}
    \cb@error
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cb@error}
%    When a mismatch between the changebar information in the
%    auxiliary file and the history stack is detected a warning is
%    issued; further checking is disabled.
%    \begin{macrocode}
\def\cb@error{%
  \PackageWarning{Changebar}%
    {Changebar info has changed.\MessageBreak
     Rerun to get the bars right}
  \gdef\cb@checkHistory##1##2##3{}%
  \let\cb@barpoint\cb@checkHistory}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Macros For Making It Work With Nested Floats/Footnotes}
%
% \begin{macro}{\end@float}
%    This is a replacement for the \LaTeX-macro of the same name.  All
%    it does is check to see if changebars are active and, if so, it
%    puts changebars around the box containing the float.  Then it
%    calls the original \LaTeX\ |\end@float|.
%
%    \begin{macrocode}
\let\ltx@end@float\end@float
%    \end{macrocode}
% \changes{v3.3g}{1999/06/11}{Added stack tracing}
% \changes{v3.4b}{2001/08/27}{Call \cs{@endfloatbox} en use
%    \cs{color@vbox} to take the extra box and group for color into
%    account}
%    \begin{macrocode}
\def\cb@end@float{%
  \cb@trace@stack{end float on page \the\c@page}%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
  \else
    \cb@push\cb@currentstack
    \global\cb@curbarwd=\cb@curbarwd
    \@endfloatbox
    \global\setbox\@currbox
      \color@vbox
      \normalcolor
      \vbox\bgroup\cb@start[\cb@curbarwd]\unvbox\@currbox\cb@end
  \fi
  \ltx@end@float}
\let\end@float\cb@end@float
%    \end{macrocode}
%    This only works if this new version of |\end@float| is really
%    used. With \LaTeX2.09 the documentstyles used to contain:
% \begin{verbatim}
%    \let\endfigure\end@float
% \end{verbatim}
%    In that case this binding has to be repeated after the
%    redefinition of |\end@float|. However, the \LaTeXe\ class files
%    use |\newenvironment| to define the \Lenv{figure} and
%    \Lenv{table} environments. In that case there is no need to
%    rebind |\endfigure|.
% \changes{3.2}{1994/04/21}{Removed
%    \cs{let}\cs{endfigure}\cs{end@float}, no longer necessary}
% \end{macro}
%
%  \begin{macro}{\float@end}
%    When the \pkg{float} package is being used we need to take care
%    of its changes to the float mechanism. It defines it's own macros
%    (|\float@end| and |\float@dblend| which need to be modified for
%    changebars to work.
%
%    First we'll save the original as |\flt@float@end|.
%    \begin{macrocode}
\let\flt@float@end\float@end
%    \end{macrocode}
%    Then we redefine it to insert the changebarcode.
%    \begin{macrocode}
\def\float@end{%
  \cb@trace@stack{end float on page \the\c@page}%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
  \else
    \cb@push\cb@currentstack
    \global\cb@curbarwd\cb@curbarwd
    \@endfloatbox
    \global\setbox\@currbox
      \color@vbox
      \normalcolor
      \vbox\bgroup\cb@start[\cb@curbarwd]\unvbox\@currbox\cb@end
  \fi
  \let\end@float\ltx@end@float
  \flt@float@end
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\end@dblfloat}
%    This is a replacement for the \LaTeX-macro of the same name.  All
%    it does is check to see if changebars are active and, if so, it
%    puts changebars around the box containing the float. In this case
%    the \LaTeX\ macro had to be rewritten.
%
% \changes{v3.4e}{2001/09/07}{Double column floats only carry a
%    changebar with an appropriate change of \cs{end@dblfloat}}
%    \begin{macrocode}
\let\ltx@end@dblfloat\end@dblfloat
\def\cb@end@dblfloat{%
  \if@twocolumn
    \cb@trace@stack{end dblfloat on page \the\c@page}%
    \cb@pop\cb@currentstack
    \ifnum\cb@topleft=\cb@nil
    \else
      \cb@push\cb@currentstack
      \global\cb@curbarwd=\cb@curbarwd
      \@endfloatbox
      \global\setbox\@currbox
        \color@vbox
        \normalcolor
        \vbox\bgroup\cb@start[\cb@curbarwd]\unvbox\@currbox\cb@end
    \fi
    \@endfloatbox
    \ifnum\@floatpenalty <\z@
      \@largefloatcheck
      \@cons\@dbldeferlist\@currbox
    \fi
    \ifnum \@floatpenalty =-\@Mii \@Esphack\fi
  \else
    \end@float
  \fi}
\let\end@dblfloat\cb@end@dblfloat
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\float@dblend}
%    Something similar needs to be done for the case where the
%    \pkg{float} package is being used...
%    \begin{macrocode}
\let\flt@float@dblend\float@dblend
\def\float@dblend{%
  \cb@trace@stack{end dbl float on page \the\c@page}%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
  \else
    \cb@push\cb@currentstack
    \global\cb@curbarwd=\cb@curbarwd
    \@endfloatbox
    \global\setbox\@currbox
      \color@vbox
      \normalcolor
      \vbox\bgroup\cb@start[\cb@curbarwd]\unvbox\@currbox\cb@end
  \fi
  \let\end@dblfloat\ltx@end@dblfloat
  \flt@float@dblend
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\@footnotetext}
%    This is a replacement for the \LaTeX\ macro of the same name.
%    It simply checks to see if changebars are active, and if so,
%    wraps the macro argument (i.e., the footnote) in changebars.
%
% \changes{3.1b}{1993/10/11}{Added missing percent sign to prevent
%    spurious white space in the output.}
%    \begin{macrocode}
\let\ltx@footnotetext\@footnotetext
%    \end{macrocode}
% \changes{v3.3g}{1999/06/11}{Added stack tracing}
%    \begin{macrocode}
\long\def\cb@footnotetext#1{%
  \cb@trace@stack{end footnote on page \the\c@page}%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
    \ltx@footnotetext{#1}%
  \else
    \cb@push\cb@currentstack
    \edef\cb@temp{\the\cb@curbarwd}%
    \ltx@footnotetext{\cb@start[\cb@temp]#1\cb@end}%
  \fi}
\let\@footnotetext\cb@footnotetext
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@mpfootnotetext}
%
%    Replacement for the \LaTeX\ macro of the same name.  Same thing
%    as |\@footnotetext|.
%
% \changes{3.1b}{1993/10/11}{Added missing percent sign to prevent
%    spurious white space in the output.}
%    \begin{macrocode}
\let\ltx@mpfootnotetext\@mpfootnotetext
%    \end{macrocode}
%    \begin{macrocode}
\long\def\cb@mpfootnotetext#1{%
  \cb@pop\cb@currentstack
  \ifnum\cb@topleft=\cb@nil
    \ltx@mpfootnotetext{#1}%
  \else
    \cb@push\cb@currentstack
    \edef\cb@temp{\the\cb@curbarwd}%
    \ltx@mpfootnotetext{\cb@start[\cb@temp]#1\cb@end}%
  \fi}
\let\@mpfootnotetext\cb@mpfootnotetext
%</package>
%    \end{macrocode}
% \end{macro}
%
% 
% \Finale
%
\endinput
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%%
%%
