在自定义 biblatex 样式中声明支持 bibstrings 字段的正确方法

在自定义 biblatex 样式中声明支持 bibstrings 字段的正确方法

问题

我正在创建自定义 biblatex 样式,并希望对 bibstrings 的支持类似于字段month在常见实现上的支持。也就是说,如果我将某些内容放在括号中,{something}则内容something将呈现在字段中。但如果我有一些没有括号的内容,它将被解释为 bibstring 并转换为其定义。

我可以通过检查字段内容是否为 bibstring 来部分实现这一点,通过\ifbibstring(和朋友)。但是,这只有在内容始终在括号内时才有效。如果不是,biber 会给出错误并且不会传递该字段进行进一步处理。

例如,下面的代码会生成警告消息

警告 - BibTeX 子系统:/tmp/M3YJZ8wGD7/mwe.bib_28410.utf8,第 21 行,警告:未定义宏“mytitle”

这使得 biber 不会在.bbl文件中创建该字段。我在biblatex/biber:在多个引用部分中使用来自一个文件的字符串宏,但这并不能解决我的问题。

平均能量损失

这是我为了演示我的问题是最小的实现。

% !BIB program = biber
\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
  @test{test1,
    title = {A},
    year = {1995},
  }

  @test{test2,
    title = {B},
    year = {1994},
  }

  @test{test3,
    title = {mytitle},
    year = {1998},
  } 

  @test{test4,
    title = mytitle,
    year = {1998},

  }
\end{filecontents}

\begin{filecontents}{test.dbx}
  \DeclareDatamodelFields[type=field, datatype=literal]{title}

  \DeclareDatamodelFields[type=field, datatype=datepart]{year}

  \DeclareDatamodelEntryfields[test]{%
    year,%
    title%
  }
\end{filecontents}

\begin{filecontents}{english-test.lbx}
  \InheritBibliographyExtras{english}

  % Bibliography strings
  \NewBibliographyString{mytitle}

  \DeclareBibliographyStrings{%
    inherit = {american},
    mytitle = {{my title}{my title}},
  }
\end{filecontents}

\begin{filecontents}{test.bbx}
  \RequireBibliographyStyle{standard}

  % map language
  \DeclareLanguageMapping{english}{english-test}

  % Dummy driver for testing
  \DeclareBibliographyDriver{test}{%
    \usebibmacro{begentry}%
    \printfield{title}%
    \newunit%
    \printfield{year}%
    \newunit%
    \usebibmacro{finentry}%
  }

  \DeclareFieldFormat[test]{title}{%
    \ifbibstring{#1}{\bibstring{#1}}{#1}%
  }
\end{filecontents}

\usepackage[backend=biber, bibstyle=test]{biblatex}
\addbibresource{\jobname.bib}


\begin{document}

  \nocite{*}
  \printbibliography

\end{document}

电流输出:

在此处输入图片描述

预期输出:

在此处输入图片描述

问题

请注意,我期望 bibstrings 的行为与 相同month。如果我有不带括号的字段,即test4中的条目的大小写.bib,则应使用 bibstring 的定义进行转换。但如果我有带括号的相同定义,例如 中的test3,则应该打印内容。

我怎样才能通过自定义样式来实现这一点?

答案1

这里至少有两个“字符串”的概念。它们单独都不能满足您的要求。只有两者结合才能实现这一点。

@strings

@string首先,有@string一种方法可以将相同的文本插入到多个.bib条目中,而无需每次都重新输入整个文本。此功能完全在.bib文件级别起作用。

每个@string条目都有一个ID(就像通常的.bib条目的条目键一样),并且可以通过该名称来调用。

@string{brontostring = {On the Theory of Brontosauruses}}

@string可以通过将字符串 ID 作为字段值来使用没有大括号。

@book{foo,
  author = {Anne Elk},
  title  = brontostring,
  date   = {1970},
}

Biber(或 BibTeX)在读取.bib文件时立即解析这些字符串。需要注意的是,@string在使用之前必须先定义 s。特别是,您不能使用没有括号的任意文本,只有已知的@strings 才有效。然后我们剩下

@book{foo,
  author = {Anne Elk},
  title  = {On the Theory of Brontosauruses},
  date   = {1970},
}

当进一步处理该条目时,没有迹象表明该文本源自@string

这将允许您将任意文本注入条目。文本不能通过 更改biblatex,但您可以通过加载.bib对同一字符串具有不同定义的不同文件来更改它。这就是 和 的作用。ieeetran您可以加载以获取缩写的期刊名称或获取完整的期刊名称。IEEEabrv.bibIEEEfull.bibIEEEabbrv.bibIEEEfull.bib

无论出于何种目的和意图,月份字符串的工作方式都类似。 例如,jan@string用于1feb用于2等等。

@string.bib当 s 用作字段值时,不要在文件中使用括号。

参考书目字符串

然后还有第二个完全不相关的“字符串”概念,即 bibstring。这些就是您使用\ifbibstring\bibstring和引用的字符串\NewBibliographyString。Bibstring 是 本地化功能的一部分biblatex,允许您将某些术语翻译成其他语言。通常它们在文件中定义.lbx,但它们的值也可以在序言中被覆盖。

Bibstrings 可以与 一起使用,\bibstring{<bibstringid>}其中<bibstringid>是用 定义的 bibstring 的名称\NewBibliographyString。理想情况下,<bibstringid>还会在文件中收到一个值.lbx,否则<bibstringid>会以粗体打印。

整个日期处理要复杂得多,但对于这个答案,我们可以假设有biblatex一个名为的函数,\mkbibmonth将 1 映射到\bibstring{january},将 2 映射到\bibstring{february}等等。因此,当\mkbibmonth{7}调用时,会导致\bibstring{july}并且如果英语是活动语言,则在文档中打印“July”或者如果德语是活动语言,则在文档中打印“Juli”。

一个更简单、更典型的 bibstring 示例是字段pubstate。字段格式pubstate

\DeclareFieldFormat{pubstate}{\ifbibstring{#1}{\bibstring{#1}}{#1}}

有一些预定义的字符串可用于该pubstate字段,例如 inpress,,forthcomingsubmitted如果你使用其中一个,即你有

pubstate = {inpress},

在您的某个.bib条目中,则biblatex不会在文档中打印“inpress”,而是使用 bibstring 中给出的该术语的翻译。(当然,也biblatex很乐意使用您提供的任何其他 bibstring,同样pubstate = {january}有效。)如果没有同名的 bibstring,则按原样打印该字段,因此pubstate = {foonostring}只需打印“foonostring”。

bibstrings文件中的输入始终.bib带有括号。

两种字符串类型的比较

据我所知,没有其他组合@strings和字符串biblatex以完全相同的方式工作。我强烈怀疑 month@string只是为了向后兼容而实现的。

正如我们所见,通常有两种方法可以创建上下文相关的输出。

  1. @string由后端解决
  2. .lbx)bibstrings 解析为biblatex

哪一个更合适取决于您的使用情况。 @string如果您只想节省打字时间,或者想要在几种输入形式(长期刊名称与短期刊名称)之间切换,那么 s 似乎更合适。一般来说,@strings 与语言或地区无关。如果您想要真正的本地化,Bibstrings 是最佳选择。

通过您问题中的例子,我无法判断这两种方法中的哪一种在您的用例中更有用。

我们能得到你想要的吗?

如果你坚持你问题中描述的方案,那么通过结合这两种方法几乎是可能的。我认为这不是一个特别好的主意,但我们继续吧。

对于每个不带括号的可能值,您需要定义一个@string替换文本。如果您想要一个可移植的解决方案,则需要在一个特殊.bib文件中完成此操作,您需要在所有项目中加载该文件。

@string{bracelessa = {bracelessa}}
@string{bracelessb = {bracelessb}}

然后让bibstringsbracelessa为人所知bracelessbbiblatex

\NewBibliographyString{bracelessa}
\NewBibliographyString{bracelessb}

并定义它们

\DeclareBibliographyStrings{%
  inherit = {american},
  bracelessa = {{A title}{A t\addddot}},
  bracelessb = {{B title}{B t\addddot}},
}

然后使用字段格式

\DeclareFieldFormat[test]{title}{\ifbibstring{#1}{\bibstring{#1}}{#1}}

对于相关领域。

现在

title = bracelessa,

将在您的文档中打印“A 标题”。

为什么这不能准确地给出您所描述的内容?

首先,无括号输入不是任意的。您需要定义 a@string和适当的bibstring。其次,title = {something}并不总是会呈现something。如果您写title = {bracelessa}'A title' 就会出现。通过为 bibstring 选择更荒谬的名称可以使冲突变得更加困难,但它们总是可能发生,因为没有办法找出字段值是直接给出的还是通过 给出的@string

相关内容