# Ignoring arguments passed to a command depending on the number of arguments specified

Consider the following code:


The rationale for this is that I want to merge different commands depending on different options, but I want to call the commands in the same way.

\documentclass{article}

\def\fl{}

\ifdefined\fl
\newcommand{\xx}[4]
{#1 #2 #3 #4}
\else
\newcommand{\xx}[6]{%
{#1 #2 #3 #4
\begin{#5}
\item foo
\end{#6}
}
} \fi

\begin{document}
\xx{a}{b}{c}{d}{enumerate}{enumerate}
\end{document}


To be clear, I want to get

a b c d


if \fl is defined, and

a b c d
\begin{enumerate}
\item foo
\end{enumerate}


if it is not.

-
In the true branch do \newcommand{\xx}[6]{#1 #2 #3 #4}; where's the problem? – egreg Jun 4 '14 at 21:12
@egreg I want to use the same code for both. – Faheem Mitha Jun 4 '14 at 21:12

Nothing requires you use all arguments in the replacement text:

\documentclass{article}

\def\fl{}

\ifdefined\fl
\newcommand{\xx}[6]
{#1 #2 #3 #4}
\else
\newcommand{\xx}[6]{%
{#1 #2 #3 #4
\begin{#5}
\item foo
\end{#6}
}
} \fi

\begin{document}
\xx{a}{b}{c}{d}{enumerate}{enumerate}
\end{document}


### Output when \fl is not defined

In order to get this, I just put % in front of \def\fl{}

If the status of \fl is changing in the document, a more complex strategy is necessary:

\documentclass{article}[12pt]

\makeatletter
\newcommand{\xx}[4]{%
#1 #2 #3 #4%
\ifdefined\fl
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\@gobbletwo}%
{\xx@aux}%
}
\newcommand\xx@aux[2]{%
\begin{#1}
\item foo
\end{#2}
}

\begin{document}
Here \verb+\fl+ is not defined

\xx{a}{b}{c}{d}{enumerate}{enumerate}

\bigskip
\newcommand{\fl}{}

Here \verb+\fl+ is defined

\xx{a}{b}{c}{d}{enumerate}{enumerate}

\end{document}


-

Here is a version that uses the xparse package to make parameters #5 and #6 optional.

If \fl is not defined, then we can process both a four parameter and a six parameter version, and report an error in case a 5 parameter version is encountered.

If \fl is defined, then we process a case of 4, 5, or 6 parameters as if it was a 4 parameter version.

## Code:

\documentclass{article}
\usepackage{xparse}

\newcommand{\MyError}[3]{%
Error: #1: #2 #3%
%\PackageError{#1}{#2}{#3}% <-- Use this once code is debugged.
}%

\NewDocumentCommand{\xx}{m m m m g g}{%
\ifdefined\fl
% only the first four parameters are useful
\xxFour{#1}{#2}{#3}{#4}%
\else
% Allow for 4 or 6 parameters
\IfNoValueTF{#5}{%
% #5 not provided, so default back to 4 parameter version
\xxFour{#1}{#2}{#3}{#4}%
}{%
\IfNoValueTF{#6}{%
% Only 5 parameters were provided
\MyError{xx}{5 Parameters were provided. Required either 4 or 6 parameters since \textbackslash fl is not defined}{C}%
}{%
\xxSix{#1}{#2}{#3}{#4}{#5}{#6}%
}%
}%
\fi
}%

\newcommand{\xxFour}[4]{%
Four parameters: #1, #2, #3, #4
}%

\newcommand{\xxSix}[6]{%
\begin{#5}
\item Parameter 1: #1
\item Parameter 2: #2
\item Parameter 3: #3
\item Parameter 4: #4
\item Parameter 5: #5
\item Parameter 6: #6
\end{#6}
}%

\newcommand{\Test}{% so that we can repeat this
\textbf{4 paramaters:}
\xx{a}{b}{c}{d}

\bigskip\par
\textbf{5 paramaters:}
\xx{a}{b}{c}{d}{enumerate}

\bigskip\par
\textbf{6 paramaters:}
\xx{a}{b}{c}{d}{enumerate}{enumerate}
}%

\begin{document}
\textbf{\textbackslash fl NOT defined}:

\Test

\bigskip\par
\def\fl{}
\textbf{\textbackslash fl defined}:

\Test

\end{document}

-

Here are some options (not extensively tested in your setup though):

## Option A:

Define \xx to work on 4 or 6 arguments by peeking ahead and see whether a new group \bgroup is started.

\documentclass{article}

\makeatletter
\newcommand{\xx@}[2]{%
#1 #2
}
\newcommand{\xx}[4]{%
#1 #2 #3 #4
\@ifnextchar\bgroup\xx@\relax
}
\makeatother

\begin{document}
\xx{a}{b}{c}{d}{enumerate}{enumerate}

\xx{a}{b}{c}{d}

\xx{a}{b}{c}{d}{enumerate}{enumerate}

\end{document}


This, of course, does not take \fl into consideration. In the above example, \xx@ would contain the environment definition, effectively designated to handle the two last arguments.

## Option B:

Use it as you specified:

\documentclass{article}

\def\fl{}

\ifdefined\fl
\newcommand{\xx}[4]{%
#1 #2 #3 #4
}
\else
\newcommand{\xx}[6]{%
#1 #2 #3 #4 #5 #6
}
\fi

\begin{document}

\xx{a}{b}{c}{d}% or \xx{a}{b}{c}{d}{enumerate}{enumerate}

\end{document}

-
• The following example tests for fl inside the definition of \xx.

• Also it uses the more natural switch \iffl instead of testing, if a macro is defined.

• The number of arguments is reduced to 5, because \begin{#5} and \end{#6} should not have different arguments.

Example:

\documentclass{article}

\newif\iffl

\newcommand{\xx}[5]{%
#1 #2 #3 #4%
\iffl
\begin{#5}
\item foo
\end{#5}%
\fi
}

\begin{document}
\flfalse
\subsection*{Case: flfalse}
\xx{a}{b}{c}{d}{enumerate}

\subsection*{Case: fltrue}
\fltrue
\xx{a}{b}{c}{d}{enumerate}
\end{document}


-