当我用定义一个环境时\newenvironment
,我可以newcommand
在“之前”部分内使用,以使命令对环境内的代码可用。
使用简单的命令可以实现这一点吗?换句话说,我可以创建一个命令,让用户在参数中使用未在外部定义的宏吗?
例如:假设我想编写一个命令\set
来排版数学集合定义,并且我想\suchthat
在里面使用一个命令,如下所示:
\set{x\in X \suchthat x > 42}
这很容易,但我希望该\suchthat
命令仅在 的参数内可用\set
。
答案1
您可以将命令定义为
\newcommand\set[1]{%%
\begingroup
\def\suchthat{... some definition...}%%
... other macro content ....
\endgroup}
这将\suchthat
在宏内部提供。
\bgroup
您可以使用和完成此操作\egroup
,但这会创建一个子公式,如果在数学模式下使用,则会影响间距的处理方式。这里的\begingroup
和\endgroup
本地化了新宏的定义。您可以使用以下任何一种来定义本地命令,\def
、\edef
和\newcommand
。
按照@barbarabeeto 的建议,你可以在序言中做这样的事情:
\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
\let\suchthat\ae@suchthat
the body of the macro: #1
\let\suchthat\undefined
}
\makeatother
这要好得多。除了 barbarabeeto 提出的原因之外,这还允许您的宏(如果您愿意的话)定义或设置您可能希望在文档中稍后访问的值。使用这种\begingroup/\endgroup
方法,这些必须全球化,这可能不是您想要的。
混合方法可能看起来像
\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
\begingroup
\let\suchthat\ae@suchthat
the body of the macro: #1
\endgroup
}
\makeatother
答案2
答:Ellett 的建议很好,但是这种方法也有一些微妙之处。
\bgroup
使用和来局部化定义\egroup
是不好的,因为\set
宏显然是在数学模式下使用的。这样的构造会产生一个子公式,结果是空间被冻结,不参与线上的拉伸和收缩;使用\begingroup
和\endgroup
不会遇到这个问题。无论如何都必须给出一个默认定义
\suchthat
,因为您可能恰好想要\suchthat
在章节标题中使用它。出于同样的原因,这两个命令都应该变得强大。
这是一个实现。
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newrobustcmd{\suchthat}{%
\@latex@error{Use \noexpand\suchthat only in \string\set}
{You are allowed to use \noexpand\suchthat only in the\MessageBreak
argument of \string\set}%
}
\newcommand\giga@suchthat{\mid}
\newrobustcmd{\set}[1]{%
\begingroup
\let\suchthat\giga@suchthat
\{\,#1\,\}%
\endgroup
}
\makeatother
\begin{document}
\tableofcontents
\section{The set $\set{x\in X \suchthat x>42}$}
Let's study $\set{x\in X \suchthat x>42}$.
\suchthat
\end{document}
终端中的输出:
! LaTeX Error: Use \suchthat only in \set.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.27 \suchthat
? h
You are allowed to use \suchthat only in the
argument of \set
输出