How can I insert a vertical line through a whole page to separate the text and the margin notes?
-
2Only on pages containing a margin note, or on all pages?– T. VerronJan 4, 2013 at 15:27
-
on pages containing a margin note– user23959Jan 4, 2013 at 15:39
-
it does not matter actually, all pages is also ok.– user23959Jan 4, 2013 at 15:59
-
have you seen How to set colored ruled margins for different pages?– cmhughesJan 4, 2013 at 23:50
2 Answers
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:
while page 3 shows rules on both sides:
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:
-
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 Jan 5, 2013 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
:
The result in oneside
:
(Sorry for the poor quality of the screenshots, I'll try to make better ones later)