我对 的后缀语法了解有限bst
,希望对系统有更多了解的人能指出我在.bst
使用期刊提供的文件时遇到的问题的根源。使用这种特定的书目样式文件会导致无法打印文件@article
中大多数条目的页码范围.bib
。我正在使用pdflatex
和bibtex
。
文件中文章的相关片段.bst
及其卷/页码的格式如下:
FUNCTION {field.or.null}
{ duplicate$ empty$
{ pop$ "" }
'skip$
if$
}
FUNCTION {bolden}
{ duplicate$ empty$
{ pop$ "" }
{ "{\bf " swap$ * "}" * }
if$
}
FUNCTION {bbl.pages}
{ "pp." }
FUNCTION {format.pages}
{ pages empty$
{ "" }
{ pages multi.page.check
{ bbl.pages pages n.dashify tie.or.space.connect }
{ bbl.page pages tie.or.space.connect }
if$
}
if$
}
FUNCTION {first.page}
{ 't :=
""
{ t empty$ not t #1 #1 substring$ "-" = not and }
{ t #1 #1 substring$ *
t #2 global.max$ substring$ 't :=
}
while$
}
FUNCTION {format.journal.pages}
{ pages empty$
'skip$
{ duplicate$ empty$
{ pop$ format.pages }
{
", " *
pages first.page *
}
if$
}
if$
}
FUNCTION {format.vol.num.pages}
{ volume field.or.null
bolden
format.journal.pages
}
FUNCTION {article}
{ output.bibitem
format.authors "author" output.check
crossref missing$
{ journal
emphasize
"journal" output.check
add.blank
format.vol.num.pages output
format.date "year" output.check
}
{ format.article.crossref output.nonnull
format.pages output
}
if$
new.sentence
format.note output
fin.entry
}
从中可以看出,article
函数调用format.vol.num.pages
,其任务是插入卷和页数。在添加和加粗卷之后,format.journal.pages
调用。在此函数中,书目条目pages
中的字段@article
将添加到堆栈中。如果它非空,则将其复制并再次检查是否为空。我不明白在已经确定非空之后复制和检查是否为空的目的。如果复制后为空,则打印页面范围(这是我想要的路径);否则,只打印第一页,这似乎是几乎总是采用的路线。如果我{ pop$ format.pages }
对语句的两个真/假路线都使用if
,则会打印完整的页面范围,但在这种情况下会删除卷(可能是因为它过早地从堆栈中弹出)。
我还删除了通过重写添加的“pp”,bbl.pages
如下所示:
FUNCTION {bbl.pages}
{ "" }
但是,我想知道是否有更干净的方法来删除“pp”。再次删除bbl.pages
会format.pages
扰乱堆栈。
以下是 MWE 及其输出:
\documentclass{article}
\usepackage{scicite}
\begin{document}
According to the theory of special relativity~\cite{einstein1905}, \ldots
\bibliography{a}
\bibliographystyle{Science}
\end{document}
Bib文件(a.bib):
@article{einstein1905,
title={Zur elektrodynamik bewegter k{\"o}rper},
author={Einstein, Albert},
journal={Annalen der physik},
volume={322},
number={10},
pages={891--921},
year={1905},
publisher={Wiley Online Library}
}
完整bst
文件可以访问这里。
样式scicite
文件可以访问这里。
答案1
先做简单的事情。是的,设置
FUNCTION {bbl.pages}
{ "" }
和
FUNCTION {bbl.page}
{ "" }
可能是摆脱参考书目中的“p.”/“pp.”的最便宜的方法。
format.pages
不过,用更简单的函数替换整个函数可能会更好一些。
FUNCTION {format.pages}
{ pages empty$
{ "" }
{ pages n.dashify }
if$
}
请注意,这两种方法都会删除所有条目类型的“p.”/“pp.”,而不仅仅是@article
s。这可能是或可能不是所希望的。
现在回答你关于 的问题format.journal.pages
。该函数在 中被调用format.vol.num.pages
。此时,先前的函数已经将相当多的内容推送到堆栈上。特别是堆栈将包含
- 格式化的卷:
{\bf 322}
和 - 格式化的日志(带有尾随空格)
{\it Annalen der Physik/}
进入format.journal.pages
并测试字段是否为空pages
。由于如果字段为空,则不会发生任何令人兴奋的事情,因此我们假设它不为空。如果字段不为空,则函数调用duplicate$
,从堆栈中弹出顶部文字({\bf 322}
)并推送它的两个副本。堆栈现在包含
- 格式化卷的副本
{\bf 332}
- 格式化的卷:
{\bf 322}
和 - 格式化的日志(带有尾随空格)
{\it Annalen der Physik/}
empty$
现在弹出顶部文字(卷的副本)并检查其是否为空。一旦我们进入,if$
堆栈就会包含之前的两个项目。
- 格式化的卷:
{\bf 322}
和 - 格式化的日志(带有尾随空格)
{\it Annalen der Physik/}
如果弹出并测试的文字为空(这意味着没有volume
字段),则函数pop$
将从堆栈中取出下一个文字(也是空的),然后继续正常格式化 pages 字段。如果测试的文字不为空,则函数将添加,
到堆栈上第一个文字的末尾(这是我们刚刚测试其是否为空的副本的原始文本,包含卷号),用 格式化字段,pages
然后first.page
将堆栈上得到的两个文字连接起来(这样您就得到了<formatted volume>, <formatted pages>
)。
duplicate$ empty$
因此,根据条目中是否有volume
字段进行分支:试一试,您会发现,如果没有volume
,则会打印整个页面范围,但如果有,则仅打印第一页volume
。它不会测试字段pages
。
如果你想在所有情况下都看到完整的页面范围,你可以尝试
FUNCTION {format.journal.pages}
{ pages empty$
'skip$
{ duplicate$ empty$
{ pop$ format.pages }
{
", " *
format.pages *
}
if$
}
if$
}
它看起来并不比之前的代码简单多少,但我们现在调用format.pages
了两个分支。不过,文件的结构使得if$
进一步简化/统一它变得相当棘手。