biblatex 书目的系统匿名化

biblatex 书目的系统匿名化

考虑以下biblatex数据库:

@misc{calvin,
    author     = {Calvin, Susan},
    title      = {Practical Aspects of Robotics},
    translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}

我想在调用时系统地排除特定作者出现在类似作者的字段(编辑、翻译等)中\pintbibliography

我希望有两个选项可以实现此目的:

第一个选项

使用双位命令可以将目标作者从参考书目中删除\remove:它的第一个参数指定要排除的作者的姓名,第二个参数指定要从中排除作者的(类似作者的)字段的逗号分隔列表。

不过,还有一个问题。所有带有被排除作者曾合作的字段的条目都会被打印出来,以指定此类合作。MWE 将是:

\documentclass{article}
\usepackage{biblatex}

\addbibresource{references.bib}
\remove{Olivaw, R. Daneel}{author, editor, translator}

\begin{document}

\nocite{*}
\printbibliography

\end{document}

这将打印:

参考

[1] 苏珊·卡尔文.机器人技术的实用方面. 翻譯R. Giskard Reventlov。

[2] 安德鲁·马丁.机器人的历史

[3]如何操纵人类而不至于丧命

[4]R. Giskard Reventlov。机器人三大定律

[5]编辑哈里谢顿。心理史学基础

(这大胆的并非用于打印LaTeX。我只是为了强调而使用。)

请注意,正常输出将是:

参考

[1] 苏珊·卡尔文.机器人技术的实用方面. 翻譯作者:R. Daneel Olivaw 和R. Giskard Reventlov。

[2] 安德鲁·马丁.机器人的历史译者:R. Daneel Olivaw。

[3]R.丹尼尔·奥利沃。 如何操纵人类而不至于丧命

[4]R.Daneel Olivaw 和R. Giskard Reventlov。机器人三大定律

[5] Hari Seldon 和 R. Daneel Olivaw,编辑心理史学基础

如果我传递的\remove{Olivaw, R. Daneel}{author}是 而不是\remove{Olivaw, R. Daneel}{author, editor, translator},则输出必须是:

参考

[1] 苏珊·卡尔文.机器人技术的实用方面. 翻譯作者:R. Daneel Olivaw 和R. Giskard Reventlov。

[2] 安德鲁·马丁.机器人的历史译者:R. Daneel Olivaw。

[3]如何操纵人类而不至于丧命

[4]R. Giskard Reventlov。机器人三大定律

[5] Hari Seldon 和 R. Daneel Olivaw,编辑心理史学基础

第二种选择

在这种情况下,我希望完全匿名化参考书目,并使用占位符指定作者/编辑/等的数量。这可以通过 two-place 命令完成\remove*:强制参数指定要匿名的(类似作者的)字段,可选参数指定要标记为的作者申请人

例如,在我们的 MWE 中调用\remove*{author, editor, translator}而不是,将打印:\remove{Olivaw, R. Daneel}{author, editor, translator}

参考

[1] [一位作者]。机器人技术的实用方面. 由[两位译者]翻译。

[2] [一位作者]。机器人的历史. 由 [一位译者] 译者翻译。

[3] [一位作者]。如何操纵人类而不至于丧命

[4] [两位作者]。机器人三大定律

[5] [两名编辑]。心理史学基础

相反,如果我们在可选参数中指定作者,如\remove*[Olivaw, R. Daneel]{author, editor, translator},则输出必须是:

参考

[1] [一位作者]。机器人技术的实用方面. 由 [申请人和一位合作者] 翻译。

[2] [一位作者]。机器人的历史. 由[申请人]翻译。

[3][申请人]。如何操纵人类而不至于丧命

[4] [申请人及一名合作者]。机器人三大定律

[5] [申请人及一名合作者],编辑心理史学基础

如何帮助?

很可能没有人能给我一个完整的答案(这没关系)。一些部分答案将有助于构建一个完整的解决方案。我特别希望得到有关以下几点的反馈:

  • 什么方法可以帮助我计算类似作者的字段中的作者数量?
  • 我可以使用什么方法来识别作者姓名是否属于某个领域。
  • editor如何从特定条目中打印字段(如)的第 n 位作者的姓名?
  • 如何灵活地打印editortype特定条目的字段值?

如果有这样的反馈,我自己也许能够提供完整的答案。

答案1

你可能想看看biblatex-publist,它实现了与您的第一个选项类似的功能。

虽然还是存在一些差异,但这并不是无法克服的。例如,它biblatex-publist总是假设您是合著者(请参阅martin),而且如果您是唯一的作者,它显然仍会打印您的姓名(请参阅olivaw)。

\documentclass{article}
\usepackage[style=publist]{biblatex}

\plauthorname[R. Daneel]{Olivaw}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

让我们进行更理论化的探讨。

为此,您首先需要的是一种在姓名列表中强有力地检测您姓名的方法。biblatex-publist使用字符串相等性测试来检查给定的姓名\plauthorname与当前处理的名称。

如果我要实现类似的东西,我会改用 Biber 的内置名称哈希来比较名称。优点是我们避免了字符串操作和测试,这在 LaTeX 中可能会有点棘手,尤其是当字符串包含非 ASCII 字符时 - 使用哈希,我们只需要比较一个包含的字符串0-9A-f。我在回答中写过关于使用哈希的内容使用 biblatex 突出显示参考书目中的作者,并允许使用参考书目样式对其进行格式化。该答案的更新后的第一部分包含从文档中自动计算名称哈希的代码.tex(因此您不必自己查找哈希)。

然后你需要一种方法来检查你的名字是否在名单中,并计算名单中没有你的名字的人数。这可以用我从 Audrey 那里学到的一个可爱的小技巧来实现biblatex:动态过滤参考文献中特定作者的出版物。这也是如何biblatex-publist计算名字的(https://github.com/jspitz/biblatex-publist/blob/57595995240ad5163ad3fd128b4e5155b311fa3d/publist.bbx#L437-L466)。

这两个问题似乎是最重要的问题,但你还需要解决一些小问题。例如,你需要确保列表分隔符(逗号和“and”)正确运行。

以下应该是“第一个选项”的相当全面的实施。

\documentclass{article}
\usepackage[style=numeric]{biblatex}

\makeatletter
% name hash extraction
\def\nhblx@bibfile@name{\jobname -removenames.bib}
\newwrite\nhblx@bibfile
\immediate\openout\nhblx@bibfile=\nhblx@bibfile@name
\newcounter{nhblx@name}
\setcounter{nhblx@name}{0}
\newcommand*{\nhblx@writenametobib}[1]{%
  \stepcounter{nhblx@name}%
  \edef\nhblx@tmp@nocite{%
    \noexpand\AfterPreamble{%
      \noexpand\setbox0\noexpand\vbox{%
        \noexpand\nhblx@getmethehash{nhblx@name@\the\value{nhblx@name}}}}%
  }%
  \nhblx@tmp@nocite
  \immediate\write\nhblx@bibfile{%
    @misc{nhblx@name@\the\value{nhblx@name}, author = {\unexpanded{#1}}, %
          options = {dataonly=true},}%
  }%
}

\AtEndDocument{%
  \closeout\nhblx@bibfile}

\addbibresource{\nhblx@bibfile@name}

\newcommand*{\nhblx@hashlist}{}
\DeclareNameWrapperFormat{nhblx@hashextract}{#1}
\DeclareNameFormat{nhblx@hashextract}{%
  \xifinlist{\thefield{hash}}{\nhblx@hashlist}
    {}
    {\listxadd{\nhblx@hashlist}{\thefield{fullhash}}}}

\DeclareCiteCommand{\nhblx@getmethehash}
  {}
  {\printnames[nhblx@hashextract][1-999]{author}}
  {}
  {}

\newcommand*{\addtonamelist}{\nhblx@writenametobib}
\newcommand*{\resetnamelist}{\let\nhblx@hashlist\@empty}

\newcommand*{\ifremovename}{%
  \ifdefvoid\nhblx@hashlist
    {\@secondoftwo}
    {\xifinlist{\thefield{hash}}{\nhblx@hashlist}}}

\newcommand*{\ifremovenamepresent}{%
  \ifnumgreater{\value{removed}}{0}}

\newcounter{removed}
\newcounter{unremoved}
\DeclareIndexNameFormat{count:removed}{%
  \ifremovename
    {\stepcounter{removed}}
    {}}

\newbibmacro*{count:removed}[1]{%
  \setcounter{removed}{0}%
  \indexnames[count:removed]{#1}%
  \global\defcounter{unremoved}{\value{#1}-\value{removed}}}
\makeatother

\NewBibliographyString{with,edited,translated}
\DefineBibliographyStrings{english}{
  with       = {with},
  edited     = {ed\adddot},
  translated = {trans\adddot},
}


\DeclareNameWrapperFormat{family-given:remove}{%
  \defcounter{listtotal}{\value{listtotal}-\value{removed}}%
  \defcounter{liststop}{\value{liststop}-\value{removed}}%
  #1%
}

\DeclareNameFormat{family-given:remove}{%
  \ifremovename
    {\addtocounter{listcount}{-1}}
    {\ifgiveninits
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiveni}
         {\namepartprefix}
         {\namepartsuffix}}
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiven}
         {\namepartprefix}
         {\namepartsuffix}}}%
  \usebibmacro{name:andothers}}


\renewbibmacro*{author}{%
  \ifboolexpr{
    test \ifuseauthor
    and
    not test {\ifnameundef{author}}
  }
    {\usebibmacro{count:removed}{author}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{author}}
          {\printnames{author}%
           \iffieldundef{authortype}
             {}
             {\setunit{\printdelim{authortypedelim}}%
              \usebibmacro{authorstrg}}}}
       {}}
    {}}

\renewbibmacro*{editor}{%
  \ifboolexpr{
    test \ifuseeditor
    and
    not test {\ifnameundef{editor}}
  }
    {\usebibmacro{count:removed}{editor}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{edited}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{editor}}
          {\printnames{editor}%
           \setunit{\printdelim{editortypedelim}}%
           \usebibmacro{editorstrg}}%
        \clearname{editor}}
       {}}
    {}}

\renewbibmacro*{editor+others}{%
  \ifboolexpr{
    test \ifuseeditor
    and
    not test {\ifnameundef{editor}}
  }
    {\usebibmacro{count:removed}{editor}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{edited}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{editor}}
          {\printnames{editor}%
           \setunit{\printdelim{editortypedelim}}%
           \usebibmacro{editor+othersstrg}}%
        \clearname{editor}}
       {}}
    {}}

\renewbibmacro*{translator}{%
  \ifboolexpr{
    test \ifusetranslator
    and
    not test {\ifnameundef{translator}}
  }
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\printnames{editor}%
           \setunit{\printdelim{translatortypedelim}}%
           \usebibmacro{translatorstrg}}}%
        \clearname{translator}}
    {}}

\renewbibmacro*{translator+others}{%
  \ifboolexpr{
    test \ifusetranslator
    and
    not test {\ifnameundef{translator}}
  }
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}
           \setunit{\addspace}
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\printnames{editor}%
           \setunit{\printdelim{translatortypedelim}}%
           \usebibmacro{translator+othersstrg}}}%
        \clearname{translator}}
    {}}

\renewbibmacro*{bytranslator}{%
  \ifnameundef{translator}
    {}
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}%
           \setunit{\addspace}%
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\bibstring{bytranslator}%
           \setunit{\addspace}%
           \printnames[bytranslator]{translator}}}
       {}}}

\renewbibmacro*{bytranslator+others}{%
  \ifnameundef{translator}
    {}
    {\usebibmacro{count:removed}{translator}%
     \ifnumgreater{\value{unremoved}}{0}
       {\ifremovenamepresent
          {\bibstring{translated}%
           \setunit{\addspace}%
           \bibstring{with}%
           \setunit{\addspace}%
           \printnames[family-given:remove]{translator}}
          {\usebibmacro{bytranslator+othersstrg}%
           \setunit{\addspace}%
           \printnames[bytranslator]{translator}}%
        \clearname{translator}%
        \newunit}
       {}}%
  \usebibmacro{withothers}}

\addtonamelist{Olivaw, R. Daneel}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
@book{olivaw-reventlov-another,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard and Anne Other},
  title      = {ORA},
}
@collection{seldon-another-olivaw,
  editor     = {Seldon, Hari and Anne Other and Olivaw, R. Daneel},
  title      = {SAO},
}
@collection{seldon-olivaw-another,
  editor     = {Seldon, Hari and Olivaw, R. Daneel and Anne Other},
  title      = {SOA},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

Susan Calvin。《机器人实用方面》。与 R. Giskard Reventlov 合译。

author对于不同的名称列表( ,, ),没有简单的选项可以启用或禁用此功能,但如果您不希望在某些名称列表中发生替换,您可以简单地注释掉相关的 bibmacro 重新定义editortranslator


第二个选项的第一部分实际上很多,很多更容易。列表中的姓名数量author可在计数器中查看author

一个非常简单的解决方案就是重新定义名称包装器格式,只打印\currentnames 的数量。然后我们只需要确保抑制其他宏会打印的“eds”等。

\documentclass{article}
\usepackage[style=numeric]{biblatex}

\DeclareNameWrapperFormat{default}{%
  \mkbibbrackets{%
    \arabic{\currentname}~%
    \ifnumgreater{\value{\currentname}}{1}
      {\ifbibstring{\currentname s}
         {\bibstring{\currentname s}}
         {\currentname s}}
      {\ifbibstring{\currentname}
         {\bibstring{\currentname}}
         {\currentname}}}}

\renewbibmacro*{authorstrg}{}
\renewbibmacro*{editorstrg}{}
\renewbibmacro*{editor+othersstrg}{}
\renewbibmacro*{translatorstrg}{}
\renewbibmacro*{translator+othersstrg}{}

\begin{filecontents}{\jobname.bib}
@misc{calvin,
  author     = {Calvin, Susan},
  title      = {Practical Aspects of Robotics},
  translator = {Olivaw, R. Daneel and Reventlov, R. Giskard},
}
@book{martin,
  author     = {Martin, Andrew},
  title      = {History of Robots},
  translator = {Olivaw, R. Daneel},
}
@book{olivaw,
  author     = {Olivaw, R. Daneel},
  title      = {How to Manipulate Humans and Not Die in the Attempt},
}
@book{olivaw-reventlov,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard},
  title      = {The Three Laws of Robotics},
}
@collection{seldon-olivaw,
  editor     = {Seldon, Hari and Olivaw, R. Daneel},
  title      = {Foundations of Psychohistory},
}
@book{olivaw-reventlov-another,
  author     = {Olivaw, R. Daneel and Reventlov, R. Giskard and Anne Other},
  title      = {ORA},
}
@collection{seldon-another-olivaw,
  editor     = {Seldon, Hari and Anne Other and Olivaw, R. Daneel},
  title      = {SAO},
}
@collection{seldon-olivaw-another,
  editor     = {Seldon, Hari and Olivaw, R. Daneel and Anne Other},
  title      = {SOA},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

[1 位作者]。《机器人实用方面》。译者 [2 位译者]。

这个答案已经很长了,应该可以从这里提出的两个建议中拼凑出一个针对剩余用例的解决方案。所以现在我就到此为止,并建议将问题的其余部分作为读者的练习(我一直想这样做)。如果对此有任何困难,我建议提出一个新问题。

相关内容