I want to define a new command that serves two slightly different purposes. Can I define a new command called \set such that it's definition is chosen according to the number of argument(s) is(are) filled? I want {1,2,3} when I use \set{1,2,3} and I want {x | x>0} when I use \set{x}{x>0}.
4 Answers
Yes, this is possible, using \NewDocumentCommand from xparse for example, making the second argument with {} behave like an optional argument then, i.e. using the g argument modifier.
Please note, that there is already a \set{} macro in the braket package, which provides for typesetting of sets, so I called the macro \myset instead and use \set{...} inside.
In principle, this could be done with an trailing optional argument with [] too, which is perhaps even better, because this enforces you to distinguish between the list version and the conditional version of the set notation.
Edit I've added the \mybetterset{}[] command as a variant to \myset, using the [] as 2nd optional argument.
\documentclass{article} \usepackage{braket} \usepackage{mathtools} \usepackage{xparse} \NewDocumentCommand{\myset}{mg}{% \IfValueTF{#2}{% \set{#1\;\vert\;#2} }{% \set{#1}% }% } %% The better command with [] as optional argument \NewDocumentCommand{\mybetterset}{mo}{% \IfValueTF{#2}{% \set{#1\;\vert\;#2} }{% \set{#1}% }% } \usepackage{hyperref} \begin{document} $\myset{1,2,3}$ $\myset{x}{x > 0}$ $\mybetterset{1,2,3}$ $\mybetterset{x}[x>0]$ \end{document} 
- I was going to add a comment about the
[]until you edited it in :) That's the approach I use in my documents and it works out much better, I think.Sean Allred– Sean Allred2015-07-07 16:37:05 +00:00Commented Jul 7, 2015 at 16:37 - @SeanAllred: Yes, I had it in mind right from the start. And you added the comment anyway :-Puser31729– user317292015-07-07 16:37:51 +00:00Commented Jul 7, 2015 at 16:37
- If that's the order, why is it better with
[]?Manuel– Manuel2015-07-07 17:37:26 +00:00Commented Jul 7, 2015 at 17:37 - @Manuel: The usual order is
[]{}... I explicitly wanted to reverse thisuser31729– user317292015-07-07 19:02:25 +00:00Commented Jul 7, 2015 at 19:02 - @ChristianHupfer I mean, if you said better
\set[..]{..}than\set{..}{..}I would think “well, that's okey” but if you say\set{..}[..]is better than\set{..}{..}, well, I don't understand why (and I don't think so, at least at this moment I don't see any reason why it would be better).Manuel– Manuel2015-07-07 19:05:22 +00:00Commented Jul 7, 2015 at 19:05
You can do it, but I discourage you to. Better defining a command that distinguishes between \set{1,2,3} and \set{x|<condition>}.
You can find perhaps better methods in the documentation of mathtools.
\documentclass{article} \usepackage{xparse} \NewDocumentCommand{\set}{>{\SplitArgument{1}{|}}m}{\printset#1} \NewDocumentCommand{\printset}{mm}{% \IfNoValueTF{#2} {% no | \{#1\}% } {% | \{\,#1\mid#2\,\}% }% } \begin{document} $\set{1,2,3}=\set{x | 1\le x\le 3}$ \end{document} 
- Took the idea right from my mind :)Sean Allred– Sean Allred2015-07-07 16:34:24 +00:00Commented Jul 7, 2015 at 16:34
- @egreg: You forgot x to be a natural number :-Puser31729– user317292015-07-07 16:40:55 +00:00Commented Jul 7, 2015 at 16:40
- @ChristianHupfer That's obvious from the context, isn't it?
;-)egreg– egreg2015-07-07 16:41:43 +00:00Commented Jul 7, 2015 at 16:41 - @egreg: In the context yes, but having the RHS as a standalone ...user31729– user317292015-07-07 16:42:25 +00:00Commented Jul 7, 2015 at 16:42
Here is another soultion, with optional argument
\documentclass{article} \newcommand{\set}[2][]{\left\lbrace\if\relax\detokenize{#1}\relax\else#1\mid\fi#2\right\rbrace} \begin{document} bla bla \[\set{a,b,c},\set[x]{x>0}\] $\set{a,b,c},\set[x]{x>0}$ \end{document} Classical method
\documentclass{article} \makeatletter \newcommand{\set}{\@ifnextchar[{\@@set}{\@set}} \def\@set#1{\left\lbrace#1\right\rbrace} \def\@@set[#1]#2{\@set{#1\mid#2}} \makeatother \begin{document} bla bla \[\set{a,b,c},\set[x]{x>0}\] $\set{a,b,c},\set[x]{x>0}$ \end{document} - There is no package required. This is good!Say OL– Say OL2015-07-07 17:24:46 +00:00Commented Jul 7, 2015 at 17:24
- @SayOL that's why i add ittouhami– touhami2015-07-07 17:26:23 +00:00Commented Jul 7, 2015 at 17:26
- 4
\ifx#1\emptyis conceptually wrong.\ifx#1\empty\relaxwould be a little better;\if\relax\detokenize{#1}\relaxis the right one.egreg– egreg2015-07-07 17:42:40 +00:00Commented Jul 7, 2015 at 17:42 - @egreg what about
\newcommand{\set}[2][\relax]{\left\lbrace\ifx #1\relax?touhami– touhami2015-07-07 20:43:23 +00:00Commented Jul 7, 2015 at 20:43 - 1
A variant solution, also with mathtools and xparse. When used for a set defined by a property, the separator between elements and properties is a semicolon, because it is easy to type, and rarely used in maths (except for sets defined by a property). The resulting sign in the .pdf file will be a vertical bar, with a correct spacing. If for some reason you really need a semi-colon, you just enclose it between a pair of braces. Thus the syntax is very close to what one writes by hand: \set{x;P(x)}.
The size of the braces and the the vertical bar will adjust automatically to the size of the contents with the star version of the \set command, or manually for fine-tining, with optional arguments: \big, \Big, \bigg,\Bigg`.
\documentclass{article} \usepackage[utf8]{inputenc} \usepackage{fourier, erewhon} \usepackage{xparse} \usepackage{mathtools, nccmath} \DeclarePairedDelimiterX{\set}[1]\{\}{\setargs{#1}} \NewDocumentCommand{\setargs}{>{\SplitArgument{1}{;}}m} {\setargsaux#1} \NewDocumentCommand{\setargsaux}{mm} {\IfNoValueTF{#2}{#1}{\nonscript\,#1\nonscript\;\delimsize\vert\nonscript\:\allowbreak #2\nonscript\,}} % % %% The following makes \big the default for the \set command % \let\oldset\set % \def\set{\futurelet\testchar\MaybeOptArgSet} % \def\MaybeOptArgSet{\ifx[\testchar \let\next\OptArgSet % \else \let\next\NoOptArgSet \fi \next} % \def\OptArgSet[#1]#2{\oldset[#1]{#2}} % \def\NoOptArgSet#1{\OptArgSet[\big]{#1}} % % \def\Set{\oldset*}% %%% Syntax: \set{x ; P(x)}) \begin{document} \begin{align*} & \set[\big]{x ; x > 5} & & \set*{x ; x > 5} \\[4pt] & \set[\bigg]{ \frac{x}{2} ; x > 5} & & \set*{ \frac{x}{2} ; x > 5} \\[4pt] & \set[\Bigg]{ \frac{1}{2},\frac{1}{3},\frac{1}{4},\dotsm} & & \set*{ \mfrac{1}{2},\mfrac{1}{3},\mfrac{1}{4},\dotsm} \end{align*} \end{document} In the above code I commented out some lines that result in the default implicit use of the \big optional argument (which looks better, in my opinion). The \set* command is the replaced with a new Set command.

xparseuses LaTeX3? Oh my.... :-Pxparseis part of the '3 in 2e' effort