问题
我正在创建自定义 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
这里至少有两个“字符串”的概念。它们单独都不能满足您的要求。只有两者结合才能实现这一点。
@string
s
@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。特别是,您不能使用没有括号的任意文本,只有已知的@string
s 才有效。然后我们剩下
@book{foo,
author = {Anne Elk},
title = {On the Theory of Brontosauruses},
date = {1970},
}
当进一步处理该条目时,没有迹象表明该文本源自@string
。
这将允许您将任意文本注入条目。文本不能通过 更改biblatex
,但您可以通过加载.bib
对同一字符串具有不同定义的不同文件来更改它。这就是 和 的作用。ieeetran
您可以加载以获取缩写的期刊名称或获取完整的期刊名称。IEEEabrv.bib
IEEEfull.bib
IEEEabbrv.bib
IEEEfull.bib
无论出于何种目的和意图,月份字符串的工作方式都类似。 例如,jan
是@string
用于1
,feb
用于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
,,forthcoming
。submitted
如果你使用其中一个,即你有
pubstate = {inpress},
在您的某个.bib
条目中,则biblatex
不会在文档中打印“inpress”,而是使用 bibstring 中给出的该术语的翻译。(当然,也biblatex
很乐意使用您提供的任何其他 bibstring,同样pubstate = {january}
有效。)如果没有同名的 bibstring,则按原样打印该字段,因此pubstate = {foonostring}
只需打印“foonostring”。
bibstrings
文件中的输入始终.bib
带有括号。
两种字符串类型的比较
据我所知,没有其他组合@strings
和字符串biblatex
以完全相同的方式工作。我强烈怀疑 month@string
只是为了向后兼容而实现的。
正如我们所见,通常有两种方法可以创建上下文相关的输出。
@string
由后端解决- (
.lbx
)bibstrings 解析为biblatex
哪一个更合适取决于您的使用情况。
@string
如果您只想节省打字时间,或者想要在几种输入形式(长期刊名称与短期刊名称)之间切换,那么 s 似乎更合适。一般来说,@string
s 与语言或地区无关。如果您想要真正的本地化,Bibstrings 是最佳选择。
通过您问题中的例子,我无法判断这两种方法中的哪一种在您的用例中更有用。
我们能得到你想要的吗?
如果你坚持你问题中描述的方案,那么通过结合这两种方法几乎是可能的。我认为这不是一个特别好的主意,但我们继续吧。
对于每个不带括号的可能值,您需要定义一个@string
替换文本。如果您想要一个可移植的解决方案,则需要在一个特殊.bib
文件中完成此操作,您需要在所有项目中加载该文件。
@string{bracelessa = {bracelessa}}
@string{bracelessb = {bracelessb}}
然后让bibstringsbracelessa
为人所知bracelessb
biblatex
\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
。