
之前的問題在這裡詢問 Biblatex 是否可以僅在條目尚未包含 DOI 時列印條目的 ISBN。 接受的答案經過安德魯·斯旺就是利用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
.bib
在應用欄位別名和資料繼承之前,來源映射在解析過程中相當早地執行。這意味著您的來源映射根本不知道條目是否會繼承某個欄位。
最好僅在所有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}