第一次学习 LaTeX 时,我认为\newcommand
它非常适合内联模式和\newenvironment
显示模式。
后来我注意到这是不正确的。所以问题是
在决定是否应该使用其中一个时,经验法则是什么?
答案1
选择环境而不是命令形式的技术原因是,如果定义仅涉及设置声明,那么它就不必提前扫描内容,因此列表环境等longtable
可以在看到环境结束之前开始排版并发送页面。命令形式必须扫描到参数的末尾。如果有可能逐字逐句地记录材料,那么使用环境形式会更容易。
其他原因大多与您正在定义的文档结构的美观有关。如果您想将其视为一个范围区域,请将其定义为环境。如果您想将其视为传递给命令的文本块,请将其定义为命令。
答案2
只是补充一点其他答案。也许最重要的考虑是问自己,你是为谁写这个命令或环境?命令和环境都向用户隐藏了 TeX 语言的复杂性,并且应该提供标记,以优化以最小化人类1记忆并最大限度地提高可读性。因此,如果没有技术原因,那就是用户界面的问题。
考虑一个简单的例子,用户要提供一个符号列表,我们将提供一个命令或环境来排版它们,其中第一个想到的是一个表格。
对于我自己来说我更喜欢这样:
\printlist{\alpha,\beta,\gamma,\zeta,
\eta,\theta,\epsilon}
如果我预计用户会输入五十个或更多的符号,那么环境可能会减少人为错误并提高可读性。
\begin{symbols}
\dosymbol{\alpha}
\dosymbol{\beta}
\dosymbol{\gamma}
\dosymbol{\zeta}
\end{symbols}
也许吧?使用下面的 MWE 进行选择:
\documentclass{book}
\usepackage{textcomp}
\makeatletter
%\def\symbols{\flushleft} %alternative way to define
%\def\endsymbols{\endflushleft} %the environment
\newenvironment{symbols}{\flushleft}{\endflushleft}
\def\dosymbol#1{%
\leavevmode\hbox to .33\textwidth{%
\hbox to 1.2em%
{\hss$#1$\hfil}%
\footnotesize\texttt{\string#1}\hss}%
\penalty10}
\parindent0pt
\begin{document}
\begin{symbols}
\dosymbol{\alpha}
\dosymbol{\beta}
\dosymbol{\gamma}
\dosymbol{\zeta}
\end{symbols}
\def\listsymbols#1{%
\@for\next:=#1\do{%
\expandafter\dosymbol\next%
}}
\long\def\printlist#1{%
\def\alist{#1}
\flushleft
\listsymbols\alist
\endflushleft
}
\printlist{\alpha,\beta,\gamma,\zeta,
\eta,\theta,\epsilon}
\end{document}
1一些 TeX 程序员也具有人类记忆。
答案3
没有人会使用一个定义的缩写环境:
\newcommand\tim{That is me}
环境foo
由两个命令内部定义:
\begingroup
\foo
...
\endfoo
\endgroup
之所以有一般来说\newcommand
a和 a之间没有太大区别\newenvironment
。对于标记语言来说,使用环境通常是更好的选择。
答案4
对我来说,决定在于\macro
或者\begin{environment}
应该做什么。
如果我需要做我会选择一个宏。
如果我需要提供某些东西,只能在某个特定区域访问,我选择一个环境。
所以基本上是一个环境提供对内容进行通用操作的起点。
而宏则执行单一操作。
一个不太奇怪的事情是提供一个重置页面计数器的命令。
\newcommand\resetpage{\setcounter{page}{1}}
但是,有人可能会认为这可能与内容从第 1 页开始的环境相同。但是,环境内容的庞大规模似乎在任何编辑器中都不容易理解。(它可以轻松扩展到几页)。而且内容格式实际上并没有改变,也没有提供宏来执行特殊操作,因此在这种情况下使用环境似乎是可疑的。正如@DavidCarlisle 所说,如果环境提供了格式化内容所需的内容(,等),那么长度就不是table
问题itemize
。