Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
2  
Only on pages containing a margin note, or on all pages? –  T. Verron Jan 4 '13 at 15:27
    
on pages containing a margin note –  user23959 Jan 4 '13 at 15:39
    
it does not matter actually, all pages is also ok. –  user23959 Jan 4 '13 at 15:59
    
have you seen How to set colored ruled margins for different pages? –  cmhughes Jan 4 '13 at 23:50

2 Answers 2

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

share|improve this answer
1  
@HarishKumar you wish? :-) that's a typical problem switching between emacs for coding and windows programs for processing ... that was a Control-W inside TeXworks without noticing and deleting this way part of the material –  Frank Mittelbach Jan 5 '13 at 7:59

Here is a solution adding a bar to all pages (unless specified otherwise). The bar is typeset as a background picture, with the package eso-pic, and drawn using tikz. There is probably an easier way to achieve it, but that way is convenient to adjust the lengths, etc.

About lengths, you will see a good example of spaghetti code, showing that I don't know half the lengths latex defines. The code works, but is definitely not minimal.

\documentclass[a4paper,twoside]{article}

\usepackage{lipsum}

\usepackage{eso-pic}

\usepackage{ifthen}

\usepackage{tikz}


\def\bottommargin{\paperheight - \topmargin - \textheight - \headheight - \headsep - 1in - \voffset}
\def\toptotalheight{\paperheight - \topmargin - \headheight - \headsep - 1in - \voffset}
\def\leftlength{
  \evensidemargin - 0.5*\marginparsep
   + 1in
   + \hoffset
}
\def\rightlength{\paperwidth
  - \evensidemargin + 0.5*\marginparsep
- 1in - \hoffset}

\makeatletter
\newcommand{\nomarginbar}{\let\ESO@HookIIBG\@empty}
\makeatother

\newcommand{\thisisfullsize}{\path (0,0) --  (\paperwidth,\paperheight);}

\newcommand\LeftBar{%
  \put(0,0){%
    \parbox[b][\paperheight]{\paperwidth}{%
      \vfill
      \centering
      \begin{tikzpicture}
        \thisisfullsize
        \draw[line width=1pt] (\leftlength,\bottommargin) -- (\leftlength,\toptotalheight);
      \end{tikzpicture}
      \vfill
  }}}

\newcommand\RightBar{% 
  \put(0,0){%
    \parbox[b][\paperheight]{\paperwidth}{%
      \vfill
      \centering
      \begin{tikzpicture}
        \thisisfullsize
        \draw[line width=1pt] (\rightlength,\bottommargin) -- (\rightlength,\toptotalheight);
      \end{tikzpicture}
      \vfill
  }}}

%%% Use this in two-side documents
\AtBeginShipout{%
  \ifthenelse{\isodd{\value{page}}}%
  {\AddToShipoutPictureBG*{\LeftBar}%
  }%
  {\AddToShipoutPictureBG*{\RightBar}%
  }%
}

% %%% Use this in one-side documents
% \AtBeginShipout{%
%   \AddToShipoutPictureBG*{\RightBar}%
% }

%%% Use this anyway (to take care of the first page of the document)
\AtBeginDocument{%
\AddToShipoutPictureBG*{\RightBar}%
}

\begin{document}

\lipsum[1-6]
\marginpar{\lipsum[1]}

\lipsum[1-6]
\marginpar{\lipsum[1]}
\lipsum[1-6]

\end{document}

In case you want some page to be bar-less, simply insert \nomarginbar somewhere in that page.

The result in twoside:

Two pages

Left page

Right page

The result in oneside:

One page

Zoom

(Sorry for the poor quality of the screenshots, I'll try to make better ones later)

share|improve this answer
    
thank you very much! this really helped. –  user23959 Jan 4 '13 at 17:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.