更改宏中 (@) 处的商业 catcode 以使其与模式匹配。

更改宏中 (@) 处的商业 catcode 以使其与模式匹配。

这个问题与TikZ:pgfutil-common:pgfutil@in@ - 它是如何工作的?是应对这个问题的结果。我已经读过如何更改宏中的 catcode,但它对我没有帮助。

这是我所拥有的简单示例。在\makeatletter ... \makeatother内部document环境中玩耍。

\documentclass{article}

\usepackage{tikz}

% Consider start of library here (this part is located in a separate file included by means of `\usetikzlibrary`).
\makeatletter

\def \myparse #1{%
    \def \myparse@ ##1 @ ##2\pgf@stop{%
        \def \beforeat{##1}%
        \def \afterat{##2}%
    }
    %
    \def \tikz@temp{#1}%
    %
    \def \beforeat{false before}%
    \def \afterat{false after}
    \edef \pgf@marshal{\noexpand \pgfutil@in@{@}{\tikz@temp}}%
    \pgf@marshal \ifpgfutil@in@%
        \expandafter \myparse@ \tikz@temp\pgf@stop%
    \fi%
}

\makeatother
% Consider end of library here.

% User's file starts here.

\begin{document}
    \makeatletter % Play with commenting out this line.
    \myparse{true before @ true after}
    \makeatother % and this one.

    \beforeat\par
    \afterat\par
\end{document}

我想消除\makeatletter ... \makeatother用户文件中的需要,同时保留@符号的使用。

答案1

你可能还想阅读\makeatletter 和 \makeatother 起什么作用?。广义上讲,要使用诸如 这样的宏\pgfutil@in@@就 TeX 而言, 必须是“字母”。这是因为 TeX 根据“字母”来确定什么是控制序列(宏名称)。如果您尝试使用诸如\pgfutil@in@without这样的宏\makeatletter,那么 TeX 将查找名为 的宏\pgfutil,这可能会导致错误,也可能不会,但肯定不是您想要的。

您发布的代码包含一个@,它必须是“其他”字符,而不是字母。包含具有“尴尬”类别代码的字符的标准方法是使用\lowercase,例如

\makeatletter
\begingroup
\lccode`\*=`\@\relax
\lowercase{%
  \endgroup
  \def\test#1*{stuff}%
}%
\makeatother
\test 123@456

这样做的原因是 TeX 在更改字符代码(广义上,当它将其变为小写时)时不会更改标记的类别代码。对于熟悉许多其他编程语言的人来说,这似乎很奇怪,但对于 TeX 程序员来说,这是一种标准方法。

答案2

以下内容似乎有效(五分钟前编辑,抱歉,但我认为我最终做对了,即使最后看起来很简单):

\documentclass{article}

\usepackage{tikz}

% Consider start of library here (this part is located in a separate file included by means of `\usetikzlibrary`).
\makeatletter

\def \myparse #1{%
    \def \myparse@ ##1 @ ##2\pgf@stop{%
        \def \beforeat{##1}%
        \def \afterat{##2}%
    }
    %
    \def \tikz@temp{#1}%
    %
    \def \beforeat{false before}%
    \def \afterat{false after}
    \edef \pgf@marshal{\noexpand \pgfutil@in@{@}{\tikz@temp}}%
    \pgf@marshal \ifpgfutil@in@%
        \expandafter \myparse@ \tikz@temp\pgf@stop%
    \fi
}

\makeatother
% Consider end of library here.

\def\MyParsei #1{\myparse{#1}\makeatother}
\def\MyParse{\makeatletter\MyParsei}

% User's file starts here.

\begin{document}
    \myparse{true before @ true after}
    \beforeat\par
    \afterat\par

    \MyParse{true before @ true after}
    \beforeat\par
    \afterat\par

    \myparse{true before @ true after}
    \beforeat\par
    \afterat\par

\end{document}

相关内容