LaTeX 新命令限制

LaTeX 新命令限制

\newcommand我想知道 LaTeX在定义和使用/调用新宏方面的可能性和局限性。我知道其中一些示例很原始,但它们可以帮助理解局限性。我只对\newcommand以“\”char+ 为名称的基本 s 感兴趣。

无效示例:

\newcommand{\newcenter}{center} 
\begin{\newcenter}
\end{center}

\newcommand{\tabularthree}{{tabular}}
\begin \tabularthree {ccc}
cell& cell
\end \tabularthree

\newcommand{\tion}{tion}
\sec\tion{mysec}

有效示例:

\newcommand{\optarg}{[myoptarg]} 
\section\optarg{mysec}

\newcommand{\cc}{cc}
\newcommand{\mybegin}{\begin}
\mybegin{tabular}{c\cc}
cell& cell
\end{tabular}

\newcommand{\tabulartwo}{tabular}
\begin{\tabulartwo} {ccc}
cell& cell
\end \tabulartwo

\newcommand{\tabularfour}{tabular}
\begin \tabularfour{ccc}
cell& cell
\end \tabularfour

答案1

Henri Menke 告诉了你如何绕过规则。这个答案将告诉你为什么你使用的语法(不)起作用。

无效的那些:

\newcommand{\newcenter}{center}
\begin{\newcenter}
\end{center}

这个命令失败了,因为\@currenvir展开为\newcenter,并且当 LaTeX 调用命令时\@checkend,它会比较 的含义\@currenvir和 的参数\end,即center。比较失败是因为它\newcenter与进行center比较而没有进一步展开,因此它们不同,并引发错误。另一方面,错误消息完全展开,\@currenvir并且错误消息具有误导性:

! LaTeX Error: \begin{center} on input line 29 ended by \end{center}.

\newcommand{\tabularthree}{{tabular}}
\begin \tabularthree {ccc}
cell& cell
\end \tabularthree

这个会失败,因为 LaTeX 会检查环境是否存在,\ifcsname它会构建一个命令,其参数为\begin,在本例中为\tabularthree,它会扩展为{tabular}\ifcsname然后检查名为的命令{tabular},它不存在,然后 LaTeX 会告诉你:

! LaTeX Error: Environment {tabular} undefined.

\newcommand{\tion}{tion}
\sec\tion{mysec}

这个命令失败了,因为它是无效的。该命令\sec被展开,并且它是割线函数,只允许在数学模式下使用,因此 TeX 认为你忘记了$

! Missing $ inserted.
<inserted text> 
                $
l.46 \sec

如果\sec不是数学模式命令,TeX 会尝试执行它。如果它有一个参数,参数将是命令\tion,然后将其扩展为tion,然后\sec命令将使用 执行其操作(无论它是什么)tion。如果它不存在,TeX 会抱怨它\sec不存在。


那个作品

\newcommand{\optarg}{[myoptarg]}
\section\optarg{mysec}

这个编译,但它并没有产生你期望的结果。可选参数的测试失败,因为的代码\section没有看到[字符(并且它没有扩展\optarg来寻找它),所以它将其\optarg作为强制参数,并且该部分的标题变为[myoptarg]mysec写在下面。


那些工作:

\newcommand{\cc}{cc}
\newcommand{\mybegin}{\begin}
\mybegin{tabular}{c\cc}
cell& cell
\end{tabular}

这个方法有效,因为 TeX 在扩展时\mybegin只会找到\begin。TeX 随后继续扩展\begin并正常执行操作。这个\cc方法有效,因为tabular它扩展了对齐前导的标记。


\newcommand{\tabulartwo}{tabular}
\begin{\tabulartwo} {ccc}
cell& cell
\end \tabulartwo

这个方法有效,原因和第一个方法无效相同。对\tabulartwo和执行环境名称检查\tabulartwo,它们是同一件事。而且那里的括号没有区别,因为根据 TeX 的参数抓取规则,正常参数要么是单个标记(\tabulartwo是单个标记),要么如果{找到一个左括号(),则参数是<balanced text>该括号对内的(\tabulartwo和在一对括号内)tabular<balanced text>


\newcommand{\tabularfour}{tabular}
\begin \tabularfour{ccc}
cell& cell
\end \tabularfour

同上。


但是你真的不应该为命令发明语法,因为即使它有效,你也会混淆你的代码,甚至几周后你都不会理解它。

答案2

\expandafter解决了几乎所有的问题。你似乎是一个 LaTeX 初学者,所以这些不是你通常必须做的事情。还请查看何时使用 \edef、\noexpand 和 \expandafter?

\documentclass{article}
\begin{document}

\newcommand{\newcenter}{center} 
\expandafter\begin\expandafter{\newcenter}
\end{center}

\newcommand{\tabularthree}{{tabular}}
\expandafter\begin\tabularthree{ccc}
cell& cell
\expandafter\end\tabularthree

\newcommand{\tion}{tion}
\csname sec\tion\endcsname{mysec}

\end{document}

相关内容