A dynamic bracketing macro in LaTeX



I was cleaning up my LaTeX header and re-coded some macros to suit my needs better. I have always had a macro called \of which takes one parameter. It used to be the very simple macro
\newcommand{\of}[1]{\left(#1\right)}
However, I sometimes want to specify the size of the brackets explicitly, so I wanted to add an optional argument to this macro such that \of[big]{\sum} will expand to \bigl(\sum\bigr). Sometimes I even want it not to do any resizing of the brackets at all. The correct way to do this is is \csname and \endcsname which allows you to delay expansion of a macro. Inside a macro definition, the command
\newcommand{\ar}[1]{\csname#1arrow\endcsname}
will be such that \ar{right} is first made into \rightarrow and then expanded. We will use that to make \bigl and \bigr out of the argument big, for instance. So the following is the working implementation of \of:
\usepackage{ifthen}
% ...
\makeatletter
 \def\ifempty#1{\def\@x{#1}\ifx\@x\@empty}
\makeatother
% ...
\newcommand{\of}[2][auto]{    % optional argument is 'auto' by default
\ifempty{#1}(#2)\else         % If optional argument is empty, do not resize
\ifthenelse{\equal{#1}{auto}} % If optional argument is set to auto, 
	{\left(#2\right)}   % then we use \left and \right. Otherwise:
	{\csname#1l\endcsname(#2\csname#1r\endcsname)} %
\fi }
Now you can write the code
\of[bigg]{ x \cdot \of[big]{y + z} }
and it will render as \[ \biggl( x \cdot \bigl( y+z \bigr) \biggr). \] if you do not want it to do any resizing at all, you have to pass an empty parameter as the optional argument, for example \of[]{\frac12}. This is pretty nice, but I decided to crank it up a notch. We can just as well implement the macro
\newcommand{\enclspacing}{\,}
\newcommand{\enclose}[4][auto]{%
\ifempty{#1}#2\enclspacing#3\enclspacing#4\else%
\ifthenelse{\equal{#1}{auto}}%
  {\left#2\enclspacing#3\enclspacing\right#4}%
  {\csname#1l\endcsname#2\enclspacing#3\enclspacing\csname#1r\endcsname#4}\fi%
}
and now define several macros of this kind:
\newcommand{of}[2][auto]{\enclose[#1]{(}{#2}{)}}
\newcommand{\abs}[2][auto]{\enclose[#1]{|}{#2}{|}}
\newcommand{\gen}[2][auto]{\enclose[#1]{\langle}{#2}{\rangle}}
\newcommand{\set}[2][auto]{\enclose[#1]{\{}{#2}{\}}}
But that's not nearly enough for me. Lots of times, I want a vertical bar in the middle of such an expression to resize with the outer brackets, for instance in set builder notation: \[ \left\{\,\sum_{i=1}^n a_i X^i\,\middle\vert\,a_i\in\Bbbk\,\right\} \] The source code for this is, of course
\left\{\, \sum_{i=1}^n a_i X^i  \,\middle\vert\,  a_i\in\Bbbk  \,\right\}
So I would really like to account for the \middle as well and possibly add some spacing everywhere. Here we go:
\newcommand{\enclmiddlespacing}{\:}
\newcommand{\cenclose}[6][auto]{%
\ifempty{#5}\enclose[#1]{#2}{#3}{#6}\else %
\ifempty{#1} %
 #2\enclspacing%
 #3\enclmiddlespacing%
 #4\enclmiddlespacing %
 #5\enclspacing#6 %
\else%
\ifthenelse{\equal{#1}{auto}}%
{
 \left#2\enclspacing%
 #3\enclmiddlespacing %
 \middle#4\enclmiddlespacing %
 #5\enclspacing\right#6
}{
 \csname#1l\endcsname#2\enclspacing%
 #3\enclmiddlespacing %
 \csname#1l\endcsname#4\enclmiddlespacing %
 #5\enclspacing\csname#1r\endcsname#6 %
}\fi\fi}
One can now easily define macros such as
\newcommand{\cset}[3][auto]{\cenclose[#1]\{{#2}\lvert{#3}\}}
with which the $\LaTeX$ for displaying the above set becomes
\cset{\sum_{i=1}^n a_i X^i}{a_i\in\Bbbk}
I personally define many macros this way, for different kinds of bracketing.

Tags: - -

Leave a Reply

Your email address will not be published. Required fields are marked *