8

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}
7

\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
}

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.