我有一个文档类test.cls
,在其中我myenvironment
使用environ
包定义了一个自定义环境,如下所示:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{test}
\LoadClass{article}
\RequirePackage{changepage}
\RequirePackage{environ}
\NewEnviron{myenvironment}{
\begin{adjustwidth}{10pt}{10pt}
\BODY
\end{adjustwidth}
}
现在,如果我尝试使用tikz-cd
inside myenvironment
,它会失败,例如这会出现错误:
\begin{myenvironment}
\[\begin{tikzcd}
1 \ar[r] \ar[d] & 2 \ar[d] \\
3 \ar[r] & 4 \\
\end{tikzcd}\]
\end{myenvironment}
另一方面,如果我只是这样写 - 即我替换环境会做的事情 - 那么一切都很好:
\begin{adjustwidth}{10pt}{10pt}
\[\begin{tikzcd}
1 \ar[r] \ar[d] & 2 \ar[d] \\
3 \ar[r] & 4 \\
\end{tikzcd}\]
\end{adjustwidth}
可能是什么问题呢?
答案1
使用 收集环境时必须非常小心environ
,因为这通常会带来问题。当environ
收集环境时,它会“冻结”环境的标记。也就是说,所有内容都将表示调用外部环境时的意思。这将破坏在某处重新定义任何字符的类别代码(例如逐字环境)或重新定义某些字符的每个环境。
&
在此特定情况下,输入 时的含义会发生变化tikzcd
。请参阅:
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz-cd}
\begin{document}
When \texttt{environ} collects the environment:
{\ttfamily\meaning&}
\bigskip
What \texttt{tikzcd} expects \texttt{\&} to be:
\begin{tikzcd}
\vbox to \textwidth{\ttfamily\meaning&}
\end{tikzcd}
\end{document}
因此基本上,里面的tikzcd
意思&
是一个意思,但是当environ
读取它时,它会冻结这个alignment tab character &
意思,所以它不起作用。
因此,请environ
仅当您确定需要它并且确定它不会破坏任何东西时才使用它。
就您而言,您根本不需要,environ
因为您没有对收集的内容应用任何操作,因此:
\newenvironment{myenvironment}
{%
\begin{adjustwidth}{10pt}{10pt}%
}%
{%
\end{adjustwidth}
}
就足够了。
答案2
它不起作用,因为myenvironment
吸收环境主体作为宏参数;在这些情况下,你必须传递ampersand replacement=\&
给tikzcd
并使用\&
而不是&
,所以
\begin{myenvironment}
\[\begin{tikzcd}[ampersand replacement=\&
1 \ar[r] \ar[d] \& 2 \ar[d] \\
3 \ar[r] \& 4 \\
\end{tikzcd}\]
\end{myenvironment}
但是,这里没有必要environ
:
\newenvironment{myenvironment}
{\begin{adjustwidth}{10pt}{10pt}}
{\end{adjustwidth}}
效果也一样好。实际上,效果更好。
货物崇拜版本将是
\newenvironment{myenvironment}
{\adjustwidth{10pt}{10pt}}
{\endadjustwidth}