Imprima el ISBN solo si el DOI no está definido (¡incluso en la entrada de referencia cruzada!)

Imprima el ISBN solo si el DOI no está definido (¡incluso en la entrada de referencia cruzada!)

Una pregunta previa aquípregunta si es posible que Biblatex imprima el ISBN de una entrada solo si aún no contiene un DOI. La respuesta aceptadaporAndres Swannes utilizar las funciones de reasignación de código fuente de Biblatex para verificar si el doicampo no es nulo y, de ser así, borrar el isbncampo para que no se imprima.

El problema con esta solución es que no funciona para entradas con referencias cruzadas. Por ejemplo, digamos que tiene una @proceedingsentrada con un isbncampo y una @inproceedingsentrada con un doicampo, así como un crossrefcampo que hace referencia a la @proceedingsentrada. En este caso, cuando la @inproceedingsentrada se imprime en la lista de referencias, se muestran tanto el DOI como el ISBN.

Aquí hay un ejemplo mínimo y el resultado:

\documentclass{article}
\usepackage[backend=biber]{biblatex}
\addbibresource{\jobname.bib}
\DeclareSourcemap{
  \maps[datatype=bibtex]{
     \map{
        \step[fieldsource=doi,final]
        \step[fieldset=isbn,null]
        }
      }
}

\begin{filecontents}{\jobname.bib}
@proceedings{book1,
  editor = {Adam Author},
  title = {Book One},
  year = 2020,
  doi = {10.1000/1010},
  note = {DOI only},
}

@proceedings{book2,
  editor = {Betty Bookwriter},
  title = {Book Two},
  year = 2020,
  doi = {10.1000/2020},
  isbn = {123-456-789},
  note = {DOI and ISBN; ISBN should not be displayed},
}

@proceedings{book3,
  editor = {Edward Editor},
  title = {Book Three},
  year = 2020,
  isbn = {123-456-789},
  note = {ISBN only},
}

@inproceedings{article4,
  author =   {Sally Scribe},
  title =    {Article Four},
  doi =      {10:1000/4040},
  crossref = {book3},
  note = {DOI from article, ISBN from crossref should not be displayed},
}

@inproceedings{article5,
  author =   {Walter Writer},
  title =    {Article Five},
  crossref = {book3},
  note = {ISBN from crossref should be displayed},
}
\end{filecontents}

\begin{document}
\nocite{book1,book2,book3,article4,article5}
\printbibliography
\end{document}

Salida del documento LaTeX anterior, que muestra que el artículo 4 está impreso incorrectamente con ISBN y DOI

¿Cómo se puede adaptar la respuesta de Andrew para que tenga en cuenta isbny doiincluya entradas con referencias cruzadas? O en su defecto, ¿existe alguna otra solución (aparte de editar manualmente las entradas de la bibliografía) que lo logre?

Respuesta1

Los mapas de origen se ejecutan bastante temprano en el .bibproceso de análisis, antes de que se apliquen los alias de campo y la herencia de datos. Esto significa que su mapa fuente simplemente no sabe si una entrada heredará un determinado campo o no.

Probablemente sea mejor suprimir el campo sólo cuando biblatextodos los datos estén disponibles. La forma conceptualmente más agradable probablemente sea \AtDataInput, pero necesita una nueva macro auxiliar.

\documentclass{article}
\usepackage[backend=biber]{biblatex}

\makeatletter
\newcommand*{\ClearFieldAtDataInput}[1]{%
  \csxappto\blx@bbl@data{%
    \undef\expandafter\noexpand\csname abx@field@#1\endcsname}}
\makeatother

\AtDataInput{%
  \iffieldundef{doi}
    {}
    {\ClearFieldAtDataInput{isbn}}}

\begin{filecontents}{\jobname.bib}
@proceedings{book1,
  editor = {Adam Author},
  title  = {Book One},
  year   = 2020,
  doi    = {10.1000/1010},
  note   = {DOI only},
}
@proceedings{book2,
  editor = {Betty Bookwriter},
  title  = {Book Two},
  year   = 2020,
  doi    = {10.1000/2020},
  isbn   = {123-456-789},
  note   = {DOI and ISBN; ISBN should not be displayed},
}
@proceedings{book3,
  editor = {Edward Editor},
  title  = {Book Three},
  year   = 2020,
  isbn   = {123-456-789},
  note   = {ISBN only},
}
@inproceedings{article4,
  author   = {Sally Scribe},
  title    = {Article Four},
  doi      = {10:1000/4040},
  crossref = {book3},
  note     = {DOI from article, ISBN from crossref should not be displayed},
}
@inproceedings{article5,
  author   = {Walter Writer},
  title    = {Article Five},
  crossref = {book3},
  note     = {ISBN from crossref should be displayed},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{book1,book2,book3,article4,article5}
\printbibliography
\end{document}

[1] Adán Autor, ed. Libro uno. Sólo DOI. 2020. doi: 10.1000/1010.//[2] Betty Bookwriter, ed. Libro dos. DOI e ISBN; El ISBN no debe mostrarse. 2020. doi: 10.1000/2020.//[3] Edward Editor, ed. Libro tres. Sólo ISBN. 2020. isbn: 123-456-789.//[4] Sally Scribe. “Artículo Cuarto”. En: Libro Tres. Ed. por Eduardo Editor. No se deben mostrar el DOI del artículo ni el ISBN de la referencia cruzada. 2020. doi: 10:1000/4040.//[5] Walter Writer. “Artículo Quinto”. En: Libro Tres. Ed. por Eduardo Editor. Debe mostrarse el ISBN de la referencia cruzada. 2020. ISBN: 123-456-789.


Alternativamente, puede utilizar los ganchos estándar \AtEveryBibitem.\AtEveryCitekey

\documentclass{article}
\usepackage[backend=biber]{biblatex}

\newcommand*{\clearisbn}{%
  \iffieldundef{doi}
    {}
    {\clearfield{isbn}}}

\AtEveryBibitem{\clearisbn}
\AtEveryCitekey{\clearisbn}

\begin{filecontents}{\jobname.bib}
@proceedings{book1,
  editor = {Adam Author},
  title  = {Book One},
  year   = 2020,
  doi    = {10.1000/1010},
  note   = {DOI only},
}
@proceedings{book2,
  editor = {Betty Bookwriter},
  title  = {Book Two},
  year   = 2020,
  doi    = {10.1000/2020},
  isbn   = {123-456-789},
  note   = {DOI and ISBN; ISBN should not be displayed},
}
@proceedings{book3,
  editor = {Edward Editor},
  title  = {Book Three},
  year   = 2020,
  isbn   = {123-456-789},
  note   = {ISBN only},
}
@inproceedings{article4,
  author   = {Sally Scribe},
  title    = {Article Four},
  doi      = {10:1000/4040},
  crossref = {book3},
  note     = {DOI from article, ISBN from crossref should not be displayed},
}
@inproceedings{article5,
  author   = {Walter Writer},
  title    = {Article Five},
  crossref = {book3},
  note     = {ISBN from crossref should be displayed},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{book1,book2,book3,article4,article5}
\printbibliography
\end{document}

información relacionada