我有一个 bibtex 键列表,定义为、、pmid123
等。pmid456
pmid789
我希望能够通过执行以下操作来引用:\pmid{[123,456,789]}
因此使用 xstring,我定义了以下宏来清理键:
\newcommand{\pmidhelper}[1]{
\noexpandarg % suppress expansions made by xstring
\StrSubstitute{#1}{,}{,pmid}[\x]
\expandafter\StrSubstitute\expandafter{\x}{[}{pmid}[\x]%
\expandafter\StrSubstitute\expandafter{\x}{]}{}[\x]%
\x
}
\newcommand{\pmid}[1]{ \cite{\pmidhelper{#1}} }
但尝试\pmid{[123,456,789]}
给了我错误:
Illegal parameter number in definition of \@citeb. \pmid{[123,456,789]}
你知道我该如何做吗?
谢谢
答案1
这是非常常见的不“可扩展”问题\StrSubstitute
;您必须在将其传递给之前准备好令牌列表\cite
。
所以它应该是这样的
\newcommand{\pmidhelper}[1]{% <--- don't forget
\noexpandarg % suppress expansions made by xstring
\StrSubstitute{#1}{,}{,pmid}[\x]%
\expandafter\StrSubstitute\expandafter{\x}{[}{pmid}[\x]%
\expandafter\StrSubstitute\expandafter{\x}{]}{}[\x]%
}
\newcommand{\pmid}[1]{{\pmidhelper{#1}\expandafter\cite\expandafter{\x}}}
完整示例:
\documentclass{article}
\usepackage{xstring}
\newcommand{\pmidhelper}[1]{% <--- don't forget
\noexpandarg % suppress expansions made by xstring
\StrSubstitute{#1}{,}{,pmid}[\x]%
\expandafter\StrSubstitute\expandafter{\x}{[}{pmid}[\x]%
\expandafter\StrSubstitute\expandafter{\x}{]}{}[\x]%
}
\newcommand{\pmid}[1]{%
{\pmidhelper{#1}\expandafter\cite\expandafter{\x}}%
}
\begin{document}
\pmid{[123,456,789]}
\end{document}
控制台将显示
LaTeX Warning: Citation `pmid123' on page 1 undefined on input line 15.
LaTeX Warning: Citation `pmid456' on page 1 undefined on input line 15.
LaTeX Warning: Citation `pmid789' on page 1 undefined on input line 15.
这意味着已经拾取到了正确的密钥。
另一种方法是expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\pmid}{m}
{
\seq_clear:N \l_tmpa_seq
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l_tmpa_seq { pmid##1 }
}
\exp_args:Nx \cite { \seq_use:Nn \l_tmpa_seq { , } }
}
\ExplSyntaxOff
\begin{document}
\pmid{123,456,789}
\end{document}
括号[
和]
实际上不起任何作用,所以我在这个版本中将它们删除了。
如果需要它们,可以通过预处理参数来删除它们:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\pmid}{m}
{
\seq_clear:N \l_tmpa_seq
\byo_process_pmid:n { #1 }
}
\cs_new:Nn \byo_process_pmid:n
{
\__byo_process_pmid:w #1
}
\cs_new:Npn \__byo_process_pmid:w [#1]
{
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l_tmpa_seq { pmid##1 }
}
\exp_args:Nx \cite { \seq_use:Nn \l_tmpa_seq { , } }
}
\ExplSyntaxOff
\begin{document}
\pmid{[123,456,789]}
\end{document}
更复杂的版本可以接受带或不带括号的两种输入。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\pmid}{m}
{
\seq_clear:N \l_tmpa_seq
\byo_process_pmid:n { #1 }
}
\tl_new:N \l__byo_input_tl
\cs_new:Nn \byo_process_pmid:n
{
\tl_set:Nn \l__byo_input_tl { #1 }
\regex_replace_once:nnN { \A \[+ (.*) \]+ \Z } { \1 } \l__byo_input_tl
\clist_map_inline:Vn \l__byo_input_tl
{
\seq_put_right:Nn \l_tmpa_seq { pmid##1 }
}
\exp_args:Nx \cite { \seq_use:Nn \l_tmpa_seq { , } }
}
\cs_generate_variant:Nn \clist_map_inline:nn { V }
\ExplSyntaxOff
\begin{document}
\pmid{[123,456,789]}
\pmid{aaa,bbb,ccc}
\end{document}