[Tex/LaTex] Applying \middle outside of a \left \right group

conditionalssymbols

Background:

I am using the solution from Creating a large "such that" symbol which checks that \currentgrouptype=16 in order to be able to determine if we are in the middle of a \left ... \right group, in which case we use \middle|, otherwise use |:

\newcommand*{\suchthat}{\;\ifnum\currentgrouptype=16 \middle\fi|\;}

In my case, the \left, \right pair are opened and closed before and after the content (#2) that uses \suchthat :

\newcommand{\@Brac}[3]{% #1,#3 = left/right bracket type
        \mathopen{\left#1\vphantom{#2}\@BracKern\right.}% left bracket
        #2%  content
        \mathclose{\left.\@BracKern\vphantom{#2}\right#3}% right bracket
}
\newcommand{\bracr}[1]{\@Brac{(}{#1}{)}}%   round brackets
\newcommand{\bracc}[1]{\@Brac{\{}{#1}{\}}}% curly brackets

This reason for this is that the \@Brac macro will work across line breaks as illustrated in the MWE.

Question:

How do modify the \suchthat macro to be able to apply the \middle when within the \@Brac macro?

Failed Solutions:

  1. I attempted to set \currentgrouptype=16 but was not able to get this to compile:

    You can't use `\currentgrouptype' in math mode.

    This probably is not a good idea anyway.

  2. I attempted to define my own \newtoggle and use that as a switch:

    \newcommand*{\suchthat}{\;%
      \ifnum\currentgrouptype=16\middle|\else%
         \iftoggle{WithinBracMacro}{\middle|}{|}% 
      \fi%
      \;}%
    

    but that results in

    Error: Missing } inserted.

    Two versions of this are defined below in \suchthatOld and \suchthatNew, and you can see the problem if you uncomment out the the lines within the first parameter to \iftoggle{WithinBracMacro}{}{}.

I'd highly prefer the toggle approach.

References:

Current Results:

Only the "problem" line should change:

enter image description here

Code:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{showframe}

% https://tex.stackexchange.com/questions/54023/how-to-compute-exact-width-added-by-left-right
\makeatletter
\newcommand{\@BracKern}{\kern-\nulldelimiterspace}%
\newtoggle{WithinBracMacro}%
\togglefalse{WithinBracMacro}% initialize
\newcommand{\@Brac}[3]{% #1,#3 = left/right bracket type
        \mathopen{\left#1\vphantom{#2}\@BracKern\right.}% left bracket
        \toggletrue{WithinBracMacro}%
        #2%  content
        \togglefalse{WithinBracMacro}%
        \mathclose{\left.\@BracKern\vphantom{#2}\right#3}% right bracket
}
\newcommand{\bracr}[1]{\@Brac{(}{#1}{)}}%   round brackets
\newcommand{\bracc}[1]{\@Brac{\{}{#1}{\}}}% curly brackets

%% https://tex.stackexchange.com/questions/45713/creating-a-large-such-that-symbol
\newcommand*{\suchthatDelimin}{}%
\newcommand*{\suchthatNew}{%
    \;%
    \ifnum\currentgrouptype=16\relax% we are in a \left...\right
        \renewcommand{\suchthatDelimin}{\middle|}%
    \else%
        \iftoggle{WithinBracMacro}{% we are in a \@Brac macro
            \renewcommand\suchthatDelimin{|}%  This works fine!
            %     (change to some other char to see)
            %
            % If uncomment any of following: "Error: Missing } inserted."
            %\def\suchthatDelimin{\middle|}% 
            %\global\def\suchthatDelimin{\middle|}%
            %\renewcommand{\suchthatDelimin}{\middle|}%
        }{% can't use \middle
            \renewcommand{\suchthatDelimin}{|}%
        }% 
    \fi%
    \suchthatDelimin%
    \;%
}%

\newcommand*{\suchthatOld}{%
    \;%
    \ifnum\currentgrouptype=16\relax% we are in a \left...\right
        \middle|%
    \else%
        \iftoggle{WithinBracMacro}{% we are in a \@Brac macro
            |% This works (change to some other char to see)
            % If uncomment followin: "Error: Missing } inserted."
            %\middle|%
        }{% can't use \middle
            |%
        }% 
    \fi%
    \;%
}%
\makeatother


\begin{document}
\noindent
Comparrison of using \verb|\suchthat| in 
\verb|\left\{ ...\right\}| and \verb|\bracc{}|:
\begin{align*}
    \left\{x \suchthatOld x \le \frac{1}{2} \right\}\quad&
    \left\{x \suchthatNew x \le \frac{1}{2} \right\}\quad
\text{This is fine}\\
    \bracc{x \suchthatOld x \le \frac{1}{2} }\quad&
    \bracc{x \suchthatNew x \le \frac{1}{2} }\quad
\text{Problem on this line only}
\end{align*}
%
\noindent
Ensure that we can compile \verb|\suchthat| without 
\verb|\left\{ ...\right\}|.
This should not resize the brackets:
\begin{align*}
    \{x \suchthatOld x \le \frac{1}{2} \}\quad
    \{x \suchthatNew x \le \frac{1}{2} \}
\end{align*}
%
As we can see in the following, the \verb|\bracr| wraps around lines: 
$\bracr{x^{-1} + x^{-2} + x^{-3} +x^{-4} + x^{-5} + \cdots }$.
\end{document}

Best Answer

\left, \middle and \right actually build two math lists (in each of which \currentgrouptype=16). There can't be a \middle without a corresponding \left and \right, so when you do \left(\right. a later \middle is disallowed. So we have to remember the contents and typeset a \left.\middle|\right. list.

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\def\@BracContents{} % default
\newcommand{\@BracKern}{\kern-\nulldelimiterspace}
\newcommand{\@Brac}[3]{% #1,#3 = left/right bracket type
  \begingroup\def\@BracContents{#2}
  \mathopen{\left#1\vphantom{#2}\@BracKern\right.}% left bracket
  #2%  content
  \mathclose{\left.\@BracKern\vphantom{#2}\right#3}% right bracket
  \endgroup
}
\newcommand{\suchthat}{\nonscript\;{ % open a group
  \let\suchthat\@empty % neutralize \suchthat inside \@Braccontents
  \left.\@BracKern % fake \left
  \vphantom{\@BracContents} % set size
  \middle| % bar
  \right.\@BracKern % fake \right
  }\nonscript\; % end group
}
\newcommand{\bracr}[1]{\@Brac{(}{#1}{)}}%   round brackets
\newcommand{\bracc}[1]{\@Brac{\{}{#1}{\}}}% curly brackets

\makeatother

\begin{document}
\begin{gather*}
\left\{x\;\middle|\;x=\frac{1}{2}\right\}\\
\bracc{x\suchthat x=\frac{1}{2}}
\end{gather*}
\end{document}

If you plan to use \suchthat also in a normal \left and \right context, you can do

\newcommand{\suchthat}{%
  \nonscript\;
  \ifnum\currentgrouptype=16
    \middle|
  \else
    \@suchthat
  \fi
  \nonscript\;}

\newcommand{\@suchthat}{%
  { % open a group
  \let\suchthat\@empty % neutralize \suchthat inside \@Braccontents
  \left.\@BracKern % fake \left
  \vphantom{\@BracContents} % set size
  \middle| % bar
  \right.\@BracKern % fake \right
  } % end group
}