[Tex/LaTex] Inserting a line to separate the text and the margin note

marginnotemarginparmarginsrules

How can I insert a vertical line through a whole page to separate the text and the margin notes?

Best Answer

The following code adds the rule only on pages with marginpars. If they appear on both sides (using a mix of \reversemarginpar and \normalmarginpar) the rules show up on both sides.

Customization possibilities are the rule itself (color, widths, etc) via \mparrule and the placement within the space given by \marginparsep via \mparrulefactor.

\documentclass[twoside]{article}

\usepackage{etoolbox}

% patching the OR of LaTeX:

\makeatletter
\patchcmd{\@outputpage}%
    {\box\@outputbox}%
    {\hbox{%
        \ifmpar@rule@lside
        \hskip-\mparrulefactor\marginparsep\mparrule
        \hskip\mparrulefactor\marginparsep
        \fi
        \box\@outputbox
        \ifmpar@rule@rside
        \hskip\mparrulefactor\marginparsep\mparrule
        \fi}%
      \global\mpar@rule@lsidefalse
      \global\mpar@rule@rsidefalse
    }%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\@addmarginpar}%
    {\global\setbox\@marbox\box\@currbox}%
    {\global\setbox\@marbox\box\@currbox
     \global\mpar@rule@lsidetrue
     \else
     \global\mpar@rule@rsidetrue
    }%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\newif\ifmpar@rule@lside
\newif\ifmpar@rule@rside
\makeatother

\usepackage{color}

% \mparrule generates the \vrule but should use no space horizontally
% using color is just for fun ...
\newcommand\mparrule{\textcolor{blue}{\hskip-.2pt\vrule\hskip-.2pt}}

% placement factor: .5 places the rule midway in the space made available 
% by \marginparsep
\newcommand\mparrulefactor{.5}

%\setlength\marginparsep{1cm}


\normalmarginpar

\usepackage{lipsum}

\begin{document}

\lipsum[1]\marginpar[where does this go?]{Test with some extra text to make more than one line}

\lipsum[2]

\newpage

\lipsum[1]\marginpar{Test with some extra text to make more than one line}

\newpage

\reversemarginpar % test odd placement .... not enough space in the default case

\lipsum[1]\marginpar[where does this go?]{Test with some extra text to make more than one line}

\normalmarginpar % and one on the other side as well

\lipsum[2]\marginpar[where does this go?]{Test with some extra text to make more than one line}

\newpage % no rule on the next page ...

\lipsum[1]

\lipsum[2]

\end{document}

Explanation: We patch \@addmarginpar to record if a marginpar is added to the left or to the right. Once one of the switches is set to to true it will remain so until we actually typeset the page (this way marginpars can be placed on either or both sides and we get the proper rules). The in \@outputpage we simply use the switches to add a rule to the left and/or right of the \@outputbox. By putting everything into an \hbox the rule automatically extends to the full height of the box. Finally we reset both stwiches back to false so that a page without marginpars will not generate rules.

As a result we get on the first page:

enter image description here

while page 3 shows rules on both sides:

enter image description here

A variation

As an alternative one could produce lines matching just the size of the marginals. Most of the previous code ideas could be reused only this time we do everything inside of \@addmarginpar:

\usepackage{etoolbox}

% patching the OR of LaTeX:

\makeatletter
\patchcmd{\@addmarginpar}%
    {\box \@marbox}%
    {\hbox{%
        \ifmpar@rule@rside
        \hskip-\mparrulefactor\marginparsep\mparrule
        \hskip\mparrulefactor\marginparsep
        \fi
                          \box \@marbox
        \ifmpar@rule@lside
        \hskip\mparrulefactor\marginparsep\mparrule
        \fi}%
     \global\mpar@rule@lsidefalse
     \global\mpar@rule@rsidefalse
    }%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\patchcmd{\@addmarginpar}%
    {\global\setbox\@marbox\box\@currbox}%
    {\global\setbox\@marbox\box\@currbox
     \global\mpar@rule@lsidetrue
     \else
     \global\mpar@rule@rsidetrue
    }%
    {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\newif\ifmpar@rule@lside
\newif\ifmpar@rule@rside
\makeatother

\usepackage{color}

% \marginparrule generates the \vrule but should use no space horizontally
% using color is just for fun ...
\newcommand\mparrule{\textcolor{blue}
    {\hskip-2pt\vrule width 4pt\hskip-2pt}}

% placement factor: .5 places the rule midway in the space made available 
% by \marginparsep
\newcommand\mparrulefactor{.4}

In that case we would get output like this:

enter image description here

Related Question