0

I need to tell LaTeX when citing an Incollection related to a Collection via crossref: if this is not the first citation of that collection, then use this driver instead of the usual one.

Is that possible?

MNWE with the code suggested below (I don't know why it doesn't run with the bibliography file inside. Btw, without the filecontents it runs but still doesn't works as expected)

% !BIB TS-program = biber
% !BIB program = biber
% !TEX encoding = UTF-8 Unicode
% !TeX TS-program = xelatexmk

\begin{filecontents}{archivio.bib}

@collection{Col4,
 Editor = {Gino Autieri AND Gaspare Porro},
 Publisher = {Routledge},
 Shorttitle = {The Grand Theater},
 Title = {The Grand Theater of the World. Music, Space, and the Performance of Identity in Early Modern Rome},
 Year = {2019}}

@incollection{Inc4,
 Author = {Mario Rossi AND Giovanni Bianchi},
 Crossref = {Col3},
 Pages = {151-163},
 Title = {Cultural Life at Villa Lante di Bagnaia. Family, gardens and sociability},
 Shorttitle = {Cultural Life}}

@book{rompi,
 Author = {Pippo Kennedy},
 Publisher = {Routledge},
 Title = {Questo è un libro per rompere l'ibidem},
 Year = {2019}}

\end{filecontents}

\documentclass[10pt, twoside, openany]{book}
\usepackage[paperwidth=210mm, paperheight=150mm, inner=5mm, outer=5mm, top=5mm, bottom=5mm]{geometry}
\usepackage{fontspec}
\usepackage{polyglossia}                        
    \setmainlanguage{italian}

\usepackage[autostyle,italian=guillemets]{csquotes}
\usepackage{xpatch}
\usepackage{etoolbox}   % necessario per il comando custom per le citazioni di incollection in crossref     
\usepackage[style=verbose-trad2,            
            language=italian,
            useprefix=true,                 
     %    giveninits=true,      nomi per esteso    
            indexing=true,
        maxbibnames=7, 
        maxcitenames=2,
            citepages=omit,                 
            backend=biber,  
            ibidpage=true,
        ]{biblatex} 

% \usepackage{biblatex-opcit-booktitle}     % per avere cit. nelle citazioni di Incollection con crosserf > non funziona in tutti i casi quindi lo commento 

\NewBibliographyString{ibidemloccit,ibidemnoloccit}
\DefineBibliographyStrings{italian}{%
     idem   = {Id\adddot},
    idemsm = {Id\adddot},
    idemsf = {Ead\adddot},
    idemsn = {Id\adddot},
    idempm = {Id\adddot},
    idempf = {Id\adddot},
    idempn = {Id\adddot},
    idempp = {Id\adddot},
  ibidemloccit   = {Ibidem}, % tolto \mkbibemph perché ho già che tutte le latinitates sono enfatiche; Se capiterà di dover avere la "i" minuscola, bisogna mettere minuscolo nel codice e distinguere tra \cite e \Cite
  ibidemnoloccit = {Ivi},
  editor           = {a cura di},
  editors          = {a cura di}
}

\xpatchbibmacro{author}
  {\printnames{author}}
  {\iffootnote
     {\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
       {\usebibmacro{cite:idem}}
       {\printnames{author}}}
     {\printnames{author}}}
  {}{}
\xpatchbibmacro{bbx:editor}
  {\printnames{editor}}
  {\iffootnote
     {\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
        {\usebibmacro{cite:idem}}
        {\printnames{editor}}}
     {\printnames{editor}}}
  {}{}
\xpatchbibmacro{bbx:translator}
  {\printnames{translator}}
  {\iffootnote
     {\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
        {\usebibmacro{cite:idem}}
        {\printnames{translator}}}
     {\printnames{translator}}}
  {}{}

\renewbibmacro*{cite:ibid}{%
  \printtext{%
    \bibhyperlink{cite\csuse{cbx@lastcite@\thefield{entrykey}}}{%
      \ifloccit
        {\bibstring[\mkibid]{ibidemloccit}%
         \global\toggletrue{cbx:loccit}}
        {\bibstring[\mkibid]{ibidemnoloccit}}}}}

\renewbibmacro*{cite:title}{%                           Ciò che segue è per avere lo shorttitle alla seconda citazione (funge solo in trad2)
  \printtext[bibhyperlink]{%
    \printfield[citetitle]{labeltitle}%
    \setunit{\addspace}%
    \bibstring[\mkibid]{opcit}}}


%%%%%%%%%%%%%%% COMANDI PER CITAZIONE DI INCOLLECTION CON CROSSREF %%%%%%%%%%

\makeatletter
% test to check if we are dealing with an @incollection
% which has a crossref that was cited before
\newcommand*{\ifincollectioncrossrefparentseen}{%
  \ifentrytype{incollection}
    {\iffieldundef{crossref}
       {\@secondoftwo}
       {\ifciteseen{\thefield{crossref}}}}
    {\@secondoftwo}}
\makeatother

\renewbibmacro*{cite:full}{%
  \usebibmacro{cite:full:citepages}%
  \printtext[bibhypertarget]{%
    \ifincollectioncrossrefparentseen
      {\usedriver
         {\DeclareNameAlias{sortname}{default}}
         {special:incollection}}
      {\usedriver
         {\DeclareNameAlias{sortname}{default}}
         {\thefield{entrytype}}}}%
  \usebibmacro{shorthandintro}}




%%%%%%%%%%%%%% RIDEFINISCO IL DRIVER COLLECTION%%%%%%%%%%%%

\DeclareBibliographyDriver{collection}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \usebibmacro{maintitle+title}%
  \setunit{\printdelim{nametitledelim}}\newblock
  \usebibmacro{byeditor+others}%
  \newunit\newblock
  \usebibmacro{editor+others}%
  \newunit
  \printlist{language}%
  \newunit\newblock
  \printfield{edition}%
  \newunit
  \iffieldundef{maintitle}
    {\printfield{volume}%
     \printfield{part}}
    {}%
  \newunit
  \printfield{volumes}%
   \newunit\newblock
  \usebibmacro{series+number}%
  \newunit\newblock
  \printfield{note}%
  \newunit\newblock
  \usebibmacro{publisher+location+date}%
  \newunit\newblock
  \usebibmacro{chapter+pages}%
  \newunit
  \printfield{pagetotal}%
  \newunit\newblock
  \iftoggle{bbx:isbn}
    {\printfield{isbn}}
    {}%
  \newunit\newblock
  \usebibmacro{doi+eprint+url}%
  \newunit\newblock
  \usebibmacro{addendum+pubstate}%
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}



\addbibresource{archivio.bib}  



%%%%%%%%%%%%%%%%%%%%

\begin{document}

\textbf{Collection first cite} -> everythong long\\
\cite{Col4}\\

Rompitraccia: \cite{rompi}\\

\textbf{Incollection first cite} -> Incollection long and Collection short\\

\cite{Inc4}\\

Something in the middle (for the ibidem): \cite{rompi}\\

\textbf{Incollection second cite} -> Just the short Incollection\\

\cite{Inc4}
2
  • 1
    Two things: Inc4 references Crossref = {Col3}, but there is no entry Col3 in the example .bib file. Only Col4. Secondly, you have not actually defined the new driver special:incollection anywhere.
    – moewe
    Apr 28, 2020 at 16:20
  • 1
    Thirdly, there was an error in my code. It should have been \ifentryseen not \ifciteseen (as in the explanation). Fixed in my answer. But you definitely need to supply an appropriate definition of special:incollection.
    – moewe
    Apr 28, 2020 at 16:25

1 Answer 1

1

Usually the verbose styles call the bibliography driver in citations in the macro cite:full, which is usually defined roughly like this (the code example here is from verbose.cbx)

\newbibmacro*{cite:full}{%
  \usebibmacro{cite:full:citepages}%
  \printtext[bibhypertarget]{%
    \usedriver
      {\DeclareNameAlias{sortname}{default}}
      {\thefield{entrytype}}}%
  \usebibmacro{shorthandintro}}

\usedriver{<precode>}{<entry type>} executes <precode> and then calls the driver for <entry type>.

Strictly speaking <entry type> need not be an existing entry type, it can be any driver that you define. You could for example defines a special driver for @incollections with

\DeclareBibliographyDriver{special:incollection}{%
  ...
}

and then call

\usedriver
  {\DeclareNameAlias{sortname}{default}}
  {special:incollection}

Now you need a way to test whether you want to use the special driver.

If I understand correctly you are thinking about a situation where you have an @incollection that crossrefs its parent @collection and you now want to determine if the @collection has been seen before.

The test you need here is \ifentryseen{<entrykey>}{<true>}{<false>}

\ifentryseen{\thefield{crossref}}
  {<parent cited already}
  {<parent not cited already>}

Note that this test can only pick up if the parent @collection was cited, not if it was seen in another context before (maybe because a different @incollection entry already mentioned it). If you wanted to pick up mentions of the parent @collection in other contexts, you would need some more advanced tracking that you probably need to code yourself.

You could combine this to something like this

\makeatletter
% test to check if we are dealing with an @incollection
% which has a crossref that was cited before
\newcommand*{\ifincollectioncrossrefparentseen}{%
  \ifentrytype{incollection}
    {\iffieldundef{crossref}
       {\@secondoftwo}
       {\ifentryseen{\thefield{crossref}}}}
    {\@secondoftwo}}
\makeatother

\renewbibmacro*{cite:full}{%
  \usebibmacro{cite:full:citepages}%
  \printtext[bibhypertarget]{%
    \ifincollectioncrossrefparentseen
      {\usedriver
         {\DeclareNameAlias{sortname}{default}}
         {special:incollection}}
      {\usedriver
         {\DeclareNameAlias{sortname}{default}}
         {\thefield{entrytype}}}}%
  \usebibmacro{shorthandintro}}

In general I'd expect that you create unnecessary overhead and code duplication when you create two very similar bibliography drivers for the same entry type. I would expect that it is slightly simpler just to code the drivers themselves in a way that they display the result differently depending on the test \ifincollectioncrossrefparentseen.

2
  • Can we use your test to change the \cite outcome instead? I need the outcome produced by the workaround that I posted in my second answer here: tex.stackexchange.com/questions/539662/…
    – Teodoro
    Apr 28, 2020 at 16:43
  • 1
    @Teodoro Sure, you can use the test anywhere. I just showed its use here in what I thought came closest to what the question asked: Select a different driver.
    – moewe
    Apr 28, 2020 at 17:07

You must log in to answer this question.

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