如何在宏中捕获冒号?

如何在宏中捕获冒号?

我正在尝试捕捉标点符号,并且我有许多宏,其中两个显示在下面的最小值中:

\documentclass{article}
\usepackage[english]{babel}
\def\isColon#1{%
\ifx:#1
    colon!
\else
   Not a colon!
\fi}

\def\isPeriod#1{%
\ifx.#1
   Period!
\else
   Not a period!
\fi}

\begin{document}
\isColon:

\isPeriod.
\end{document}

如果babel语言更改为[french,english]冒号,则不会捕获,因为 babel 会将其激活。需要对isColon宏进行哪些修改才能在两种情况下正常工作?

答案1

我会用\if

\documentclass{article}
\usepackage[english]{babel}
\def\isColon#1{%
\if:\noexpand#1%
    colon!
\else
   Not a colon!
\fi}

\def\isPeriod#1{%
\if.\noexpand#1%
   Period!
\else
   Not a period!
\fi}

\begin{document}
\isColon:

\isPeriod.
\end{document}

另一种选择是\pdfstrcmp,但在这里这可能有点过度了。

答案2

\documentclass{article}
\usepackage[english,french]{babel}
\shorthandon{:}
\def\isColon#1{%
  \ifx:#1
    colon!
  \else
     Not a colon!
  \fi}%

\def\isPeriod#1{%
\ifx.#1
   Period!
\else
   Not a period!
\fi}

\begin{document}
\isColon: \isColon;

\isPeriod.
\end{document}

答案3

问题是,在宏的外部,:是一个扩展为 的宏\active@prefix :\normal@char: ,但在宏的内部,:只是一个字符:。我相信这是因为 Babel 使用 来注册 catcode 的变化\AtBeginDocument;将宏定义移动到 之后\begin{document}就可以正常工作。我还发现,只需更改\ifx为就可以正常\if工作,而无需移动宏定义。但我认为最干净的解决方案(尽管有点具体)可能是将:的 catcode 更改为 active 。定义\isColon

\catcode`\:=\active
\def\isColon#1{%
\ifx:#1
    colon!
\else
   Not a colon!
\fi}
\catcode`\:=12

编辑:如果:其 catcode 已被其他内容更改,则您应该改用此版本:

\begingroup
  \catcode`\:=\active
  \gdef\isColon#1{%
    \ifx:#1
      colon!%
    \else
      Not a colon!%
    \fi}
\endgroup

这会将 的 catcode 重置:为之前的状态,而不是简单地重置为12

相关内容