% \iffalse meta-comment % %% Copyright 1994-2024 (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{2954} % %\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} % %<+package>\ProvidesPackage{changebar} [2024/01/09 v3.7d 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} \usepackage[pdftex,rightbars,color,traceon,tracestacks]{changebar} \cbcolor{red} \DoNotIndex{\@@,\@Esphack,\@Mii,\@cons,\@empty,\@gobble} \DoNotIndex{\@ifundefined,\@ne,\@spaces,\@whilenum} \DoNotIndex{\advance,\begingroup,\bgroup,\egrou,\endgroup} \DoNotIndex{\catcode,\chardef,\clearpage,\closein,\closeout} \DoNotIndex{\csname,\endcsname,\def,\dimen@,\divide,\do,\dp} \DoNotIndex{\edef,\expandafter} \DoNotIndex{\gdef,\global} \DoNotIndex{\GenericWarning,\hoffset,\ht} \DoNotIndex{\ifcase,\or,\fi,\ifdim,\else,\fi,\ifeof,\fi,\ifnum,\fi} \DoNotIndex{\ifvmode,\fi,\ifx,\fi,\ignorespaces,\immediate,\InputIfFileExists} \DoNotIndex{\jobname,\let,\long,\m@ne,\maxdepth,\MessageBreak} \DoNotIndex{\newcommand,\newcount,\newcounter,\newdimen,\newenvironment} \DoNotIndex{\newlength,\newread,\newwrite,\next,\noexpand,\normalcolor} \DoNotIndex{\openin,\openout,\OptionNotUsed,\p,\PacakgeError} \DoNotIndex{\PackageWarning,\point,\ProcessOptions,\read,\relax} \DoNotIndex{\RequirePackage,\setbox,\setcounter,\setlength,\space} \DoNotIndex{\string,\strutbox,\t,\textwidth,\the,\thr@@,\tw@} \DoNotIndex{\unvbox,\uppercase,\vadjust,\vbox,\vskip,\vss,\write,\xdef,\z@} % \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} % % \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.} % \changes{v3.5a}{2005/05/23}{Piet van Oostrum: Resolved bugs in twocolumn % mode, mid-document changes to page number, added pdflatex support.} % \changes{v3.6a}{2011/04/30}{Added support for XeTeX provided by % Apostolos Syropoulos} % \changes{v3.6b}{2018/02/03}{Added a macro for pdf scaling for % Xe\TeX} % \changes{v3.6e}{2023/08/13}{Added supprt for luaTeX} % \changes{v3.7b}{2023/12/28}{Added a few lines that were inadvertantly removed} % \changes{v3.7b}{2023/12/30}{the cb2-file use delimiting chars may % change meaning when they end up in the wrong situation} % % \title{The Changebar package % \thanks{This file has version number \fileversion, % last revised \filedate.}} % % \author{Michael Fine\\Distributed Systems Architecture \and % Johannes Braams\\ % \texttt{johannes.braams at texniek.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 % \changes{v3.5a}{2005/05/23}{PDF\TeX{} support added} % \changes{v3.6a}{2011/04/30}{Xe\TeX{} support added} % drivers are supported, plus pdftex, Xe\TeX\ and lua\TeX\ % support. 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 % \changes{v3.5a}{2005/05/23}{Pdftex support added} % \changes{v3.6a}{2011/05/02}{xetex support added} % been tested with the \Lopt{dvips}, \Lopt{pdftex}, % \Lopt{vtex} and\Lopt{xetex} 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 % \changes{v3.5a}{2005/05/23}{Option xcolor mentioned} % option \Lopt{color} or \Lopt{xcolor}. % \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 % \changes{v3.5a}{2005/05/23}{Pdftex support added} % \item PDF\TeX % \changes{v3.6a}{2011/04/30}{XeTeX added} % \item Xe\TeX % \changes{3.6e}{2023/08/13}{luaTeX added} % \begin{changebar} % \item lua\TeX % \end{changebar} % \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 options % \Lopt{color} and \Lopt{xcolor} are available. They define the % user command |\cbcolor| and load either the \pkg{color} or the % \pkg{xcolor} 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. % % % \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. % \changes{v3.5a}{2005/05/23}{Pdftex support added} % \changes{v3.6a}{2011/04/30}{XeTeX suport added} % There is no such limit with PDF\TeX or Xe\TeX. % % \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} % \changes{v3.5a}{2005/05/23}{Pdftex support added} % and \Lopt{pdftex} drivers. % \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. % With PDF\LaTeX{} generally three (or even more) runs % are necessary. % % 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} % \changes{v3.5a}{2005/05/23}{Twocolumn support changes} % The macros need to keep track of the number of pages/columns % 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{macro}{\cb@barsplace} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % A switch is provided to control where the changebars will be % printed. % The value depends on the options given: % \begin{itemize} % \item[0] for innerbars (default), % \item[1] for outerbars, % \item[2] gives leftbars, % \item[3] gives rightbars. % \end{itemize} % \begin{macrocode} \def\cb@barsplace{0} % \end{macrocode} % \end{macro} % % \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{Var}{@cb@firstcolumn} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % A switch to find out if a point is in the left column of a % twocolumn page. % \begin{macrocode} \newif\if@cb@firstcolumn % \end{macrocode} % \end{Var} % % \begin{macro}{\cb@pdfxy} % \changes{v3.5a}{2005/05/23}{Pdftex support added} % The macro |\cb@pdfxy| populates the pdf x,y coordinates file. % In \Lopt{pdftex} and \Lopt{xetex} mode it writes one line to % \file{.cb2} file which is equivalent to one bar point. The % default implementation is a noop. % If the \Lopt{pdftex} or \Lopt{xetex} option is given it is % redefined. % \begin{macrocode} \def\cb@pdfxy#1#2#3#4#5{} % \end{macrocode} % \end{macro} % % \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. % \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. % \changes{v3.5a}{2005/05/23}{Added the option \Lopt{PDFTeX}} % \changes{v3.6a}{2011/04/30}{Added the option \Lopt{XeTeX}} % \changes{v3.6e}{2023/08/13}{Added the option \Lopt{luaTeX}} % Possible choices are: % \begin{itemize} % \item DVItoLN03 % \item DVItoPS % \item DVIps % \item em\TeX % \item Textures % \item V\TeX % \item PDF\TeX % \item Xe\TeX % \cbstart\item luaTeX\cbend % \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}} % \changes{v3.5a}{2005/05/23}{Added the option \Lopt{PDFTeX}} % \changes{v3.6a}{2011/04/30}{Added the option \Lopt{XeTeX}} % \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} % \begin{macrocode} \DeclareOption{PDFTeX}{\cb@pdftexcheck} \DeclareOption{pdftex}{\cb@pdftexcheck} % \end{macrocode} % \changes{v3.5a}{2005/05/23}{PDFTeX support added} % For the \Lopt{pdftex} option we have to check that the current % \LaTeX{} run is using PDF\TeX{} and that PDF output is selected. % If it is, we initialize the option and open an additional output file. % If not, we ignore the option and issue a warning. % \begin{macrocode} \def\cb@pdftexcheck{% \ifx\pdfsavepos\@undefined\cb@pdftexerror \else\ifx\pdfoutput\@undefined\cb@pdftexerror \else\ifnum\pdfoutput>0 \global\chardef\cb@driver@setup=6\relax \ifx\cb@writexy\@undefined \newwrite\cb@writexy \newread\cb@readxy \immediate\openout\cb@writexy=\jobname.cb2\relax \fi % \end{macrocode} % Redefine the |\cb@pdfxy| macro to write point coordinates to the % \file{.cb2} file. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \gdef\cb@pdfxy##1##2##3##4##5{% \immediate\write\cb@writexy{##1.##2p##3;##4;##5}% \expandafter\gdef\csname cb@##1.##2\endcsname{##3,##4,##5}} \else\cb@pdftexerror\fi\fi\fi} % \end{macrocode} % Give a warning if we cannot support the \Lopt{pdftex} option. % \begin{macrocode} \def\cb@pdftexerror{\PackageError {changebar}% {PDFTeX option cannot be used}% {You are using a LaTeX run which does not generate PDF\MessageBreak or you are using a very old version of PDFTeX}} % \end{macrocode} % % \begin{macrocode} \DeclareOption{XeTeX}{\cb@xetexcheck} \DeclareOption{xetex}{\cb@xetexcheck} % \end{macrocode} % \changes{v3.6a}{2005/05/23}{XeTeX support added} % For the \Lopt{xetex} option we have to check that the current % \LaTeX{} run is using Xe\TeX{}. % If it is, we initialize the option and open an additional output file. % If not, we ignore the option and issue a warning.. % \begin{macrocode} \def\cb@xetexcheck{% \expandafter\ifx\csname XeTeXrevision\endcsname\@undefined \cb@xetexerror \else \global\chardef\cb@driver@setup=7\relax \ifx\cb@writexy\@undefined \newwrite\cb@writexy \newread\cb@readxy \immediate\openout\cb@writexy=\jobname.cb2\relax \fi % \end{macrocode} % Redefine the |\cb@pdfxy| macro to write point coordinates to the % \file{.cb2} file. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \gdef\cb@pdfxy##1##2##3##4##5{% \immediate\write\cb@writexy{##1.##2p##3;##4;##5}% \expandafter\gdef\csname cb@##1.##2\endcsname{##3,##4,##5}} \gdef\sec@nd@ftw@##1 ##2{##2} \fi} % \end{macrocode} % % Give a warning if we cannot support the \Lopt{xetex} option. % \begin{macrocode} \def\cb@xetexerror{\PackageError {changebar}% {XeTeX option cannot be used}% {You are not using XeLaTeX}} % \end{macrocode} % % \begin{changebar} % \begin{macrocode} \DeclareOption{luaTeX}{\cb@luatexcheck} \DeclareOption{luatex}{\cb@luatexcheck} % \end{macrocode} % \changes{v3.6e}{2023/08/13}{luaTeX support added} % For the \Lopt{luatex} option we have to check that the current % \LaTeX{} run is using lua\TeX{}. % If it is, we initialize the option and open an additional output file. % If not, we ignore the option and issue a warning.. % \begin{macrocode} \def\cb@luatexcheck{% \ifx\directlua\@undefined \cb@luatexerror \else \global\chardef\cb@driver@setup=8\relax \ifx\cb@writexy\@undefined \newwrite\cb@writexy \newread\cb@readxy \immediate\openout\cb@writexy=\jobname.cb2\relax \fi % \end{macrocode} % Redefine the |\cb@pdfxy| macro to write point coordinates to the % \file{.cb2} file. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \gdef\cb@pdfxy##1##2##3##4##5{% \immediate\write\cb@writexy{##1.##2p##3;##4;##5}% \expandafter\gdef\csname cb@##1.##2\endcsname{##3,##4,##5}} \fi} % \end{macrocode} % % Give a warning if we cannot support the \Lopt{luatex} option. % \begin{macrocode} \def\cb@luatexerror{\PackageError {changebar}% {luaTeX option cannot be used}% {You are not using luaLaTeX}} % \end{macrocode} % \end{changebar} % % The new features of \LaTeXe\ make it possible to implement the % \Lopt{outerbars} option. % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % \begin{macrocode} \DeclareOption{outerbars}{\def\cb@barsplace{1}} \DeclareOption{innerbars}{\def\cb@barsplace{0}} % \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} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % \begin{macrocode} \DeclareOption{leftbars}{\def\cb@barsplace{2}} \DeclareOption{rightbars}{\def\cb@barsplace{3}} % \end{macrocode} % \changes{v3.3j}{2000/09/26}{\cs{cb@even@right} erroneously wasn't % set in the oneside mode with option rightbars} % 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} % Three 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}} % \end{macrocode} % The second option activates support for the \pkg{color} package. % \begin{macrocode} \DeclareOption{color}{% \def\cb@ps@color{\expandafter\c@lor@to@ps\cb@current@color\@@}% \def\cb@color@pkg{color}} % \end{macrocode} % The third option adds support for the \pkg{xcolor} package. % \changes{v3.4h}{2004/08/26}{Added option \Lopt{xcolor} to support % the \pkg{xcolor} package} % \begin{macrocode} \DeclareOption{xcolor}{% \def\cb@ps@color{\expandafter\c@lor@to@ps\cb@current@color\@@}% \def\cb@color@pkg{xcolor}} % \end{macrocode} % % Signal an error if an unknown option was specified. % \changes{v3.5a}{2005/05/23}{Added 'pdftex' to the option list} % \changes{v3.6a}{2011/04/30}{Added 'xetex' to the option list} % \begin{macrocode} \DeclareOption*{\OptionNotUsed\PackageError {changebar}% {Unrecognised option `\CurrentOption'\MessageBreak known options are dvitoln03, dvitops, dvips,\MessageBreak emtex, textures, pdftex, vtex and xetex, grey, color, xcolor,\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. % When PDF\TeX{} is producing PDF output, the \Lopt{pdftex} option is % selected. % \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} % \changes{v3.5a}{2005/05/23}{Added detection of PDF\TeX} % \changes{v3.6a}{2011/04/30}{Added detection of Xe\TeX} % \begin{macrocode} \ifx\VTeXversion\@undefined \expandafter\ifx\csname XeTeXrevision\endcsname\@undefined \ifx\pdfoutput\@undefined \ExecuteOptions{innerbars,traceoff,dvips,grey} \else \ifnum\pdfoutput>0 \ExecuteOptions{innerbars,traceoff,pdftex,grey} \else \ExecuteOptions{innerbars,traceoff,dvips,grey} \fi \fi \else \ExecuteOptions{innerbars,traceoff,xetex,grey} \fi \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 achieved 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} % % Now make all the selected options active, but... % \begin{macrocode} \ProcessOptions\relax % \end{macrocode} % % We have to make sure that when the document is being processed by % pdf\LaTeX, while also creating pdf as output, the driver to be % used is the pdf driver. Therefore we add an extra check, possibly % overriding a \Lopt{dvips} option that might still have been in % the doucment. % \changes{v3.5b}{2005/05/31}{Added an extra check for pdftex in pdf % mode} % \begin{macrocode} \ifx\pdfsavepos\@undefined \else \ifx\pdfoutput\@undefined \else \ifnum\pdfoutput>0 \global\chardef\cb@driver@setup=6\relax \fi \fi \fi % \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}|}|. % \changes{v3.5a}{2005/05/23}{Added 'PDFtex' option} % Possible choices are: % \begin{itemize} % \item DVItoLN03 % \item DVItoPS % \item DVIps % \item em\TeX % \item \TeX tures % \item V\TeX % \item PDF\TeX % \item Xe\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}} % \changes{v3.5a}{2005/05/23}{Added 'PDFtex' option} % \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}% \def\pdfTeX{PDFTEX}% % \end{macrocode} % \changes{v3.6a}{2011/04/30}{Added 'XeTeX' option} % \begin{macrocode} \def\xeTeX{XETEX} % \end{macrocode} % \changes{v3.6e}{2023/08/13}{Added 'luaTeX' option} % \begin{changebar} % \begin{macrocode} \def\luaTeX{LUATEX} % \end{macrocode} % \end{changebar} % % 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=. % \changes{v3.6a}{2011/04/30}{Added 'XeTeX' option} % \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 \ifx\tempa\pdfTeX \cb@pdftexcheck\fi \ifx\tempa\xeTeX \cb@xetexcheck\fi % \end{macrocode} % \changes{v3.6e}{2023/08/13}{Added 'luaTeX' option} % \begin{changebar} % \begin{macrocode} \ifx\tempa\luaTeX \cb@luatexcheck\fi % \end{macrocode} % \end{changebar} % \begin{macrocode} \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 \textsf{changebar} package 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 following 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} % \changes{v3.5c}{2005/09/18}{A small change was submitted by Gordon % Lee from Blue Sky Systems} % \begin{macrocode} \or \def\cb@defpoint##1##2{% \special{postscript 0 0 transform}% leave [x,y] on the stack \special{rawpostscript \expandafter\cb@removedim\the##2\space /CBarX\the##1\space exch def itransform 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} % \changes{v3.5a}{2005/05/23}{PDF\TeX{} support added} % The code for PDF\TeX{} is more elaborate as the calculations have to % be done in \TeX. |\cb@defpoint| will write information about the % coordinates of the point to the \file{.aux} file, from where it will % be picked up in the next run. Then we will construct the PDF % code necessary to draw the changebars. % \begin{macrocode} \or \immediate\closeout\cb@writexy \immediate\openin\cb@readxy=\jobname.cb2\relax % \end{macrocode} % % \begin{macro}{\cb@pdfpoints} % \begin{macro}{\cb@pdfpagenr} % The |\cb@pdfpoints| macro contains the list of coordinates of points % that have been read in memory from the \file{.cb2} file. The % |\cb@pdfpagenr| macro contains the next pagecount to be read in. % \begin{macrocode} \def\cb@pdfpoints{} \def\cb@pdfpagenr{0} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\cb@findpdfpoint} % The |\cb@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. First we expand the arguments to get the real values. % \begin{macrocode} \def\cb@findpdfpoint##1##2{% \edef\cb@temp {\noexpand\cb@@findpdfpoint{\the##1}{\the##2}}% \cb@temp } % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@@findpdfpoint} % The |\cb@@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. If the information is not yet in memory is it read from % the \file{.cb2} file. The coordinates of the current point in the text % will be delivered in |\cb@pdfx| and |\cb@pdfy|, and |\cb@pdfz| will get % the x coordinate of the changebar. If the point is unknown, |\cb@pdfx| % will be set to |\relax|. % \begin{macrocode} \def\cb@@findpdfpoint##1##2{% \ifnum##2<\cb@pdfpagenr\relax\else \cb@pdfreadxy{##2}% \fi \let\cb@pdfx\relax \ifx\cb@pdfpoints\@empty\else \ifnum##2<0\relax \else \edef\cb@temp{\noexpand\cb@pdffind{##1}{##2}\cb@pdfpoints\relax{}}% \cb@temp \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdffind} % The |\cb@pdffind| recursively searches through |\cb@pdfpoints| to find % point \#1 on pagecount \#2. |\cb@pdfpoints| contains entries of the % form\\ % \meta{pointnr}.\meta{pagecount}p\meta{x},\meta{y},\meta{z}pt. % When the point is found it is removed from |\cb@pdfpoints|. \#9 % contains the cumulative head of the list to construct the new list % with the entry removed. \#3--\#8 are for pattern matching. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \def\cb@pdffind##1##2##3.##4p##5;##6;##7pt##8\relax##9{% \def\cb@next{% \cb@pdffind{##1}{##2}##8\relax{##9##3.##4p##5;##6;##7pt}}% \ifnum ##1=##3 \ifnum ##2=##4 \def\cb@pdfx{##5sp}% \def\cb@pdfy{##6sp}% \def\cb@pdfz{##7pt}% \let\cb@next\relax \gdef\cb@pdfpoints{##9##8}% \fi \fi \ifx\relax##8\relax \let\cb@next\relax \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfreadxy} % The |\cb@pdfreadxy| macro reads lines from the \file{.cb2} file in % |\cb@pdfpoints| until the pagecount is greater than \#1 or the end of % the file is reached. This ensures that all entries belonging to the % current column are in memory. % \begin{macrocode} \def\cb@pdfreadxy##1{% \let\cb@next\relax \ifeof\cb@readxy \global\let\cb@pdfpagenr\cb@maxpoint \else {\endlinechar=-1\read\cb@readxy to\cb@temp \ifx\cb@temp\@empty\else \expandafter\cb@pdfparsexy\cb@temp \ifnum\cb@pdfpg<0\else \xdef\cb@pdfpoints{\cb@pdfpoints\cb@temp}% \cb@trace{PDFpoints=\cb@pdfpoints}% \global\let\cb@pdfpagenr\cb@pdfpg \fi \ifnum\cb@pdfpg>##1\else \global\def\cb@next{\cb@pdfreadxy{##1}}% \fi \fi }% \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfparsexy} % The |\cb@pdfparsexy| macro extracts the pagecount from an entry read in % from the \file{.cb2} file. % \begin{macrocode} \def\cb@pdfparsexy##1.##2p##3;##4;##5pt{% \def\cb@pdfpg{##2}}% % \end{macrocode} % \end{macro} % % As PDF is not a programming language it does not have any variables to % remember the coordinates of the current point. Therefore we write the % information to the \file{.aux} file and read it in in the next run. We % write the x,y coordinates of the current point in the text and the x % coordinate of the change bar. % We also need the value of |\cb@pagecount| here, not during the write. % \begin{macrocode} \def\cb@defpoint##1##2{% \if@filesw \begingroup \edef\point{{\the##1}{\the\cb@pagecount}}% \let\the=\z@ \pdfsavepos \edef\cb@temp{\write\@auxout {\string\cb@pdfxy\point {\the\pdflastxpos}{\the\pdflastypos}{\the##2}}}% \cb@temp \endgroup \fi \cb@trace@defpoint##1##2% }% % \end{macrocode} % % \begin{macro}{\cb@cvtpct} % The macro |\cb@cvtpct| converts a percentage between 0 and 100 to a % decimal fraction. % \begin{macrocode} \def\cb@cvtpct##1{% \ifnum##1<0 0\else \ifnum##1>99 1\else \ifnum##1<10 0.0\the##1\else 0.\the##1\fi\fi\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdf@scale} % \changes{v3.6a}{2018/02/03}{Added macro for scale factor} % In order to get things in the right spot we need a little scaling % factor. We define it here. % \begin{macrocode} \def\cb@pdf@scale{0.996264009963} % \end{macrocode} % \end{macro} % % The |\cb@connect| finds the coordinates of the begin and end points, % converts them to PDF units and draws the bar with |\pdfliteral|. It % also sets the color or gray level, if necessary. When any of the % points is unknown the bar is skipped and a rerun is signalled. % \begin{macrocode} \def\cb@connect##1##2##3{% \cb@findpdfpoint{##1}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else \let\cb@pdftopy\cb@pdfy \cb@findpdfpoint{##2}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else % \end{macrocode} % We do everything in a group, so that we can freely use all kinds of % registers. % \begin{macrocode} \begingroup \cb@dima=\cb@pdfz \advance\cb@dima by-\cb@pdfx \advance\cb@dima by1in% \cb@dima=\cb@pdf@scale\cb@dima\relax % \end{macrocode} % First we let PDF save the graphics state. Then we generate the color % selection code followed by the code to draw the changebar. Finally the % graphics state is restored. We cannot use the color commands from the % color package here, as the generated PDF code may be moved to the next % line. % \begin{macrocode} \ifx\cb@current@color\@undefined \def\cb@temp{\cb@cvtpct\c@changebargrey}% \pdfliteral{q \cb@temp\space g \cb@temp\space G}% \else \pdfliteral{q \cb@current@color}% \fi \edef\cb@temp{\expandafter\cb@removedim\the\cb@dima\space}% \cb@dima=\cb@pdftopy \advance\cb@dima-\cb@pdfy\relax \cb@dima=\cb@pdf@scale\cb@dima\relax ##3=\cb@pdf@scale##3\relax \pdfliteral direct{\expandafter\cb@removedim\the##3 w \cb@temp 0 m \cb@temp \expandafter\cb@removedim\the\cb@dima\space l S Q}% \endgroup % \end{macrocode} % We look up the two unused points to get them removed from |\cb@pdfpoints|. % \begin{macrocode} \cb@cntb=##1\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \cb@cntb=##2\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \fi \fi \cb@trace@connect##1##2##3% }% % \end{macrocode} % % \begin{macro}{\cb@checkPdfxy} % The macro |\cb@checkPdfxy| checks if the coordinates of a point have % changed during the current run. If so, we need to rerun \LaTeX. % \changes{v3.6c}{2018/03/09}{Use \cs{ifdim} instead of \cs{ifnum} as % \cs{cb@pdfx} is defined as a dimension} % \begin{macrocode} \gdef\cb@checkPdfxy##1##2##3##4##5{% \cb@@findpdfpoint{##1}{##2}% % \end{macrocdode} % \begin{changebar} % \begin{macrocode \ifdim##3sp=\cb@pdfx\relax \ifdim##4sp=\cb@pdfy\relax % \end{macrocdode} % \end{changebar} % \begin{macrocode \ifdim##5=\cb@pdfz\relax \else \cb@error \fi \else \cb@error \fi \else \cb@error \fi } % \end{macrocode} % \end{macro} % % For PDF\TeX{} we don't need a limit on the number of bar points. % \begin{macrocode} \def\cb@maxpoint{9999999} \let\cb@resetpoints\relax \or % \end{macrocode} % % \changes{v3.6a}{2011/04/30}{Xe\TeX{} support added} % The code for Xe\TeX{} is, like for PDF\TeX{}, more elaborate as % the calculations have to % be done in \TeX. |\cb@defpoint| will write information about the % coordinates of the point to the \file{.aux} file, from where it will % be picked up in the next run. Then we will construct the PDF % code necessary to draw the changebars. % \begin{macrocode} \immediate\closeout\cb@writexy \immediate\openin\cb@readxy=\jobname.cb2\relax % \end{macrocode} % % \begin{macro}{\cb@pdfpoints} % \begin{macro}{\cb@pdfpagenr} % The |\cb@pdfpoints| macro contains the list of coordinates of points % that have been read in memory from the \file{.cb2} file. The % |\cb@pdfpagenr| macro contains the next pagecount to be read in. % \begin{macrocode} \def\cb@pdfpoints{} \def\cb@pdfpagenr{0} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\cb@findpdfpoint} % The |\cb@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. First we expand the arguments to get the real values. % \begin{macrocode} \def\cb@findpdfpoint##1##2{% \edef\cb@temp {\noexpand\cb@@findpdfpoint{\the##1}{\the##2}}% \cb@temp } % \end{macrocode} % \end{macro} % % \begin{macro}{\pdfliteral} % For Xe\TeX{} we mimick PDF\TeX's command |\pdfliteral|. % \begin{macrocode} \def\pdfliteral##1{\special{pdf:literal ##1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@@findpdfpoint} % The |\cb@@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. If the information is not yet in memory is it read from % the \file{.cb2} file. The coordinates of the current point in the text % will be delivered in |\cb@pdfx| and |\cb@pdfy|, and |\cb@pdfz| will get % the x coordinate of the changebar. If the point is unknown, |\cb@pdfx| % will be set to |\relax|. % \begin{macrocode} \def\cb@@findpdfpoint##1##2{% \ifnum##2<\cb@pdfpagenr\relax\else \cb@pdfreadxy{##2}% \fi \let\cb@pdfx\relax \ifx\cb@pdfpoints\@empty\else \ifnum##2<0\relax \else \edef\cb@temp{% \noexpand\cb@pdffind{##1}{##2}\cb@pdfpoints\relax{}}% \cb@temp \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdffind} % The |\cb@pdffind| recursively searches through |\cb@pdfpoints| to find % point \#1 on pagecount \#2. |\cb@pdfpoints| contains entries of the % form\\ % \meta{pointnr}.\meta{pagecount}p\meta{x},\meta{y},\meta{z}pt. % When the point is found it is removed from |\cb@pdfpoints|. \#9 % contains the cumulative head of the list to construct the new list % with the entry removed. \#3--\#8 are for pattern matching. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \def\cb@pdffind##1##2##3.##4p##5;##6;##7pt##8\relax##9{% \def\cb@next{% \cb@pdffind{##1}{##2}##8\relax{##9##3.##4p##5;##6;##7pt}}% \ifnum ##1=##3 \ifnum ##2=##4 \def\cb@pdfx{##5sp}% \def\cb@pdfy{##6sp}% \def\cb@pdfz{##7pt}% \let\cb@next\relax \gdef\cb@pdfpoints{##9##8}% \fi \fi \ifx\relax##8\relax \let\cb@next\relax \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfreadxy} % The |\cb@pdfreadxy| macro reads lines from the \file{.cb2} file in % |\cb@pdfpoints| until the pagecount is greater than \#1 or the end of % the file is reached. This ensures that all entries belonging to the % current column are in memory. % \begin{macrocode} \def\cb@pdfreadxy##1{% \let\cb@next\relax \ifeof\cb@readxy \global\let\cb@pdfpagenr\cb@maxpoint \else {\endlinechar=-1\read\cb@readxy to\cb@temp \ifx\cb@temp\@empty\else \expandafter\cb@pdfparsexy\cb@temp \ifnum\cb@pdfpg<0\else \xdef\cb@pdfpoints{\cb@pdfpoints\cb@temp}% \cb@trace{PDFpoints=\cb@pdfpoints}% \global\let\cb@pdfpagenr\cb@pdfpg \fi \ifnum\cb@pdfpg>##1\else \global\def\cb@next{\cb@pdfreadxy{##1}}% \fi \fi }% \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfparsexy} % The |\cb@pdfparsexy| macro extracts the pagecount from an entry read in % from the \file{.cb2} file. % \begin{macrocode} \def\cb@pdfparsexy##1.##2p##3;##4;##5pt{% \def\cb@pdfpg{##2}}% % \end{macrocode} % \end{macro} % % As \textsc{pdf} is not a programming language it does not have % any variables to remember the coordinates of the current % point. Therefore we write the information to the \file{.aux} file % and read it in in the next run. We write the x,y coordinates of % the current point in the text and the x coordinate of the change bar. % We also need the value of |\cb@pagecount| here, not during the write. % \begin{macrocode} \def\cb@defpoint##1##2{% \if@filesw \begingroup \edef\point{{\the##1}{\the\cb@pagecount}}% \let\the=\z@ \pdfsavepos \edef\cb@temp{\write\@auxout {\string\cb@pdfxy\point {\the\pdflastxpos}{\the\pdflastypos}{\the##2}}}% \cb@temp \endgroup \fi \cb@trace@defpoint##1##2% }% % \end{macrocode} % % \begin{macro}{\cb@cvtpct} % The macro |\cb@cvtpct| converts a percentage between 0 and 100 to a % decimal fraction. % \begin{macrocode} \def\cb@cvtpct##1{% \ifnum##1<0 0\else \ifnum##1>99 1\else \ifnum##1<10 0.0\the##1\else 0.\the##1\fi\fi\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdf@scale} % \changes{v3.6a}{2018/02/03}{Added macro for scale factor} % In order to get things in the right spot we need a little scaling % factor. We define it here. % \begin{macrocode} \def\cb@pdf@scale{0.996264009963} % \end{macrocode} % \end{macro} % % The |\cb@connect| finds the coordinates of the begin and end points, % converts them to PDF units and draws the bar with |\pdfliteral|. It % also sets the color or gray level, if necessary. When any of the % points is unknown the bar is skipped and a rerun is signalled. % \begin{macrocode} \def\cb@connect##1##2##3{% \cb@findpdfpoint{##1}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else \let\cb@pdftopy\cb@pdfy \cb@findpdfpoint{##2}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else % \end{macrocode} % We do everything in a group, so that we can freely use all kinds of % registers. % \begin{macrocode} \begingroup \cb@dima=\cb@pdfz \advance\cb@dima by-\cb@pdfx \advance\cb@dima by1in% \cb@dima=\cb@pdf@scale\cb@dima\relax % \end{macrocode} % First we let PDF save the graphics state. Then we generate the color % selection code followed by the code to draw the changebar. Finally the % graphics state is restored. We cannot use the color commands from the % color package here, as the generated PDF code may be moved to the next % line. % \begin{macrocode} \ifx\cb@current@color\@undefined \def\cb@temp{\cb@cvtpct\c@changebargrey}% \pdfliteral{q \cb@temp\space g \cb@temp\space G}% \else \pdfliteral{q \expandafter\sec@nd@ftw@\cb@current@color\space RG \expandafter\sec@nd@ftw@\cb@current@color\space rg}% \fi \edef\cb@temp{\expandafter\cb@removedim\the\cb@dima\space}% \cb@dima=\cb@pdftopy \advance\cb@dima-\cb@pdfy\relax \cb@dima=\cb@pdf@scale\cb@dima\relax ##3=\cb@pdf@scale##3\relax \pdfliteral{\expandafter\cb@removedim\the##3 w \cb@temp 0 m \cb@temp \expandafter\cb@removedim\the\cb@dima\space l S Q}% \endgroup % \end{macrocode} % We look up the two unused points to get them removed from |\cb@pdfpoints|. % \begin{macrocode} \cb@cntb=##1\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \cb@cntb=##2\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \fi \fi \cb@trace@connect##1##2##3% }% % \end{macrocode} % % \begin{macro}{\cb@checkPdfxy} % The macro |\cb@checkPdfxy| checks if the coordinates of a point have % changed during the current run. If so, we need to rerun \LaTeX. % \begin{macrocode} \gdef\cb@checkPdfxy##1##2##3##4##5{% \cb@@findpdfpoint{##1}{##2}% \ifdim##3sp=\cb@pdfx\relax \ifdim##4sp=\cb@pdfy\relax \ifdim##5=\cb@pdfz\relax \else \cb@error \fi \else \cb@error \fi \else \cb@error \fi } % \end{macrocode} % \end{macro} % % For Xe\TeX{} we don't need a limit on the number of bar points. % \begin{macrocode} \def\cb@maxpoint{9999999} \let\cb@resetpoints\relax % \end{macrocode} % % \begin{changebar} % \changes{v3.6e}{2023/08/13}{lua\TeX{} support added} % The code for lua\TeX{}, like for pdf\TeX\ and Xe\TeX, % is more elaborate as the calculations have to % be done in \TeX. |\cb@defpoint| will write information about the % coordinates of the point to the \file{.aux} file, from where it will % be picked up in the next run. Then we will construct the PDF % code necessary to draw the changebars. % \begin{macrocode} \or \immediate\closeout\cb@writexy \immediate\openin\cb@readxy=\jobname.cb2\relax % \end{macrocode} % % \begin{macro}{\cb@pdfpoints} % \begin{macro}{\cb@pdfpagenr} % The |\cb@pdfpoints| macro contains the list of coordinates of points % that have been read in memory from the \file{.cb2} file. The % |\cb@pdfpagenr| macro contains the next pagecount to be read in. % \begin{macrocode} \def\cb@pdfpoints{} \def\cb@pdfpagenr{0} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\cb@findpdfpoint} % The |\cb@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. First we expand the arguments to get the real values. % \begin{macrocode} \def\cb@findpdfpoint##1##2{% \edef\cb@temp {\noexpand\cb@@findpdfpoint{\the##1}{\the##2}}% \cb@temp } % \end{macrocode} % \end{macro} % % \begin{macro}{\pdfliteral} % For lua\TeX{} we also mimick PDF\TeX's command |\pdfliteral|. % \begin{macrocode} \def\pdfliteral##1{\pdfextension literal {##1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@@findpdfpoint} % The |\cb@@findpdfpoint| macro finds the coordinates of point \#1 on % pagecount \#2. If the information is not yet in memory is it read from % the \file{.cb2} file. The coordinates of the current point in the text % will be delivered in |\cb@pdfx| and |\cb@pdfy|, and |\cb@pdfz| will get % the x coordinate of the changebar. If the point is unknown, |\cb@pdfx| % will be set to |\relax|. % \begin{macrocode} \def\cb@@findpdfpoint##1##2{% \ifnum##2<\cb@pdfpagenr\relax\else \cb@pdfreadxy{##2}% \fi \let\cb@pdfx\relax \ifx\cb@pdfpoints\@empty\else \ifnum##2<0\relax \else \edef\cb@temp{% \noexpand\cb@pdffind{##1}{##2}\cb@pdfpoints\relax{}}% \cb@temp \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdffind} % The |\cb@pdffind| recursively searches through |\cb@pdfpoints| to find % point \#1 on pagecount \#2. |\cb@pdfpoints| contains entries of the % form\\ % \meta{pointnr}.\meta{pagecount}p\meta{x},\meta{y},\meta{z}pt. % When the point is found it is removed from |\cb@pdfpoints|. \#9 % contains the cumulative head of the list to construct the new list % with the entry removed. \#3--\#8 are for pattern matching. % \changes{v3.7b}{2023/12/30}{use ¨;¨ instead of ¨,¨ as delimiter} % \begin{macrocode} \def\cb@pdffind##1##2##3.##4p##5;##6;##7pt##8\relax##9{% \def\cb@next{% \cb@pdffind{##1}{##2}##8\relax{##9##3.##4p##5;##6;##7pt}}% \ifnum ##1=##3 \ifnum ##2=##4 \def\cb@pdfx{##5sp}% \def\cb@pdfy{##6sp}% \def\cb@pdfz{##7pt}% \let\cb@next\relax \gdef\cb@pdfpoints{##9##8}% \fi \fi \ifx\relax##8\relax \let\cb@next\relax \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfreadxy} % The |\cb@pdfreadxy| macro reads lines from the \file{.cb2} file in % |\cb@pdfpoints| until the pagecount is greater than \#1 or the end of % the file is reached. This ensures that all entries belonging to the % current column are in memory. % \begin{macrocode} \def\cb@pdfreadxy##1{% \let\cb@next\relax \ifeof\cb@readxy \global\let\cb@pdfpagenr\cb@maxpoint \else {\endlinechar=-1\read\cb@readxy to\cb@temp \ifx\cb@temp\@empty\else \expandafter\cb@pdfparsexy\cb@temp \ifnum\cb@pdfpg<0\else \xdef\cb@pdfpoints{\cb@pdfpoints\cb@temp}% \cb@trace{PDFpoints=\cb@pdfpoints}% \global\let\cb@pdfpagenr\cb@pdfpg \fi \ifnum\cb@pdfpg>##1\else \global\def\cb@next{\cb@pdfreadxy{##1}}% \fi \fi }% \fi \cb@next }% % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdfparsexy} % The |\cb@pdfparsexy| macro extracts the pagecount from an entry read in % from the \file{.cb2} file. % \begin{macrocode} \def\cb@pdfparsexy##1.##2p##3;##4;##5pt{% \def\cb@pdfpg{##2}}% % \end{macrocode} % \end{macro} % % As PDF is not a programming language it does not have any variables to % remember the coordinates of the current point. Therefore we write the % information to the \file{.aux} file and read it in in the next run. We % write the x,y coordinates of the current point in the text and the x % coordinate of the change bar. % We also need the value of |\cb@pagecount| here, not during the write. % \begin{macrocode} \def\cb@defpoint##1##2{% \if@filesw \begingroup \edef\point{{\the##1}{\the\cb@pagecount}}% \let\the=\z@ \savepos \edef\cb@temp{\write\@auxout {\string\cb@pdfxy\point {\the\lastxpos}{\the\lastypos}{\the##2}}}% \cb@temp \endgroup \fi \cb@trace@defpoint##1##2% }% % \end{macrocode} % % \begin{macro}{\cb@cvtpct} % The macro |\cb@cvtpct| converts a percentage between 0 and 100 to a % decimal fraction. % \begin{macrocode} \def\cb@cvtpct##1{% \ifnum##1<0 0\else \ifnum##1>99 1\else \ifnum##1<10 0.0\the##1\else 0.\the##1\fi\fi\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@pdf@scale} % \changes{v3.6a}{2018/02/03}{Added macro for scale factor} % In order to get things in the right spot we need a little scaling % factor. We define it here. % \begin{macrocode} \def\cb@pdf@scale{0.996264009963} % \end{macrocode} % \end{macro} % % The |\cb@connect| finds the coordinates of the begin and end points, % converts them to PDF units and draws the bar with |\pdfliteral|. It % also sets the color or gray level, if necessary. When any of the % points is unknown the bar is skipped and a rerun is signalled. % \begin{macrocode} \def\cb@connect##1##2##3{% \cb@findpdfpoint{##1}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else \let\cb@pdftopy\cb@pdfy \cb@findpdfpoint{##2}\cb@pagecount \ifx\cb@pdfx\relax\cb@rerun \else % \end{macrocode} % We do everything in a group, so that we can freely use all kinds of % registers. % \begin{macrocode} \begingroup \cb@dima=\cb@pdfz \advance\cb@dima by-\cb@pdfx \advance\cb@dima by1in% \cb@dima=\cb@pdf@scale\cb@dima\relax % \end{macrocode} % First we let PDF save the graphics state. Then we generate the color % selection code followed by the code to draw the changebar. Finally the % graphics state is restored. We cannot use the color commands from the % color package here, as the generated PDF code may be moved to the next % line. % \begin{macrocode} \ifx\cb@current@color\@undefined \def\cb@temp{\cb@cvtpct\c@changebargrey}% \pdfliteral{q \cb@temp\space g \cb@temp\space G}% \else \pdfliteral{q \cb@current@color}% \fi \edef\cb@temp{\expandafter\cb@removedim\the\cb@dima\space}% \cb@dima=\cb@pdftopy \advance\cb@dima-\cb@pdfy\relax \cb@dima=\cb@pdf@scale\cb@dima\relax ##3=\cb@pdf@scale##3\relax \pdfliteral{\expandafter\cb@removedim\the##3 w \cb@temp 0 m \cb@temp \expandafter\cb@removedim\the\cb@dima\space l S Q}% \endgroup % \end{macrocode} % We look up the two unused points to get them removed from |\cb@pdfpoints|. % \begin{macrocode} \cb@cntb=##1\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \cb@cntb=##2\relax \ifodd\cb@cntb\advance\cb@cntb 1\else\advance\cb@cntb -1\fi \cb@findpdfpoint\cb@cntb\cb@pagecount \fi \fi \cb@trace@connect##1##2##3% }% % \end{macrocode} % % \begin{macro}{\cb@checkPdfxy} % The macro |\cb@checkPdfxy| checks if the coordinates of a point have % changed during the current run. If so, we need to rerun \LaTeX. % \begin{macrocode} \gdef\cb@checkPdfxy##1##2##3##4##5{% \cb@@findpdfpoint{##1}{##2}% \ifdim##3sp=\cb@pdfx\relax \ifdim##4sp=\cb@pdfy\relax \ifdim##5=\cb@pdfz\relax \else \cb@error \fi \else \cb@error \fi \else \cb@error \fi } % \end{macrocode} % \end{macro} % % For lua\TeX{} we don't need a limit on the number of bar points. % \begin{macrocode} \def\cb@maxpoint{9999999} \let\cb@resetpoints\relax % \end{macrocode} %\end{changebar} % % 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} \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} % \end{macro} % \end{macro} % \end{macro} % % The last thing to do is to forget about |\cb@setup@specials|. % \begin{macrocode} \global\let\cb@setup@specials\relax} % \end{macrocode} % \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. % \changes{v3.7d}{2024/01/09}{Make sure spaces are ignored (cf. change % 3.7c)} % \begin{macrocode} \newcommand*{\nochangebars}{% \def\cb@start[##1]{\ignorespaces}% \def\cb@delete[##1]{}% \def\cb@end{\ignorespacesafterend} } % \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|. % \changes{v3.6b}{2018/02/04}{set the default separtion between text % and changebars to half the separation between text and marginal % paragraphs} % \begin{macrocode} \newlength{\changebarsep} \setlength{\changebarsep}{0.5\marginparsep} % \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 one of the options \Lopt{color} or \Lopt{xcolor} was % selected we need to load the appropriate package. When we're run % by pdf\LaTeX\ we need to pass that information on to that package. % \changes{v3.4e}{2001/09/14}{Detect pdf mode} % \changes{v3.5a}{2005/05/23}{The option \Lopt{pdftex} will be supplied % automatically with the current color packages. Leave out % \Lopt{dvipsnames} as it is usually automatically loaded and may clash % if the color or xcolor package has already been loaded. Also % \cs{cb@color@pkg} is undefined when no color option has been given.} % \begin{macrocode} \@ifpackagewith{changebar}{\csname cb@color@pkg\endcsname}{% \RequirePackage{\cb@color@pkg}% % \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|. % \changes{v3.5c}{2005/09/18}{Use the higher level interface throug % \cs{color} to prevent problemns with \texttt{color.sty} or % \texttt{xcolor.sty}} % \begin{macrocode} \def\@undeclaredcbcolor[#1]#2{% \begingroup \color[#1]{#2}% \global\let\cb@current@color\current@color \endgroup \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\@declaredcbcolor} % \changes{v3.5c}{2005/09/18}{Use the higher level interface throug % \cs{color} to prevent problemns with \texttt{color.sty} or % \texttt{xcolor.sty}} % \begin{macrocode} \def\@declaredcbcolor#1{% \begingroup \color{#1}% \global\let\cb@current@color\current@color \endgroup \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. % \changes{v3.5a}{2005/05/23}{Correction for nested changebars} % \begin{macrocode} \cb@checkpage\z@ % \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|. % \changes{v3.7c}{2024/01/01}{Added \cs{ignorespaces} at the end to % prevent a spcae token from creaping into the output} % \begin{macrocode} \cb@pagecount\cb@cnta \cb@advancePoint\ignorespaces} % \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. % When in horizontal mode we put the call to |\cb@setEndPoints| % inside a |\vadjust|. This ensures that things with a large depth, % e.g. a parbox or formula will be completely covered. By default % these have their baseline centered, and thus otherwise the % changebar would stop there. % % \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} % \changes{v3.5a}{2005/05/23}{Added \cs{vadjust} in horizontal mode.} % \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. % \changes{v3.5a}{2005/05/23}{Correction for nested changebars} % \begin{macrocode} \cb@checkpage\thr@@ % \end{macrocode} % Again, we need to temporarily overwrite |\cb@pagecount|. % \changes{v3.7c}{2024/01/01}{We need \cs{ignorespacesafterend} here, % not \cs{ignorespaces}} % \begin{macrocode} \cb@cnta\cb@pagecount \cb@pagecount\cb@page\advance\cb@pagecount\m@ne \ifvmode \cb@setEndPoints \else \vadjust{\cb@setEndPoints}% \fi \cb@pagecount\cb@cnta \fi \ignorespacesafterend} % \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|. % The parameter indicates whether we are searching for a begin % point (0) or end point (3). % \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} % \changes{v3.5a}{2005/05/23}{Correction for nested changebars} % \begin{macrocode} \def\cb@checkpage#1{% % \end{macrocode} % First store the identifiers in temporary registers. % \begin{macrocode} \cb@cnta\cb@topleft\relax \advance\cb@cnta by #1\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} % \changes{v3.5a}{2005/05/23}{Correction for moving floats} % Now keep popping the stack until |\cb@topleft| is found. 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} \cb@FindPageNum % \end{macrocode} % \changes{v3.5a}{2005/05/23}{Correction for nested changebars} % \begin{macrocode} \ifnum\cb@topleft>\cb@maxpoint\else % \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 % \changes{v3.5a}{2005/05/23}{Correction for nested changebars} % \begin{macrocode} \advance\cb@cnta by -#1\relax \cb@topleft\cb@cnta\relax \cb@page\cb@cntb\relax \cb@curbarwd\cb@dima\relax } % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@FindPageNum} % |\cb@FindPageNum| recursively searches through the history stack until % an entry is found that is equal to |\cb@cnta|. % \begin{macrocode} \def\cb@FindPageNum{% \ifnum\cb@topleft=\cb@cnta % \end{macrocode} % We have found it, exit the macro, otherwise push the current entry on % the temporary stack and pop a new one from the history stack. % \begin{macrocode} \else \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 \else % \end{macrocode} % Recursively call ourselves. % \begin{macrocode} \expandafter\expandafter\expandafter\cb@FindPageNum \fi \fi }% % \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. % \changes{v3.5a}{2005/05/23}{Correction for mixed onecolumn and twocolumn % documents and page number changes} % \begin{macrocode} \def\cb@setBeginPoints{% \cb@topright=\cb@topleft\advance\cb@topright by\@ne \cb@cntb=\cb@pagecount \divide\cb@cntb by\tw@ \ifodd\cb@cntb \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} % \changes{v3.5a}{2005/05/23}{The test for \Lopt{twoside} is really % unnecessary if the even side is always chosen for an even page} % \changes{v3.5a}{2005/05/23}{Correction for mixed onecolumn and twocolumn % documents and page number changes} % \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@@ \cb@cntb=\cb@pagecount \divide\cb@cntb by\tw@ \ifodd\cb@cntb \cb@defpoint\cb@botleft\cb@even@left \cb@defpoint\cb@botright\cb@even@right \else \cb@defpoint\cb@botleft\cb@odd@left \cb@defpoint\cb@botright\cb@odd@right \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} % \changes{v3.5a}{2005/05/23}{Checking |@firstcolumn| outside the output % routine is unreliable; check \cs{cb@pagecount} instead} % In twocolumn pages always use outerbars % \begin{macrocode} \if@twocolumn \ifodd\cb@pagecount\cb@rightbar\else\cb@leftbar\fi % \end{macrocode} % % \changes{v3.4e}{2001/09/07}{The \cs{outerbars} conditional should be % inside an \cs{else} clause} % \changes{v3.5a}{2005/05/23}{Series of \cs{if}s replaced by % \cs{ifcase} on \cs{cb@barsplace}} % \begin{macrocode} \else \ifcase\cb@barsplace % \end{macrocode} % 0=innerbars % \begin{macrocode} \ifodd\cb@cntb \cb@rightbar \else \if@twoside\cb@leftbar\else\cb@rightbar\fi \fi \or % \end{macrocode} % 1=outerbars % \begin{macrocode} \ifodd\cb@cntb \cb@leftbar \else \if@twoside\cb@rightbar\else\cb@leftbar\fi \fi \or % \end{macrocode} % 2=leftbars % \begin{macrocode} \cb@leftbar \or % \end{macrocode} % 3=rightbars % \begin{macrocode} \cb@rightbar \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} % % \changes{v3.5a}{2005/05/23}{Changes for twocolumn support: Detect page % number changes in righthand columns.} % \begin{Var}{@cb@pagejump} % A switch to indicate that we have made a page correction. % \begin{macrocode} \newif\if@cb@pagejump % \end{macrocode} % \end{Var} % \begin{macro}{\cb@pagejumplist} % The list of pagecounts to be corrected. % \begin{macrocode} \def\cb@pagejumplst{-1} % \end{macrocode} % \end{macro} % \begin{macro}{\cb@nextpagejump} % The next pagecount from the list. % \begin{macrocode} \def\cb@nextpagejump{-1} % \end{macrocode} % \end{macro} % \begin{macro}{\cb@pagejump} % This macro is written to the \file{.aux} file when a pagecount in a % lefthand column should be corrected. The argument is the incorrect % pagecount. % \begin{macrocode} \def\cb@pagejump#1{\xdef\cb@pagejumplst{\cb@pagejumplst,#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\cb@writepagejump} % This macro writes a |\cb@pagejump| entry to the \file{.aux} file. % It does it by putting the |\write| command in the |\@leftcolumn| so % that it will be properly positioned relative to the bar points. % \begin{macrocode} \def\cb@writepagejump#1{ \cb@cntb=\cb@pagecount \advance\cb@cntb by#1\relax \global\setbox\@leftcolumn\vbox to\@colht{% \edef\cb@temp{\write\@auxout{\string\cb@pagejump{\the\cb@cntb}}}% \cb@temp \dimen@ \dp\@leftcolumn \unvbox \@leftcolumn \vskip -\dimen@ }% } % \end{macrocode} % \end{macro} % \begin{macro}{\cb@poppagejump} % Pop an entry from |pagejumplst|. The entry is put in |\cb@nextpagejump|. % \begin{macrocode} \def\cb@poppagejump#1,#2\relax{% \gdef\cb@nextpagejump{#1}% \gdef\cb@pagejumplst{#2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@checkpagecount} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % This macro checks that |\cb@pagecount| is correct at the beginning of % a column or page. % First we ensure that |\cb@pagecount| has the proper parity: odd in the % righthand column of a twocolumn page, even in the lefthand column of a % twocolumn page and in onecolumn pages. % \begin{macrocode} \def\cb@checkpagecount{% \if@twocolumn \if@firstcolumn \ifodd\cb@pagecount\global\advance\cb@pagecount by\@ne\fi \fi \else \ifodd\cb@pagecount\global\advance\cb@pagecount by\@ne\fi \fi % \end{macrocode} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % Also, in twosided documents, |\cb@pagecount|/2 must be odd on even pages % and even on odd pages. If necessary, increase |\cb@pagecount| by 2. For % onesided documents, we don't do this as it doesn't matter (but it % would be harmless). % In the righthand column in twoside documents we must check if % |\cb@pagecount|/2 has the proper parity (see below). % If it is incorrect, the page number has changed after the lefthand % column, so |\cb@pagecount| is incorrect there. Therefore we write a % command in the \file{.aux} file so that in the next run the lefthand % column will correct its |\cb@pagecount|. We also need to signal % a rerun. If the correction was % made in the lefthand column, the flag |@cb@pagejump| is set, and we have % to be careful in the righthand column. If in the righthand column the % flag is set and |\cb@pagecount| is correct, the correction in the % lefthand column worked, but we still have to write into the % \file{.aux} file for the next run. If on the other hand % |\cb@pagecount| is incorrect while the flag is set, apparently the % correction in the lefthand column should not have been done (probably % because the document has changed), so we do nothing. % \begin{macrocode} \if@twoside \cb@cntb=\cb@pagecount \divide\cb@cntb by\tw@ \advance\cb@cntb by-\c@page \ifodd\cb@cntb % \end{macrocode} % Here |\cb@pagecount| seems correct. Check if there is a page jump. % \begin{macrocode} \if@twocolumn \if@firstcolumn \@whilenum\cb@pagecount>\cb@nextpagejump\do{% \expandafter\cb@poppagejump\cb@pagejumplst\relax}% \ifnum\cb@pagecount=\cb@nextpagejump \cb@trace{Page jump: \string\cb@pagecount=\the\cb@pagecount} \global\advance\cb@pagecount by\tw@ \global\@cb@pagejumptrue \else \global\@cb@pagejumpfalse \fi \else % \end{macrocode} % In the righthand column check the flag (see above). If set, write a % pagejump, but compensate for the increase done in the lefthand column. % \begin{macrocode} \if@cb@pagejump \cb@writepagejump{-3}% \fi \fi \fi \else % \end{macrocode} % Here |\cb@pagecount| is incorrect. % \begin{macrocode} \if@twocolumn \if@firstcolumn \global\advance\cb@pagecount by\tw@ \global\@cb@pagejumpfalse \else \if@cb@pagejump \cb@trace{Page jump annulled, % \string\cb@pagecount=\the\cb@pagecount} \else \cb@writepagejump{-1}% \global\advance\cb@pagecount by\tw@ \cb@rerun \fi \fi \else \global\advance\cb@pagecount by\tw@ \fi \fi \fi } % \end{macrocode} % \end{macro} % % \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} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % \begin{macrocode} \let\ltx@makecol\@makecol \def\cb@makecol{% \if@twocolumn \cb@trace{Twocolumn: \if@firstcolumn Left \else Right \fi column}% \fi \cb@trace@stack{before makecol, page \the\c@page, \string\cb@pagecount=\the\cb@pagecount}% \let\cb@writeAux\@gobble % \end{macrocode} % First make sure that |\cb@pagecount| is correct. % Then add the necessary bar points at beginning and end. % \begin{macrocode} \cb@checkpagecount \setbox\@cclv \vbox{% \cb@resetpoints \cb@startSpanBars \unvbox\@cclv \boxmaxdepth\maxdepth}% \global\advance\cb@pagecount by\@ne \cb@buildstack\cb@processActive \ltx@makecol % \end{macrocode} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % In twocolumn pages write information to the aux file to indicate which % column we are in. This write must precede the whole column, including % floats. Therefore we insert it in the front of |\@outputbox|. % \begin{macrocode} \if@twocolumn \global\setbox\@outputbox \vbox to\@colht {% \if@firstcolumn\write\@auxout{\string\@cb@firstcolumntrue}% \else\write\@auxout{\string\@cb@firstcolumnfalse}% \fi \dimen@ \dp\@outputbox \unvbox \@outputbox \vskip -\dimen@ }% \fi \cb@trace@stack{after makecol, page \the\c@page, \string\cb@pagecount=\the\cb@pagecount}% } \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} % \changes{v3.5a}{2005/05/23}{We don't want spanning changebars from a % previous page in a float column. % The original code didn't work anyway. It did set \@outputbox, % which is immediately discarded in \cs{@ltx@vtryfc}.} % In twocolumn mode we must write either \cs{@cb@firstcolumntrue} or % \cs{@cb@firstcolumnfalse} to the \file{.aux} file. % \begin{macrocode} \let\ltx@vtryfc\@vtryfc \def\cb@vtryfc#1{% \cb@trace{In vtryfc, page \the\c@page, \string\cb@pagecount=\the\cb@pagecount}% \let\cb@writeAux\@gobble % \end{macrocode} % First make sure that |\cb@pagecount| is correct. % Then generate a |\@cb@firstcolumntrue| or |\@cb@firstcolumnfalse| in % twocolumn mode. % \begin{macrocode} \cb@checkpagecount \ltx@vtryfc{#1}% \if@twocolumn \global\setbox\@outputbox \vbox to\@colht{% \if@firstcolumn\write\@auxout{\string\@cb@firstcolumntrue}% \else\write\@auxout{\string\@cb@firstcolumnfalse}% \fi \unvbox\@outputbox \boxmaxdepth\maxdepth }% \fi \global\advance\cb@pagecount by \@ne } \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{ % ... } % % 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} % \changes{v3.5a}{2005/05/23}{The check for history stack is improved. % Originally it succeeded if the stack contents was equal to the history % stack; now it specifically checks that we are popping the history % stack itself. Moreover we read from file only if the history % stack is empty.} % \begin{macrocode} \def\cb@thehistorystack{\cb@historystack} \def\cb@pop#1{% \ifx #1\@empty \def\cb@temp{#1}% \ifx\cb@temp\cb@thehistorystack \ifeof\cb@read \else {\endlinechar=-1\read\cb@read to\cb@temp \xdef\cb@historystack{\cb@historystack\cb@temp}% }% \fi \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. % \changes{v3.5a}{2005/05/23}{Changes for twocolumn support: if a bar point % is in the left column we have to subtract one from the pagecount.} % \begin{macrocode} \def\cb@barpoint#1#2#3{\cb@cnta=#2 \if@cb@firstcolumn\advance\cb@cnta by\m@ne\fi \immediate\write\cb@write{#1n\the\cb@cnta p#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} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % Add a sentinel to \cs{cb@pagejumplst}. % \begin{macrocode} \cb@pagejump{999999999,}% % \end{macrocode} % \changes{v3.5a}{2005/05/23}{Adaption of \cs{cb@pagecount} is no longer % necessary, as \cs{cb@pagecount} will be adjusted at the beginning of % \cs{@makecol} and \cs{@vtryfc}.} % Compute the left and right positions of the changebars. % \changes{v3.4g}{2004/01/09}{Added tracing information for the left % and right postions} % \changes{v3.6d}{2022-05-06}{Added \cs{relax} to end the filename} % \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\relax} % \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}} % \changes{v3.6d}{2022-05-06}{Added \cs{relax} to end the filename} % \begin{macrocode} \AtEndDocument{% \clearpage \cb@initstack\cb@historystack \immediate\closein\cb@read \immediate\openin\cb@read=\jobname.cb\relax % \end{macrocode} % % \changes{v3.5a}{2005/05/23}{For pdftex we also close and reread the % \file{.cb2} file.} % Let |\cb@pdfxy=\cb@checkPdfxy| for checking. Make |\cb@pagejump| dummy. % \begin{macrocode} \ifx\cb@readxy\@undefined \else \immediate\closein\cb@readxy \immediate\openin\cb@readxy=\jobname.cb2\relax \def\cb@pdfpoints{}% \def\cb@pdfpagenr{0}% \fi \@cb@firstcolumnfalse \cb@checkrerun \let\cb@pdfxy\cb@checkPdfxy \let\cb@pagejump\@gobble \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. % \changes{v3.5a}{2005/05/23}{Changes for twocolumn support: if a bar point % is in the left column we have to subtract one from the pagecount.} % \begin{macrocode} \def\cb@checkHistory#1#2#3{% \cb@pop\cb@historystack \ifnum #1=\cb@topleft\relax \cb@cnta=#2 \if@cb@firstcolumn\advance\cb@cnta by\m@ne\fi \ifnum \cb@cnta=\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} % Dummy definition for |\cb@checkPdfxy|. This will be overwritten by % the \Lopt{pdftex} and \Lopt{xetex} options. % \begin{macrocode} \def\cb@checkPdfxy#1#2#3#4#5{} % \end{macrocode} % \end{macro} % % \begin{macro}{\cb@rerun} % \changes{v3.5a}{2005/05/23}{Changes for better twocolumn support} % The macro |\cb@rerun| is called when we detect that we need to rerun % \LaTeX. % \begin{macrocode} \def\cb@rerun{% \global\let\cb@checkrerun\cb@error} \let\cb@checkrerun\relax % \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. % \changes{v3.5a}{2005/05/23}{Added pdftex support} % For pdf\TeX and Xe\TeX we also disable % |\cb@checkPdfxy|. % \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 \gdef\cb@checkPdfxy##1##2##3##4##5{}% \let\cb@pdfxy\cb@checkPdfxy} % \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} % % \begin{macro}{\@xympar} % There is one snag with this redefinition in that the macro % |\end@float| is also used by the command |\marginpar|. This may % lead to problems with stack underflow. Therefore we need to % redefine an internal macro from the marginal paragraph mechanism % as well. The solution is to make sure the this macro uses the % original definition of |\end@float|. % \changes{v3.5d}{2005/12/24}{Redefine \cs{@xympar} to use the % original version of \cs{end@float}} % \begin{macrocode} \let\ltx@@xympar\@xympar \def\@xympar{% \let\end@float\ltx@end@float \ltx@@xympar \let\end@float\cb@end@float} % \end{macrocode} % \end{macro} % % \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 % % \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 \~} %% %%