我正在使用解决了我之前的一个问题的 as。我需要比较 token 的这个值,看看它是否以不同的方式\protected\def
初始化为与相同的值。\protected\def
下面的 MWE 检查我需要的情况。我真的更希望不是对变量的声明方式进行任何更改,而是定义自定义版本以\MyIfStrEq
根据需要进行比较。
笔记:
- 如果我简单地删除,下面的 MWE 会产生正确的结果,但根据下面引用的问题,
\protected
我需要在另一种情况下使用。\protected
- 我通常不会在前缀之外使用诸如“特殊”之类的神奇文本,但在这种情况下,我需要比较的文本来自文件系统。
参考:
代码:
\documentclass{article}
\usepackage{xstring}
\usepackage{xparse}
\NewDocumentCommand{\MyIfStrEq}{m m m m}
{%
\IfStrEq{#1}{#2}{#3}{#4}%
}
%\NewDocumentCommand{\MyIfStrEq}{m m m m}
% {%
% \ifx#1#2%
% #3%
% \else%
% #4%
% \fi%
% }
%% -------------------------------------------------------------
%% Would prefer to NOT change code from here to \begin{document}
\protected\def\SpecialValue{special}
\newtoks{\MyToken}
\MyToken={\SpecialValue}
%% -------------------------------------------------------------
\begin{document}
\MyIfStrEq{\SpecialValue}{special}{Pass 1}{Fail 1}%
\MyIfStrEq{\the\MyToken}{special}{Pass 2}{Fail 2}%
\MyIfStrEq{\the\MyToken}{\SpecialValue}{Pass 3}{Fail 3}%
\end{document}
答案1
如果我理解正确的话,
\documentclass{article}
\usepackage{xstring}
\usepackage{xparse}
\NewDocumentCommand{\MyIfStrEq}{m m m m}
{%
\begingroup
\edef\x{%
\endgroup
\noexpand\MyIfStrEqAux{#1}{#2}%
}%
\x{#3}{#4}%
}
\protected\def\MyIfStrEqAux#1#2#3#4{%
\IfStrEq{#1}{#2}
{#3}
{\expandafter\IfStrEq\expandafter{#1}{#2}{#3}{#4}}%
}
%% -------------------------------------------------------------
%% Would prefer to NOT change code from here to \begin{document}
\protected\def\SpecialValue{special}
\newtoks{\MyToken}
\MyToken={\SpecialValue}
%% -------------------------------------------------------------
\begin{document}
\MyIfStrEq{\SpecialValue}{special}{Pass 1}{Fail 1}%
\MyIfStrEq{\the\MyToken}{special}{Pass 2}{Fail 2}%
\MyIfStrEq{\the\MyToken}{\SpecialValue}{Pass 3}{Fail 3}%
\end{document}
会起作用。这里的方法如下。我们首先假设#1
和#2
可能包括:
- 受保护的宏(例如
\SpecialValue
) - 使用 toks(例如
\the\MyToken
) - 文本(例如
special
)
不会\edef
影响受保护的宏或文本情况,并且只会扩展 toks 情况一次。然后有两个比较:
- 现在这两个论点一致吗?
- 如果不是,如果我们将第一个扩展一次,它们是否匹配。
通过查看三个演示案例,我们得到了以下逻辑:
没有任何变化
\edef
,因此第一个测试为假(\SpecialValue
与相比special
)。单次扩展会扩展\SpecialValue
为special
,因此第二个测试为真。转换
\edef
为,\the\MyToken
然后\SpecialValue
我们按照情况(1)进行操作。转换
\edef
为,\the\MyToken
这\SpecialValue
意味着第一个测试比较\SpecialValue
和\SpecialValue
,它们是相同的,所以第一个测试是正确的,我们永远不会扩展\SpecialValue
。
如果第二个参数可能需要扩展(如果我们可以在第一个参数中使用文字文本而在第二个参数中使用宏),那么就需要进行一些参数改组。
以上作品,但我要提醒大家不要这么做。一般来说,指定论据的性质是更好的“风格”:“可能扩展”的做法是有风险的,因为如果论据是你没有考虑到的,它可能会失败。