灵活的括号命令

灵活的括号命令

我想创建一个不使用 xparse 包的智能括号命令。

\p(1)   prints  (1)
\p[1]           [1]
\p{1}           {1}
\p(1|2)         (1|2)

我试过这个代码,但它不适用于括号。
另外,我不知道该怎么做(1|2)

\documentclass{article}

\makeatletter

\def\p
{
    \@ifnextchar(
        {\@parenthesis}
        {
            \ifx\@let@token[
                \expandafter\@bracket
            \else
                \expandafter\@brace
            \fi
        }
}

\def\@parenthesis(#1){\left( #1 \right)}
\def\@bracket[#1]{\left[ #1 \right]}
\def\@brace#1{\left{ #1 \right}}

\makeatother


\begin{document}

$\p(1)$ 
$\p[1]$ 
$\p{1}$ 
$\p(1|2)$    
\end{document}

我这样做的动机是为了获得更具表现力的语法。

答案1

这似乎有效:

更新:请参见下面的不同实现,它执行\left和操作并且与 中间\right 兼容。\middle

第二次更新mathcodes没有 catcodes 的所有限制。基于此,mathcodes我提出了一种比前一种方法更强大的方法:它允许(看似)非常复杂的嵌套。我梦想有 textcodes……重点是mathcodes不要冻结。这非常有用。

编辑:经过一些额外的工作后,正确恢复了mathcodes。我保证不会再编辑……

\documentclass{article}

\makeatletter

\def\p{\afterassignment\p@aux\let\next=}

\def\p@aux{\ifx\next\bgroup\lbrace\bgroup\aftergroup\rbrace\else
               \expandafter\next\fi}

\makeatother


\begin{document}

$\p(1)$ 
$\p[1]$ 
$\p{1}$ 
$\p(1|2)$    
\end{document}

括号

使用自动\left 和\right。我还应该做中间的事情吗?

更新:在结束行添加了缺失的 ̀%并思考了\middle导致我出现一些问题的 e-TeX 问题......

(请参阅下文了解最后的方法:\middle 这是一个相当大的挑战)

\documentclass{article}
\usepackage{amsmath}

\makeatletter

\def\p{\afterassignment\p@aux\let\next=}

\def\p@aux{\ifx\next\bgroup
             \left\lbrace\bgroup\aftergroup\right\aftergroup\rbrace
           \else
             \ifx\next(%
                   \left(\bgroup\catcode`\)=\tw@
                   \aftergroup\right\aftergroup)%
             \else
             \ifx\next[%
                   \left[\bgroup\catcode`\]=\tw@
                   \aftergroup\right\aftergroup]%
             \else\next
             \fi\fi
           \fi}

\makeatother


\begin{document}\thispagestyle{empty}

$\p(1) \p(\dfrac{1}{2})$

$\p[1] \p[\dfrac{1}{2}]$

$\p{1} \p{\dfrac{1}{2}}$

$\p(1|2) \p(\dfrac{1}{2}|3)$
\end{document}

第二


eTeX \middle完全改变方法 以满足要求。请注意,以下内容适用于后面的任意分隔符\middle

\documentclass{article}
\usepackage{amsmath} % for \dfrac 

\makeatletter

\def\p{\afterassignment\p@aux\let\next=}


\newtoks\p@toks

\def\@ybrace{\expandafter\left\expandafter\lbrace\the\p@toks\right\rbrace}
%% \def\@yparen{\expandafter\left\expandafter(\the\p@toks\right)\endgroup}
\def\@yparen{\expandafter\endgroup\expandafter\left\expandafter(\the\p@toks\right)}
%% \def\@ybrack{\expandafter\left\expandafter[\the\p@toks\right]\endgroup}
\def\@ybrack{\expandafter\endgroup\expandafter\left\expandafter[\the\p@toks\right]}

\def\p@aux{\ifx\next\bgroup
                      \def\p@tmp{\p@toks=\bgroup}%
                      \afterassignment\@ybrace
             \else
             \ifx\next(%
                   \begingroup\catcode`\)=\tw@ 
                   \def\p@tmp{\p@toks=\bgroup}%
                      \afterassignment\@yparen
             \else
             \ifx\next[%
                   \begingroup\catcode`\]=\tw@
                   \def\p@tmp{\p@toks=\bgroup}%
                      \afterassignment\@ybrack
             \else
                 \let\p@tmp\next
           \fi\fi\fi
           \p@tmp}

\makeatother


\begin{document}\thispagestyle{empty}

$\p(1) \p(\dfrac{1}{2}) \p(\dfrac{1}{2}\middle|3)$

$\p[1] \p[\dfrac{1}{2}] \p[\dfrac{1}{2}\middle|3]$

$\p{1} \p{1\middle|2} \p{\dfrac{1}{2}\middle|3}$

\end{document}

第三种方法

$\p{1} \p{1\middle>2} \p{\dfrac{1}{2}\middle<3}$

中间有 <


现在是基于 的方法mathcodes。也许我必须重新考虑括号的情况,这里的括号处理方式与之前的方法相同。我只对它们使用标记列表。标记列表是 ,因此\middle尝试某种技术时会遇到困难\aftergroup

也正因为\middle如此,我必须明确恢复mathcodes),而]不是将其信任给源于使用\left和 的组\right。问题是\middle关闭此组,然后打开第二个组。

编辑: 和 有问题$ \p( ( A ) )$,我已编辑宏,以便mathcodes正确重置。我无法使用\left和创建的组,\right因为\middle

\documentclass{article}

\makeatletter

\def\p{\afterassignment\p@aux\let\next=}

\newtoks\p@toks

\def\@ybrace{\expandafter\left\expandafter\lbrace\the\p@toks\right\rbrace}


% To get correct nesting I added the \restore@paren and \restore@brack macros

\def\p@aux{\ifx\next\bgroup
                      \def\p@tmp{\p@toks=\bgroup}%
                      \afterassignment\@ybrace
             \else
             \ifx\next(%
                      \ifnum\mathcode`)="8000 
                           \let\restore@paren\relax
                           \def\p@tmp{\left(}%
                     \else
                       \edef\restore@paren{\mathcode`)=\the\mathcode`)\relax}%
                       \begingroup
                         \lccode`\~=`)
                         \lowercase{%
                       \endgroup
                       \def~{\right)\restore@paren}}%
                       \def\p@tmp{\mathcode`)="8000 \left(}%
                     \fi
              \else
             \ifx\next[%
                     \ifnum\mathcode`]="8000 
                           \let\restore@brack\relax
                           \def\p@tmp{\left[}%
                     \else
                       \edef\restore@brack{\mathcode`]=\the\mathcode`]\relax}%
                       \begingroup
                         \lccode`\~=`]
                         \lowercase{%
                       \endgroup
                       \def~{\right]\restore@brack}}%
                       \def\p@tmp{\mathcode`]="8000 \left[}%
                     \fi
             \else
                 \let\p@tmp\next
           \fi\fi\fi
           \p@tmp}


\makeatother
\begin{document}\thispagestyle{empty}

\delimitershortfall=-1pt

\[\p(\frac{1}{2}\p{\p{3^T:4}}\p[\p(A_B^C)]\p(\big]\middle>\big[)\middle\Vert\p[\frac{1}{2}])\]

\[\p{\p(\p[A_B^C\middle< \p{X^Y}])\middle\vert\p[\p(A_B^C\middle> \p(X^Y))]} \]
\end{document}

嵌套

\[\the\mathcode`) \ \the\mathcode`] \p( \p{ \p[ \p( \p{ \p[ A ]})]})
  \the\mathcode`)\ \the\mathcode`] \]

嵌套2

答案2

这将实现你想要的效果:

\documentclass{article}
\usepackage{amsmath} % just for \dfrac in the example

\makeatletter
\def\p{\@ifnextchar(\neb@p@parens{\@ifnextchar[\neb@p@bracket\neb@p@brace}}
\def\neb@p@brace#1{\left\{#1\right\}}
\def\neb@p@bracket[#1]{\left[#1\right]}
\def\neb@p@parens(#1){\neb@p@checkbar#1||\@nil}

\def\neb@p@checkbar#1|#2|#3\@nil{%
  \if\relax\detokenize{#2}\relax
    \left(#1\right)
  \else
    \left(#1\;\middle|\;#2\right)
  \fi}
\makeatother

\begin{document}
$\p(1) \p(\dfrac{1}{2})$

$\p[1] \p[\dfrac{1}{2}]$

$\p{1} \p{\dfrac{1}{2}}$

$\p(1|2) \p(\dfrac{1}{2}|3)$
\end{document}

在此处输入图片描述

话虽如此,我不建议使用这些容易出错的“灵活”命令:不同的构造应该用不同的命令来实现。

相关内容