最近,在使用 xstring 从列表中选择,Geoff 询问如何定义\variation
执行以下操作的命令:
\variation{1}{aaa;bbb;ccc} ----> aaa
\variation{2}{aaa;bbb;ccc} ----> bbb
\variation{3}{aaa;bbb;ccc} ----> ccc
关于这个问题有很多不错的答案。然而,我发现它们都有相同的缺点:当我尝试使用包 refcount 中的结果时,我收到一条错误消息\variation
。\ref
\getrefnumber
更具体地说,考虑基于 Heiko Oberdiek 解决方案的不起作用的示例,
\documentclass{article}
\usepackage{xstring}
\newcommand*{\variation}[2]{%
\edef\variationNext{%
\noexpand\StrBetween[%
\the\numexpr(#1)\relax,%
\the\numexpr(#1)+1\relax
]%
}%
\variationNext{;#2;}{;}{;}\relax
}
\begin{document}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
I can refer to these equations as equation~\ref{aaa} and
equation~\ref{bbb}.
Now I have the string ``aaa;bbb''. If I refer to these equations as
equation~\ref{\variation{1}{aaa;bbb}} and
equation~\ref{\variation{2}{aaa;bbb}}, I get an error message.
\end{document}
我使用所有其他建议的解决方案时都遇到了相同的错误消息。是否可以重新定义命令\variation
,使其能够与\ref
和 一起正确运行\getrefnumber
?
答案1
包xstring
知道\StrBetween
最后一个可选参数,该参数需要一个命令标记来存储结果。因此\variation
可以给出一个可选参数(在开头以避免在结尾处丢失空格)。使用可选参数,结果将存储在给出的宏中。
\documentclass{article}
\usepackage{xstring}
\newcommand*{\variation}[3][]{%
\edef\variationNext{%
\noexpand\StrBetween[%
\the\numexpr(#2)\relax,%
\the\numexpr(#2)+1\relax
]%
}%
\variationNext{;#3;}{;}{;}[#1]\relax
}
\newcommand*{\variationref}[2]{%
\variation[\tmp]{#1}{#2}\ref{\tmp}%
}
\begin{document}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
I can refer to these equations as equation~\ref{aaa} and
equation~\ref{bbb}.
Now I have the string ``aaa;bbb''. If I refer to these equations as
equation~\variation[\tmp]{1}{aaa;bbb}\ref{\tmp} and
equation~\variationref{2}{aaa;bbb}.
\end{document}
答案2
问题在于\ref
它需要它的参数是一个字符串,而不是生成该字符串的指令集。
最好对此类引用使用不同的命令,例如
\varref{1}{aaa;bbb}
对我的答案进行几乎直接的修改就可以实现您想要的效果:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\variation}{ s O{;} m m }
{
\IfBooleanTF{#1}
{
\geoff_variation_check:nnn { #2 } { #3 } { #4 }
}
{
\geoff_variation_nocheck:nnn { #2 } { #3 } { #4 }
}
\tl_use:N \l__geoff_item_tl
}
\NewDocumentCommand{\varref}{s O{;} m m }
{
\IfBooleanTF{#1}
{
\geoff_variation_check:nnn { #2 } { #3 } { #4 }
}
{
\geoff_variation_nocheck:nnn { #2 } { #3 } { #4 }
}
\exp_args:NV \ref \l__geoff_item_tl
}
\msg_new:nnn { variation }
{ index~out~of~bounds }
{ You~have~requested~an~item~that~doesn't~exist }
\seq_new:N \l__geoff_item_list_seq
\tl_new:N \l__geoff_item_tl
\cs_new_protected:Npn \geoff_variation_nocheck:nnn #1 #2 #3
{
\seq_set_split:Nnn \l__geoff_item_list_seq { #1 } { #3 }
\tl_set:Nx \l__geoff_item_tl { \seq_item:Nn \l__geoff_item_list_seq { #2 } }
}
\cs_new_protected:Npn \geoff_variation_check:nnn #1 #2 #3
{
\seq_set_split:Nnn \l__geoff_item_list_seq { #1 } { #3 }
\int_compare:nTF { #2 > \seq_count:N \l__geoff_item_list_seq }
{
\msg_warning:nn { variation }{ index~out~of~bounds }
\tl_set:Nn \l__geoff_item_tl { --inexistentitem-- }
}
{
\tl_set:Nx \l__geoff_item_tl { \seq_item:Nn \l__geoff_item_list_seq { #2 } }
}
}
\ExplSyntaxOff
\begin{document}
\variation{3}{aaa;bbb;ccc;ddd;eee}
\variation[,]{3}{aaa,bbb,ccc,ddd,eee}
\variation{1}{aaa}
\variation{2}{aaa}
\variation*{2}{aaa}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
I can refer to these equations as equation~\ref{aaa} and
equation~\ref{bbb}.
If I refer to these equations as equation~\varref{1}{aaa;bbb} and
equation~\varref{2}{aaa;bbb}, I get correct numbers.
\end{document}
我保留了原始\variation
命令,尽管它看起来并不是真正需要的。
不同之处在于,现在\geoff_variation_nocheck:nnn
将结果存储在标记列表变量中并\varref
调用它(或check
变体),然后执行
\exp_args:NV \ref \l__geoff_item_tl
如果没有溢出,\varref
和的行为是相同的; 如果,您会收到警告并且会产生 ; 如果 ,您只会得到。\varref*
\varref*{3}{aaa;bbb}
\ref{--inexistentitem--}
\varref{3}{aaa;bbb}
\ref{}