我已经养成了\ensuremath
在每一个我定义的宏,这样我就可以在数学模式内外使用相同的宏。但 egreg 的评论\DeclareMathOperator 不接受参数让我思考也许我不应该总是这样做:
我认为添加 不是一个好主意;为什么要添加?免责声明:这是我的“仅在真正需要时”活动
\ensuremath
的一部分。:) -\ensuremath
埃格尔
为什么
\ensuremath
?$\scriptstyle#1$
阅读起来不是更容易吗? -埃格尔
在这种情况下,需要使用数学模式,因为我们处于\makebox
(即文本模式)中。因此,出于习惯,我使用了,\ensuremath
但 egreg 是对的,在这种情况下使用$...$
效果同样好,而且肯定更容易阅读。但是,即使在这种情况下,我仍然更喜欢使用,\ensuremath
这样更明显地表明它可以在数学和文本模式下使用,而不必考虑\makebox
在文本模式下。
\ensuremath
那么,至少对于我的任何个人宏来说,一直使用 真的有什么坏处吗?我意识到在处理过程中会有一点额外的开销,但还有其他需要考虑的吗?
如果宏在用于通用目的的软件包中还有其他注意事项,我也会对此感兴趣。最明显的一点是,我们可能希望确保宏的用户知道该宏需要数学模式,因此要求他们仅在数学模式下使用该宏。
由于这引用了 egreg 的竞选活动,我觉得我应该包括一个平均能量损失对于新用户,按照我的 MWE-as-often-as-possible 活动:
\documentclass{article}
\newcommand{\FunctionF}{\ensuremath{x^2}}%
\begin{document}
Text mode: \FunctionF
Math mode: $G(x) = x^3 - \FunctionF$
\end{document}
答案1
我想到两个反对意见:
- 如果您不知道自己将进入数学模式,那么您可能会写出一些“语义上”正确但却不准确的东西。
例如:
\documentclass{article}
\newcommand\mathmacro[1][A]{\ensuremath{{#1}_1}}
\begin{document}
\mathmacro[$x^2$] % The dollar signs *leave* math mode
\end{document}
这里发生的事情是\mathmacro[$x^2$]
扩展为
\ensuremath{{$x^2$}_1}
扩展为(有效)
\ifmmode
{$x^2$}_1
\else
${$x^2$}_1$
\fi
你会发现如果你这样写外部数学模式,则采用第二个分支,因此第一个美元符号将您带入数学模式,而前面的美元符号$x^2$
将您带出数学模式,随后将发生逆操作。这会产生错误。
当然,你不应该这样做,因为它\mathmacro
实际上是一个“可在文本模式下使用的数学宏”,所以你应该将其参数括号内的内容视为数学模式。唉,这会让作者和文本编辑器的语法突出显示都感到困惑,因为这是一个非标准假设。
编辑:我将这个宏定义为:
\newcommand\mathmacro[1][A]{{#1}_1}
并将其用作:
$x^2$ sub one: $\mathmacro[x^2]$.
这样,数学的部分就清晰明了了。
- 万一您或某些软件包发生了这样的情况
\everymath
,当您的文本模式宏开始看起来不同时,您会感到非常惊讶。
不过,就语义而言,问题很明显:\ensuremath
打破了数学和文本之间的区别,这是两个截然不同的东西。TeX 甚至内置了区别:不同的字体、不同的间距规则、不同的解析规则。利用这些,你很可能可以构造出更多的反例。
我的意思是,在以下情况下:
\documentclass{article}
\newcommand\mathmacro[1][A]{\ensuremath{{#1}_1}}
\begin{document}
A sub one: \mathmacro
\bfseries A sub one: \mathmacro
\end{document}
您可能会感到惊讶,粗体文本并没有延伸到明显的文本模式的内容\mathmacro
。
我要说的并不是\ensuremath
实际上破坏任何事情,因为它违背了你的期望,使事情变得更难而不是更容易。
答案2
没有什么不好的\ensuremath
本身。然而,如果我们检查你这个问题我认为能够\FunctionF
同时在文本模式和数学模式下说没有任何好处,而不是总是坚持\(\FunctionF\)
(或者$\FunctionF$
像其他人可能喜欢的那样)。TeX.SX 上还有许多其他帖子也这样做。采取这个:如果一个人想要那个命令的话,那么能够写the ring~\Z{n}
而不是写有什么好处呢the ring~$\Z{n}$
?也许,一个人还必须写the ring $\Z{m}\times\Z{n}$
,而这很有可能?
另一篇帖子有以下代码:
\newcommand{\vrel}[3]{
\vcenter{\halign{\hfill##\hfill\cr
\ensuremath{#1}\cr
\rotatebox[origin=c]{270}{\ensuremath{#2}}\cr
\ensuremath{#3}\cr
}}}
在我看来,这是糟糕的编程,因为里面的内容\ensuremath
是在数学模式下排版;“正确”的代码应该是
\newcommand{\vrel}[3]{
\vcenter{\mathsurround=0pt \halign{\hfill##\hfill\cr
$#1$}\cr
\rotatebox[origin=c]{270}{$#2$}\cr
$#3$\cr
}}}
答案3
这用户 egreg 的评论针对这个问题为什么这么多符号被限制在数学模式中?“非常有价值:
如果允许这样做,人们就会写错
\alpha+\beta
空格。数学应该始终被视为数学,即使是单个符号;如果您愿意,可以将其视为标记。
简单地说,使用\ensuremath
可以很容易地教会相关宏的用户懒于明确切换到数学模式(如果没有上标或下标,则通常“不需要”所有符号都出现在页面上),结果是表达式的间距可能错误如果表达式应该遵循数学模式间距,但却以水平文本模式排版。这违背了 (La)TeX 的一个目的,即正确排版数学表达式。
如果用户在应该输入“ ”的地方输入了“ \myalpha+\mybeta
”(或“ \myalpha + \mybeta
”,那么不应该是“ \myalpha{} + \mybeta{}
”吗?等等)\(\myalpha+\mybeta\)
,这可能会导致不良习惯,导致间距不正常。
答案4
我认为答案已在中提供fixltx2e
,尽管在大多数情况下我不认为这是一个问题,但从文档中可以看出:
4.4.1 实施策略注意事项
Pr/3400
\@fnsymbol
决定在文本模式和数学模式之间做出选择,这需要一定的稳健性,因为必须在排版时而不是在内部\protected@edef
或类似命令中做出文本和数学之间的决定。处理这个问题的一种方法是确保看到的值\@fnsymbol
是一个完全扩展的数字,这可以通过以下代码来处理\def\fnsymbol#1{\expandafter\@fnsymbol \expandafter{\the\csname c@#1\endcsname}}
如果每个人都只通过编写代码来使用高级命令,那么这将是一个很好的解决方案
\fnsymbol{footnote}
。不幸的是,许多类(包括标准类)和包直接使用内部形式,因此\@fnsymbol\c@footnote
更改的简单解决方案\fnsymbol
会破坏过去 20 年来一直有效的代码。因此,这里的实现
\@fnsymbol
再次使自己成为一个非健壮命令,而是使用一个新的健壮命令\TextOrMath
,它将负责排版数学或文本符号。为了做到这一点,我们面临 TeX 中一个古老的问题和无法解决的问题:对数学模式进行可靠的测试,而不会破坏字距调整。幸运的是,这个问题可以在使用 eTeX 时得到解决,因此如果您按照 LaTeX3 项目的建议使用它作为 LaTeX 格式的引擎,您将获得一个功能齐全的\TextOrMath
命令,而没有副作用。如果您使用常规 TeX 作为 LaTeX 格式的引擎,那么我们必须在两害相权取其轻:1) 破坏连字并阻止字距调整或 2) 面临在对齐单元格开头选择文本模式的风险,而对齐单元格应该是数学模式。我们决定 1) 按照 LaTeX 中常规健壮命令的习惯。