[Tex/LaTex] Marginpar appearing on the wrong side (using memoir)

marginparmemoirpage-breakingpositioning

The subject line pretty much says it all: some marginal notes (beginning of the second page) do not appear on the correct side. (The question is: how can I fix this automatically?) Below is a MWE that I got from my code, where I removed as much text as possible (and replace the missing text by a vertical space). I tried to remove some equations and the itemize environment to simplify things further, but could not get the right value of \vspace to still illustrate the problem.


This is a partial answer to my problem … If I write \strictpagecheck before each \marginpar and if I explictly write \marginparmargin{outer} (which is supposed to be the default), the notes on the second page all get positioned on the correct side. The problem is that the notes that were previously on the wrong side now partly overlap the other ones.


Commenting on an answer which was deleted by its author: I do not want the oneside option as this is going to be printed as a book. Also, I tried sidepar and it definitely does not work: the notes on the first page are on the wrong side and some of the ones on the second overlap. Eventually, I will want to add figures as well as text in the margins.

\documentclass[11pt,openany]{memoir}

\setstocksize{11in}{8.5in}
\settrimmedsize{\stockheight}{\stockwidth}{*}
\settypeblocksize{9.0in}{30pc}{*}
\setlrmargins{0.7in}{*}{*}
\setulmargins{1.0in}{*}{*}
\setheadfoot{30pt}{26pt}
\setheaderspaces{*}{30pt}{*}
\setmarginnotes{0.2in}{1.5in}{0.2in}
\checkandfixthelayout
%

\begin{document}
Some text to get things started.
\vspace*{17cm} % to minimize the amount of text on the page.

Some text\marginpar{First note} with some notes in the margin.
Some text\marginpar{Second note} with some notes in the margin.
Some text\marginpar{Third note} with some notes in the margin.

\begin{itemize}
\item First item.  
    $$A=B$$
\item Second item.
    $$A=B$$
\end{itemize}

Yet more text with a note\marginpar{Fourth note} followed by an equation.
$$
A = B
$$

Now we can see the problem.\marginpar{This note is on the wrong side.}. 
With some more text\marginpar{And another note on the wrong side.} 
so we can perhaps start seeing what is going on.
Some text added with other notes and a reasonably long sentence to keep
the notes somewhat separate\marginpar{Note 1 on the correct side}.
Some text added with other notes and a reasonably long sentence to keep 
the notes somewhat separate\marginpar{Note 2 also}.

\end{document}

Best Answer

The problem is intrinsic to LaTeX's marginpar implementation. One possible solution is as follows. This uses pdftex's \pdfsavepos extension, I think other newer engines have similar extensions. Also it would need to be packaged and made a bit more generic (and tested on more than this one input file). But basically the idea is that \marginpar just saves its text in a box (actually two boxes a left and right hand version) then on the next run, LaTeX uses information from \pdfsavepos to align the margin notes at the vertical position of the callout as saved in the aux file. If it would overlap a previous one it is moved down, the positioning is done with shrinkable glue so if the margin column gets too full, the glue will shrink (so notes will move up to allow later ones to fit).

enter image description here

\documentclass[11pt,twoside]{article}
% Adjust paperheight for more useful image


\makeatletter

\newbox\@mpbox
\global\setbox\@mpbox\vbox{}


\def\savedpos#1#2#3#4{%
\begingroup
\let\@positions\relax
\expandafter\xdef\csname sp@#1-#2\endcsname{%
\expandafter\ifx\csname sp@#1-#2\endcsname\relax
\else
\csname sp@#1-#2\endcsname
\fi
  \@positions{#3}{#4}}%
\endgroup}

\def\marginpar#1{%
  \saveposition{mpar}%
  \global\setbox\@mpbox\vbox{\unvbox\@mpbox\hbox{%
  \hbox{\parbox{\marginparwidth}{\@marginparreset\raggedright#1}}%
  \hbox{\parbox{\marginparwidth}{\@marginparreset\raggedleft#1}}%
}\break}}



\def\saveposition#1{%
\pdfsavepos\write\@auxout{%
  \noexpand\savedpos
    {#1}{\the\c@page}{\the\pdflastxpos}{\the\pdflastypos}}}


\def\@oddfoot{%
  \hss\thepage\hss\rlap{\hskip\marginparsep\mcolumn}}
\def\@evenfoot{%
  \llap{\mcolumn\hskip\marginparsep}\hss\thepage\hss\saveposition{foot}}

\def\mcolumn{%
\saveposition{foot}%
\expandafter\ifx\csname sp@foot-\the\c@page\endcsname\relax
\else
\let\@positions\origin@positions
\csname sp@foot-\the\c@page\endcsname
\smash{\raise\footskip\vbox to \textheight{\hsize\marginparwidth
\hrule\@height\z@
\let\@positions\mp@positions
\csname sp@mpar-\the\c@page\endcsname
\vskip\z@\@plus\textheight
\hrule\@height\z@}}%
\fi}

\def\origin@positions#1#2{%
\@tempdima\z@
\dimen@\textheight
\advance\dimen@\headsep
\advance\dimen@ #2sp
}
\def\mp@positions#1#2{%
\setbox\tw@=\vsplit\@mpbox to \maxdimen
\setbox\tw@\vbox{%
\unvbox\tw@
\setbox\tw@\lastbox
\setbox\tw@\hbox{%
\unhbox\tw@
\ifodd\c@page
\global\setbox1\lastbox
\fi
\global\setbox1\lastbox
}}%
\@tempdimb\dimen@
\advance\@tempdimb-#2sp
\ifdim\@tempdimb<2\p@
\@tempdimb2\p@
\fi
\vskip\@tempdimb\@minus\@tempdimb
\advance\dimen@-\@tempdimb
\advance\dimen@-\ht\@ne
\advance\dimen@-\dp\@ne
\hrule\@height\z@
\box\@ne
\hrule\@height\z@
}

\showboxdepth=2
\showboxbreadth=50

\begin{document}


Some text to get things started.
\vspace*{14cm} % to minimize the amount of text on the page.

\begin{itemize}
\item First item.  
    $$A=B$$
\item Second item.
    $$A=B$$
\end{itemize}

Yet more text with a noteZZ\marginpar{zeroth note} followed by an equation.
\[
A = B
\]

Now we can see the problem.AA\marginpar{This is the first note. I'm making it quite long to see some overlapping with mparhack.}. 
With some more textBB\marginpar{Second note} 
so we can perhaps start seeing what is going on.
Some text added with other notes and a reasonably long sentence to keep
the notes somewhat separateCC\marginpar{Third note}.
Some text added with other notes and a reasonably long sentence to keep 
the notes somewhat separateDD\marginpar{Fourth note}.
\end{document}
Related Question