Margin note automatic concatenation

Please always post compete documents not just fragments, your fragment if used at default article text width puts all three notes on the same line. So I had to experiment with widths to get the requested effect:

enter image description here

\documentclass{article}
\newcounter{xmarginpar}
\newlength\xmarginparshift
\setlength\textwidth{8cm}
\makeatletter
\def\xmarginpar#1{%
\stepcounter{xmarginpar}%
\strut\pdfsavepos
\protected@write\@auxout{}{%
\global\string\@namedef{pos@\thexmarginpar}{\thepage/\noexpand\the\pdflastypos}%
}%
% if defined
\expandafter\ifx\csname pos@\thexmarginpar\endcsname\relax\else
% if on same line as previous
\expandafter\ifx\csname pos@\thexmarginpar\expandafter\endcsname
            \csname pos@\the\numexpr\thexmarginpar-1\relax\endcsname
\setbox0\hbox{\kern\xmarginparshift,#1}%
\else
\setbox0\hbox{\kern\textwidth\,#1}%
\fi
\global\xmarginparshift\wd\z@
\vadjust{\kern-\dp\strutbox\hbox{\smash{\box0}}\kern\dp\strutbox}%
\fi
\relax}

\begin{document}

A pendulum of length $5\,\mathrm{cm}$\xmarginpar{$l$} and
mass $10\,\mathrm{g}$\xmarginpar{$m$}
is displaced by $6^\circ$\xmarginpar{$\phi$} and released.
Calculate the momentum in the equilibrium position.

\end{document}

Based on Davids idea a made up a version using \marginpar which has the advantage that 1. the notes are alway on the right side of the text and that the settings for margin pars (\marginparsep and \marginparwidth) apply here too.

enter image description here

The main difference compared to David’s implementation is that I check if another note follows (David checks for preceding ones). And only if no other follows in this line (or at all, i.e. at end of the document) the previously collected noted get printed combined in one \marginpar.

\documentclass{scrbook}

\usepackage{geometry}
\geometry{paper=a5paper,textwidth=8cm,showframe}

\usepackage{xparse}

\ExplSyntaxOn\makeatletter

\cs_generate_variant:Nn \cs_if_eq:NNTF { ccTF }

% Variables
%% Counter for itentifiying mpars
\newcounter { combinedmpars }
%% Sequence for storing the mpars to be combined
\seq_new:N \g_tobi_mpars_seq

% User level macro to set the margin par
\NewDocumentCommand { \mpar } { m } {
   % increment counter
   \stepcounter { combinedmpars }
   % save current absolute position on page
   \strut \pdfsavepos
   % write position of this note to aux file
   \protected@write \@auxout { } {
      \global \string \@namedef
         { tobi_mpar_pos_ \number \value { combinedmpars } }
         { \thepage / \noexpand\the\pdflastypos }
   }
   % append current ref to list of refs
   \seq_gput_right:Nn \g_tobi_mpars_seq { #1 }
   % check if a _next_ mpar position is defined
   \cs_if_exist:cTF { tobi_mpar_pos_ \int_eval:n { \value { combinedmpars } + 1 } } {
      % if TRUE
      % check if it has the same position
      \cs_if_eq:ccF
         { tobi_mpar_pos_ \number \value { combinedmpars } }
         { tobi_mpar_pos_ \int_eval:n { \value { combinedmpars } + 1 } }
         {
            % if FALSE
            % ship out complete margin par
            \tobi_print_mpars:
         }
   } {
      % if FALSE
      % ship out complete margin par
      \tobi_print_mpars:
   }
}

% internal macro to print all marginpars of a line
\cs_new:Nn \tobi_print_mpars: {
   \marginline {
      \seq_map_function:NN \g_tobi_mpars_seq \tobi_format_mpar:n
   }
   \seq_gclear:N \g_tobi_mpars_seq
}

% internal macro to format a marginpar (cross reference in my case)
\cs_new:Nn \tobi_format_mpar:n {
   $\to$ ~ #1
   \quad
}

\ExplSyntaxOff\makeatother

\begin{document}
odd page\clearpage

A pendulum of length $5\,\mathrm{cm}$\mpar{$l$} and
mass $10\,\mathrm{g}$\mpar{$m$}
is displaced by $6^\circ$\mpar{$\phi$} and released.
Calculate the momentum in the equilibrium position.

\clearpage
A pendulum of length $5\,\mathrm{cm}$\mpar{$l$} and
mass $10\,\mathrm{g}$\mpar{$m$}
is displaced by $6^\circ$\mpar{$\phi$} and released.
Calculate the momentum in the equilibrium position.

\end{document}

Edit/Fix (2017/06/29): The incrementation of \g_tobi_mpar_int must be done globally.

Edit/Fix (2017/06/30): Change from L3 int to L2 counter. This has the advantage that the counter value is stored in the aux file and the solution works with multiple \includes, where the L3 version would require an additional manual saving of the value at each chapter end. Since \stepcounter is always global, there is no need to take special care of \mpars in environment etc.

Tags:

Marginpar