![期望的行为](https://linux22.com/image/396368/%E6%9C%9F%E6%9C%9B%E7%9A%84%E8%A1%8C%E4%B8%BA.png)
期望的行为
\{
和\}
应该变成\left\{
和\right\{
。
尝试 1
\edef\{{\left\{}
\edef\}{\right\}}
错误信息
TeX capacity exceeded, sorry [input stack size=5000].
\font@name ->
\OT1/cmr/m/n/10
l.16 \edef\{{\left\{
}
If you really absolutely need more capacity,
you can ask a wizard to enlarge me.
第二次尝试
\documentclass{standalone}
\edef\{{\left\string{}
\edef\}{\right\string}}
\begin{document}
$\{\}$
\end{document}
结果
错误信息
Missing delimiter (. inserted).
<to be read again>
{
l.7 $\{
\}$
I was expecting to see something like `(' or `\{' or
`\}' here. If you typed, e.g., `{' instead of `\{', you
should probably delete the `{' by typing `1' now, so that
braces don't get unbalanced. Otherwise just proceed.
Acceptable delimiters are characters whose \delcode is
nonnegative, or you can use `\delimiter <delimiter code>'.
! Missing delimiter (. inserted).
<to be read again>
}
l.7 $\{\}
$
I was expecting to see something like `(' or `\{' or
`\}' here. If you typed, e.g., `{' instead of `\{', you
should probably delete the `{' by typing `1' now, so that
braces don't get unbalanced. Otherwise just proceed.
Acceptable delimiters are characters whose \delcode is
nonnegative, or you can use `\delimiter <delimiter code>'.
第三次尝试
\documentclass{standalone}
\edef\{{\left\string\{}
\edef\}{\right\string\}}
\begin{document}
$\{\}$
\end{document}
输出
相关、有效的解决方案
\langle
这样做,\rangle
效果很好:
\edef\langle{\left\langle}
\edef\rangle{\right\rangle}
即使对(
和执行此操作也)
有点复杂,但有效:
\begingroup
\catcode`(\active
\xdef({\left\string(}
\catcode`)\active
\xdef){\right\string)}
\endgroup
\mathcode`(="8000
\mathcode`)="8000
答案1
答案2
这真是个坏主意。使用 \left 和 \right 是否有坏处?
然而,我们可以在中找到\{
和的定义,并看到\}
latex.ltx
\DeclareRobustCommand{\{}{\ifmmode\lbrace\else\textbraceleft\fi}
\DeclareRobustCommand{\}}{\ifmmode\rbrace\else\textbraceright\fi}
所以很简单:添加
\let\{\relax \let\}\relax
\DeclareRobustCommand{\{}{\ifmmode\left\lbrace\else\textbraceleft\fi}
\DeclareRobustCommand{\}}{\ifmmode\right\rbrace\else\textbraceright\fi}
到文档序言中。第一行是为了避免有关重新定义的警告。这仍然允许在文本模式下使用\{
和(当然,没有和,这在该上下文中没有意义)。\}
\left
\right
更好的方法是加载mathtools
并执行
\DeclarePairedDelimiter{\braces}{\{}{\}}
所以你可以
\braces{x} \braces[\big]{x} \braces[\Big]{x} \braces[\bigg]{x} \braces[\Bigg]{x}
用于手动选择尺寸
\braces*{x}
用于自动选择尺寸。
你的尝试
尝试 1
因为\edef\{{\left\{}
我们需要检查各种扩展步骤。第一级扩展\{
是
\x@protect\{\protect\{•
(项目符号代表控制序列名称中的空格)。下一个扩展步骤是
\ifx\protect\@typeset@protect\else\@x@protect\{\fi\protect\{•
在文件序言中,\protect
是与 相同\@typeset@protect
(两者都是\relax
),因此遵循真正的分支,不产生任何结果,因此最终得到
\protect\{•
即成为
\protect\ifmmode \lbrace \else \textbraceleft \fi
(因为\protect
不可扩展)。因为你不是在数学模式下,遵循错误分支,导致
\protect\textbraceleft
(应该有一个尾随的\fi
,但它最终会消失,因为\edef
完全展开)。它还没有完成,因为我们需要知道什么\textbraceleft
。我们得到
\protect\OMS-cmd \textbraceleft \OMS\textbraceleft
哦,好吧,这是什么?\OMS-cmd
是永远不应该出现在里面的东西\edef
,因为它要执行分配。
你完了。
第二次尝试
您的\edef\{{\left\string{}
定义\{
为\left{
(其中括号变为“可打印字符”)。这是非法的,因为{
可打印字符的 设置\delcode
为 -1,因此您会在 处收到“缺少分隔符”错误\{
。
第三次尝试
你\edef\{{\left\string\{}
会得到一个令人费解的输出。你实际上是\left
在应用类别代码为 12 的反斜杠,而这有正数\delcode
,即"26E30F
表示"6E
如果不需要调整大小,则使用数学系列 2 中的字符(符号字体确实在那里有一个反斜杠),否则"0F
使用数学系列 3 中的字符(再次得到一个反斜杠)。左括号告诉 TeX 使用数学代码 打印"007B
,因此插槽中的字符"7B
来自数学系列 0,这是普通文本字体,并在该插槽中包含短划线。
为什么\edef\langle{\left\langle}
有效?
因为\langle
的定义非常不同:它的定义是
\delimiter"426830A
(末尾有一个空格),所以它的\edef
作用与
\def\langle{\left\delimiter"426830A }
因为的扩展\langle
由不可扩展的标记组成。
答案3
导致问题的原因是 LaTeX 定义\{
为\ifmmode\lbrace \else\textbraceleft\fi
。如果您使用 LaTeX,那么您\edef
将转到分支\textbraceleft
。
但你可以定义:
\edef\{{\left\lbrace}
\edef\}{\right\rbrace}