3

I intend to use the sidenote package along with David Carlisle's implementation of \marginpar based on \pdfsavedpos from the answer here: https://tex.stackexchange.com/a/52436/44160. I've simplified the \sidenote command a little, this is not the full version.

The basic idea behind the code below is to offer an alternative implementation of \marginpar, which uses the saved position of the marginpar, rather than using the regular \c@page-related macros (which don't always use the correct page number).

The code below produces an "Underfull \vbox while \output is active (badness 10000)" message, and I'm unsure where the problem lies.

What can I do to make the error go away?

PS: The code below requires two LaTeX runs to show the errors.

\documentclass[twoside]{article}

\usepackage{xparse}
\makeatletter


\NewDocumentCommand \sidenote { +m }
{
  \marginpar{#1}
}
%\let\sidenote\marginpar


\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#1}}%
  \hbox{\parbox{\marginparwidth}{\@marginparreset#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% not here
\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% not here either apparently
\advance\dimen@-\@tempdimb
\advance\dimen@-\ht\@ne
\advance\dimen@-\dp\@ne
\hrule\@height\z@
\box\@ne
\hrule\@height\z@
}

\makeatother

% just some filler text, equations, etc.
\def\someequation{%
\begin{equation}
\left[\frac{\hat p^2}{2m}+V(r)\right]\psi(r)=E\psi(r).
\end{equation}
}
\def\elementarytext{%
One two three four, united states marine core.
}
\def\sometext{%
\elementarytext\elementarytext\elementarytext\elementarytext\par
\elementarytext\elementarytext\elementarytext\elementarytext\par
\elementarytext\elementarytext\elementarytext\elementarytext\par
}

\begin{document}

\sometext

\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext\sidenote{Here is a side note with some text.}
\someequation
\elementarytext\sidenote{Here is a side note with some text.}

\end{document}
1010011010
  • 6,357
  • Don't expect that anybody will go into that complicated code. I'll vote for closing as too broad. – egreg May 04 '15 at 20:55

1 Answers1

3

If the warnings (which are spurious) bother you, just turn them off:

I simplified the MWE, removing xparse definition of \sidenote and added a setting of \vbadness to silence the warning.

\documentclass[twoside]{article}


\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}

\long\def\marginpar#1{%
  \saveposition{mpar}%
  \global\setbox\@mpbox\vbox{\unvbox\@mpbox\hbox{%
  \hbox{\parbox{\marginparwidth}{\@marginparreset#1}}%
  \hbox{\parbox{\marginparwidth}{\@marginparreset#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% not here
\hrule\@height\z@}}%
\fi}

\def\origin@positions#1#2{%
\@tempdima\z@
\dimen@\textheight
\advance\dimen@\headsep
\advance\dimen@ #2sp
}
\def\mp@positions#1#2{%
\advance\vbadness\@M
\setbox\tw@=\vsplit\@mpbox to \maxdimen
\advance\vbadness-\@M
\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% not here either apparently
\advance\dimen@-\@tempdimb
\advance\dimen@-\ht\@ne
\advance\dimen@-\dp\@ne
\hrule\@height\z@
\box\@ne
\hrule\@height\z@
}

\makeatother

% just some filler text, equations, etc.
\def\someequation{%
\begin{equation}
\left[\frac{\hat p^2}{2m}+V(r)\right]\psi(r)=E\psi(r).
\end{equation}
}
\def\elementarytext{%
One two three four, united states marine core.
}
\def\sometext{%
\elementarytext\elementarytext\elementarytext\elementarytext\par
\elementarytext\elementarytext\elementarytext\elementarytext\par
\elementarytext\elementarytext\elementarytext\elementarytext\par
}

\begin{document}

\sometext

\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext
\someequation
\elementarytext\marginpar{Here is a side note with some text.}
\someequation
\elementarytext\marginpar{Here is a side note with some text.}
\end{document}
David Carlisle
  • 757,742
  • It should be \long\def\marginpar#1{...} – egreg May 04 '15 at 22:52
  • @egreg if more than one paragraph is allowed it ought to be called \marginpars :-) But I'll add. – David Carlisle May 04 '15 at 22:57
  • The original \marginpar command allows multiple paragraphs. – egreg May 04 '15 at 22:57
  • @egreg I know ! – David Carlisle May 04 '15 at 22:58
  • ... so what is actually causing the error? I found another answer by @egreg in a similar question with the same workaround.... but what's actually happening here? – 1010011010 May 04 '15 at 23:29
  • @1010011010 it's not an error I just stored the marginpars into a temporary box that needed to be split up and positioned once the saved coordinates are known I split with \vsplit which causes some warnings but they do not relate to any underfull box that is actually output, \vbadness is a setting that doesn't affect anything except warnings, make it bigger than 10000 and you never get warnings about underfull boxes – David Carlisle May 04 '15 at 23:33