代码:

代码:

我正在使用解决了我之前的一个问题的 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 情况一次。然后有两个比较:

  1. 现在这两个论点一致吗?
  2. 如果不是,如果我们将第一个扩展一次,它们是否匹配。

通过查看三个演示案例,我们得到了以下逻辑:

  1. 没有任何变化\edef,因此第一个测试为假(\SpecialValue与相比special)。单次扩展会扩展\SpecialValuespecial,因此第二个测试为真。

  2. 转换\edef为,\the\MyToken然后\SpecialValue我们按照情况(1)进行操作。

  3. 转换\edef为,\the\MyToken\SpecialValue意味着第一个测试比较\SpecialValue\SpecialValue,它们是相同的,所以第一个测试是正确的,我们永远不会扩展\SpecialValue

如果第二个参数可能需要扩展(如果我们可以在第一个参数中使用文字文本而在第二个参数中使用宏),那么就需要进行一些参数改组。

以上作品,但我要提醒大家不要这么做。一般来说,指定论据的性质是更好的“风格”:“可能扩展”的做法是有风险的,因为如果论据是你没有考虑到的,它可能会失败。

相关内容