4

I am looking for a way to have auto-resizing parenthesis on math mode. In a formula like (a * (b + c)), I'd like the external parenthesis to be a little bigger.

Ideally, this would be done without alteration to the math syntax. That is, the above would be produced by $(a * (b+c))$. But if that is not easily achievable, I'd be ok with using some special syntax.

I've seen mention of nath, a package that seems to do this auto-formatting. As far as I can tell, that package is really old and hard to work with. I've tested it, and it produces dozens of errors in my document, even when its \usepackage is called last of all packages.

  • 2
    So you don't want to do by hand via \bigl( \bigr)? – Sigur Jan 26 '16 at 19:12
  • preferably not. Ideally, I'd just write the expression itself. If not possible, I'd prefer to use some small - and size independent - command – josinalvo Jan 26 '16 at 19:20
  • See the "Supplement" part of my answer at tex.stackexchange.com/questions/267171/…. Perhaps something like that might be helpful. – Steven B. Segletes Jan 26 '16 at 19:38
  • 1
    the standard tex syntax for auto-sizing parens is \left(...\right) but usually it is best to choose the size as in Sigur's comment, without the extra left-right markup you can not reliably match brackets, consider a half open interval (1,2] and even with it the automatically determined size is often not ideal. Any package that tries to do this will have to parse the entire expression to match brackets so liable to be incompatible with other code. – David Carlisle Jan 26 '16 at 20:07
  • 1
    I'm afraid you're starting from the wrong premise that in $(a+(b+c))$ the outer parentheses should be bigger. In general this is not true and normal size is good; for more complex formulas or special emphasis one can choose to have outer parentheses bigger, but it's a case based decision. – egreg Jan 26 '16 at 23:43
6

No Warranty nor Liability for any purpose.

\documentclass{article}
% \usepackage{amsmath} % for testing
\newcommand*\autoop{\left(}
\newcommand*\autocp{\right)}
\newcommand*\autoob{\left[}
\newcommand*\autocb{\right]}
\AtBeginDocument {%
   \mathcode`( 32768
   \mathcode`) 32768
   \mathcode`[ 32768
   \mathcode`] 32768
   \begingroup
       \lccode`\~`(
       \lowercase{%
   \endgroup
       \let~\autoop
   }\begingroup
       \lccode`\~`)
       \lowercase{%
   \endgroup
       \let~\autocp
   }\begingroup
       \lccode`\~`[
       \lowercase{%
   \endgroup
       \let~\autoob
   }\begingroup
       \lccode`\~`]
       \lowercase{%
   \endgroup
       \let~\autocb
   }}

\delimiterfactor 1001

\makeatletter
% for amsmath "compatibility" (not sophisticated)
% \usepackage{amsmath}
\AtBeginDocument {%
          \def\resetMathstrut@{%
           \setbox\z@\hbox{\the\textfont\symoperators\char40}%
           \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@}%
}%
\makeatother

\begin{document}

\[ [X+(u*[a  * (b+c)])]*Y \]

\end{document}

produces (external frame added):

Blockquote

updated (Nov. 2018) for curly braces

as requested per comment:

\documentclass{article}
\newcommand*\autoop{\left(}
\newcommand*\autocp{\right)}
\newcommand*\autoob{\left[}
\newcommand*\autocb{\right]}
\DeclareRobustCommand*\{{\ifmmode \left\lbrace \else \textbraceleft \fi }
\DeclareRobustCommand*\}{\ifmmode \right\rbrace \else \textbraceright \fi }
\AtBeginDocument {%
   \mathcode`( 32768
   \mathcode`) 32768
   \mathcode`[ 32768
   \mathcode`] 32768
   \begingroup
       \lccode`\~`(
       \lowercase{%
   \endgroup
       \let~\autoop
   }\begingroup
       \lccode`\~`)
       \lowercase{%
   \endgroup
       \let~\autocp
   }\begingroup
       \lccode`\~`[
       \lowercase{%
   \endgroup
       \let~\autoob
   }\begingroup
       \lccode`\~`]
       \lowercase{%
   \endgroup
       \let~\autocb
   }}

\delimiterfactor 1001

\makeatletter
% for amsmath "compatibility" (not sophisticated)
% \usepackage{amsmath}
\AtBeginDocument {%
          \def\resetMathstrut@{%
           \setbox\z@\hbox{\the\textfont\symoperators\char40}%
           \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@}%
}%
\makeatother

\begin{document}

\[ \{[X+(\{u*[a  * (\{b+c\})]\})]\}*Y \]

\end{document}

enter image description here

second request for \| but I think it would be better to use mathtools declarations and input syntax for this.

Here, no nesting of \| and they must be used in pairs.

\documentclass{article}
\makeatletter
% for amsmath "compatibility" (not sophisticated)
\usepackage{amsmath}
\AtBeginDocument {%
          \def\resetMathstrut@{%
           \setbox\z@\hbox{\the\textfont\symoperators\char40}%
           \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@}%
}%
\makeatother
\newcommand*\autoop{\left(}
\newcommand*\autocp{\right)}
\newcommand*\autoob{\left[}
\newcommand*\autocb{\right]}
\DeclareRobustCommand*\{{\ifmmode \left\lbrace \else \textbraceleft \fi }
\DeclareRobustCommand*\}{\ifmmode \right\rbrace \else \textbraceright \fi }

\AtBeginDocument {%
   \let\originalbardelimiter\|
   \def\myleftbar{\global\let\|\myrightbar\left\originalbardelimiter}%
   \def\myrightbar{\global\let\|\myleftbar\right\originalbardelimiter}%
   \let\|\myleftbar
   \mathcode`( 32768
   \mathcode`) 32768
   \mathcode`[ 32768
   \mathcode`] 32768
   \begingroup
       \lccode`\~`(
       \lowercase{%
   \endgroup
       \let~\autoop
   }\begingroup
       \lccode`\~`)
       \lowercase{%
   \endgroup
       \let~\autocp
   }\begingroup
       \lccode`\~`[
       \lowercase{%
   \endgroup
       \let~\autoob
   }\begingroup
       \lccode`\~`]
       \lowercase{%
   \endgroup
       \let~\autocb
   }}

\delimiterfactor 1001


\begin{document}

\[ \{[X+(\{\|u\|*\| [ a * (\{b+c\})] \|\} )] \}*\|Y\| \]

\end{document}

enter image description here

Finally, (but this is becoming hacky), a trick to allow nesting \| one-level deep. Might be enough for use case in Banach space theory (I hear this is some 20th century old-fashioned math, that long time ago, so that might be enough for elementary human thinking pre-dating AI)(*)

(*) should I explain I don't believe anything about what the highly paid software industry is throwing at us about what AI will be soon?

\documentclass{article}
\makeatletter
% for amsmath "compatibility" (not sophisticated)
\usepackage{amsmath}
\AtBeginDocument {%
          \def\resetMathstrut@{%
           \setbox\z@\hbox{\the\textfont\symoperators\char40}%
           \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@}%
}%
\makeatother
\newcommand*\autoop{\left(}
\newcommand*\autocp{\right)}
\newcommand*\autoob{\left[}
\newcommand*\autocb{\right]}
\DeclareRobustCommand*\{{\ifmmode \left\lbrace \else \textbraceleft \fi }
\DeclareRobustCommand*\}{\ifmmode \right\rbrace \else \textbraceright \fi }

\newif\ifinsidebracedgroup
\AtBeginDocument {%
   \let\originalbardelimiter\|
   \def\myleftbar{\ifinsidebracedgroup
                        \right\originalbardelimiter
                        \global\insidebracedgroupfalse
                  \else
                        \left\originalbardelimiter
                  \fi
                  \global\let\|\myrightbar}%
   \def\myrightbar{\ifnum\currentgrouptype=9
                        \left\originalbardelimiter
                        \global\insidebracedgrouptrue
                  \else
                        \right\originalbardelimiter
                  \fi
                 \global\let\|\myleftbar}%
   \let\|\myleftbar
   \mathcode`( 32768
   \mathcode`) 32768
   \mathcode`[ 32768
   \mathcode`] 32768
   \begingroup
       \lccode`\~`(
       \lowercase{%
   \endgroup
       \let~\autoop
   }\begingroup
       \lccode`\~`)
       \lowercase{%
   \endgroup
       \let~\autocp
   }\begingroup
       \lccode`\~`[
       \lowercase{%
   \endgroup
       \let~\autoob
   }\begingroup
       \lccode`\~`]
       \lowercase{%
   \endgroup
       \let~\autocb
   }}

\delimiterfactor 1001


\begin{document}

\[ \{[X+(\{\|u\|*\| [ a * (\{{\|b+c\|}\})] \|\} )] \}*\|Y\| \]

\[ \| (X - {\|X\|} e)\|^2 + \| (X + {\|X\|} e)\|^2 = 4\|(X)\|^2 \]

\end{document}

enter image description here

  • seems to be working fine for me! – josinalvo Jun 29 '16 at 22:38
  • How would it be possible to do the same for the \{ and \} brackets? This code does not work in this case. – Carucel Nov 8 '18 at 12:40
  • Wow, this is amazing, your solution looks much easier. I have no idea how difficult it would be,... but would it be possible to do the same for \|? Normally a \| would become \left\|, and after this opening \| the next \| would become \right\|. (nested \| often don't make sense anyway in Banach space theory). – Carucel Nov 8 '18 at 13:40
  • @Carucel: \| x - \|x\| e\|^2 + \| x + \|x\| e\|^2 = 4\|x\|^2 might be encountered in Banach spaces... – user4686 Nov 8 '18 at 14:03
  • 1
    @Carucel: global is need for other reasons, I added a still more hacky way, but this is becoming unreasonable.. – user4686 Nov 8 '18 at 15:06
0

This is too long for a comment. All credit goes to jfbu.

I edited jfbu's solution to

  • allow for an arbitrary depth of nested \|...\| (provided a different kind of bracket is 'in between'), by using a stack.
  • also auto-size the |...|

example

\documentclass{article}
\usepackage{ifthen}
% https://tex.stackexchange.com/questions/45946/stack-datastructure-using-latex
\makeatletter
\newcommand\newstack[1]{\let#1\@empty}
\newcommand{\addQelement}[2]{\gdef\element{#2}\pushQelement{#1}}
\newcommand{\pushQelement}[1]{\xdef#1{\element+#1}}
\long\def\popQ#1+#2\@nil#3{\gdef\poppedQelement{#1}\gdef#3{#2}}
\long\def\peekQ#1+#2\@nil#3{\gdef\poppedQelement{#1}}
\newcommand\popQelement[1]{\ifx #1\@empty  Error\else\expandafter\popQ#1\@nil#1\fi}
\newcommand\peekQelement[1]{\ifx #1\@empty  Error\else\expandafter\peekQ#1\@nil#1\fi}
\makeatother

\makeatletter
% for amsmath "compatibility" (not sophisticated)
\usepackage{amsmath}
\AtBeginDocument {%
          \def\resetMathstrut@{%
           \setbox\z@\hbox{\the\textfont\symoperators\char40}%
           \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@}%
}%
\makeatother
\newcommand*\autooS{\peekQelement{\bracketstack}\ifthenelse{\equal{\poppedQelement}{S}}{\right\originalbardelimiterS\popQelement{\bracketstack}}{\left\originalbardelimiterS\addQelement{\bracketstack}{S}}}
\newcommand*\autoop{\left(\addQelement{\bracketstack}{p}}
\newcommand*\autocp{\right)\popQelement{\bracketstack}}
\newcommand*\autoob{\left[\addQelement{\bracketstack}{b}}
\newcommand*\autocb{\right]\popQelement{\bracketstack}}
\DeclareRobustCommand*\{{\ifmmode \left\lbrace\addQelement{\bracketstack}{c} \else \textbraceleft \fi }
\DeclareRobustCommand*\}{\ifmmode \right\rbrace\popQelement{\bracketstack} \else \textbraceright \fi }

\newstack{\bracketstack}
\addQelement{\bracketstack}{START}
\newif\ifinsidebracedgroup
\AtBeginDocument {%
   \let\originalbardelimiter\|
   \let\originalbardelimiterS|
   \def\mysbar{\peekQelement{\bracketstack}\ifthenelse{\equal{\poppedQelement}{s}}{\right\originalbardelimiter\popQelement{\bracketstack}}{\left\originalbardelimiter\addQelement{\bracketstack}{s}}}%
   \let\|\mysbar
   \mathcode`( 32768
   \mathcode`) 32768
   \mathcode`[ 32768
   \mathcode`] 32768
   \mathcode`| 32768

   \begingroup
       \lccode`\~`(
       \lowercase{%
   \endgroup
       \let~\autoop
   }\begingroup
       \lccode`\~`)
       \lowercase{%
   \endgroup
       \let~\autocp
   }\begingroup
       \lccode`\~`[
       \lowercase{%
   \endgroup
       \let~\autoob
   }\begingroup
       \lccode`\~`]
       \lowercase{%
   \endgroup
       \let~\autocb
   }\begingroup
       \lccode`\~`|
       \lowercase{%
   \endgroup
       \let~\autooS
   }}

\delimiterfactor 1001
\begin{document}
\[ \{[X+(\{\|u\|*\| [ a * (\{{\|b+c\|}\})] \|\} )] \}*\|Y\| \]
\[ \| (X - {\|X\|} e)\|^2 + \| (X + {\|X\|} e)\|^2 = 4\|(X)\|^2 \]
\[ \|(\|\{\|[\|a\|]\|\}\|)\|+\|a\| \]
\[ \|(\|\{\|[\|a\|]\|\}\|)\|+\||\||a|+|a|\|+\|a\||\| \]
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.