这个问题是我上一个问题的延伸如何从列表中选择使用 \ref 中的结果?。我得到了非常好的、有趣的答案。不幸的是,我无法将它们应用于我的最终任务。
让我们考虑几个对象,比如方程,它们被标记为\label
,
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
...............
\begin{equation}
22+22=44 \label{zzz}
\end{equation}
将命令\theequation
重新定义为
\renewcommand{\theequation}{eq.~\arabic{equation}}
在这种情况下,\ref{aaa}
给出 eq.~1,\ref{bbb}
给出 eq.~2 等等。我需要\IfRefList
检查给定引用是否包含在某个引用列表中的命令。换句话说,它应该像
\IfRefList{eq.~1}{aaa;bbb;ccc} --> true
\IfRefList{eq.~4}{aaa;bbb;ccc} --> false
\IfRefList{eq.~2}{aaa;ccc} --> false
\IfRefList{eq.~1}{bbb;aaa;ccc} --> true
我将在 中使用结果\ifthenelse
。列表可以包含任意数量的项目,包括 1。我已经使用上述问题中 Heiko Oberdiek 提出的解决方案检查了几种可能性。我的尝试没有奏效。非常感谢您的帮助。
答案1
引用被写入.aux
文件并重新读取。命令可以部分扩展,例如~
变成。因此,在前面添加\nobreakspace{}
的重新定义可以防止扩展。\theequation
\protect
~
以下示例使用逗号分隔列表的解析器:
\documentclass{article}
\renewcommand*{\theequation}{eq.\protect~\arabic{equation}}
\usepackage{kvsetkeys}[2011/03/03]
\usepackage{refcount}[2010/12/01]
\makeatletter
\newif\if@IfRefList
\newcommand*{\IfRefList}[2]{%
\@IfRefListfalse
\def\IfRefList@key{#1}%
% \comma@parse{#2}\IfRefList@test
\begingroup
\csname @safe@activestrue\endcsname % babel shorthands
\edef\x{\endgroup
\noexpand\comma@parse{#2}\noexpand\IfRefList@test
}\x
\if@IfRefList
true%
\else
false%
\fi
}
\newcommand*{\IfRefList@test}[1]{%
\IfRefUndefinedBabel{#1}{%
}{%
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\IfRefList@entry
\expandafter\expandafter\expandafter{%
\getrefbykeydefault{#1}{}{}%
}%
\ifx\IfRefList@key\IfRefList@entry
\@IfRefListtrue
\comma@break
\fi
}%
}%
\makeatother
\begin{document}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
\begin{equation}
22+22=44 \label{zzz}
\end{equation}
\begin{center}
\newcommand*{\test}[1]{%
\texttt{\detokenize\expandafter{\string#1}} & #1\\%
}
\begin{tabular}{l@{ $\rightarrow$ }l}
\test{\IfRefList{eq.~1}{aaa,bbb,ccc}}
\test{\IfRefList{eq.~4}{aaa,bbb,ccc}}
\test{\IfRefList{eq.~2}{aaa,ccc}}
\test{\IfRefList{eq.~1}{bbb,aaa,ccc}}
\end{tabular}
\end{center}
\end{document}
下面是一个使用分号分隔列表的解析器的示例:
\documentclass{article}
\renewcommand*{\theequation}{eq.\protect~\arabic{equation}}
\usepackage{refcount}[2010/12/01]
\usepackage{etoolbox}
\DeclareListParser*{\SemicolonForeachParser}{;}
\newif\ifIfRefList
\newcommand*{\IfRefList}[2]{%
\IfRefListfalse
\def\IfRefListKey{#1}%
% \SemicolonForeachParser\IfRefListTest{#2}%
% Expansion of #2
\begingroup
\csname @safe@activestrue\endcsname
\edef\x{\endgroup
\noexpand\SemicolonForeachParser\noexpand\IfRefListTest{#2}%
}\x
\ifIfRefList
true%
\else
false%
\fi
}
\newcommand*{\IfRefListTest}[1]{%
\IfRefUndefinedBabel{#1}{%
}{%
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\IfRefListEntry
\expandafter\expandafter\expandafter{%
\getrefbykeydefault{#1}{}{}%
}%
\ifx\IfRefListKey\IfRefListEntry
\IfRefListtrue
\fi
}%
}%
\begin{document}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
\begin{equation}
22+22=44 \label{zzz}
\end{equation}
\begin{center}
\newcommand*{\test}[1]{%
\texttt{\detokenize\expandafter{\string#1}} & #1\\%
}
\begin{tabular}{l@{ $\rightarrow$ }l}
\test{\IfRefList{eq.~1}{aaa;bbb;ccc}}
\test{\IfRefList{eq.~4}{aaa;bbb;ccc}}
\test{\IfRefList{eq.~2}{aaa;ccc}}
\test{\IfRefList{eq.~1}{bbb;aaa;ccc}}
\end{tabular}
\end{center}
\end{document}
更新:针对列表以宏形式给出的情况添加了列表的扩展。
答案2
xparse
基于 (LaTeX3) 的解决方案:
\documentclass{article}
\usepackage{refcount,xparse}
\renewcommand{\theequation}{eq.~\arabic{equation}}
\ExplSyntaxOn
\NewDocumentCommand{\IfRefList}{ m m m m}
{
\andrew_ifreflist:nnnn { #1 } { #2 } { #3 } { #4 }
}
\cs_set_eq:NN \__andrew_getrefnumber:n \getrefnumber
\cs_set_eq:Nc \__andrew_protected_edef:w { protected@edef }
\tl_new:N \l__andrew_temp_a_tl
\tl_new:N \l__andrew_temp_b_tl
\bool_new:N \l__andrew_hit_bool
\seq_new:N \l__andrew_labellist_seq
\cs_new_protected:Npn \andrew_ifreflist:nnnn #1 #2 #3 #4
{
\bool_set_false:N \l__andrew_hit_bool
\seq_set_split:Nnn \l__andrew_labellist_seq { ; } { #2 }
\seq_map_inline:Nn \l__andrew_labellist_seq
{
\__andrew_compare_label_ref:nn { #1 } { ##1 }
\bool_if:NT \l__andrew_hit_bool { \seq_map_break: }
}
\bool_if:NTF \l__andrew_hit_bool { #3 } { #4 }
}
\cs_new_protected:Npn \__andrew_compare_label_ref:nn #1 #2
{
\__andrew_protected_edef:w \l__andrew_temp_a_tl { #1 }
\__andrew_protected_edef:w \l__andrew_temp_b_tl { \__andrew_getrefnumber:n { #2 } }
\tl_if_eq:NNT \l__andrew_temp_a_tl \l__andrew_temp_b_tl
{
\bool_set_true:N \l__andrew_hit_bool
}
}
\ExplSyntaxOff
\begin{document}
\begin{equation}
2+2=4 \label{aaa}
\end{equation}
\begin{equation}
3+3=6 \label{bbb}
\end{equation}
\begin{equation}
22+22=44 \label{zzz}
\end{equation}
\IfRefList{eq.~1}{aaa;bbb;ccc}{HIT}{NO HIT}
\IfRefList{eq.~2}{aaa;ccc}{HIT}{NO HIT}
\end{document}