4

I have a layout with a fairly large margin which I want to use to add citation information. For this, I defined a sidecite command, to put this info in the margin. A MWE is the following

\documentclass{memoir}

\setstocksize{297mm}{210mm}
\settrimmedsize{\stockheight}{\stockwidth}{*}
\setulmarginsandblock{27.4mm}{*}{1}
\setlrmarginsandblock{24mm}{79mm}{*}
\setmarginnotes{9mm}{50mm}{1em}
\setheadfoot{1.25\baselineskip}{10mm}
\setheaderspaces{*}{8mm}{*}
\checkandfixthelayout[fixed]

\usepackage[style=alphabetic]{biblatex}

\providecommand\sidecite[2]{\mbox{#1}\marginpar{\footnotesize[\mbox{#1}] #2}}

\DeclareCiteCommand{\cite}[\mkbibbrackets]
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\ifciteindex
     {\indexfield{indextitle}}
     {}%
     \sidecite{\printfield{labelalpha}}{%
               \usebibmacro{author}
               \setunit{\addcomma\space}
               \printfield[citetitle]{labeltitle}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\usepackage{filecontents}
\begin{filecontents*}{test.bib}
@book{test,
  author="John Smith",
  title="The title",
  year=1099,
  publisher="nobody",  
}
\end{filecontents*}

\bibliography{test}

\begin{document}
\cite{test}
\cite{test}
\end{document}

This obviously prints the cite informations multiple times, if more then one sidecite command appears per page.

Can someone help me with automatically detecting such a double cite and only printing the information once in the margin per page?

And how would I modify the textcite macro accordingly?

asante
  • 367

1 Answers1

4

You'll need a conditional like \iflastciteonsamepage from biblatex: is there a command analogous to \ifciteseen but within one page?. For that to work you need to turn on the citetracker and pagetracker.

\documentclass{memoir}

\setstocksize{297mm}{210mm}
\settrimmedsize{\stockheight}{\stockwidth}{*}
\setulmarginsandblock{27.4mm}{*}{1}
\setlrmarginsandblock{24mm}{79mm}{*}
\setmarginnotes{9mm}{50mm}{1em}
\setheadfoot{1.25\baselineskip}{10mm}
\setheaderspaces{*}{8mm}{*}
\checkandfixthelayout[fixed]

\usepackage[style=alphabetic,citetracker=true,pagetracker=true]{biblatex}

\makeatletter
\newcommand*{\scbx@registerkey}{%
  \ifcsundef{cbx@instcount@curr@\the\c@refsection @\thefield{entrykey}}
    {\csnumgdef{cbx@instcount@curr@\the\c@refsection @\thefield{entrykey}}{0}}
    {}%
  \csnumgdef{cbx@instcount@last@\the\c@refsection @\thefield{entrykey}}{%
    \csuse{cbx@instcount@curr@\the\c@refsection @\thefield{entrykey}}}%
  \csnumgdef{cbx@instcount@curr@\the\c@refsection @\thefield{entrykey}}{\value{instcount}}}

\def\iflastciteonsamepage{%
  \ifsamepage
    {\number\csuse{cbx@instcount@curr@\the\c@refsection @\thefield{entrykey}}}
    {\number\csuse{cbx@instcount@last@\the\c@refsection @\thefield{entrykey}}}}

\newcommand*{\scbx@savepunctstate}{%
  \let\scbx@saved@unitpunct\blx@unitpunct
  \let\scbx@saved@tgl@unit\etb@tgl@blx@unit
  \let\scbx@saved@tgl@block\etb@tgl@blx@block
  \let\scbx@saved@tgl@insert\etb@tgl@blx@insert
  \let\scbx@saved@tgl@lastins\etb@tgl@blx@lastins
  \let\scbx@saved@tgl@keepunit\etb@tgl@blx@keepunit
}

\newcommand*{\scbx@restorepunctstate}{%
  \global\let\blx@unitpunct\scbx@saved@unitpunct
  \global\let\etb@tgl@blx@unit\scbx@saved@tgl@unit
  \global\let\etb@tgl@blx@block\scbx@saved@tgl@block
  \global\let\etb@tgl@blx@insert\scbx@saved@tgl@insert
  \global\let\etb@tgl@blx@lastins\scbx@saved@tgl@lastins
  \global\let\etb@tgl@blx@keepunit\scbx@saved@tgl@keepunit
}

\newcommand*{\scbx@resetpunctstate}{%
  \let\blx@unitpunct\@empty
  \global\togglefalse{blx@block}%
  \global\togglefalse{blx@unit}%
  \global\togglefalse{blx@insert}%
  \global\togglefalse{blx@lastins}%
  \global\togglefalse{blx@keepunit}%
}


\newbibmacro{sidecite}{%
  \scbx@savepunctstate
  \scbx@resetpunctstate
  \marginpar{%
    \toggletrue{blx@footnote}%
    \printtext[labelalphawidth]{%
      \printfield{labelprefix}%
      \printfield{labelalpha}%
      \printfield{extraalpha}}
    \setunit{\addspace}%
    \printnames{labelname}%
    \setunit{\printdelim{nametitledelim}}%
    \printfield[citetitle]{labeltitle}%
  }%
  \scbx@restorepunctstate
}


\DeclareCiteCommand{\cite}[\mkbibbrackets]
  {\usebibmacro{prenote}}
  {\scbx@registerkey
   \ifciteindex
     {\indexfield{indextitle}}
     {}%
   \usebibmacro{cite}%
   \iflastciteonsamepage
     {}
     {\usebibmacro{sidecite}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\cbx@textcite}
  {\usebibmacro{textcite:init}}
  {\scbx@registerkey
   \usebibmacro{citeindex}%
   \usebibmacro{textcite}%
   \iflastciteonsamepage
     {}
     {\usebibmacro{sidecite}}}
  {}
  {\usebibmacro{textcite:postnote}}



\makeatother
\addbibresource{biblatex-examples.bib}

\begin{document}
Lorem \cite{sigfridsson,worman,geer}
ipsum \cite{sigfridsson}
dolor \textcite{sigfridsson,knuth:ct:a}
\clearpage
dolor \cite{sigfridsson}
sit \cite{worman,sigfridsson,knuth:ct:b}
amet \cite{knuth:ct:a}
\end{document}

The body reads "Lorem [SR98; Wor02; Gee85] ipsum [SR98] dolor Sigfridsson and Ryde [SR98] and Knuth [Knu84]" and has a margin note for each of the references exactly once.

moewe
  • 175,683
  • Thanks! Could you also add a DeclareCiteCommand for the textcite macro? – asante Aug 06 '18 at 14:48
  • 1
    @asante Have a look at the edited answer, please. \textcite is quite a bit more complicated because the margin note has to be invisible for the punctuation tracker. – moewe Aug 06 '18 at 15:16
  • [SR98] is still put twice in the margin, I would like to have it only once, also in the case that it's once cited with \cite and once with \textcite – asante Aug 06 '18 at 16:06
  • @asante Check the edit, please. – moewe Aug 06 '18 at 16:27
  • The MWE works for me, but when I modify my not-so-minimal memoir template, I get an error, see my updated question. – asante Aug 07 '18 at 11:48
  • @asante Sorry, you will have to show me something that reproduces this error. – moewe Aug 07 '18 at 11:52
  • Arr, I wrongly copied your solutions to the full template, sorry. It works now. Thanks for your help! – asante Aug 07 '18 at 12:05
  • I am using this macro, but when I have a sidenote with a citation inside, it does not work. Float issues. With '\citeonly', it does not give an error, but It only shows the reference name, for example "[STr18]", not the citation. – Fred Guth Nov 10 '21 at 19:28
  • what do cbx@ and scbx@ stand for? – Fred Guth Mar 04 '22 at 16:34
  • @FredGuth cbx@ is biblatex's usual prefix for internal macros in the citations. I guess scbx@ was invented in analogy to cbx@ for this answer. – moewe Mar 04 '22 at 16:38