4

The following definition, from How to continue a piece of text so it is aligned with the last line of an inline multiline box?, allows splitting a math set-builder expression across two lines:

\newcommand\setst[2]{\{#1 : 
   \begin{array}[t]{@{}l@{}}#2 \}\end{array}}

I want:

  1. to change \{ and \} to \left\{ and \right\}, respectively. The following attempt generates an error of a missing `\right. ; and
  2. not to have symbols that would normally be tall in display math, such as integral signs, get squashed down by the array environment.

    What's wrong with my syntax?

    \newcommand\Setst2{\left{#1 : \right. % \begin{array}[t]{@{}l@{}}\left.#2 \right}\end{array}}

And how fix the issue of squashed normally-tall symbols retain their noraml display-math height? (See 2nd source file below.)

Example source (modified from above-cited link):

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}

\newcommand\setst[2]{\{#1 : 
  \begin{array}[t]{@{}l@{}}#2 \}\end{array}}

% my attempted mod
\newcommand\Setst[2]{\left\{#1 : \right. %
  \begin{array}[t]{@{}l@{}}\left.#2 \right\}\end{array}}

\begin{document}

Braces OK:
\[
\setst{x}{ x \in S_1 \land {} \\
          (x \in S_2 \lor x \in S_3) }
\]

Error:
\[
\Setst{x}{ x \in S_1 \land {} \\
          (x \in S_2 \lor x \in S_3) }
\]

\end{document}

Here's the printed output from just the "OK" version, using the original command \setst:

Split-line set-builder

The aim is to replace the { and the } in the output with the coresponding large versions — assuming, of course, that the math expression within causes those braces to expand. But each brace should not expand so as to encompass both lines of the printed output!

Here's a more realistic example, where larger braces are really needed:

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}

\newcommand\setst[2]{\{#1 : 
  \begin{array}[t]{@{}l@{}}#2 \}\end{array}}

% my attempted mod
\newcommand\Setst[2]{\left\{#1 : \right. %
  \begin{array}[t]{@{}l@{}}\left.#2 \right\}\end{array}}

\begin{document}

Works, but integral sign and absolute value get squashed down smaller than they ought to appear in display math:
\[
\setst{f}{f(t) > 0 \text{ for all $t$ with } 0 < t < 1\\
    \text{and }\left|\int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t) dt\right| \leq 1 }
\]

\end{document}

And the output from that, with the two braces indicated:

Split-line set-builder #2

11
  • So what should be the span of the brackets in your example? Should \left\{ and \right\} span from the top of x to the bottom of S_3 (say)? Or should they have differing heights?
    – Werner
    Commented Feb 22, 2017 at 20:26
  • The error occurs because the argument #2 contains a double backslash, which ends the array line before processing reaches \right. I'm not sure what result you want, so I don't know what fix to suggest. Commented Feb 22, 2017 at 20:28
  • @Werner: Ideally, the \left\{ and \right\} should span from the initial x to the final S_3. I tried to do that directly, but think there may be an issue with putting a single \left\{ before the array but then a single \right\} inside the array.
    – murray
    Commented Feb 22, 2017 at 20:29
  • I want essentially the same result as with the unmodified \setstexcept that the printed braces should be proportionately larger, as in the usual situation with \left\{ and \right\}.
    – murray
    Commented Feb 22, 2017 at 20:31
  • Why not just use something like \bigl\{ ... \bigr\}. Will the expected expansion be larger than that?
    – Werner
    Commented Feb 22, 2017 at 20:49

4 Answers 4

5

I suggest pursuing a less-than-fully-automatic approach to sizing the outer curly braces. In the code below the default size of the outer curly braces is \big, but this may be changed by specifying an optional sizing-related parameter, which may take on values Bigg, bigg, Big (and, of course, big). I favor a minimum size of big (rather than normalsize) as IMNSHO, the curly braces simply need to "look" a bit more prominent.

In the following screenshot, the curly braces in the first example are of size \big (the default); they are of size \bigg in the second, where \displaystyle is in effect for the second row.

enter image description here

\documentclass{article}
\usepackage{mathtools} % for '\DeclarePairedDelimiter' macro
\DeclarePairedDelimiter{\abs}{\lvert}{\rvert} % "absolute value" macro

\newcommand\Setst[3][big]{\csname #1l\endcsname\{ #2 : 
  \begin{array}[t]{@{}l@{}}#3\csname #1r\endcsname \}\end{array}}

\begin{document}
\[
\Setst{f}{\text{$f(t)>0$ for all $t$ with $0<t<1$}\\
          \text{and }\abs[\big]{\int_0^1 e^{-\frac{1}{2}t^2}\!f(t)\,dt}\leq1}
\]

\[ % use \displaystyle directive in second row; hence, use "bigg" curly braces
\Setst[bigg]{f}{\text{$f(t)>0$ for all $t$ with $0<t<1$}\\
  \displaystyle \text{and }\abs[\bigg]{\int_0^1 e^{-\frac{1}{2}t^2}\!f(t)\,dt}\leq1}
\] 
\end{document}
3
  • With both big and bigg, the integral sign (and enclosing absolute value) is getting squashed down to be much smaller than it would normally appear in display math. That happens, unfortunately, even with the original macro \setst of my original post. (I'll add that there.)
    – murray
    Commented Feb 23, 2017 at 1:29
  • @murray - I've updated the example code to provide a better motivation for using bigg curly braces in the second equation: \displaystyle is now in effect in the second row of the array. (The default style in an array is text style, not display style.) The updated code also features and "absolute value" macro, which makes the code more "LaTeX-y" since it provides more of a distinction between the intended meaning on the one hand and the underlying TeX code on the other.
    – Mico
    Commented Feb 23, 2017 at 2:38
  • If you prefer to have display math style be the default in the array contained in the \Setst macro, I suggest you load the array package in the preamble and change the setup of the array from {@{}l@{}} to {@{}>{\displaystyle}l@{}}. Then, as you may see fit, you can still revert to text style by issuing the directive \textstyle at the start of a row.
    – Mico
    Commented Feb 23, 2017 at 5:58
4

I'd set the components slightly differently to allow for \left-\right to be used to span the entire construction:

enter image description here

\documentclass{article}

\usepackage{amsmath,amssymb}

\newcommand\setst[2]{\{#1 : 
  \begin{array}[t]{@{}l@{}}#2 \}\end{array}}

% my attempted mod
\newcommand\Setst[2]{%
  \expandafter\setsttopandbottom#2\relax
  \begin{array}{@{}l @{\ } l@{}}
    \left\{#1 :\vphantom{\setsttop}\vphantom{\setstbottom}\right.\kern-\nulldelimiterspace & 
    \begin{array}[t]{@{}l@{}}
      \setsttop \\ \kern-\nulldelimiterspace\left.\setstbottom\vphantom{\setsttop}\right\}
    \end{array}
  \end{array}
  }

\def\setsttopandbottom#1\\#2\relax{\def\setsttop{#1}\def\setstbottom{#2}}

\begin{document}

OK:
\[
  \setst{f}{f(t) > 0 \text{ for all $t$ with } 0 < t < 1 \\
      \text{and }\left|\int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t) dt\right| \leq 1 }
\]

Modified:
\[
  \Setst{f}{f(t) > 0 \text{ for all $t$ with } 0 < t < 1\\
      \text{and }\left|\int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t) dt\right| \leq 1 }
\]

\end{document}

In particular, the top and bottom part of the construction in the second argument is extracted and used in measurements for the first row (for the opening \{) as well as the last row (for the closing \}).

The above solution assumes that you will always use a \\ inside your construction and therefore have two lines. A separate macro would have to be constructed for a single-line application.


Using

\usepackage{array}

\newcommand\Setst[2]{%
  \expandafter\setsttopandbottom#2\relax
  \begin{array}{@{}>{\displaystyle}l @{\ } l@{}}
    \left\{#1 :\vphantom{\setsttop}\vphantom{\setstbottom}\right.\kern-\nulldelimiterspace & 
    \begin{array}[t]{@{}>{\displaystyle}l@{}}
      \setsttop \\ \kern-\nulldelimiterspace\left.\setstbottom\vphantom{\setsttop}\right\}
    \end{array}
  \end{array}
  }

you can always ensure that the cells within the array construction will be set using \displaystyle.

10
  • No, I do not want each brace to expand to enclose both of the printed lines.
    – murray
    Commented Feb 22, 2017 at 20:45
  • @murray: I've updated my answer based on you mentioning that there will be exactly two lines within the construction.
    – Werner
    Commented Feb 22, 2017 at 22:43
  • @murray: But do you really want the two braces (opening and closing) to have different sizes? Have you tried, instead, something along the lines of Sebastien Gouezel’s trick reported on p. 29 of the manual of the mathtools package? In the present case, it would be, on hand, easier to implement it, since there are no & tokens occurring, and hence no need to re-assign category codes with \scantokens; but on the other, you need to redefine \array to do nothing, yet absorb its arguments.
    – GuM
    Commented Feb 22, 2017 at 22:57
  • 1
    @murray: I've updated my answer to use some more \vphantom content. For future reference, please think about all the use cases for your question and supply that information from the start. Asking good questions are difficult, I understand; keep you audience in mind when doing so.
    – Werner
    Commented Feb 23, 2017 at 1:34
  • 1
    @murray: This is the default behaviour. Within an array, the default placement of content uses \textstyle. If you want content to be set "normally", use \displaystyle.
    – Werner
    Commented Feb 23, 2017 at 2:00
4

This answer is just a draft intended to explain what I had in mind when I posted my comment.

% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly 
                                 % declare the paper format.

\usepackage[T1]{fontenc}         % Not always necessary, but recommended.
% End of standard header.  What follows pertains to the problem at hand.

\usepackage{amsmath}

\makeatletter

\newcommand*{\SetSt}[2]{%
    \setbox\z@ \hbox{%
        % Inside this box, the "\\" command is `turned off'. 
        % BEWARE: WE ASSUME THAT "&" IS **NOT** USED INSIDE #2!
        \let\\\relax
        $#2$%
    }%
    \dimen@   \ht\z@
    \dimen@ii \dp\z@
    % Now typesetting begins:
    \left\{\,#1%
    % select one of the two following alternatives:
    % {}:{}% colon as separator
    \,\middle|\,% vertical bar as separator
    \vrule \@height\dimen@ \@depth\dimen@ii \@width\z@
    \right.\kern-\nulldelimiterspace
    \begin{array}[t]{@{}l@{}}%
        #2%
        \left.\kern-\nulldelimiterspace
        \vrule \@height\dimen@ \@depth\dimen@ii \@width\z@
        \right\}%
    \end{array}%
}

\makeatother



\begin{document}

With tall symbols:
\[
    \SetSt{f}{f(t) > 0 \text{ for all $t$ with } 0 < t < 1\\
        \text{and }\left|\int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t) dt\right| \leq 1 }
\]

WIthout tall symbols:
\[ \SetSt{x}{x\in A \land x\in B\\x\in C \land x\in D\\x\in E \land x\in F} \]
As you can see, no restriction is imposed on the number of lines.  Even a 
single line is OK\@:
\[ \SetSt{x}{\int_{0}^{x} f(t)\,dt > 0} \]

Another example with two lines:
\[
    \SetSt{x}{\int_{0}^{x} f(t)\,dt > 0\\\int_{0}^{x} g(t)\,dt > 0}
\]

\end{document}

It can be refined in at least two respects:

  • the \\ command shouldn’t be simply redefined as \relax, it should gobble a star and an optional argument, if present;

  • the \SetSt command should take the current math style into account; this is easily achived with a routine application of \mathpalette.

I’m sorry, but now I’m too tired to make these refinements…

Edit

I’m now able to post an amended version of the code:

% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly 
                                 % declare the paper format.

\usepackage[T1]{fontenc}         % Not always necessary, but recommended.
% End of standard header.  What follows pertains to the problem at hand.

\usepackage{amsmath}
\usepackage{array}

\makeatletter

\newcommand*\SetSt[2]{\mathpalette{\@SetSt{#1}}{#2}}
\newcommand*\@SetSt[3]{%
    % #1 := 1st argument of "\SetSt"
    % #2 := style selector (e.g., "\displaystyle")
    % #3 := 2nd argument of "\SetSt"
    \setbox\z@ \hbox{%
        % Inside this box, the "\\" command is `turned off'. 
        % BEWARE: WE ASSUME THAT "&" IS **NOT** USED INSIDE #3!
        \let\\\@Murray@NoopCR
        $#2#3$%
    }%
    \dimen@   \ht\z@
    \dimen@ii \dp\z@
    % Now typesetting begins:
    \left\{\@nonscript@thinspace #2% style selector
    % The following group protects the value of "\dimen@" and "\dimen@ii":
    \begingroup #1\endgroup
    % select one of the two following alternatives:
    % {}:{}% colon as separator
    \@nonscript@thinspace\middle|\@nonscript@thinspace % vertical bar as separator
    \@Murray@mathstrut
    \right.\kern-\nulldelimiterspace
    % The group around the cells allows this macro to be nested;
    % it is important only for the last row, but we cannot avoid specifying it 
    % for every entry.
    \begin{array}[t]{@{}>{#2\begingroup}l<{\endgroup}@{}}%
        #3\endgroup % end the group to restore the values of "\dimen@" and 
                    % "dimen@ii"
        \left.\kern-\nulldelimiterspace
        \@Murray@mathstrut
        \right\}%
        \begingroup % to balance the "\endgroup" at the end of the entry
    \end{array}%
}
\newcommand*\@Murray@NoopCR{\@ifstar\x@Murray@NoopCR\x@Murray@NoopCR}
\newcommand*\x@Murray@NoopCR{\@ifnextchar[\y@Murray@NoopCR {}}
\@ifdefinable\y@Murray@NoopCR{\def\y@Murray@NoopCR[#1]{}}
\newcommand*\@nonscript@thinspace{\nonscript\mskip\thinmuskip}
\newcommand*\@Murray@mathstrut{%
    \vrule \@height\dimen@ \@depth\dimen@ii \@width\z@
}

\makeatother



\begin{document}

With tall symbols:
\[
    \SetSt{f}{f(t) > 0 \text{ for all $t$ with } 0 < t < 1\\[\medskipamount]
        \text{and }\left|\int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t) dt\right| \leq 1 }
\]

WIthout tall symbols:
\[ \SetSt{x}{x\in A \land x\in B\\x\in C \land x\in D\\x\in E \land x\in F} \]
As you can see, no restriction is imposed on the number of lines.  Even a 
single line is OK\@:
\[ \SetSt{x}{\int_{0}^{x} f(t)\,dt > 0} \]

Another example with two lines:
\[
    \SetSt{x}{\int_{0}^{x} f(t)\,dt > 0
    \\*[\bigskipamount]% the star serves no purpose, we just want to check that 
                       % it is handled correctly
    \int_{0}^{x} g(t)\,dt > 0}
\]

An example of nesting:
\[
    \SetSt{x}{x\in A\\x\in B\\x\in\SetSt{y}{y<-1\\y>1}}
\]
This last example clearly shows the limits of the algorithm.

\end{document}

And here is the output it produces:

Output of the amended code

6
  • In the 1st, 3rd, and 4th examples, the integral sign is getting squashed down to be much smaller than it would normally appear in display math.
    – murray
    Commented Feb 23, 2017 at 1:21
  • @murray - The size of the integrals is determined by the math "style" that's in use: For an array environment, the default style is text style. To override this setting (say, to get larger integral symbols), insert the directive \displaystyle.
    – Mico
    Commented Feb 23, 2017 at 2:45
  • I don't understand the 3-argument version of your amended version: where is it that I specify the display style? alreadyt your first example (the "tall version" already sems to be using \displaystyle.
    – murray
    Commented Feb 23, 2017 at 20:16
  • @murray: \displaystyle (or other style selectors as appropriate) is supplied by the \mathpalette macro as the 2nd argument of \@SetSt; that’s precisely the way \mathpalette works, and the reason for using it. For an explanation, see, for example, The mysteries of \mathpalette, or Understanding expansion of \mathpalette (the latter, to understand where the 3rd argument of \@SetSt comes from).
    – GuM
    Commented Feb 25, 2017 at 0:13
  • @Gustavo Mezzetti: Got it! (I had a hard time deciding between answers that met my original specification of using \left and \right, on the one hand, the one that suggested the optional argument to indicate \bigx, \biggx, etc.
    – murray
    Commented Feb 26, 2017 at 1:02
2

I propose another layout for this set builder notation, with a simple solution based on delarray and stackengine. In addition, I defined an \abs command with \DeclarePairedDelimiterX from mathtools, and a diffrential symbol with a correct spacing in integrals:

\documentclass{article}
\usepackage{mathtools}
\usepackage{amssymb, delarray}
\usepackage[usestackEOL]{stackengine}

\DeclarePairedDelimiterX{\abs}[1]{\lvert}{\rvert}{\ifblank{#1}{\:\cdot\:}{#1}}%%

\newcommand\mySetst[2]{ \begin{array}\{{@{}>{\everymath{\displaystyle}}c@{\::\:}>{\everymath{\displaystyle}}l@{}}\}
#1 & \stackMath\Shortunderstack[l]{#2}
 \end{array}}

\newcommand\dd[1]{\,\mathrm{d}\mkern 1mu#1} %% differential symbol for integrals

\begin{document}

 \[ \mySetst{f}{f(t)>0 \text{ for all $t$ with } 0<t<1\\\text{and }\abs*{int_{0}^{1}e^{-\frac{1}{2} t^{2}}f(t)\dd t} \leq 1} \]%
\
\end{document} 

enter image description here

2
  • @Mico: Ah! I understood exactly the contrary. I should remove it then, but maybe this code might be of interest for someone else?
    – Bernard
    Commented Feb 23, 2017 at 3:09
  • I guess you're right. I'll add some words. Anyway, I don't see what the difficulty was to get the other look.
    – Bernard
    Commented Feb 23, 2017 at 3:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .