
Mi pregunta es sobre declarar un "nuevo comando" con una opción.
he definido
\newcommand{\bforall}[2]{\forall #1\, (#2)}
entonces eso $\bforall{x}{x \in A}$
escribe $\forall x (x \in A)$
.
Me gustaría tener algo de control sobre los corchetes. Es decir, me gustaría
\bforall[s]{x}{x \in A}
utilizar llaves cuadradas, y
\bforall[c]{x}{x \in A}
utilizar llaves.
¿Cómo se puede lograr esto?
Busqué en el foro y encontré 1/Diferentes definiciones de comandos con y sin argumento opcional y 2/¿Argumento opcional para el nuevo comando? y ninguno me ayudó.
Respuesta1
Aquí tienes una forma, sin paquetes.
\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}
Como señala acertadamente Touhami, la penalización por utilizar la simplicidad de la \ifx
construcción es que un error de sintaxis accidental, como el uso de un argumento opcional de dos caracteres, [rs]
no producirá un mensaje de error, sino que simplemente establecerá incorrectamente el término.
Respuesta2
Aquí hay una manera de hacerlo usando elxstring
paquetes \IfStrEqCase
:
La opción predeterminada son r
llaves cerradas, c
llaves de urly y s
llaves cuadradas. También puede agregar un segundo parámetro opcional para controlar el tamaño de la llave:
Código:
\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}
Código 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}
Respuesta3
Para una macro de cambio de caso, lo mejor es expl3
; Utilicé las letras que ya son comunes con amsmath
, p
para paréntesis, b
corchetes B
y llaves.
\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}
Respuesta4
Uno simple TeX con una sintaxis diferente.
\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
Puedes usar esas definiciones también en LaTeX sin necesidad de ningún paquete. La sintaxis me parece más fácil \bforall{x}(x\in A)
y \bforall{x}{x\in A}
. \bforall{x}[x\in A]
En cualquier caso, para sus necesidades, ¿es posible que no necesite esa macro en absoluto, simplemente \def\bforall#1{\forall#1\,}
y luego le sigue lo que ingrese?
Con un poco de refinamiento para permitirte usar \bforall x {x \in A}
la sintaxis. (En LaTeX sería más fácil gracias a \@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