![bst 文件如何将用逗号分隔的子字符串拆分为一个项目](https://linux22.com/image/390462/bst%20%E6%96%87%E4%BB%B6%E5%A6%82%E4%BD%95%E5%B0%86%E7%94%A8%E9%80%97%E5%8F%B7%E5%88%86%E9%9A%94%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8B%86%E5%88%86%E4%B8%BA%E4%B8%80%E4%B8%AA%E9%A1%B9%E7%9B%AE.png)
我想知道如何将用逗号分隔的子字符串拆分为.bst
文件项。例如,我的.bib
文件中有以下内容:
Author = {... and ...},
Title = {...},
Doi = {doi1, doi2},
我编写了一个函数来处理 DOI:
FUNCTION {format.doi}
{ doi empty$
{ "" }
{"\href{http://dx.doi.org/" doi * "}{doi:" * doi * "}" *}
if$
}
当 DOI 字段中只有一个项目时,这种方法非常有效。但是当有更多项目时,这种方法就不再有效了。我想知道如何在这个函数内部创建一个循环,以使其适用于多个 DOI。我找不到任何文档来了解如何做到这一点。这是我想要做的等效 Python:
FUNCTION {format.doi}
{ doi empty$
{ "" }
mylist = doi.split(',')
for element in mylist :
{"\href{http://dx.doi.org/" element * "}{doi:" * element * "}" *}
(+ stuffs to deal with comma between the element in the loop)
if$
}
答案1
据我所知,BibTeX 除了名称列表之外没有原生列表处理功能。这意味着我们必须为逗号分隔列表构建自己的解析器。
csv.split.inner
我偷用了frombiblatex.bst
的想法input:control:parse
。请注意,这个简单的解析器假设你的 DOI列表用逗号分隔后面跟着一个空格。
上传的样式https://gist.github.com/moewew/6bc573b5f90ba13bb8d2115dfc836e87显示了 修改版中的函数plainnat.bst
。总体思路可以移植到各种风格,但和.bst
的细节可能因风格而异。与标准的差异如下format.doi
doi.split.outer
plainnat.bst
--- plainnat.bst 2010-09-14 11:10:56.000000000 +0200
+++ plainnat-multidoi.bst 2019-02-13 12:36:50.034850700 +0100
@@ -1,3 +1,10 @@
+%%%% File: `plainnat-multidoi.bst'
+%%%% A modification of `plainnat.bst' that can deal with multiple DOIs in the
+%%%% doi field.
+%%%% MW, 2019-02-13
+%%%%
+%%%% original copyright header follows
+%%%%
%% File: `plainnat.bst'
%% A modification of `plain.bst' for use with natbib package
%%
@@ -289,10 +296,49 @@
if$
}
+INTEGERS { tempctra tempctrb }
+
+FUNCTION {csv.split.inner} {
+ 's :=
+ "" 't :=
+ #1 'tempctra :=
+ { s empty$ not
+ tempctra and }
+ { s #1 #2 substring$ ", " =
+ { #0 'tempctra :=
+ s #2 global.max$ substring$ 's := }
+ { t s #1 #1 substring$ * 't := }
+ if$
+ s #2 global.max$ substring$ 's :=
+ }
+ while$
+ s
+ t
+}
+
+FUNCTION {doi.split.outer} {
+ 's :=
+ ""
+ #0 'tempctrb :=
+ { s empty$ not }
+ { s csv.split.inner
+ 't :=
+ 's :=
+ tempctrb #0 =
+ {}
+ { ", " * }
+ if$
+ tempctrb #1 + 'tempctrb :=
+ "\doi{" t * "}" * *
+ }
+ while$
+}
+
FUNCTION {format.doi}
{ doi empty$
{ "" }
- { new.block "\doi{" doi * "}" * }
+ { new.block
+ doi doi.split.outer }
if$
}
平均能量损失
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{natbib}
\usepackage[colorlinks]{hyperref}
\newcommand*{\doi}[1]{%
\href{https://doi.org/#1}{doi: \nolinkurl{#1}}}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@article{uthor:one,
Author = {Anne Uthor},
Title = {One DOI},
Doi = {10.1000/182},
year = {2001},
journal = {J. Res.},
}
@article{uthor:two,
Author = {Anne Uthor},
Title = {Two DOIs},
Doi = {10.1130/0091-7613(2001), 10.1371/journal.pbio.0020449},
year = {2002},
journal = {J. Res.},
}
@article{uthor:three,
Author = {Anne Uthor},
Title = {Three DOIs},
Doi = {10.1037/a0028240, 10.1090/S0002-9939-00-05422-8, 10.1103/PhysRevLett.88.088302},
year = {2003},
journal = {J. Res.},
}
\end{filecontents}
\begin{document}
\nocite{*}
\bibliographystyle{plainnat-multidoi}
\bibliography{\jobname}
\end{document}