How to automatically resize the vertical bar in a set comprehension?

I have a simple command which I use to write set comprehensions so that the braces automatically resize with respect to size of the enclosed arguments, e.g.

\usepackage{amsmath}
\newcommand{\set}[1]{\left\lbrace #1\right\rbrace}

\begin{equation*}
\set{x \in X \mid x > \frac{1}{2}}
\end{equation*}
% Produces something like: { x : X | x > 1/2 }


However, the \mid vertical bar wont resize like the braces { .. } do. How can I get the \mid to resize as well?

You can use \middle| instead of \mid like

$\left\{ x \in X \middle| x > \frac{1}{2}\right\}$


or with better spacing

$\left\{ x \in X \,\middle|\, x > \frac{1}{2}\right\}$


(I think this requires a somewhat modern TeX-distribution.)

• @Andrew: It is an eTeX primitive (not included in the original TeX). But nowadays LaTeX always is run on the pdftex engine, which includes the eTeX stuff. – Paŭlo Ebermann Aug 15 '11 at 13:34
• What if you want it to be slightly taller, so that extends slightly above and below the height of the brackets? Is there a way to adjust this? – Anomaly Sep 29 '16 at 16:10

I think the best idea is to use the braket package, which provides markup for these sorts of constructions, for which the brackets and "pipes" expand where necessary.

• Thanks. Leaving a comment here for future reference: Braket lets you write \Set{ x | 0<x<5} etc., expanding the | as necessary. – ShreevatsaR Jul 29 '10 at 12:28

There is the \middle command, it is like \left and \right but for the middle =)

However, LaTeX does not consider \mid to be a delimiter, so you have to use pipe instead (or vertical bar).

• However, LaTeX does not consider \mid to be a delimiter — Is there a way to make it do so? I would consider this the best solution in terms of pretty source code. – Marian Nov 26 '17 at 23:36
• If you want pretty source code, why not just define your own macro for set notation, instead of writing \{ ... | ... \} all the time? I have defined in my macro set \DeclarePairedDelimiterX\set[2]\lbrace\rbrace{#1\;\delimsize\vert\;#2}. The spacing \; can be further optimized according to egreg. // As to the question you asked: \mid is defined to be a \mathrel (see slac.stanford.edu/comp/unix/package/tex/latex/fntguide/…).. – Willie Wong Nov 27 '17 at 2:47
• .. unfortunately the original TeX engine does not have a "middle delimiter" (there's only \mathopen and \mathclose), so you cannot really declare a delimiter in your sense. An alternative is to not use \left and \middle and \right and hand code the sizes yourself using \big and friends. If you do that there is a \bigm version suitable for use here. See this answer of Mico. – Willie Wong Nov 27 '17 at 2:50

Here is a nice solution using mathtools, which is quite versatile and produces the right spacing (thin space withing braces, and thick space around the mid symbol):

\usepackage{mathtools}
\DeclarePairedDelimiterX\setc[2]{\{}{\}}{\,#1 \;\delimsize\vert\; #2\,}


Now if you use the starred version of the macro you get the desired result:

\setc*{x \in X}{x > \frac{1}{2}}


You can even adjust to a different size if you think that the braces are too big, with the syntax

\setc[\Big]{x \in X}{x > \frac{1}{2}}


• Is there any way to modify this so that \setc adjusts the size while \setc* does not? – Monstrous Moonshine Sep 25 '17 at 5:03

This seems to work for me, possibly the horizontal spacing around the bar needs adjusting.

\documentclass{article}

\usepackage{amssymb}

\makeatletter
\newcommand{\my@set}[1]{\left\lbrace #1\right\rbrace}
\newcommand{\my@cset}[2]{%
\left\lbrace #1\vphantom{#2}\right\vert%
\left.\vphantom{#1}#2\right\rbrace}

\def\my@first#1|#2\relax{#1}
\def\my@second#1|#2\relax{#2}
\newcommand{\set}[1]{%
\edef\my@given{#1}
\edef\my@start{\my@first #1|\relax}%
\ifx\my@start\my@given
\my@set{#1}
\else
\edef\my@last{\my@second #1\relax}%
\my@cset{\my@start}{\my@last}%
\fi}

\begin{document}

$\set{x \in X \int_0^1 | y \in Y} \; \set{x \in X \int_0^1 y \in Y}$

$\set{x | y} \set{a b}$

\end{document}