.png)
Предыдущий вопрос здесьспрашивает, может ли 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}
Как можно адаптировать ответ Эндрю, чтобы он учитывал поля 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}
В качестве альтернативы вы можете использовать стандартные крючки \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}