逆波兰语法是一种后缀语句。其内容并不算难,但是网上的资料几乎没有,而且也一般情况下没有人会去编写它。但是在需要自己设计 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. 。