我目前正在完成论文的参考书目。我正在使用
\bibliographystyle{unsrtdin}
\bibliography{bibtex/library}
现在,我的问题是,我的 Zotero 库有时有作者的全名,有时只有首字母。这导致参考书目不一致。我觉得从我的 Zotero 库中删除信息并不是正确的解决方案,所以我想让 BibTeX 缩写所有名字。
样式不是固定的,我只需要 unsrt 行为和包含的 URL,因为我引用了在线资源。(这就是我使用 -din 的原因,有些东西是德语的,这是不希望的,但也不是太关键。)
如果 Biber 或其他更复杂的实现简化了解决方案:我试图让它工作,但 TeXlipse 告诉我这\cite
是未定义的,所以我放弃了,因为在这种情况下我没有看到太多优势。
如果这一切太复杂,我仍然可以破解 Zotero 翻译器进行.bib
导出。
答案1
以下是一些可能的解决方案。您可以选择最适合您的方案。
1- 切换到biblatex
。这是一个处理参考书目的较新的软件包;它比 bibtex 样式更容易配置。手册可能看起来很吓人,但你只需要更改几行就可以让它工作。
2- 正如评论中所建议的那样,如果您有空闲时间,可以使用自动化工具从头开始生成新的 bst 文件。您可以使用makebst
,或包含在bib-it
。
3 - 直接破解 bst 文件也是可能的。您需要一些编程经验才能理解发生了什么,但既然您谈到破解 Zotero,我想这不会是个问题;请记住,bst 文件是用一种相当不寻常的基于堆栈的语言编写的,一开始可能很难理解。对于您来说,您可能只需要将format.name
中使用的函数复制abbrv.bst
到 中unsrt.bst
,替换现有的函数。
编辑:也许我应该澄清一下什么是 bst 文件。bibtex 中的参考书目样式通过扩展名为 的样式文件来处理.bst
。如果使用\bibliographystyle{unsrtdin}
,则将加载的文件是unsrtdin.bst
。默认样式可以在 tex 安装目录中找到(例如,在我的 Ubuntu 上是/usr/share/texlive/texmf-dist/bibtex/bst/
);但是,如果您愿意,您可以自己创建一个新的样式并将其放在与您的文件相同的文件夹中.tex
(或者,如果您认为需要多个 tex 文件,请使用更复杂的“本地安装”方法)。
答案2
假设您对参考书目样式产生的格式化输出感到满意unsrtdin
- 即,如果您要在样式文件中更改的唯一内容是强制 BibTeX 始终将名字缩写为首字母 - 您可以按如下方式进行:
复制该文件
unsrtdin.bst
并将其命名为myunsrtdin.bst
。(切勿直接编辑原始样式文件。)myunsrtdin.bst
用您最喜欢的文本编辑器打开该文件。搜索以下行(在函数中
format.names
):{ s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't :=
并将其更改为
{ s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't :=
接下来,在函数中
format.crossref.editor
搜索以下行{ editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
并将其更改为
{ editor #2 "{f. }{vv }{ll}{ jj}" format.name$ "others" =
保存文件并通过发出指令开始使用它
\bibliographystyle{unsrtdin}
。
我忍不住要对 Zotero 的使用提出一些意见。您已经发现了一个不一致之处:有时该工具会提供作者和编辑的完整名字,而有时它只提供缩写的名字。遗憾的是,这可能是您在使用 Zotero 输出时最不用担心的问题。请务必始终检查.bib
此工具生成的文件(或多个文件)的所有输入字段是否正确。根据我自己使用 Zotero 的经验,它的输出可能包含相当多令人尴尬的拼写错误,更糟糕的是,它的输出可能包含彻头彻尾的错误,例如在多作者出版物中缺少作者。
关于仔细检查 Zotero(或任何其他类似的在线工具!)生成的文件的有效性的建议与您最终使用 unsrtdin/BibTeX 还是 biblatex/biber 无关:BibTeX 和 bibLaTeX 无法对它们操作的输入中包含的错误执行任何操作。
答案3
编辑:对于 的当前版本 (3.12) biblatex
,firstinits
参数已弃用。请giveninits
改用(参见这个问题)。
使用时biblatex
,只需在序言中说明这一点:
\usepackage[backend=bibtex,firstinits=true]{biblatex}
如果您想添加未分类的样式,请使用以下命令:
\usepackage[backend=bibtex,style=numeric-comp,sorting=none,firstinits=true]{biblatex}
我目前使用这一行:
\usepackage[backend=bibtex,citestyle=numeric-comp,bibstyle=ieee,sorting=none,minbibnames=5,maxbibnames=5,defernumbers=true,firstinits=true]{biblatex}
这允许多个参考书目,将参考名称的数量限制为 5 个,并使用不同的引用和参考书目样式。
答案4
# FILENAME: abbrv_bib.py
#!/usr/bin/env python3
from bibtexparser.bwriter import BibTexWriter
import bibtexparser
from pybtex.database import parse_file
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input', help='input file name')
parser.add_argument('output', help='output file name')
parser.add_argument('--no-middle', action='store_true',
help='do not abbreviate middle name')
args = parser.parse_args()
# %%
# Parse the original bib file with pybtex
# pybtex can distinguish first/middle/last names
bib_database = parse_file(args.input)
for k in bib_database.entries.keys():
item = bib_database.entries[k]
persons = item.persons
print(k)
for i in range(len(persons['author'])):
oldFirstNames = persons['author'][i].first_names
newFirstNames = []
for j in oldFirstNames:
if j[-1] == '.':
newFirstNames.append(j)
else:
newFirstNames.append(j[0].upper() + '.')
oldMiddleNames = persons['author'][i].middle_names
if args.no_middle:
newMiddleNames = oldMiddleNames[:]
else:
newMiddleNames = []
for j in oldMiddleNames:
if j[-1] == '.':
newMiddleNames.append(j)
else:
newMiddleNames.append(j[0].upper() + '.')
oldName = ' '.join(
[' '.join(persons['author'][i].last_names) + ','] + oldFirstNames + oldMiddleNames)
newName = ' '.join(
[' '.join(persons['author'][i].last_names) + ','] + newFirstNames + newMiddleNames)
if (oldName != newName):
print(' - {:s} => {:s}'.format(oldName, newName))
persons['author'][i].first_names = newFirstNames
persons['author'][i].middle_names = newMiddleNames
# %%
# Write the new bib file with bibtexparser
# I use bibtexparser here because pybtex prefers quote instead of curly bracket
# e.g. pybtex: title = "This is a paper"
# bibtexparser: title = {This is a paper}
# This makes it escape some underscores incorrectly
with open(args.input, 'r', encoding='utf-8') as bibtex_file:
bibtex_str = bibtex_file.read()
bib = bibtexparser.loads(bibtex_str)
for k in bib.entries_dict:
bib.entries_dict[k]['author'] = ' and '.join(['{:s}, {:s} {:s}'.format(' '.join(p.last_names), ' '.join(p.first_names), ' '.join(p.middle_names))
for p in bib_database.entries[k].persons['author']])
writer = BibTexWriter()
with open(args.output, 'w', encoding='utf-8') as bibfile:
bibfile.write(writer.write(bib))
我编写了一个 Python 脚本来手动执行此操作。这避免了 biblatex 与其他包的不兼容性。你可以将其用作
python3 abbrv_bib.py input.bib output.bib
如果不想缩写中间名,只需添加参数--no-middle
该脚本可以缩写以下类型的名称:
Cruden, Brett A. => Cruden, B. A.
Johann Sebastian Bach => Bach, J. S.
Surname, Given Name III. => Surname, G. N. III.
Johann Sebastian Jr. Bach => Bach, J. S. Jr.
它还将名称重新排列为Last name, First name Middle name