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. Jul 7, 2015 at 16:37 -
@SeanAllred: Yes, I had it in mind right from the start. And you added the comment anyway :-P– user31729Jul 7, 2015 at 16:37
-
-
@Manuel: The usual order is
[]{}
... I explicitly wanted to reverse this– user31729Jul 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).– ManuelJul 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}
-
-
@egreg: You forgot x to be a natural number :-P– user31729Jul 7, 2015 at 16:40
-
-
@egreg: In the context yes, but having the RHS as a standalone ...– user31729Jul 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}
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.
xparse
uses LaTeX3? Oh my.... :-Pxparse
is part of the '3 in 2e' effort