
Meine Frage betrifft das Deklarieren eines „newcommand“ mit einer Option.
Ich habe definiert
\newcommand{\bforall}[2]{\forall #1\, (#2)}
so dass $\bforall{x}{x \in A}$
schreibt $\forall x (x \in A)$
.
Ich hätte gern etwas Kontrolle über die Klammern. Und zwar möchte ich
\bforall[s]{x}{x \in A}
eckige Klammern zu verwenden und
\bforall[c]{x}{x \in A}
geschweifte Klammern verwenden.
Wie kann dies erreicht werden?
Ich habe das Forum durchsucht und gefunden 1/Unterschiedliche Befehlsdefinitionen mit und ohne optionales Argument und 2/Optionales Argument für neuen Befehl? und keines von beiden hat mir geholfen.
Antwort1
Hier ist ein Weg, ohne Pakete.
\documentclass{article}
\newcommand\bforall[3][r]{%
\ifx r#1\forall #2\, (#3)\else
\ifx s#1\forall #2\, [#3]\else
\ifx c#1\forall #2\, \{#3\}\else
\mathrm{Illegal~option}%
\fi\fi\fi
}
\begin{document}
$\bforall{x}{x \in A}$
$\bforall[r]{x}{x \in A}$
$\bforall[s]{x}{x \in A}$
$\bforall[c]{x}{x \in A}$
\end{document}
Wie touhami richtig anmerkt, besteht die Strafe für die Verwendung der Einfachheit der \ifx
Konstruktion darin, dass ein versehentlicher Syntaxfehler, wie etwa die Verwendung eines optionalen Arguments mit zwei Zeichen, [rs]
keine Fehlermeldung erzeugt, sondern lediglich den Begriff falsch setzt.
Antwort2
Hier ist eine Möglichkeit, dies zu tun, mit demxstring
Pakete \IfStrEqCase
:
Die Standardoption sind r
runde Klammern, c
kurze Klammern und s
eckige Klammern. Sie können auch einen optionalen zweiten Parameter hinzufügen, um die Klammerngröße zu steuern:
Code:
\documentclass{article}
\usepackage{xstring}
\newcommand{\bforall}[3][r]{%
\forall #2\,
\IfStrEqCase{#1}{%
{r}{(#3)}%
{c}{\{#3\}}%
{s}{{[#3]}}%
}[%
%% Issue error message here about unsuported bracket type
]%
}
\begin{document}
$\bforall{x}{x \in A}$
$\bforall[r]{x}{x \in A}$
$\bforall[c]{x}{x \in A}$
$\bforall[s]{x}{x \in A}$
\end{document}
Code Resizing Brackets
:
\documentclass{article}
\usepackage{xstring}
\usepackage{xparse}
\usepackage{amsmath}
\NewDocumentCommand{\bforall}{%
O{r}% #1 = r, c or s (bracket shape)
O{}% #2 = optional size specifier
m% #3
m% #4
}{%
\forall #3\,
\IfStrEqCase{#1}{%
{r}{#2(#4#2)}%
{c}{#2\{#4#2\}}%
{s}{{#2[#4#2]}}%
}[%
%% Issue error message here about unsupported bracket type
\PackageError{tree}{Undefined option to tree: #1}{}
]%
}
\begin{document}
\begin{minipage}{0.25\linewidth}
$\bforall{x}{x \in A}$
$\bforall[r]{x}{x \in A}$
$\bforall[c]{x}{x \in A}$
$\bforall[s]{x}{x \in A}$
\end{minipage}
\hspace*{0.5cm}
\begin{minipage}{0.25\linewidth}
$\bforall[r][\Big]{x}{x \in A, x > \dfrac{1}{2}}$
$\bforall[c][\Big]{x}{x \in A, x > \dfrac{1}{2}}$
$\bforall[s][\bigg]{x}{x \in A, x > \dfrac{1}{2}}$
\end{minipage}
\end{document}
Antwort3
Für ein Makro zum Wechseln der Groß-/Kleinschreibung ist am besten geeignet . Ich habe die bereits bei , expl3
üblichen Buchstaben für Klammern, für eckige Klammern und für geschweifte Klammern verwendet.amsmath
p
b
B
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\bforall}{O{p}mm}
{
\forall #2\,
\str_case:nnF { #1 }
{
{p}{(#3)}
{b}{[#3]}
{B}{\{#3\}}
}
{\@latex@error{Illegal~option~#1}{I~used~p}}
}
\ExplSyntaxOff
\begin{document}
$\bforall{x}{x \in A}$
$\bforall[p]{x}{x \in A}$
$\bforall[b]{x}{x \in A}$
$\bforall[B]{x}{x \in A}$
\end{document}
Antwort4
Eine einfache TeX-Version mit anderer Syntax
\def\bforall#1{\forall#1\,\futurelet\tmptoken\dobforall}
\def\dobforall{\ifx\tmptoken\bgroup\expandafter\bforallbraces\fi
\ifx\tmptoken[\expandafter\bforallbrackets\fi
\ifx\tmptoken(\expandafter\bforallparenthesis\fi
\relax}
\def\bforallbraces#1\relax#2{\{#2\}}
\def\bforallbrackets#1\relax[#2]{[#2]}
\def\bforallparenthesis#1\relax(#2){(#2)}
$\bforall{x}(x \in A)$\par
$\bforall{x}{x \in A}$\par
$\bforall{x}[x \in A]$\par
\bye
Sie können diese Definitionen auch in LaTeX verwenden, ohne dass ein Paket erforderlich ist. Die Syntax scheint mir einfacher zu sein \bforall{x}(x\in A)
, \bforall{x}{x\in A}
und \bforall{x}[x\in A]
. Vielleicht brauchen Sie für Ihre Anforderungen dieses Makro überhaupt nicht, sondern nur \def\bforall#1{\forall#1\,}
und dann folgt darauf, was auch immer Sie eingeben?
Mit ein wenig Verfeinerung können Sie \bforall x {x \in A}
die Syntax verwenden. (In LaTeX wäre es aufgrund von einfacher \@ifnextchar
.)
\def\bforall#1{\forall#1\,\futurelet\tmptoken\dobforall}
\def\dobforall{\ifx\tmptoken\spacetoken\expandafter\bforallspace\fi
\ifx\tmptoken\bgroup\expandafter\bforallbraces\fi
\ifx\tmptoken[\expandafter\bforallbrackets\fi
\ifx\tmptoken(\expandafter\bforallparenthesis\fi
\relax}
\def\bforallbraces#1\relax#2{\{#2\}}
\def\bforallbrackets#1\relax[#2]{[#2]}
\def\bforallparenthesis#1\relax(#2){(#2)}
\def\bforallspace#1\relax{\dobforallspace}
\expandafter\def\expandafter\dobforallspace\space{\futurelet\tmptoken\dobforall}
\lowercase{\let\spacetoken= } %
$\bforall x (x \in A)$\par
$\bforall x {x \in A}$\par
$\bforall x [x \in A]$\par
\bye