这个问题与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}