makebst 创建的 bst 文件中 bibinfo.check 函数中 swap$ 的作用

makebst 创建的 bst 文件中 bibinfo.check 函数中 swap$ 的作用

我尝试理解makebst创建的.bst文件。它有一个名为的函数bibinfo.check。该函数定义如下:

FUNCTION {bibinfo.check}
{ swap$
  duplicate$ missing$
    {
      pop$ pop$
          ""
    }
    { duplicate$ empty$
        {
          swap$ pop$
        }
        { swap$
          pop$
        }
      if$
    }
  if$
} 

我不明白启动swap$内部函数的作用。我知道它做什么,但我不明白为什么这里需要它。

bibinfo.check函数由函数调用format.names,该函数由格式作者函数调用,如下所示:

FUNCTION {format.authors}
{ author "author" format.names
}

这是format.names函数:

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$
}

如果我理解正确的话,在format.names函数中将"author"其分配给bibinfo字符串,并且作者字段(所有作者)的全部内容都分配给s字符串。

bibinfo.check在函数中被调用format.names如下:

      format.name$
      remove.dots
      bibinfo bibinfo.check

也就是说,当调用bibitem.check时,堆栈如下所示:

"formatted name string" "author"

字符串"author"位于堆栈顶部。

bibitem.check交换这两个,然后检查顶部项目(即“格式化的名称字符串”)是否丢失。

我不明白为什么swap$如果我们想检查author字段是否缺失,那么这个是必要的。在当前形式下,该函数检查“格式化名称字符串”是否缺失或为空,而不是作者字段是否缺失。我不明白其中的逻辑。还是我误解了什么或误解了代码?

有人可以解释一下吗?

答案1

你的分析几乎是对的。当bibinfo.check被调用时format.names,堆栈包含

<formatted names> "author"

<formatted names>我们需要检查"author"的是那个字符串文字,而不是字段author。如果省略代码,swap$它将检查文字字符串是否存在,而不是格式化的内容。由于bibinfo.check始终会使用字符串文字进行调用(用于任何生成的错误消息),因此堆栈上的最后一个条目将始终存在且非空:它是需要检查的倒数第二个条目。

(当然,可以在进行任何格式化之前将字符串文字放入堆栈,但总的来说,这会比在最后快速添加它更加费力且更令人困惑swap$。)

相关内容