Печатать ISBN только в том случае, если DOI не определен (включая запись перекрестной ссылки!)

Печатать ISBN только в том случае, если DOI не определен (включая запись перекрестной ссылки!)

Предыдущий вопрос здесьспрашивает, может ли Biblatex распечатать ISBN записи, только если она еще не содержит DOI. Принятый ответкЭндрю Суоннзаключается в использовании функций перераспределения источников Biblatex для проверки того, doiявляется ли поле ненулевым, и если это так, то для очистки isbnполя, чтобы оно не выводилось на печать.

Проблема с этим решением в том, что оно не работает для записей с перекрестными ссылками. Например, предположим, что у вас есть @proceedingsзапись с isbnполем, @inproceedingsзапись с doiполем, а также crossrefполе, которое ссылается на @proceedingsзапись. В этом случае, когда @inproceedingsзапись печатается в списке ссылок, отображаются и DOI, и ISBN.

Вот минимальный пример и результат:

\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}

Вывод вышеуказанного документа LaTeX, показывающий, что статья4 неправильно напечатана с ISBN и DOI

Как можно адаптировать ответ Эндрю, чтобы он учитывал поля isbnи doiв перекрестно-ссылочных записях? Или, если это невозможно, есть ли какое-то другое решение (кроме ручного редактирования записей библиографии), которое позволит этого добиться?

решение1

Sourcemaps выполняются довольно рано в .bibпроцессе разбора, до того, как были применены псевдонимы полей и наследование данных. Это означает, что ваш sourcemap просто не знает, унаследует ли запись определенное поле или нет.

Вероятно, лучше всего подавлять поле только после того, biblatexкак все данные будут доступны. Концептуально самый лучший способ, вероятно, проходит через \AtDataInput, но для этого нужен новый вспомогательный макрос.

\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] Адам Автор, ред. Книга первая. Только DOI. 2020. doi: 10.1000/1010.//[2] Бетти Букрайтер, ред. Книга вторая. DOI и ISBN; ISBN не должен отображаться. 2020. doi: 10.1000/2020.//[3] Эдвард Редактор, ред. Книга третья. Только ISBN. 2020. isbn: 123-456-789.//[4] Салли Скрайб. «Статья четвертая». В: Книга третья. Ред. Эдварда Редактора. DOI из статьи, ISBN из crossref не должен отображаться. 2020. doi: 10:1000/4040.//[5] Уолтер Райтер. «Статья пятая». В: Книга третья. Ред. Эдварда Редактора. ISBN из crossref должен отображаться. 2020. ISBN: 123-456-789.


В качестве альтернативы вы можете использовать стандартные крючки \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}

Связанный контент