问题描述
在用latex对文章排版时,发现在参考文献列表中,有的文章作者人数很多,一篇文章的作者就能占好几页,所以必须要做到从某一作者处截断作者列表,让后续作者都变成et. al。
但是往上的相关资源却是很少,通常是有2种方法,一种是用makebst,一种是自己手动修改bst文件。这里用的是第二种,bst文件中涉及作者列表的函数如下:
FUNCTION {format.names}
{ 'bibinfo :=
duplicate$ empty$ 'skip$ {
's :=
"" 't :=
#1 'nameptr :=
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > }
{ s nameptr
"{vv~}{ll}{ f{~}}{ jj}"
format.name$
remove.dots
bibinfo bibinfo.check
't :=
nameptr #1 >
{
namesleft #1 >
{ ", " * t * }
{
s nameptr "{ll}" format.name$ duplicate$ "others" =
{ 't := }
{ pop$ }
if$
"," *
t "others" =
{
" " * bbl.etal *
}
{ " " * t * }
if$
}
if$
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
} if$
}
不熟悉Bibtex语法的可能很容易被各种教程搞得云里雾里,但经过研究,这段代码的意思是这样(看%后面的注释):
FUNCTION {format.names}
{ 'bibinfo :=
duplicate$ empty$ 'skip$ {
's :=
"" 't :=
#1 'nameptr :=
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > } %combine with "while"
{ s nameptr
"{vv~}{ll}{ f{~}}{ jj}"
format.name$
remove.dots
bibinfo bibinfo.check
't := %let t = s[nameptr] in that be formated, and modify t below
nameptr #1 >
{
namesleft #1 >
{ ", " * t * }
{ % If final author's name is 'others', let 'others' change to 'bbl.etal
s nameptr "{ll}" format.name$ duplicate$ "others" =
{ 't := }%if true, let t = others
{ pop$ }%if not
if$
"," * %like ", " in { ", " * t * }. between final author's name and et.al
t "others" =
{
" " * bbl.etal *
}
{ " " * t * }
if$
}
if$
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
} if$
}
看懂这段代码这里需要对BibTex的一些基本语法有所了解:
1.在BibTex中,赋值是通过:=实现,而不是=实现,如相将变量A赋值给变量B,应该用如下语句:
A ‘B :=
2.在BibTex中,if-else,或者其它判断语句的嵌套结构是:
条件语句(如a #1 >)
{}如果条件语句为真执行的
{}如果条件语句为假执行的
if¥
有2个“{}”
3.了解一些内置的函数如skip
、
p
o
p
、pop
、pop
解决方案:
FUNCTION {format.names}
{ 'bibinfo :=
duplicate$ empty$ 'skip$ {
's :=
"" 't :=
#1 'nameptr :=
#0 'num_already_define_by_jlzeng :=
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > } %combine with "while"
{ s nameptr
"{vv~}{ll}{ f{~}}{ jj}"
format.name$
remove.dots
bibinfo bibinfo.check
't := %let t = s[nameptr] in that be formated, and modify t below
nameptr #1 >
{
%--------------------自己写的部分--------------------
nameptr 'num_already_define_by_jlzeng :=
num_already_define_by_jlzeng #4 <
{ ", " * t * }
{
namesleft #1 >
{skip$}
{
"." * bbl.etal *
}
if$
}
if$
%--------------------自己写的部分--------------------
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
} if$
}
新定义一个变量num_already_define_by_jlzeng,储存已经处理的作者个数,如果这个数量小于4,则通过
{ ", " * t * }
继续添加作者,如果这个数量大于4,并且剩余作者数量满足
namesleft #1 >
则
{skip$}
,不处理这些作者,如果已经处理到最后一个作者,就通过
{
“.” * bbl.etal *
}
加上et.al。
有问题的话欢迎留言,看到会第一时间解答,转载请注明出处。
码字不易,如果感觉有帮助的话点个赞吧~