\left 和 \right 与 \ifthenelse 的交互

\left 和 \right 与 \ifthenelse 的交互

目的

我想要一个将表达式括在括号中的函数\left\right其中括号的形状作为参数给出,例如

\brackets[(][]]{\frac{1}{2}} % should return \left(\frac{1}{2}\right]

我还希望该函数能够检测左括号的形状并提供匹配的右括号,除非另有说明。

背景

如果你想要了解详细信息,我实际上已经做了这样一个功能,它看起来像这样:

\usepackage{amsmath,xargs,xifthen}
\newcommandx{\brackets}[3][1=r, 2=default]{
    \ifthenelse{\equal{#1}{r}}{ % r for round bracket
        \ifthenelse{\equal{#2}{default}}{\left(#3\right)}{}
        \ifthenelse{\equal{#2}{r}}{\left(#3\right)}{}
        \ifthenelse{\equal{#2}{s}}{\left(#3\right]}{}
        \ifthenelse{\equal{#2}{c}}{\left(#3\right\}}{}
        \ifthenelse{\equal{#2}{v}}{\left(#3\right|}{}
        \ifthenelse{\equal{#2}{}}{\left(#3\right.}{}
    }{}
    \ifthenelse{\equal{#1}{s}}{ % s for square bracket
        \ifthenelse{\equal{#2}{default}}{\left[#3\right]}{}
        \ifthenelse{\equal{#2}{r}}{\left[#3\right)}{}
        \ifthenelse{\equal{#2}{s}}{\left[#3\right]}{}
        \ifthenelse{\equal{#2}{c}}{\left[#3\right\}}{}
        \ifthenelse{\equal{#2}{v}}{\left[#3\right|}{}
        \ifthenelse{\equal{#2}{}}{\left[#3\right.}{}
    }{}
    \ifthenelse{\equal{#1}{c}}{ % c for curly brace
        \ifthenelse{\equal{#2}{default}}{\left\{#3\right\}}{}
        \ifthenelse{\equal{#2}{r}}{\left\{#3\right)}{}
        \ifthenelse{\equal{#2}{s}}{\left\{#3\right]}{}
        \ifthenelse{\equal{#2}{c}}{\left\{#3\right\}}{}
        \ifthenelse{\equal{#2}{v}}{\left\{#3\right|}{}
        \ifthenelse{\equal{#2}{}}{\left\{#3\right.}{}
    }{}
    \ifthenelse{\equal{#1}{v}}{ % v for vertical bar
        \ifthenelse{\equal{#2}{default}}{\left|#3\right|}{}
        \ifthenelse{\equal{#2}{r}}{\left|#3\right)}{}
        \ifthenelse{\equal{#2}{s}}{\left|#3\right]}{}
        \ifthenelse{\equal{#2}{c}}{\left|#3\right\}}{}
        \ifthenelse{\equal{#2}{v}}{\left|#3\right|}{}
        \ifthenelse{\equal{#2}{}}{\left|#3\right.}{}
    }{}
    \ifthenelse{\equal{#1}{}}{
        \ifthenelse{\equal{#2}{default}}{#3}{}
        \ifthenelse{\equal{#2}{r}}{\left.#3\right)}{}
        \ifthenelse{\equal{#2}{s}}{\left.#3\right]}{}
        \ifthenelse{\equal{#2}{c}}{\left.#3\right\}}{}
        \ifthenelse{\equal{#2}{v}}{\left.#3\right|}{}
        \ifthenelse{\equal{#2}{}}{\left.#3\right.}{}
    }{}
}

我想这可以短得多。

问题

当我尝试编写一个辅助函数来检测左括号并提供匹配的右括号时,我似乎遇到了困难:

\newcommand{\partner}[1]{%
    \ifthenelse{\equal{#1}{.}}{.}{}%
    \ifthenelse{\equal{#1}{(}}{)}{}%
    \ifthenelse{\equal{#1}{)}}{(}{}%
    \ifthenelse{\equal{#1}{[}}{]}{}%
    \ifthenelse{\equal{#1}{]}}{[}{}%
    \ifthenelse{\equal{#1}{\{}}{\}}{}%
    \ifthenelse{\equal{#1}{\}}}{\{}{}%
}

\left/\right和之间的互动似乎有些尴尬ifthenelse

问题的最小示例

\documentclass{article}
\usepackage{amsmath,xifthen}

\newcommand{\funcA}{
    )
}
\newcommand{\funcB}{
    \ifthenelse{1=1}{)}{}
}

\begin{document}
    \begin{align*}
        \csname left\endcsname(\frac{1}{2}\csname right\endcsname\funcA \\ % works
        \csname left\endcsname(\frac{1}{2}\csname right\endcsname\funcB % doesn't work
    \end{align*}
\end{document}

答案1

只是为了学术兴趣,因为

  1. 您不应滥用\left\right原因如下;
  2. 打字(a+b)比 容易得多\brackets{a+b}

我使用了 所使用的分隔符的标准缩写amsmath

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\brackets}{O{p}O{#1}m}
 {
  \left
  \str_case:nnF { #1 } { {p}{(} {b}{[} {B}{\{} {v}{|} {V}{\|} {.}{.} } {.}
  #3
  \right
  \str_case:nnF { #2 } { {p}{)} {b}{]} {B}{\}} {v}{|} {V}{\|} {.}{.} } {.}
 }
\ExplSyntaxOff

\begin{document}

$\brackets{a+b}$
$\brackets[b]{a+b}$
$\brackets[b][p]{a+b}$
$\brackets[B]{a+b}$
$\brackets[v]{a+b}$
$\brackets[V]{a+b}$
$\brackets[?]{a+b}$

\end{document}

在此处输入图片描述

该命令有两个可选参数:第一个参数默认为p(括号,圆括号);第二个参数默认为“与第一个可选参数相同”。

如果其中一个或两个都不属于定义的缩写,则返回空分隔符(\brackets[.]{a+b}顺便说一下,您也可以使用)。

如果不匹配,还可能会添加警告/错误消息。

有什么问题\ifthenelse\left\right进行宏扩展以找到合适的分隔符(非负字符\delcode或原始的\delimiter),但\ifthenelse并不简单地返回真或假分支,因为它不能通过纯扩展和赋值来工作。

相反,\str_case:nnF通过纯粹的扩展来工作。

答案2

这可能不是您所要求的,但在这里,\brackets要么不带参数,给出默认()括号,要么在后面提供两个标记\brackets。此外,在两个括号标记之前和之后允许有可选空格。

正如 Don 在评论中指出的那样,可选参数的问题在于可选参数内的括号很棘手。

\documentclass{article}
\def\brackets{\futurelet\z\brakA}
\def\brakA{\ifx\bgroup\z\expandafter\brakC
  \else\expandafter\brakB\fi}
\def\brakB#1#2{\brakD{#1}{#2}}
\def\brakC{\brakD{(}{)}}
\newcommand\brakD[3]{\left#1#3\right#2}
\begin{document}\noindent
$\brackets {\frac{x}{2}}$\\
$\brackets [) {\frac{x}{2}}$\\
$\brackets \{\} {\frac{x}{2}}$\\
$\brackets (\} {\frac{x}{2}}$\\
$\brackets (. {\frac{x}{2}}$\\
\end{document}

在此处输入图片描述

补充

这是一个更复杂的版本,它还允许提供单个分隔符,其中隐含了第二个(缺失的)分隔符。与以前一样,两个括号标记之前和之后允许有可选空格,但在本例中,它们之间不允许有空格。

\documentclass{article}
\usepackage{etoolbox}
\csdef{brak[}{]}
\csdef{brak(}{)}
\csdef{brak\string\{}{\}}
\csdef{brak.}{.}
\def\brackets{\futurelet\z\brakA}
\def\brakA{\ifx\bgroup\z\expandafter\brakC
  \else\expandafter\brakB\fi}
\def\brakB#1{\def\zz{#1}\futurelet\zzz\brakD}
\def\brakC{\brakF()}
\makeatletter
\def\brakD{%
  \edef\zzzz{\csname brak\expandafter\string\zz\endcsname}%
  \ifx\bgroup\zzz\def\next{\zzzz}\else
  \ifx\@sptoken\zzz\def\next{\zzzz}\else
  \def\next{}\fi\fi\expandafter\brakE\next}
\makeatother
\def\brakE#1{\brakF\zz#1}
\newcommand\brakF[3]{\left#1#3\right#2}
\begin{document}\noindent
No Delimiter\\
$\brackets {\frac{x}{2}}$\\
One Delimiter:\\
$\brackets ( {\frac{x}{2}}$\\
$\brackets [ {\frac{x}{2}}$\\
$\brackets \{ {\frac{x}{2}}$\\
$\brackets . {\frac{x}{2}}$\\
Two Delimiters:\\
$\brackets [) {\frac{x}{2}}$\\
$\brackets \{) {\frac{x}{2}}$\\
$\brackets (\} {\frac{x}{2}}$\\
$\brackets (. {\frac{x}{2}}$\\
\end{document}

在此处输入图片描述

相关内容