I would like to make a macro with two parameters which return a text. For instance, I want \M{1}{5}
to return [1,5]
, and \M{2}{2}
to return [2]
(because the two arguments are the same). So I need to have a "check" or condition in my macro to see if the two parameters are the same and perform different executions… How do I implement this "if" in a macro?
[Tex/LaTex] How to make a “condition” in a macro
conditionalsmacros
Related Solutions
I'd use the xparse
package to do this, as everything is then 'pre-packaged':
\documentclass{article}
\usepackage{color,xparse}
\NewDocumentCommand\MyTextColor{m+g}{%
\IfNoValueTF{#2}
{\color{#1}}
{\textcolor{#1}{#2}}%
}
\begin{document}
\MyTextColor{green}{stuff}
\MyTextColor{red} Some text
\end{document}
The same can of course be done using \@ifnextchar
\documentclass{article}
\usepackage{color}
\makeatletter
\newcommand*\MyTextColor[1]{%
\@ifnextchar\bgroup
{\textcolor{#1}}
{\color{#1}}%
}
\makeatother
\begin{document}
\MyTextColor{green}{stuff}
\MyTextColor{red} Some text
\end{document}
The key point is that you need to look for {
using \bgroup
rather than trying to use it directly (as it is the begin-group character).
To explain how the \@ifnextchar
part deals with the need for either 1 or 2 arguments, what happens in my second approach is that
\newcommand*\MyTextColor[1]{%
defines a macro which absorbs one argument. So:
\MyTextColor{red}{stuff}
absorbs red
as #1
and leaves {stuff}
in the input stream, while
\MyTextColor{red} other stuff
also absorbs red
as #1
and leaves other stuff
in the input stream. We now apply \@ifnextchar
, which 'peeks' at the next token without absorbing it. The test reads
\@ifnextchar\bgroup
{\textcolor{#1}}
{\color{#1}}%
and so depending on the result, either \textcolor{red}
or \color{red}
is inserted into the input stream. Thus we end up with either
\textcolor{red}{stuff}
or
\color{red} other stuff
which means that \textcolor
will get the required two arguments, while \color
only gets one. The key is that {red}
is reinserted into the input after either \textcolor
or \color
.
Although it is not directly related to the question, a few notes on the xparse
approach may be useful. When using the xparse
package, arguments are described by letter, with m
representing a mandatory argument and g
representing an optional argument in braces (i.e. an optional TeX group). A +
before the letter allows that argument to accept paragraph tokens, so in my definition the first argument cannot (it's supposed to be the name of a colour), while the second one can (it is arbitrary text).
The g
argument returns a special token (\NoValue
) if the optional argument was not present at all. If a default value was wanted, I'd have used G{<default>}
. The same approach applies to standard LaTeX optional arguments, which are represented as o
or O
, depending on whether a default value is required. I have tested for \NoValue
with the test \IfNoValueTF
; \IfNoValueT
and \IfNoValueT
are also available.
This is probably what you're after:
The standard TeX conditional \ifx#1#2 <true> \else <false> \fi
works in this case, executing <true>
if #1
=#2
and <false>
otherwise.
\documentclass{standalone}
%\url{http://tex.stackexchange.com/q/27278/86}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
my funny rectangle/.style n args={4}{%
rectangle,
draw,
fit={(#3,#1) (#4,#2)},
append after command={\pgfextra{\let\mainnode=\tikzlastnode}
node[above right] at (\mainnode.north west) {#3}%
node[above left] at (\mainnode.north east) {#4}%
\ifx#1#2
node[left] at (\mainnode.west) {#1}%
\else
node[below left] at (\mainnode.north west) {#1}%
node[above left] at (\mainnode.south west) {#2}%
\fi
},
}
}
\begin{document}
\begin{tikzpicture}
\node[my funny rectangle={1}{1}{4}{8}] {text};
\end{tikzpicture}
\end{document}
Edit: Here's the updated code that addresses passing some non-numeric arguments to my funny rectangle
. With the node no longer fit
ted, you need to specify additional width and height parameters:
\documentclass{article}
\usepackage{tikz}% http://ctan.org/pkg/pgf
%\usetikzlibrary{fit}
\tikzset{
my funny rectangle/.style n args={4}{%
rectangle,
draw,
%fit={(#3,#1) (#4,#2)},
append after command={\pgfextra{%
\let\mainnode=\tikzlastnode%
\def\argone{#1}\def\argtwo{#2}}
node[above right] at (\mainnode.north west) {#3}%
node[above left] at (\mainnode.north east) {#4}%
\ifx\argone\argtwo
node[left] at (\mainnode.west) {#1}%
\else
node[below left] at (\mainnode.north west) {#1}%
node[above left] at (\mainnode.south west) {#2}%
\fi
},
}
}
\begin{document}
\begin{tikzpicture}
\node[my funny rectangle={$i$}{$i$}{4}{8}, text width={3cm}, minimum height={3cm}, text centered] (abc) at (5,5) {text};
\end{tikzpicture}
\end{document}
Best Answer
To complete the list I want to present the package
etoolbox
. If you are loadingbiblatex
the packageetoolbox
will be loaded automatically.