仅当未定义 DOI 时才打印 ISBN(包括在 crossref 条目中!)

仅当未定义 DOI 时才打印 ISBN(包括在 crossref 条目中!)

之前有一个问题询问 Biblatex 是否可以仅在条目不包含 DOI 的情况下打印条目的 ISBN。 接受的答案经过安德鲁·斯旺是使用 Biblatex 的源重映射功能来检查该doi字段是否非空,如果是,则清除该isbn字段以免打印。

此解决方案的问题在于它不适用于交叉引用的条目。例如,假设您有一个包含字段@proceedings的条目isbn,以及一个@inproceedings包含字段 doicrossref引用该条目的字段的条目@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 文档的输出显示,article4 错误地打印了 ISBN 和 DOI

如何调整 Andrew 的答案,使其能够考虑交叉引用条目中的isbndoi字段?或者如果失败了,是否有其他解决方案(无需手动编辑参考书目条目)可以实现此目的?

答案1

Sourcemap 在解析过程中的执行时间相当早,.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] Adam Author,编辑。第一册。仅 DOI。2020。doi:10.1000/1010。//[2] Betty Bookwriter,编辑。第二册。DOI 和 ISBN;不应显示 ISBN。2020。doi:10.1000/2020。//[3] Edward Editor,编辑。第三册。仅 ISBN。2020。isbn:123-456-789。//[4] Sally Scribe。“第四条”。在:第三册。Edward Editor 编辑。不应显示文章中的 DOI 和 crossref 中的 ISBN。2020。doi:10:1000/4040。//[5] Walter Writer。“第五条”。在:第三册。Edward Editor 编辑。应显示 crossref 中的 ISBN。 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}

相关内容