BibTeX 定制自己的参考文献模板 bst

时间:2022-05-20 06:47:54

逆波兰语法是一种后缀语句。其内容并不算难,但是网上的资料几乎没有,而且也一般情况下没有人会去编写它。但是在需要自己设计 bibliography-style 文件 bst 之时,就需要了解这方面的知识了。

btxhak.pdf 是介绍 BibTeX 配置文件中的逆波兰代码基本语法的,位于系统 CTeX 安装目录下: /doc/texlive-base/bibtex/base/btxhak.pdf

命令

命令 功能
ENTRY 定义词条变量
EXECUTE 执行一个函数
FUNCTION 函数
INTEGERS 整数变量
ITERATE 执行一个函数
MACRO 宏定义:用于定义一些月份缩写,或是期刊名缩写
READ 未知
REVERSE 和 ITERATE 一样,不过以逆序执行
SORT 排序
STRINGS 字符串变量

内置函数

这里一共介绍 37 个内置函数。每一个函数都以 $ 为结尾。这里的第一个和第二个指的是弹出堆栈的顺序(与压入堆栈时相反)。

built-in 函数 功能
> 弹出堆栈最上层的两个整数,并比较它们,如果第二个大于第一个,则压入 1;否则,压入 0 。
< 弹出堆栈最上层的两个整数,并比较它们,如果第一个大于第二个,则压入 1;否则,压入 0 。
= 弹出堆栈最上层的两个元素,并比较它们,如果二者相等,则压入 1;否则,压入 0 。
+ 弹出堆栈最上层的两个整数,两者相加,结果压入栈 。
- 弹出堆栈最上层的两个整数,第二个减去第一个,结果压入栈 。
* 弹出堆栈最上层的两个元素,并将它们连接起来,顺序为 “第二个”“第一个”,并把结果压入堆栈中。
:= 弹出堆栈最上层的两个元素,将第二个元素赋值给第一个(变量)。
add.period$ 弹出堆栈最上层的(字符串)元素,如果最后一个非 } 字符不是 .,?,或 !,加一个 .,然后将结果压入堆栈。
call.type$ 执行一个名称和词条类型一致的函数。比如词条类型是 book,那么执行 book 函数。
change.case$ 弹出堆栈最上层的两个字符串,根据第一个字符串的值来改变。如果第一个字符串是“t”,那么将第二个字符串的所有字母都改为小写(除了第一个字母,和冒号之后的第一个字母);如果第一个字符串是“l”,那么将第二个字符串所有的字母都转为小写;如果第一个字符串是“u”,那么将第二个字符串所有的字母都转为大写;然后将结果压入堆栈中。如果任意一个字符串的格式不对,那么会报错,并压入一个空字符串。如果类型对了,但是指定的值不是“l,t,u”,直接将第二个字符串压回堆栈。(“t”或“T”大小写没有区别)
chr.to.int$ 弹出堆栈最上层的字符串,确保其只是一个简单的字符,将其转化为对应的 ASCII 码整数,然后压回堆栈。
cite$ 将这个 \cite 命令参数的词条,以字符串形式压入堆栈。
duplicate$ 弹出堆栈最上层的一个元素,复制一个后,两个都压回堆栈。
empty$ 弹出堆栈最上层的一个元素,如果它是空白字符串或没有内容,压入 1 至堆栈;否则,压入 0 。
format.name$ 弹出堆栈最上层的三个元素,分别是字符串,整数,字符串。第一个字符串代表一个名字列表(人名),第二个整数表示将列表中哪一个人名提出,最后一个字符串代表如何进行格式化。最后将格式化后的人名结果压回堆栈。
if$ 弹出堆栈最上层的三个元素,按顺序分别是(两个函数,一个整数),如果整数大于 0,执行第二个函数,否则,执行第一个函数。
int.to.chr$ 弹出堆栈最上层的整数,将其转化为对应的 ASCII 码单字符,然后压回堆栈。
int.to.str$ 弹出堆栈最上层的整数,将其转化为唯一对应的字符串(根据编码),然后压回堆栈。
missing$ 弹出堆栈最上层的一个元素,如果它是没有内容,压入 1 至堆栈;否则,压入 0 。
newline$ 将输出缓存中的内容写入到 bbl 文件中去。如果缓存是空的,就会写入一个空行。由于 write$ 函数能进行合理的断行,所以只在需要一个空行或是断行的时候使用该函数。
num.name$ 弹出堆栈最上层的字符串,计算其中的人名的个数,其中每出现一个 “and” (忽略大小写),并之前有非空的字符,则计数加一。最后将结果压入堆栈。
pop$ 弹出堆栈最上层的元素,但是不打印它,用于除去一些不需要的堆栈内容。
preamble$ 将所有 @premable 字符串(来自数据文件 bib)连接起来,并压入堆栈中。
purify$ 弹出堆栈最上层的字符串,除去其中所有的非字母数字符号,除去特殊字符,但空格例外,(连接符和波浪符会变成空格),结果压回堆栈。
quote$ 将含有双引号的字符串压入堆栈。
skip$ 一个空操作,什么也不执行。
stack$ 将此时堆栈中的所有内容按顺序弹出,并打印出来。仅供调试使用。
substring$ 弹出堆栈最上层的三个元素,按顺序分别是(两个整数,长度 len 和起始位置 start,一个字符串),取出长度为 len,从第 start 个字符开始(索引从 1 开始)的子字符串,并压回堆栈。如果 start 是负数,只将第 -start 个字符取出,压回堆栈。
swap$ 交换堆栈顶部的两个元素。
text.length$ 弹出堆栈最上层的字符串,计算其中的文本字符的数量,带音标的字符也记作一个字符,括号不计。结果压入堆栈。
text.prefix$ 弹出堆栈最上层的两个元素,按顺序分别是(一个整数 len,一个字符串),取出从第一个文本字符开始,长度为 len 的子字符串,并压回堆栈。类似于 substring$,但是带音标的字符也记作一个文本字符,括号不会被当作文本字符。另外,此函数会添加需要的匹配的右括号。
top$ 将堆栈最上层的元素弹出,并输出到终端或 log 文件中,用于调试。
type$ 将当前词条的类型压入堆栈中(比如,book,atricle,inproceedings),但是如果类型未知,会压入空字符串。
warning$ 弹出堆栈最上层的元素,并打印到 warning 信息中。
while$ 弹出堆栈最上层的两个函数,只要留在堆栈中的整数值大于 0(在第一个函数中判断),就继续执行第二个函数。
width$ 弹出堆栈最上层的字符串,计算其宽度,并压入堆栈中。使用一些相对单位,目前是 cmr10 字体,六月 1987 版。该函数会将字符串按真实打印处理。此函数用于比较标签字符串。
write$ 弹出堆栈最上层的元素,并写入到 *.bbl 文件中

注意到 while$ 和 if$ 命令都需要 2 个函数在堆栈中。一种是方法是在函数名前加一个单引号,或是直接将一段语句用 { } 包住,即表示一个函数定义,比如:

label "" =
    'skip$ { label "a" * 'label := } if$

人名格式化

人名在 bibtex 中被看作四部分,分别是:First name,von,Last name, Jr 。每一部分都对应着名字的一部分,比如:

author = "Charles Louis Xavier Joseph de la Vall{\'e}e Poussin"

如果按照如下的格式进行格式化:

"{vv~}{ll}{, jj}{, f{.}.}"

那么会得到如下的人名输出:

de~la Vall{\'e}e~Poussin, C.L.X.J.

仔细分析:vv 表示将 de la 部分不缩写(单个 v 表示缩写),vv~表示必要时会加上波浪号;ll 表示姓不缩写(单个 l 表示缩写);, jj 表示先输出一个逗号加一个空格,然后将 Jr 部分按原样输出(此例中没有出现);, f{.}. 表示名进行缩写为一个大写首字母,然后紧跟一个句号,多个之间格式一致,即 C.L.X.J. 。