# marking conditional versions with line in margin

I have two versions of a document, which I have implemented using the versions package. So I can use \includeversion/\excludeversion to generate the different versions from the same source.

I would like to generate a single document, in which the conditional material is neither included nor excluded, but marked. The versions package provides the \markversion command and the hooks \beginmarkversion and \endmarkversion for this purpose. I want my marks to be a vertical line that runs in the margin along the entire conditional material.

Here is my implementation so far. I know this is probably an abuse of TikZ, but it's the only way I know how to begin:

\documentclass{article}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{versions}
% customize the marks of beginning and ending version
\makeatletter
%% TikZ style
\newcounter{versionmark}
\renewcommand{\beginmarkversion}{%
\stepcounter{versionmark}%
\begin{tikzpicture}[overlay, remember picture]
\node[coordinate] (bv\theversionmark) at ([xshift=2cm]0,0 -| current page.south west) {};
\end{tikzpicture}%
}
\renewcommand{\endmarkversion}{%
\edef\theversion{\@currenvir}
\begin{tikzpicture}[overlay, remember picture]
\node[coordinate] (ev\theversionmark) at ([xshift=2cm]0,0 -| current page.south west) {};
\draw[red!80!black]
(ev\theversionmark)
-- (bv\theversionmark) node[midway,sloped,anchor=south] {\theversion};
\draw[red!80!black]
(ev\theversionmark) --++ (1ex,0cm)
(bv\theversionmark) --++ (1ex,0cm);
\end{tikzpicture}%
}
\makeatother
\markversion{A}
\markversion{B}
%\includeversion{A}
%\excludeversion{B}

\begin{document}

\begin{A}
\lipsum[1]
\end{A}

\begin{B}
\lipsum[2]
\end{B}

\begin{A}
\lipsum
\end{A}

\end{document}


This works in the first two cases, but not in the third because the conditional material is longer than a page. When the second \end{A} is found, the line begins not at the point of the second \begin{A}, but the point on the page of \end{A} that's in the same position as \begin{A} is on its page:

How can I fix this so the line starts at the beginning of the conditional material and ends at the end of it?

-
This question should be helpful: Test if a paragraph has a page break in it? –  Seamus Jan 23 '12 at 13:19
@Seamus: Thanks! –  Matthew Leingang Jan 23 '12 at 13:26

I followed Seamus's pointer to Martin's answer to Test if a paragraph has a page break in it? and got something that works pretty well:

\documentclass{article}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{versions}
\usepackage{zref-abspage}
\usepackage{zref-user}
\usepackage{tikz}
\usepackage{atbegshi}
\usetikzlibrary{calc}

\makeatletter
\newcommand{\currentsidemargin}{%
\ifodd\zref@extract{textarea-\thetextarea}{abspage}%
\oddsidemargin%
\else%
\evensidemargin%
\fi%
}

\newcounter{textarea}
\newcommand{\settextarea}{%
\stepcounter{textarea}%
\zlabel{textarea-\thetextarea}%
\begin{tikzpicture}[overlay,remember picture]
% Helper nodes
\path (current page.north west) ++(\hoffset, -\voffset)
node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\paperwidth, minimum height=\paperheight]
(pagearea) {};
node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\textwidth, minimum height=\textheight]
(textarea) {};
\end{tikzpicture}%
}

\tikzset{tikzborder/.style={line width=1mm,red,double=blue}}

\newcounter{tikzborder}
\newcounter{tikzborderpages}
\newenvironment{tikzborder}[1][]{%
\medskip\par
% Allow user to overwrite the used style locally
\ifx&#1&\else
\tikzset{tikzborder/.style={#1}}%
\fi
\settextarea
\stepcounter{tikzborder}%
\tikz[overlay,remember picture] \coordinate (tikzborder-\thetikzborder);% Modified \tikzmark macro
\zlabel{tikzborder-begin-\thetikzborder}%
% Test if end-label is at the same page and draw first half of border if not
\ifnum\zref@extract{tikzborder-begin-\thetikzborder}{abspage}=\zref@extract{tikzborder-end-\thetikzborder}{abspage} \else
\begin{tikzpicture}[overlay,remember picture]
\draw [tikzborder]
let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
(\x0-\fboxsep-.5\pgflinewidth,\y2-\fboxsep-.5\pgflinewidth)
--
(\x0-\fboxsep-.5\pgflinewidth,\ht\strutbox+\fboxsep+.5\pgflinewidth)
node[midway,anchor=east] {\currver}
;
\end{tikzpicture}%
% If it spreads over more than two pages:
\setcounter{tikzborderpages}{\numexpr-\zref@extract{tikzborder-begin-\thetikzborder}{abspage}+\zref@extract{tikzborder-end-\thetikzborder}{abspage}}
\ifnum\value{tikzborderpages}>1
\AtBeginShipoutNext{\tikzborderpage}%
\fi
\fi
}{%
\zlabel{tikzborder-end-\thetikzborder}%
% Test if begin-label is at the same page and draw whole border if so
\ifnum\zref@extract{tikzborder-begin-\thetikzborder}{abspage}=\zref@extract{tikzborder-end-\thetikzborder}{abspage}
\begin{tikzpicture}[overlay,remember picture]
\draw [tikzborder]
let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
(\x0-\fboxsep-.5\pgflinewidth,\y1+\ht\strutbox+\fboxsep+.5\pgflinewidth)
--
(\x0-\fboxsep-.5\pgflinewidth,-\dp\strutbox-\fboxsep-.5\pgflinewidth)
node [midway,anchor=east] {\currver};
;
\end{tikzpicture}%
% Otherwise draw second half of border
\else
\settextarea
\begin{tikzpicture}[overlay,remember picture]
\draw [tikzborder]
let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
(\x0-\fboxsep-.5\pgflinewidth,\y0+\fboxsep+.5\pgflinewidth)
--
(\x0-\fboxsep-.5\pgflinewidth,-\dp\strutbox-\fboxsep-.5\pgflinewidth)
node[midway,anchor=east] {\currver}
;
\end{tikzpicture}%
\fi
\par\medskip
}

\newcommand{\tikzborderpage}{%
\settextarea
\begin{tikzpicture}[overlay,remember picture]
\draw [tikzborder]
([shift={(-\fboxsep-.5\pgflinewidth, \fboxsep+.5\pgflinewidth)}]textarea.north west)
--
([shift={(-\fboxsep-.5\pgflinewidth,-\fboxsep-.5\pgflinewidth)}]textarea.south west)
node[midway,anchor=east] {\currver}
;
\end{tikzpicture}%
\ifnum\value{tikzborderpages}>1
\AtBeginShipoutNext{\tikzborderpage}%
\fi
\vspace{-\baselineskip}% Compensate for the generated extra line at begin of the page. No idea why exactly this happens. Also \baselineskip seems not to be 100% right.
}
\makeatother

\usepackage{lipsum}
\newcommand\xlipsum[1][]{{\let\par\relax\lipsum*[#1]}}

% customize the marks of beginning and ending version
\makeatletter
\newcounter{versionmark}
\renewcommand{\beginmarkversion}{%
\makeatletter
\edef\currver{\@currenvir}
\makeatother
\begin{tikzborder}
}
\renewcommand{\endmarkversion}{%
\end{tikzborder}
}
\makeatother
\markversion{A}
\markversion{B}

\begin{document}

\begin{A}
\lipsum[1]
\end{A}

\begin{B}
\lipsum[2]
\end{B}

\begin{A}
\lipsum
\end{A}

\begin{B}
\lipsum
\lipsum
\end{B}

\end{document}


I'm sure that some pgfkeys magic would make this more flexible.

-
pgfkeys makes everything more flexible. pgfkeys even makes pgfkeys more flexible… what? –  Seamus Jan 23 '12 at 16:06
Doesn't work, even your fixed example. Some vertical lines appeared in the middle of the text, not at the margin. Attached a small screen shot. P.S.: Ubuntu 12.04, TexLive 2009-15. !enter image description here –  user1038377 Nov 22 '13 at 7:56

I'm not a TeX-wizard, but why don't you use the changespackage, see here:

http://changes.sourceforge.net/

-
Thanks for the suggestion, but the changes to my documents are not edits but concurrent versions. So to adapt the changes package to my needs would be square peg in a round hole. –  Matthew Leingang Jan 23 '12 at 13:26