1

I'm using marginpar to put graphs and tables in the margins of my document. Sometimes, I end up starting a long note toward the bottom of the page, and it runs off the bottom. To solve this, I can add some negative vspace before the marginpar. But then if an edit moves the marginpar to the top of the next page, it will start too high. Consequently, when I get to the end of editing my document, I need to go back through and check every page to make sure nothing is too far out of place.

What I'd like to do is add a test to see if the marginpar starts too high or ends too low. If it does, I'll put a warning message in the log file. Then I'll be able to search through the log file to see if any marginpars are out of place, and manually fix their location. How can I test if the top or bottom of a box is too high or low? Here's a MWE:

\documentclass{article}
\usepackage[textheight=8in,textwidth=4in]{geometry}
\usepackage{lipsum}
%\usepackage{ifthen}
\newcommand{\mnote}[2][0ex]{%
    \marginpar{\vspace{#1}%
    \begin{minipage}[c]{\marginparwidth}
%       \ifthenelse{currentlocation.y < texttop}{\typeout{marginpar too high on page \thepage}}{}
        #2
%       \ifthenelse{currentlocation.y > textbottom}{\typeout{marginpar too low on page \thepage}}{}
    \end{minipage}%
}}

\begin{document}

\lipsum[1-4]

A paragraph at the bottom of the page
\mnote{\lipsum[5]}
with a long note that goes too low on the page.

\lipsum[6]

A paragraph at the top of the page
\mnote[-3in]{\lipsum[7]}
where the note has been moved too high up.

\end{document}
1

You can use the \pdfsavepos primitive (or its new name \savepos if you use the the latest luatex) to test the final typeset position.

The values are in sp from some reference point at the bottom of the page, you can just adjust by eye or use something like

 \pdfsavepos\write20{here=\the\pdflastypos}

at a reference point eg the first or last line of a page to get the numbers to use as the bounds in \toptest and \bottest

As posted here it produces a log

Package mnote Warning: marginpar 1 very low on page 1.


Package mnote Warning: marginpar 2 very high on page 2.


\documentclass{article}
\usepackage[textheight=8in,textwidth=4in]{geometry}
\usepackage{lipsum}
%\usepackage{ifthen}
\newcounter{mpcount}
\makeatletter
\newcommand{\mnote}[2][0ex]{%
    \marginpar{\vspace{#1}%
    \begin{minipage}[c]{\marginparwidth}
\stepcounter{mpcount}%
\strut\pdfsavepos\write\@auxout{\string\toptest{\thempcount}{\thepage}{\the\pdflastypos}}%
        #2\ifhmode\unskip\fi
\strut\pdfsavepos\write\@auxout{\string\bottest{\thempcount}{\thepage}{\the\pdflastypos}}%
    \end{minipage}%
}}
\def\toptest#1#2#3{\ifnum#3> 50000000
\PackageWarningNoLine{mnote}{marginpar #1 very high on page #2}%
\fi}
\def\bottest#1#2#3{\ifnum#3< 0
\PackageWarningNoLine{mnote}{marginpar #1 very low on page #2}%
\fi}

\makeatother

\begin{document}


\lipsum[1-4]

A paragraph at the bottom of the page
\mnote{\lipsum[5]}
with a long note that goes too low on the page.

\lipsum[6]

A paragraph at the top of the page
\mnote[-3in]{\lipsum[7]}
where the note has been moved too high up.

\end{document}
| improve this answer | |
  • This did the trick. It did take me awhile to figure out that \pdflastypos not being known atshipout meant that I couldn't just call \toptest in the macro, but had to write the test into the aux file as you did. – Teepeemm Nov 2 '16 at 1:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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