DOI が定義されていない場合にのみ ISBN を印刷します (crossref エントリを含む)

DOI が定義されていない場合にのみ ISBN を印刷します (crossref エントリを含む)

以前の質問はこちらBiblatex では、エントリに DOI が含まれていない場合にのみ、エントリの ISBN を印刷できるかどうかを尋ねます。 受け入れられた答えによるアンドリュー・スワンBiblatex のソース再マッピング機能を使用して、フィールドが null でないかどうかを確認しdoi、そうである場合は、isbnフィールドをクリアして印刷されないようにすることです。

このソリューションの問題点は、相互参照されたエントリには機能しないことです。たとえば、フィールドを持つエントリと、フィールドを持つエントリ、およびエントリを参照するフィールドがあるとします@proceedingsisbnこの@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の両方で誤って印刷されていることを示しています。

isbnAndrew の回答をどのように修正すれば、相互参照エントリのフィールドを考慮に入れることができるでしょうか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}

[1] Adam Author、編。Book One。DOIのみ。2020年。doi:10.1000/1010。//[2] Betty Bookwriter、編。Book Two。DOIとISBN。ISBNは表示しないでください。2020年。doi:10.1000/2020。//[3] Edward Editor、編。Book Three。ISBNのみ。2020年。isbn:123-456-789。//[4] Sally Scribe。「Article Four」。Book Threeに収録。Edward Editor編集。記事からのDOI、crossrefからのISBNは表示しないでください。2020年。doi:10:1000/4040。//[5] Walter Writer。「Article Five」。Book Threeに収録。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}

関連情報