I try to understand a makebst
-created .bst
file.
It has a function called bibinfo.check
. The function is defined as:
FUNCTION {bibinfo.check}
{ swap$
duplicate$ missing$
{
pop$ pop$
""
}
{ duplicate$ empty$
{
swap$ pop$
}
{ swap$
pop$
}
if$
}
if$
}
I don't understand the role of the starting swap$
internal function. I know what it does but I don't understand why it is necessary here.
The bibinfo.check
function is called by the format.names
function, which is called by the format authors function as:
FUNCTION {format.authors}
{ author "author" format.names
}
This is the format.names
function:
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 >
{
nameptr #6
#1 + =
numnames #6
> and
{ "others" 't :=
#1 'namesleft := }
'skip$
if$
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$
}
If I understand correctly, in the format.names
function "author"
is assigned to bibinfo
string and the whole content of the author-field (all authors) is assigned to s
string.
bibinfo.check
is called in format.names
function like this:
format.name$
remove.dots
bibinfo bibinfo.check
That is, when bibitem.check is called, the stack looks like:
"formatted name string" "author"
with "author"
string at the top of the stack.
bibitem.check
swaps these two and then checks if the top item (that is the "formatted name string" is missing).
I don't understand why the swap$
is necessary if we want to check whether the author
field is missing. In its current form the function checks if the "formatted name string" is missing or empty, not if the author field is missing. I don't understand the logic. Or do I misunderstand something or misinterpret the code?
Could someone please explain it?
Best Answer
You're almost right in your analysis. When
bibinfo.check
is called byformat.names
, the stack containswhere
<formatted names>
is what we need to check and"author"
is that string literal, not the fieldauthor
. If the code omittedswap$
it would check that the literal string was there, not the formatted content. Asbibinfo.check
will always be called with a string literal (to be used in any resulting error message) the final entry on the stack will always be present and non-empty: it's the penultimate one that needs to be checked.(It would of course be possible to put the string literal onto the stack before doing any formatting, but overall that would be more effort and more confusing than adding it at the end with a quick
swap$
.)