8

The \Set command (from the braket package) is useful for set builder notation, but it adds spaces before and after the brackets.

Compare \Set{1, 2, 3}:

<code>\Set{1, 2, 3}</code>

To \{1, 2, 3\}:

<code>\{1, 2, 3\}</code>

Looking through the source code, \Set seems to add \, spaces before and after each curly bracket. How do I temporarily make these spaces zero-width? I'd like to re-define \set to be just \Set with the spaces taken out, but neither seem to be defined with \newcommand.

I tried something like this, but it gets some sort of TeX "stack overflow" (! TeX capacity exceeded, sorry [input stack size=5000].).

\renewcommand{\set}[1]{%
    \let \lbrace = \{\!%
    \let \rbrace = \!\}%
%
    \Set{#1}%
%
    \let \lbrace = \{%
    \let \rbrace = \}%
}

Even if I do get the redefined command to work, my approach won't account for the other spaces. Here's a minimal working example:

\documentclass[12pt]{article}

\usepackage{braket}

\begin{document}
    \noindent Compare \[
        \Set{1, 2, 3}
    \]
%
    To \[
        \{1, 2, 3\}
    \]
\end{document}
Mico
  • 506,678
Blender
  • 485
  • why not simply \newcommand\Set#1{\{#1\}} if that's the layout you want? – David Carlisle Mar 13 '14 at 18:34
  • @DavidCarlisle: \Set lets you write \Set{ x \in S | x > 0 }, which is equivalent to \left\{\, x \in S \mid x > 0 \,\right\}. – Blender Mar 13 '14 at 18:35
  • What about \newcommand{\SET}[1]{\Set{\!#1\!}} and use \SET instead? – Werner Mar 13 '14 at 18:38
  • @Werner: That works, thank you. I'm going to see if there are any more generic answers, but if there aren't, I'm definitely using this. – Blender Mar 13 '14 at 18:39
  • @Werner -\medmuskip rather than ! (which is -\thinmuskip) I think (see my answer) – David Carlisle Mar 13 '14 at 18:52
  • Since nobody else has said it, I will remark that you can't \let a command equal to more than one token. Instead of \let\lbrace\{\!, you would need \def\lbrace{\{\!}, although that wouldn't work either: LaTeX defines \{ in terms of \lbrace and trying to define \lbrace in terms of \{ leads to an infinite loop. – Dan Mar 13 '14 at 19:17

3 Answers3

5

As shown below, the space is \: so you can negate that by redefining the command as

\renewcommand\Set[1]{%
    \csname Set \endcsname{\mskip-\medmuskip#1\mskip-\medmuskip}}

\documentclass[12pt]{article}

\usepackage{braket}

\begin{document}
    \noindent Compare \[
        \Set{1, 2, 3}
    \]
   \noindent Compare \[\let\:\relax
        \Set{1, 2, 3}
    \]
%
    To \[
        \{1, 2, 3\}
    \]
\end{document}

enter image description here

David Carlisle
  • 757,742
4

The definition of \Set includes a \medmuskip \: around its argument (from braket.sty):

  \expandafter\gdef\csname Set \endcsname#1{\left\{%
     \ifx\SavedDoubleVert\relax \let\SavedDoubleVert\|\fi
     \:{\let\|\SetDoubleVert
     \mathcode`\|32768\let|\SetVert
     #1}\:\right\}}

Note the use of \: after \left\{ and before \right\}. You can redefine remove this using an alternative \SET macro:

enter image description here

\documentclass[12pt]{article}
\usepackage{braket}

\newcommand{\SET}[1]{\Set{\mskip-\medmuskip #1 \mskip-\medmuskip}}

\begin{document}

\begin{tabular}{rl}
  \texttt{\detokenize{\Set}}: & $\Set{1, 2, 3}$ \\
  \texttt{\{1, 2, 3\}}: & $\{1, 2, 3\}$ \\
  \texttt{\detokenize{\SET}}: & $\SET{1, 2, 3}$ \\
\end{tabular}
\end{document}

Alternatively, redefine \Set to suit your needs by including this after you load braket:

{\catcode`\|=\active
  \xdef\set{\protect\expandafter\noexpand\csname set \endcsname}
  \expandafter\gdef\csname set \endcsname#1{\mathinner
        {\lbrace\,{\mathcode`\|32768\let|\midvert #1}\,\rbrace}}
  \xdef\Set{\protect\expandafter\noexpand\csname Set \endcsname}
  \expandafter\gdef\csname Set \endcsname#1{\left\{%
     \ifx\SavedDoubleVert\relax \let\SavedDoubleVert\|\fi
     {\let\|\SetDoubleVert
     \mathcode`\|32768\let|\SetVert
     #1}\right\}}
}
Werner
  • 603,163
3

For strange reason, braket uses \: for \Set, where \, would be sufficient.

I propose to redefine the commands with a *-variant that suppresses the spaces next to the braces (and with \, in the “big” form).

\documentclass{article}
\usepackage{braket,xparse}

\begingroup
\catcode`\|=\active
\gdef\changebarto#1{\mathcode`\|="8000 \let|#1}
\endgroup

\RenewDocumentCommand{\set}{sm}{%
  \mathinner{%
    \lbrace
    \IfBooleanF{#1}{\,}%
    {\changebarto\midvert #2}%
    \IfBooleanF{#1}{\,}%
    \rbrace
  }%
}
\RenewDocumentCommand{\Set}{sm}{%
  \left\lbrace
    \ifx\SavedDoubleVert\relax \let\SavedDoubleVert\|\fi
    \IfBooleanF{#1}{\,}%
    {\let\|\SetDoubleVert\changebarto\SetVert #2}%
    \IfBooleanF{#1}{\,}%
  \right\rbrace
}

\begin{document}
$\set{1,2,3}\ne\set*{1,2,3}$

$\set{x|x\notin x}$

$\displaystyle\Set{x|x\ne\frac{1}{2}}$

$\displaystyle\Set*{x|x\ne\frac{1}{2}}$
\end{document}

enter image description here

egreg
  • 1,121,712
  • "For some strange reason..." -- I think it's related to conventional Dirac notation for \bra, \ket, \braket, etc... – Mico Mar 13 '14 at 19:07
  • @Mico \: is definitely too wide, and \set\Set have nothing to do with Dirac's notation. They are in the package just because they were in the same style as \bra and \ket. – egreg Mar 13 '14 at 19:07
  • Thanks. I was always wondering how the \set and \Set macros wandered into the braket package. – Mico Mar 13 '14 at 19:58