0

I use marginnotes (sometimes inside of mdframed environments) to write at the margin whenever a concept is defined, e.g.:

\documentclass{article}
\usepackage{marginnote,tikz,mdframed}
\usepackage{amsthm}

\newmdtheoremenv[linecolor=black]{definition}{Definition}

\newcommand{\defi}[1]{%
  \marginnote{\tiny #1}%
  \emph{#1}}

\begin{document}

\begin{definition}
An \defi{apple} is a fruit, a \defi{mirror} is an object 
and a \defi{fish} is an animal.
\end{definition}
\end{document}

Alas, I have a problem when two or more things are defined in the same line---in the example, "apple", "mirror" and "fish" overlap in the margin.

I am aware that this is a feature, but wonder whether it would be possible to combine the contents of both calls to marginnote.

(Replacing marginnote by marginpar gives me "Float(s) lost.")

Ideally, in the margin I would read "apple, mirror, fish"

I wonder if it is possible to change marginnote so that

  • when a \marginnote is reached, its argument is appended to some list (of tokens?) ... ideally, adding some separator such as ,);
  • when the marginnote is typeset, it resets this list of tokens to nothing

I am also aware of the advanced sidenotes features of memoir, but I have to stick with article.


As a last resort, if this is not possible, I am considering the following:

  • every time \defi is called it appends to a comma-separated list of definitions;
  • using something like everypage to then call a tikzpicture to overlay the list on the margin of the document and reset the list contents

Edit: @TeXnician pointed out a similar question at Margin note automatic concatenation, however David's answer there has the side effect of adding the notes inside the mdframed box. (And I did not manage to run Tobi's answer, but I'm guessing I might run into the same Float(s) lost problem.)

2

1 Answer 1

2

You could try something like this. It only checks if the definitions (their begin) are on the same line and the same page.

\documentclass{article}
\usepackage{marginnote}
\usepackage{zref-savepos,zref-abspage}
\usepackage{expl3}


\ExplSyntaxOn\makeatletter
\int_new:N \g_tassio_note_int
\seq_new:N\g_tassio_note_seq

\newcommand{\defi}[1]{%
  \int_gincr:N \g_tassio_note_int
  \bool_if:nTF
  {
   \int_compare_p:n 
    {
     \zposy{tassionotepos\int_eval:n{\g_tassio_note_int}} 
     =  
     \zposy{tassionotepos\int_eval:n{\g_tassio_note_int +1}}
    }
   &&
   \int_compare_p:n  
   {
    \zref@extractdefault { tassionotepage\int_eval:n{\g_tassio_note_int } }{abspage}{-1}
    =
    \zref@extractdefault { tassionotepage\int_eval:n{\g_tassio_note_int +1} }{abspage}{-1}
   }
  }
   {
    \seq_gput_left:Nn \g_tassio_note_seq {#1}
   }
   {
    \seq_gput_left:Nn \g_tassio_note_seq {#1}
    \marginnote{\tiny \seq_use:Nn \g_tassio_note_seq {,~}}%
    \seq_gclear:N \g_tassio_note_seq
   } 
  \zref@label {tassionotepage\int_use:N\g_tassio_note_int}\zsaveposy {tassionotepos\int_use:N\g_tassio_note_int}
  \emph{#1}}

\ExplSyntaxOff\makeatother

\begin{document}
An \defi{apple} is a fruit, a \defi{mirror} is an object
and a \defi{fish} is an animal.
\\ \defi{duck} 


\newpage \defi{snowmann}

\end{document}

enter image description here

4
  • Nice solution :) yet I keep wondering if the expl3 syntax is designed specifically to scare away uninitiated programmers...
    – Marijn
    Commented Jun 12, 2018 at 14:06
  • Nice! How can I shift it down to avoid collisions with previous (long, multi-line) notes?
    – Tássio
    Commented Jun 12, 2018 at 17:41
  • You could add other \zsaveposy-labels in the marginnotes (e.g. at the begin and the end), and use their position to decide about shifts. Commented Jun 12, 2018 at 18:37
  • Thank you very much! This is great to begin learning expl3. While I incorporate \zsaveposy, I'll use a hack: put the contents of the marginnote in a parbox and use \setstretch from (setspace package) to mitigate collisions, since the marginnotes rarely reach 3 lines.
    – Tássio
    Commented Jun 13, 2018 at 9:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .