分隔参数并在其内部使用宏

分隔参数并在其内部使用宏

我想在不使用、等的情况下调整分隔符大小,\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
}

相关内容