7

I am considering a beamer presentation with notes at the right. To establish a better connection between the notes and the content they are referring to, I modified the \notes command in such a way (using zref's savepos) that the note text is printed at the same vertical position as the text where it appears. Therefore, it is not always feasible to put the \notes command directly in the frame, but sometimes it needs to appear within a different environment.

That's for the motivation, and it works great in most cases. However, consider this MWE:

\documentclass{beamer}

\usepackage{amsmath,pgfpages}

\setbeameroption{show notes on second screen=right}

\newcounter{notecounter}

\begin{document}
   \begin{frame}
      \begin{align*}
         a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}\\} \\
         b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}\\}
      \end{align*}
   \end{frame}
\end{document}

This is without any redefinitions, just using the plain beamer command which I of course internally use. The notes page will output the following content:

This is the first note: 0

This is the second note 1

This is the first note: 2

This is the second note 3

For some reason, the notes are repeated (even worse, expanded multiple times) whenever they occur in a multiline math environment (tested with align and gather, both starred and unstarred). But this does not seem to be a fundamental problem that you may not use \note at all in math mode, since it works for \[ \] and equation.

Is there a way to circumvent this problem, which completely messes up my spacing when I change to the aligned \note definition?

Edit: On request by samcarter, I give a MWE that contains parts of my code to provide the aligned notes. This is very boiled down, the original code also contains fixing of misplaced hyperlinks, incorporating scaleboxes, ..., but this is not relevant to show the problem. Probably, tikzmark would make the positioning algorithm more elegant. Since I typically use tikz, this would not come as a drawback for me; however, the implementation I imagine would fix the problem only superficially: Probably the alignment would be correct (and tikz will give a warning about using the same name twice), but the two identical notes would be printed on top of each other.

\documentclass{beamer}

\usepackage{amsmath,pgfpages,zref-user,zref-savepos}

\setbeameroption{show notes on second screen=right}
\setbeamertemplate{note page}[plain]

\newcounter{notecounter}

\makeatletter
\let\oldnote\note
\newcounter{pposes}
\newcounter{poses}
\AtBeginNote{%
   \setcounter{poses}{0}%
}
\AtEndNote{%
   \setcounter{poses}{0}%
   \stepcounter{pposes}%
}
\renewcommand<>{\note}[1]{%
   \only#2{%
      \stepcounter{poses}%
      \vbox to 0pt{%
         \edef\l{p\the\value{pposes}-\the\value{poses}}%
         \zsaveposy{\l}%
         \zrefused{\l}%
         \oldnote{%
            \stepcounter{poses}%
            \edef\l{p\the\value{pposes}-\the\value{poses}}%
            \zref@ifrefundefined{\l}{}{%
               \parbox[l][0pt][t]{0pt}{%
                  \hfuzz=\maxdimen%
                  \parbox{\textwidth}{%
                     \vspace{\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
                     #1%
                  }%
               }%
            }%
         }%
      }%
   }%
}

\begin{document}
   \begin{frame}
      \begin{align*}
         a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
         b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
      \end{align*}
      Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
   \end{frame}
\end{document}

Note that in this way, the problem has shifted: Now it is not that the notes are visible twice (since the macro does not find an associated position of the second appearances), but the \note command is used after the align-environment, first the unprinted doubled notes are given. Therefore, this MWE generates the first two notes correctly aligned, followed by the first note again, which is not aligned to the position of `Problem'. The duplicated second note and the actual third note are not shown at all.

  • Can you maybe also add a MWE how you use your redefined notes command? Maybe a tikzmark solution could be used to store the position. – user36296 Jul 15 '18 at 12:31
  • @samcarter: Done, though I don't think this affects the true problem. But it might indeed make my positioning algorithm more refined. – Benjamin Desef Jul 15 '18 at 15:06
  • I tried a few things using tikzmarks and I run into exactly the problems you described. Sorry for having caused the extra work to include this in your question! – user36296 Jul 15 '18 at 15:31
  • You could use and modify @Circumscribe's great answer from here. I managed to get it working—with some adjustments, as the default counter doesn't work. If you are interested in that I could clean up the code and post an answer (possibly tomorrow). This is just another work-around though, and doesn't solve the mystery of your result. – nox Jul 16 '18 at 19:00
  • @nox: But isn't this answer building on exactly the same mechanism I use, apart from the fact that it uses atbegshi for positioning the content? It must be your adjustments that fix the problem. Do you somehow insert code to check for the uniqueness of the notes (I thought of doing this before, but a fix for the original cause of the note expanding twice would feel much more comfortable)? – Benjamin Desef Jul 17 '18 at 15:13
5
+100

This problem is caused by the fact that the align environment needs to perform some measurements and computations before actually printing anything. To do this, it first has to typeset everything in box registers that will not be printed, only measured. Everything is typeset a second time afterwards, this time for real.

A consequence of this procedure is that any assignments made inside an align environment are performed twice, which is what is happening in your case. (Note: all LaTeX counters are reset when the measurements are completed, so \setcounter and \stepcounter do work as expected inside an align environment.)

One way to circumvent this problem is by using the conditional \ifmeasuring@, which is set to true while these measurements are being performed. The following comes from the amsmath documentation:

\ifmeasuring@
All display environments get typeset twice—once during a “measuring” phase and then again during a “production” phase; \ifmeasuring@ will be used to determine which case we’re in, so we can take appropriate action.

You could thus redefine \note so that it does nothing during the measuring phase, like this:

\documentclass{beamer}

\usepackage{amsmath,pgfpages}

\makeatletter
\let\originalnote\note
\renewcommand<>\note[2][]{\ifmeasuring@\else\originalnote#3[#1]{#2}\fi}
\makeatother

\setbeameroption{show notes on second screen=right}

\newcounter{notecounter}

\begin{document}
   \begin{frame}
      \begin{align*}
         a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}\\} \\
         b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}\\}
      \end{align*}
   \end{frame}
\end{document}

enter image description here

  • Good explanation - I used to look in the amsldoc documentation, which does not talk about these problems. Apparently, the implementation reference is also worth a glance. – Benjamin Desef Jul 18 '18 at 14:00
2
+50

For some reason, code within align* is executed twice. Thus, the first two notes are defined twice, too. The notes get the labels p0-1, p0-2, p0-1, p0-2 and p0-3 (note the duplicate labels). Beamer has stored 5 notes now. When typesetting the notes page, your code tries to use the labels p0-1 to p0-5 for the stored notes. And of course, the last two are unknown.

The positions stored by your code are correct. But now, the third stored note is the duplicate of the first. This is set with the position of the third real note. The other notes are not given out, because the labels now used are undefined.

A possible solution is to prevent the first execution of the notes (I also tried to prevent the second one, but this didn't work). Here this is done with \manote (ma for math align), which executes the \note only if the flag \ifexecutenote is true. The flag is set to false with \AtBeginEnvironment (requires the etoolbox package). Unfortunately, it can not be reset with \AtEndEnvironment, because at this point it is already to late. So the flag is set with either a) using \lmanote (sets the flag internally) for the last note or b) using \executemanotes after the last \manote, but in the environment.

For each other environment you have to add a line \AtBeginEnvironment{someenv}{\global\executemanotefalse} in the preamble.

I left some (commented out) debug code in, because it was very useful for figuring out, what happens. It may be helpful in case your complete code shows some problems. The code writes some information to the log file.

enter image description here

\documentclass{beamer}

\usepackage{amsmath,pgfpages,zref-user,zref-savepos}

\usepackage{etoolbox} % <---- new

\setbeameroption{show notes on second screen=right}
\setbeamertemplate{note page}[plain]

\newcounter{notecounter}

\makeatletter
\let\oldnote\note
\newcounter{pposes}
\newcounter{poses}
\AtBeginNote{%
   \setcounter{poses}{0}%
}
\AtEndNote{%
   \setcounter{poses}{0}%
   \stepcounter{pposes}%
}
\renewcommand<>{\note}[1]{%
   \only#2{%
      \stepcounter{poses}%
      \vbox to 0pt{%
         \edef\l{p\the\value{pposes}-\the\value{poses}}%
%         \typeout{XXXXXXXXXXXXXXXXXXXX label: \l}%
         \zsaveposy{\l}%
         \zrefused{\l}%
%         \typeout{AAAAAAAAAAAAAAAAAAAA pos: \the\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
         \oldnote{%
            \stepcounter{poses}%
            \edef\l{p\the\value{pposes}-\the\value{poses}}%
%            \typeout{YYYYYYYYYYYYYYYYYYYY label: \l}%
            \zref@ifrefundefined{\l}{%
%               \typeout{ZZZZZZZZZZZZZZZZZZZZ label undefined: \l}%
            }{%
%               \typeout{ZZZZZZZZZZZZZZZZZZZZ label defined: \l}%
               \parbox[l][0pt][t]{0pt}{%
                  \hfuzz=\maxdimen%
                  \parbox{\textwidth}{%
                     \vspace{\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
%                     \typeout{BBBBBBBBBBBBBBBBBBBB pos: \the\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
                     #1%
                  }%
               }%
            }%
         }%
      }%
   }%
}

%-------------------------------------------------------------------------------
\newif\ifexecutemanote
\newcommand<>{\manote}[1]{%
    \ifexecutemanote
        \note#2{#1}%
    \fi
}
\newcommand<>{\lmanote}[1]{%
    \manote#2{#1}%
    \global\executemanotetrue
}
\newcommand*{\executemanotes}{\global\executemanotetrue}

\AtBeginEnvironment{align*}{\global\executemanotefalse}
%-------------------------------------------------------------------------------

\begin{document}
   \begin{frame}
      \begin{align*}
         a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
         b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
      \end{align*}
      Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
%      \typeout{EEEEEEEEEEEEEEEEEEEE: with note}
   \end{frame}
%   \typeout{EEEEEEEEEEEEEEEEEEEE: 1. frame end}

   \begin{frame}
      \begin{align*}
         a & = 1 \manote{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
         b & = 2 \lmanote{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
      \end{align*}
      or
      \begin{align*}
         a & = 1 \manote{This is the third note: \arabic{notecounter}\stepcounter{notecounter}} \\
         b & = 2 \manote{This is the fourth note \arabic{notecounter}\stepcounter{notecounter}}
         \executemanotes
      \end{align*}
      Problem \note{This is the fifth note: \arabic{notecounter}\stepcounter{notecounter}}
%      \typeout{EEEEEEEEEEEEEEEEEEEE: with tablenote}
   \end{frame}
%   \typeout{EEEEEEEEEEEEEEEEEEEE: 2. frame end}

   \begin{frame}
      \begin{tabular}{cc}
         a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
         b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
      \end{tabular}

      Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
%      \typeout{EEEEEEEEEEEEEEEEEEEE: with tabular}
   \end{frame}
%   \typeout{EEEEEEEEEEEEEEEEEEEE: 3. frame end}
\end{document}
  • Right now I've finished my code. I wanted to post an answer, having determined exactly the same behavior, just to see you having posted an answer already... Even earlier than my analysis. The debugging was still didactic for me though. And it looks like your code is cleaner than mine :) – nox Jul 18 '18 at 7:39

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.