我有一个宏,\command
用于确保文档中宏的名称格式一致。一直效果很好,直到我有一种拖延的冲动,才有了这杰出的我可以通过检查宏是否存在,轻松捕获宏名称的大多数拼写错误。
看起来很简单。所以我补充道:
\ifcsname#1\endcsname%
\else%
\par\textbf{\textcolor{red}{\textbackslash#1} is not defined.}
\fi%
到执行格式化的宏,其中#1
是宏的名称。这在基本情况下似乎工作正常,如下面的 MWE 所示,它产生:
并正确地告诉我bfseriess
和\foo
未定义。
但是,如果我尝试以嵌套方式使用它
\command{foo=\command{MyDef}}
我收到错误消息
Missing \endcsname inserted. <to be read again> \protect l.25 \command{foo=\command{MyDef}}
问题:
我感觉解决方案就在参考文献中列出的问题中,但我不知道具体怎么做\protect
。那么,我可以对宏进行哪些更改,\command
以便我可以取消注释 MWE 中的最后一行并显示正确的错误消息。
参考:
代码:
\documentclass{article}
\usepackage{xcolor}
%% The last line should not produce any error
%% messages (red text) if these two are defined.
%
%\newcommand*{\foo}{}%
%\newcommand*{\MyDef}{}%
\newcommand{\command}[1]{%
\textbf{\textbackslash#1}%
%% Since this is used to typeset macro names, we
%% can check for typos by ensuring the macro exists
\ifcsname#1\endcsname%
\else%
\par\fcolorbox{red}{red!20}{\textcolor{blue}{\textbackslash#1} is not defined.}
\fi%
}%
\begin{document}
To bold text use \command{textbf} or \command{bfseriess}.
A useful token is \command{foo}.
This token needs to be set with:
%\command{foo=\command{MyDef}}
\end{document}
答案1
当参数\command
不是命令名时,我完全不确定预期的行为是什么,但是这会做一些事情:
\documentclass{article}
\usepackage{xcolor}
%% The last line should not produce any error
%% messages (red text) if these two are defined.
%
%\newcommand*{\foo}{}%
%\newcommand*{\MyDef}{}%
\protected\def\command#1{%
\textbf{\textbackslash#1}%
%% Since this is used to typeset macro names, we
%% can check for typos by ensuring the macro exists
\ifcsname\detokenize{#1}\endcsname%
\else%
\par\fcolorbox{red}{red!20}{\textcolor{blue}{\textbackslash#1} is not defined.}
\fi%
}%
\begin{document}
To bold text use \command{textbf} or \command{bfseriess}.
A useful token is \command{foo}.
This token needs to be set with:
\command{foo=\command{MyDef}}
\end{document}
或者根据评论中的要求进行更新,以删除之前的论点=
\documentclass{article}
\usepackage{xcolor}
%% The last line should not produce any error
%% messages (red text) if these two are defined.
%
%\newcommand*{\foo}{}%
%\newcommand*{\MyDef}{}%
\protected\def\command#1{%
\textbf{\textbackslash#1}%
%% Since this is used to typeset macro names, we
%% can check for typos by ensuring the macro exists
\ifcsname\expandafter\beforeeq\detokenize{#1}=\beforeeq\endcsname%
\else%
\par\fcolorbox{red}{red!20}{\textcolor{blue}{\textbackslash\expandafter\beforeeq\detokenize{#1}=\beforeeq} is not defined.}
\fi%
}%
\def\beforeeq#1=#2\beforeeq{#1}
\begin{document}
To bold text use \command{textbf} or \command{bfseriess}.
A useful token is \command{foo}.
This token needs to be set with:
\command{foo=\command{MyDef}}
\end{document}
答案2
\doifundefined
通过简单地模仿ConTeXt 中的定义(在文件中定义syst-gen.mkii
),添加\detokenize
定义就可以了。
\newcommand\command[1]
{\textbf{\textbackslash#1}%
%% Since this is used to typeset macro names, we
%% can check for typos by ensuring the macro exists
\ifcsname\detokenize{#1}\endcsname%
\else%
\par\fcolorbox{red}{red!20}{\textcolor{blue}{\textbackslash#1} is not defined.}
\fi%
}%
答案3
我会选择类似的东西:
\documentclass{article}
\begin{document}
\makeatletter
\def\mytypeset#1{%
\def\command##1{%
\ifcsname##1\endcsname%
\expandafter\@firstoftwo
\else%
\expandafter\@secondoftwo
\fi%
}%
\def\z{\detokenize{#1}}
\command{\z}{\fbox{TRUE}}{\fbox{FALSE}}
}
\mytypeset{deff{f}f}
\mytypeset{def}
\mytypeset{foo=\command{MyDef}}
\end{document}
请注意,当您检查“嵌套”命令时,实际上代码会检查:
foo=\command{MyDef}
是一个定义的宏!使用csname
... endcsname
,可以使用任意字符的任意命令。!$%.#!.o>,p\def}
例如,您可以有一个命令。您可以将以下代码片段添加到演示该概念的示例中。
\expandafter\def\csname My$Def\endcsname{MyDef...}
\mytypeset{My$Def}
% prints MyDef...
\csname My$Def\endcsname
\My$Def
MyDef..
now 是一个命令,执行时会打印。