这是一个后续问题智能括号?
在上述问题中,括号很智能,它们会根据嵌套级别改变其形式。我想知道是否有可能让括号更智能一些。我希望看到这样的输出
(一层)
[外层(内层)]
即外如果存在内部层级,则层级应更改为括号。为了便于理解,以下是来自Przemysław Scherwentl 的回答对于原始问题。
\documentclass{article}
\newcount\smcount
\def\smart#1{\ifcase\smcount(\or[\or\{\else TOO DEEP!\fi%
\advance\smcount by1 #1\ifcase\smcount\or)\or]\or\}\else TOO DEEP!\fi%
\advance\smcount by-1 }
\begin{document}
\smart{Ala \smart{ma \smart {kota}}}
\end{document}
这个实现了三个级别,并且括号的顺序是“错误的”。
我需要两个级别,如上所述,并且仅在数学模式下,但后者应该对一般实现有所作为。
答案1
自动化过度使用\left
是\right
错误的,但是......
\documentclass{article}
\newcount\smcount
\delimitershortfall-1sp
\def\smart#1{\left\ifodd\smcount[\else(\fi
\advance\smcount by1 #1\right\ifodd\smcount)\else]\fi}
\begin{document}
$\smart{aaa\smart{Ala \smart{ma \smart {kota}}}}$
\end{document}
或者在评论中澄清之后,也许你想要
\documentclass{article}
\delimitershortfall-1sp
\def\xsmart#1{\left(#1\right)}
\def\smarttest#1\smart#2#3\endsmarttest#4{%
\ifx\valign#2%
\left(\let\smart\xsmart#4\right)%
\else
\left[\let\smart\xsmart#4\right]%
\fi}
\def\smart#1{\smarttest#1\smart\valign\endsmarttest{#1}}%
\begin{document}
$\smart{aaa\smart{Ala \smart{ma \smart {kota}}}}$
$\smart{aaa}$
\end{document}
但这似乎仍然很奇怪:-)
答案2
您可以尝试以下操作:
\def\smart#1{\let\smartA=\empty
\setbox0=\hbox{\def\smart{\global\let\smartA=\relax}$#1$}%
\begingroup\def\smart##1{(##1)}\ifx\smartA\relax [#1]\else (#1)\fi\endgroup
}
\smart{abc\smart{d\smart{ef}g}h} % -> [abc(d(ef)g)h]
\smart{pq{\smart{ru}v}w} % -> [pq(ru)vw]
\smart{xyz} % -> (xyz)
\end
我没有解决超过两个级别。所有内部级别都有圆角(括号)。隐藏在组中的内部级别不会造成影响。
答案3
这个问题看起来很有趣,尤其是当任意数量的括号是预期结果。我尝试解决这个问题。可以使用任意数量的级别,并且可以声明每个级别的括号类型。
\brk{formula}
括号内的公式用(是“括号”的缩写)键入\brk
。公式中可以包含另一个公式\brk{...}
(嵌套任意层级)。例如:
\brk{a\brk{b\brk{c\brk{d}e}f}g\brk{h}i\brk{jk\brk{l}pq}r}
this means:
(a(b(c(d)e)f)g(h)i(jk(l)pq)r)
我的解决方案实现了两遍算法。\brk
第一遍处理最外层的整个参数,以确定嵌套括号的数量。第一遍完成后,每个括号都知道其子公式中的嵌套层数。对于我们的例子来说,这意味着:
宏的第二遍\brk
打印所需的括号。您必须通过宏声明这些括号的形状\brkDecl
:
\brkDecl <left0><right0><left1><right1><left2><right2>etc<left-n><right-n><dot><dot>
例子:
\brkDecl ()[]..
\brk{a\brk{b\brk{c\brk{d}e}f}g\brk{h}i\brk{jk\brk{l}pq}r}
\brkDecl ()[]\{\}\langle\rangle..
$\brk{a\brk{b\brk{c\brk{d}e}f}g\brk{h}i\brk{jk\brk{l}pq}r}$
\brkDecl (){\bigl(}{\bigr)}{\Bigl(}{\Bigr)}{\biggl(}{\biggr)}{\Biggl(}{\Biggr)}..
$\brk{a\brk{b\brk{c\brk{d}e}f}g\brk{h}i\brk{jk\brk{l}pq}r}$
您可以使用\ensurebalanced
宏这里和数学活动字符设置,以便用户可以简单地输入圆括号:
\def\brkX#1){\ensurebalanced()\brk{#1}}
{\catcode`\(=13 \global\let(=\brkX}
\def\brkActive{\mathcode`\(="8000 }
\brkDecl {\mathopen{\mathchar`(}}{)}{\bigl(}{\bigr)}{\Bigl(}{\Bigr)}{\biggl(}{\biggr)}{\Biggl(}{\Biggr)}..
\brkActive
$(a(b(c(d)e)f)g(h)i(jk(l)pq)r)$
请注意,这里<left0>
的声明\brkDecl
有些复杂,因为该字符(
在数学中被声明为活动字符。
该宏的实现\brk
如下:
\newcount\brkN \newcount\brkL
\def\brk#1{\def\brkS{0}\global\brkN=0 \let\brk=\brkA
\ifmmode \setbox0=\hbox{$#1$}\else \setbox0=\hbox{#1}\fi
\sxdef{brk.0}{\the\brkL}%
\global\brkN=0 \let\brk=\brkB
\brkE L0#1\brkE R0\let\brk=\brkC
}
\def\brkA#1{{\global\brkL=0 \global\advance\brkN by1
\def\brkS{0}\edef\brkM{\the\brkN}%
#1%
\sxdef{brk.\brkM}{\the\brkL}\global\advance\brkL by1}%
\ifnum\brkS>\brkL \global\brkL=\brkS\relax \else \edef\brkS{\the\brkL}\fi
}
\def\brkB{\global\advance\brkN by1 \expandafter\brkD\expandafter{\the\brkN}}
\let\brkC=\brk
\def\brkD#1#2{\brkE L{#1}#2\brkE R{#1}}
\def\brkE #1#2{\csname brk.#1.%
\ifnum\csname brk.#2\endcsname>\brkF\space \brkF \else \csname brk.#2\endcsname \fi
\endcsname
}
\def\brkDecl{\brkL=0 \brkG}
\def\brkG#1#2{\ifx#1.\advance\brkL by-1 \edef\brkF{\the\brkL}\else
\sdef{brk.L.\the\brkL}{#1}\sdef{brk.R.\the\brkL}{#2}%
\advance\brkL by1 \expandafter\brkG \fi
}
\def\sdef#1{\expandafter\def\csname#1\endcsname}
\def\sxdef#1{\global\expandafter\edef\csname#1\endcsname}
实施说明。
在第一遍中,\brk
参数中的宏被处理为
\brkA
。在第二遍中,它们被处理为。 的\brkB
正常含义是由 返回。\brk
\brkC
第一遍在 box0 内处理,即材料已完全处理但未打印。左括号从左到右从零开始编号(通过\brkN
计数器),级别数由\brkL
计数器计算。宏\csname brk.\the\brkN\endcsname
包括第一遍完成后每个左括号的子括号数。
这些宏\csname brk.L.\the\brkL\endcsname
包括级别的左括号类型\bkrL
。右括号存储在中
\csname brk.R.\the\brkL\endcsname
。这些宏由初始化\brkDecl
。