我想在不使用、等的情况下调整分隔符大小,\delimiterfactor
并-shortfall
进行了以下操作:
\newdimen\bigdim \bigdim = 1.9743ex
\newdimen\Bigdim \Bigdim = 2.671ex
\newdimen\biggdim \biggdim = 3.3678ex
\newdimen\Biggdim \Biggdim = 4.0646ex
\def\fence#1#2#3{
\setbox0\hbox{$\displaystyle #3$}
\ifdim\ht0 < .9\bigdim #1\box0 #2\else
\ifdim\ht0 < .9\Bigdim \bigl#1\box0\bigr#2\else
\ifdim\ht0 < .9\biggdim \Bigl#1\box0\Bigr#2\else
\ifdim\ht0 < .9\Biggdim \biggl#1\box0\biggr#2\else
\ifdim\ht0 < .9\Biggdim \Biggl#1\box0\Biggr#2\else
\left#1\box0\right#2
\fi\fi\fi\fi\fi}
\def\args(#1){\fence(){#1}}
$$
\args(bar\args(baz))
$$
\bye
(在您按下评论按钮之前,我知道\mathsurround=0pt
那里应该有这样的内容,我只是想保持简单)但这会导致错误,提示的参数\args
有一个额外的}
。
我认为这与宏参数分隔符有关,因此进行了快速测试:
\def\foo(#1){(#1)}
\foo(bar\foo(baz))
\bye
但似乎运行得很好。现在我不知道还有什么问题。请注意,如果没有 内部\args
,\args
它就可以工作。
答案1
你有
\args(bar\args(baz))
所以外部的参数\args
是
bar\args(baz
因为它停在第一个)
你要
\args({bar\args(baz)})
在\foo
示例中,参数的解释方式相同,但它意外地起作用了。
因为外面\foo
'#1
的是
bar\foo(baz
这样就扩展为
(bar\foo(baz)
然后内部\foo
扩展为
(baz)
最后,对)
从未用作宏分隔符的进行排版。
答案2
您可以\ensurebalanced
通过以下方式将宏用于其他类型的括号:
\def\macro(#1){\ensurebalanced()\macroA{#1}}
\def\macroA#1{the "#1" is balanced here in () meaning}
\macro(abc(de(f))g(hi)) % prints: the "abc(de(f))g(hi)" is balanced here in () meaning.
或者你的例子:
\def\args(#1){\ensurebalanced(){\fence()}{#1}}
我的宏\ensurebalanced
如下所示:
\newcount\tmpnum
\def\ensurebalanced#1#2#3#4{%
\isbalanced#1#2{#4}\iftrue #3{#4}%
\else
\def\ensurebalancedA##1##2#2{%
\isbalanced#1#2{##1#2##2}\iftrue #3{##1#2##2}%
\else \def\next{\ensurebalancedA{##1#2##2}}\expandafter\next\fi
}%
\def\next{\ensurebalancedA{#4}}\expandafter\next\fi
}
\def\isbalanced#1#2#3\iftrue{\tmpnum=0 \isbalancedA#1#2#3\isbalanced}
\def\isbalancedA#1#2#3{%
\ifx\isbalanced#3\def\next{\csname ifnum\endcsname\tmpnum=0 }%
\else \def\next{\isbalancedA#1#2}%
\ifx#3#1\advance\tmpnum by1\fi
\ifx#3#2\advance\tmpnum by-1\fi
\fi \next
}