是否可以访问.bst 文件内的宏的值?

是否可以访问.bst 文件内的宏的值?

在自定义 .bst 文件中,我想定义一个可以从 .bib 文件中修改的字符串。据我所知,实现此目的的方法是定义一个

MACRO {mystring} {"Original"} 

在 .bst 中,如果需要,可以使用

@string{mystring = "Modified"}

在 .bib 中。

但是,在 .bst 文件中,我需要访问字符串的值。具体来说,我想编写一个 if 语句来检查字符串是否被 .bib 文件替换。我认为对此有意义的代码如下:

mystring "Original" =
{}
{"mystring changed" warning$}
if$

然而,这会导致错误

mystring is an unknown function

因为显然不可能将宏的内容推送到堆栈上。

有趣的是,如果我将其定义为

FUNCTION {mystring} {"Original"} 

但在这种情况下,就无法再从 bib 文件中修改值。

所以我的问题是,是否有可能以某种方式将 MACRO 的内容推送到堆栈,或者是否存在其他机制,通过该机制我可以将全局信息从 .bib 文件传递​​到不属于任何单独条目的 .bst 文件。

下面是我尽可能简化的一个(不起作用的)示例:

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{my.bib}
@string{mystring = "Modified"}
@Misc{AAA,
  title = "The best title"
}
\end{filecontents}
\begin{filecontents}{my.bst}
ENTRY
  { 
    title
  }
  {}
  { label }
INTEGERS { output.state before.all mid.sentence after.sentence after.block }
FUNCTION {init.state.consts}
{ #0 'before.all :=
  #1 'mid.sentence :=
  #2 'after.sentence :=
  #3 'after.block :=
}
STRINGS { s t}
FUNCTION {output.nonnull}
{ 's :=
  output.state mid.sentence =
    { ", " * write$ }
    { output.state after.block =
        { add.period$ write$
          newline$
          "\newblock " write$
        }
        { output.state before.all =
            'write$
            { add.period$ " " * write$ }
          if$
        }
      if$
      mid.sentence 'output.state :=
    }
  if$
  s
}
FUNCTION {output}
{ duplicate$ empty$
    'pop$
    'output.nonnull
  if$
}

FUNCTION {fin.entry}
{ add.period$
  write$
  newline$
}

INTEGERS { nameptr namesleft numnames }


FUNCTION {format.title}
{ title
  duplicate$ empty$ 'skip$
    { "t" change.case$ }
  if$
}
FUNCTION {output.bibitem}
{ newline$
  "\bibitem{" write$
  cite$ write$
  "}" write$
  newline$
  ""
  before.all 'output.state :=
}

MACRO {mystring}{"Original"}

FUNCTION {misc}
{ output.bibitem
  format.title output
  mystring "Original" =
  {}
  {"mystring changed" warning$}
  if$
  fin.entry
}

READ
SORT
FUNCTION {begin.bib}
{ preamble$ empty$
    'skip$
    { preamble$ write$ newline$ }
  if$
  "\begin{thebibliography}{}"
  write$ newline$
  "\expandafter\ifx\csname urlstyle\endcsname\relax"
  write$ newline$
  "  \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else"
  write$ newline$
  "  \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi"
  write$ newline$
}
EXECUTE {begin.bib}
EXECUTE {init.state.consts}
ITERATE {call.type$}
FUNCTION {end.bib}
{ newline$
  "\end{thebibliography}" write$ newline$
}
EXECUTE {end.bib}
\end{filecontents}
\begin{document}
  \cite{AAA}

  \bibliographystyle{my}
  \bibliography{my}
\end{document}

答案1

不,不可能。BibTeX 中的宏/字符串机制是为了“方便”而存在的:替换发生在很早的时候,在字段传递给代码.bst进行格式化之前。因此,从编程可访问的角度来看,这些替换“不存在”:字段的值已经发生了变化。

如果您想要更灵活的东西,您可能想要一个 TeX 宏或一个可以搜索和替换的标记值。或者,您可以考虑使用例如achemsobiblatex传递数据的机制:使用带有专用数据字段的特殊引用。

相关内容