While I was looking at my old paracol solution I started thinking I could do it better. In particular, I should be able to handle more than one note per paragraph.
The advantage of this solution is that it will never overlap and will break across pages. Because the notes are being written to the AUX file, I put most of the formatting into \marginparformat
. Also, it takes two runs.
The main problem in implementing this is that you can only switch columns between paragraphs, which can be solved using \everypar
. Even then, you need to know at the beginning of the paragraph what will be coming up later. The solution is to write the needed information to the AUX file. When you switch back to the original column, it immediately kicks off another \everypar
which you have to ignore or get trapped in a loop.
It should be noted that \everypar
tends not to be preserved. I rewrote \@afterheading
, but there are bound to be others.
\documentclass{article}
\usepackage[ %
%top=Bcm,
%bottom=Hcm,
%outer=Ccm,
%inner=Acm,
%heightrounded,
textwidth={\dimexpr 5in+5cm+2\columnsep},
marginparwidth=0pt,
marginparsep=0pt
]{geometry}
\usepackage[nopar]{lipsum}
\usepackage{soul} % for highlighting the text: \hl
\usepackage{setspace} % for setting the linespace for a portion of the text: \setstretch
\usepackage{color}
\definecolor{dkblue}{rgb}{0.0, 0.0, 0.6}
\definecolor{ltblue}{rgb}{0.6, 0.6, 1.0}
\usepackage{paracol}
\setcolumnwidth{2.5cm, 5in, 2.5cm}
\newcommand{\marginparformat}% only change between paragraphs
{\tiny% affects em and ex
\parindent=2em
\parskip=1ex
\sloppy
\setstretch{0.5}%
\color{dkblue}%
\noindent note: }
\newcounter{absparagraph}
\newcounter{leftmarginpar}
\newcounter{rightmarginpar}
\globalcounter{absparagraph}
\globalcounter{leftmarginpar}
\globalcounter{rightmarginpar}
\makeatletter
\newcommand{\leftmarginpar}[1]% #1=text
{\stepcounter{leftmarginpar}%
\pdfsavepos
\protected@write\@auxout{}{\string\newleftmarginpar{\theleftmarginpar}{\theabsparagraph}%
{\thepage}{\noexpand\number\pdflastypos}{#1}}}%
\newcommand{\rightmarginpar}[1]% #1=text
{\stepcounter{rightmarginpar}%
\pdfsavepos
\protected@write\@auxout{}{\string\newrightmarginpar{\therightmarginpar}{\theabsparagraph}%
{\thepage}{\noexpand\number\pdflastypos}{#1}}}%
%begin gory details
\newcommand{\pagetop@y}{\dimexpr \paperheight-1in-\topmargin-\headheight-\headsep}
\newcommand{\current@page}{}% reserve global name
\newif\ifrepeatpar
\newlength{\leftmarginpar@y}
\newlength{\rightmarginpar@y}
\setlength{\leftmarginpar@y}{\pagetop@y}
\setlength{\rightmarginpar@y}{\pagetop@y}
\newcommand{\newleftmarginpar}[5]% #1 = index, #2 = paragraph, $3 = page, #4 = y location, #5 = text
{\expandafter\gdef\csname leftmarginpar@#2\endcsname{#1}%
\expandafter\gdef\csname leftmarginpar@page@#1\endcsname{#3}%
\expandafter\gdef\csname leftmarginpar@y@#1\endcsname{#4}%
\expandafter\gdef\csname leftmarginpar@text@#1\endcsname{#5}}
\newcommand{\newrightmarginpar}[5]% #1 = index, #2 = page, #3 = y location, #4 = text
{\expandafter\gdef\csname rightmarginpar@#2\endcsname{#1}%
\expandafter\gdef\csname rightmarginpar@page@#1\endcsname{#3}%
\expandafter\gdef\csname rightmarginpar@y@#1\endcsname{#4}%
\expandafter\gdef\csname rightmarginpar@text@#1\endcsname{#5}}
\newcommand{\AtBeginParagraph}{\everypar{}%
\ifrepeatpar\repeatparfalse\else
\stepcounter{absparagraph}%
\xdef\current@page{\arabic{page}}%
\switchcolumn[0]
\loop\ifnum\value{page}<\current@page\relax% sync pages
\newpage
\global\leftmarginpar@y=\pagetop@y\relax
\repeat
\@ifundefined{leftmarginpar@\theabsparagraph}{}{\bgroup
\count1=\csname leftmarginpar@\theabsparagraph\endcsname\relax
\count2=\value{leftmarginpar}%
\loop\ifnum\count2<\count1
\advance\count2 by 1
\count3=\csname leftmarginpar@page@\number\count2\endcsname\relax% check page
{\loop\ifnum\value{page}<\count3
\newpage
\global\leftmarginpar@y=\pagetop@y\relax
\repeat}% sync page
\dimen0=\csname leftmarginpar@y@\number\count2\endcsname sp\relax% compute offset
\ifdim\dimen0<\leftmarginpar@y
\dimen1=\dimexpr \leftmarginpar@y-\dimen0\relax
\else
\dimen1=\topskip
\fi
\setbox0=\vbox{\everypar{}%
{\marginparformat
\rule{0pt}{\dimen1}% I can't tell is fhis is adding space
\csname leftmarginpar@text@\number\count2\endcsname
\par}}%
\global\advance\leftmarginpar@y by \dimexpr-\ht0-\dp0\relax
\unvbox0%
\repeat
\egroup}%
\switchcolumn[2]
\loop\ifnum\value{page}<\current@page\relax% sync pages
\newpage
\global\rightmarginpar@y=\pagetop@y\relax
\repeat
\@ifundefined{rightmarginpar@\theabsparagraph}{}{\bgroup
\count1=\csname rightmarginpar@\theabsparagraph\endcsname\relax
\count2=\value{rightmarginpar}%
\loop\ifnum\count2<\count1
\advance\count2 by 1
\count3=\csname rightmarginpar@page@\number\count2\endcsname\relax% check page
{\loop\ifnum\value{page}<\count3
\newpage
\global\rightmarginpar@y=\pagetop@y\relax
\repeat}% sync page
\dimen0=\csname rightmarginpar@y@\number\count2\endcsname sp\relax% compute offset
\ifdim\dimen0<\rightmarginpar@y
\dimen1=\dimexpr \rightmarginpar@y-\dimen0\relax
\else
\dimen1=\topskip
\fi
\setbox0=\vbox{\everypar{}% write text
{\marginparformat
\rule{0pt}{\dimen1}%
\csname rightmarginpar@text@\number\count2\endcsname
\par}}%
\global\advance\rightmarginpar@y by \dimexpr-\ht0-\dp0\relax
\unvbox0%
\repeat
\egroup}%
\switchcolumn[1]
\everypar{\AtBeginParagraph}%
\repeatpartrue
\fi}
\def\@afterheading{%
\@nobreaktrue
\everypar{%
\if@nobreak
\@nobreakfalse
\clubpenalty \@M
\if@afterindent \else
{\setbox\z@\lastbox}%
\fi
\else
\clubpenalty \@clubpenalty
\everypar{\AtBeginParagraph}%
\fi
\AtBeginParagraph}}
\makeatother
\newcommand{\lmargin}[2]{\sethlcolor{ltblue}\hl{#1}\leftmarginpar{#2}}
\newcommand{\rmargin}[2]{\sethlcolor{ltblue}\hl{#1}\rightmarginpar{#2}}
\usepackage{blindtext}
\begin{document}
\begin{paracol}{3}
\switchcolumn[1]
\everypar{\AtBeginParagraph}
And even there \lmargin{are}{there's something here that I need to pay attention to, and I need to be very clear about it, so I am going to write everything that comes to my mind here in the margin so that it doesn't take anyone 400 years to come up with the same thing!} more things that can be said, but I am \rmargin{not sure}{Same thing here: there's something here that I need to pay attention to, and I need to be very clear about it, so I am going to write everything that comes to my mind here in the margin so that it doesn't take anyone 400 years to come up with the same thing!} exactly what. \lipsum[7]
\lmargin{test}{test}
Do you see the problem \rmargin{here}{And this is what I need}? If I don't go to a new paragraph, everything changes altogether! and overlaps even when I do!
\end{paracol}
\end{document}
