如何在 \ifcase 分支中使用 \csname 测试 if 条件

如何在 \ifcase 分支中使用 \csname 测试 if 条件

我正在尝试测试一个 if 条件,其中条件的名称取决于宏参数。为此,我使用\csname ifcondition#1 \endcsname。这在简单的宏中运行良好,如下所示:

\newif\ifconditionA
\conditionAtrue
\def\test#1{
    \csname ifcondition#1\endcsname
        A: True
    \fi
}
\test{A}

但是,在我的实际用例中,这个测试是分支的一部分\ifcase,如下所示:

\documentclass{article}
\begin{document}
\newif\ifconditionA
\conditionAtrue

\def\test#1#2{
\ifcase#2
    Case 0
\or
    %\ifconditionA % This works
    \csname ifcondition#1\endcsname
        Case 1, A: true
    \fi
\fi
}

\test{A}{0}
%\test{A}{1} % This works

\end{document}

此操作失败,并显示错误消息! Extra \fi. \test ...tion#1\endcsname Case 1, A: true \fi \fi

如果我直接使用条件的名称,不带\csname,它可以正常工作,并且如果执行包含条件的分支,它也可以工作。

发生了什么事?我该如何解决这个问题?

答案1

限制是条件必须匹配,否则跳过未使用的分支将无法按预期工作。

方法有很多种。下面的例子使用\ifx并将构造的条件与进行比较\iftrue。因为我们已经有了\ifx,所以后者也被掩盖了\csname

\documentclass{article}
\begin{document}
\newif\ifconditionA
\conditionAtrue

\def\test#1#2{%
  \ifcase#2
    Case 0
  \or
    \expandafter
    \ifx\csname ifcondition#1\expandafter\endcsname
        \csname iftrue\endcsname
      Case 1, A: true
    \fi
  \fi
}

\test{A}{0}
\test{A}{1}

\end{document}

如果您希望在宏中使用一些更清晰的东西\test,那么魔法可以隐藏在宏中,例如:

\documentclass{article}
\begin{document}
\newif\ifconditionA
\conditionAtrue

\newcommand*{\getcondition}[1]{%
  T\expandafter
  \ifx\csname ifcondition#1\endcsname\iftrue
    \expandafter T%
  \else
    \expandafter F%
  \fi
}

\def\test#1#2{%
  \ifcase#2
    Case 0%
  \or
    \if\getcondition{#1}%
      Case 1, #1: true%
    \else
      Case 1, #1: false%
    \fi
  \else
    Other case%
  \fi
}

[\test{A}{0}]
[\test{A}{1}]
[\test{B}{0}]
[\test{B}{1}]
[\test{A}{2}]

\end{document}

结果

答案2

你可以利用扩展标记的事实\if,直到找到不可扩展的标记:

\documentclass{article}
\begin{document}
\newif\ifconditionA
\conditionAtrue

\def\testcondition#1{\expandafter\TTfi\csname ifcondition#1\endcsname}
\def\TTfi{TT\fi}

\def\test#1#2{%
  \ifcase#2
    Case 0
  \or
    \if\testcondition{#1}%
      Case 1, A: true
    \fi
  \fi
}

\test{A}{0}
\test{A}{1}

\end{document}

让我们看看它是如何工作的。如果我们处于跳过的文本中,即条件的假分支或\or要忽略的分支,TeX 将匹配\if真正对应于的\fi(和可能的) 。如果它处于真实分支中,则扩展为\else\ifconditionA

\if\testcondition{A}
\if\expandafter\TTfi\csname ifconditionA\endcsname
\if\TTfi\ifconditionA
\if TT\fi\ifconditionA
\ifconditionA

因此与\if第一个匹配\fi,整个组\if TT\fi消失,不做任何事。然后构造的与其和\ifconditionA匹配。\else\fi

相关内容