# How to create two commands with the same name but different number of parameters

I want to define a command with the same name, but a different number of parameters.

I'm considering something like this:

\documentclass{article}

\usepackage{hyperref}

\newcommand{\quelle}[1]{\textit{(Quelle: \url{#1})})}
\newcommand{\quelle}[2]{\textit{(Quelle: \url{#1} Absatz: #2)})}

\begin{document}

Test: \quelle{www.wikipedia.de}
Test: \quelle{www.wikipedia.de, sometext}

\end{document}


If I try to compile this, I get the following result:

Command \quelle already defined. ...2]{\textit{(Quelle: \url{#1} Absatz: #2)})}


• Traditional LaTeX does not allow macros with the same name having a different mandatory number of arguments. You can always define a macro having a certain number of arguments, but you have to check whether they are empty (i.e. not specified). With expl3 you could use \cs_new:Nn \foo_bar:nn or \cs_new:Nn \foo_bar:nnnn for example, but those macros are not meant for user space – user31729 Jan 31 at 19:44

The only change from the requested syntax is to use a ! as the separator between the http reference and "sometext", as I figured a comma , was much more likely to appear as part of "sometext:.

\documentclass{article}
\usepackage{hyperref,listofitems}
\newcommand{\quelle}[1]{%
\setsepchar{!}%
(\textit{Quelle: \url{\qarg[1]}}%
\ifnum\listlen\qarg[]>1\relax\textit{ Absatz: \qarg[2]}\fi%
)%
}
\begin{document}
Test: \quelle{www.wikipedia.de}
Test: \quelle{www.wikipedia.de! sometext}
\end{document}


I'd prefer a syntax with a leading optional argument, that's more in line with common LaTeX conventions.

Anyway, you can have your preferred syntax by defining a single \quelle command: TeX cannot have two meanings for the same command.

\documentclass{article}
\usepackage{xparse}
\usepackage{hyperref}

\NewDocumentCommand{\quelle}{ >{\SplitArgument{1}{,}}m }{%
\makequelle#1%
}
\NewDocumentCommand{\makequelle}{mm}{%
\textit{%
(Quelle: \url{#1}%
\IfValueT{#2}{ Absatz: #2})%
}%
}

\begin{document}

Test: \quelle{www.wikipedia.de}

Test: \quelle{www.wikipedia.de, sometext}

\end{document}


The argument is split at the first comma, if present, and passed as a pair of arguments to \makequelle. If no comma is present, the second argument will make the test \IfValueT false, so nothing will be printed.

The same output with a more common syntax:

\documentclass{article}
\usepackage{xparse}
\usepackage{hyperref}

\NewDocumentCommand{\quelle}{om}{%
\textit{%
(Quelle: \url{#2}%
\IfValueT{#1}{ Absatz: #1})%
}%
}

\begin{document}

Test: \quelle{www.wikipedia.de}

Test: \quelle[sometext]{www.wikipedia.de}

\end{document}

• Is it my imagination, or is TeX inserting customary space after your periods in the website name? Of course, the same applies to my own answer. – Steven B. Segletes Feb 1 at 10:54
• @StevenB.Segletes That's a fault of hyperref or url, as far as I can see. Using \textit{\url{example.org}} will show a space after the period. – egreg Feb 1 at 11:30

I suggest an optional argument at the end, for example, with xparse and \NewDocumentCommand.

If the optional argument is not given, \quelle works like the intended one-argument version, if it is given Absatz #2 is printed in addition.

The check, whether it has been specified can be done with \IfValueT{#2}{}.

\documentclass{article}

\usepackage{xparse}
\usepackage{hyperref}

%\newcommand{\quelle}[1]{\textit{(Quelle: \url{#1})})}
\NewDocumentCommand{\quelle}{m+o}{\textit{(Quelle: \url{#1}\IfValueT{#2}{Absatz: #2)}}}

\begin{document}

Test: \quelle{www.wikipedia.de}

Test: \quelle{www.wikipedia.de}[sometext]

\end{document}


The following code delivers what you're after using the following setup:

1. Use \quelleattributes{<list>} to define the prefixes/attribute names in a comma-separate <list> you'll be supplying (Quelle, Absatz, ...).

2. Using etoolbox, we process the list sequentially, setting the attribute name, followed by the attribute. A text-comparison is done with each attribute name to see whether it matches Quelle. Only those are set using \url, while the others are set as-is.

\documentclass{article}

\usepackage{etoolbox}
\usepackage{hyperref}

\newcounter{quellecnt}
\makeatletter
\newcommand{\quelleattributes}[1]{%
\setcounter{quellecnt}{0}% Restart counter
\renewcommand*{\do}[1]{% How to update each item
\stepcounter{quellecnt}% Step counter
\@namedef{quelle@\thequellecnt}{##1}% Define \quelle@<num> to attribute
}%
\docsvlist{#1}% Process list
}

\newcommand{\quelle}[1]{%
\setcounter{quellecnt}{0}% Restart counter
\renewcommand*{\do}[1]{%
\stepcounter{quellecnt}% Step counter
\let\quelleformat\relax% Default formatting of attribute
\ifnum\pdfstrcmp{\@nameuse{quelle@\thequellecnt}}{Quelle}=0
\def\quelleformat{\url}% Attribute should be a \url
\fi
\@nameuse{quelle@\thequellecnt}: \quelleformat{##1} % Set attribute
}
(\textit{%
\docsvlist{#1}\unskip% Process list
})%
}

\makeatother

\begin{document}

\quelleattributes{%
Quelle,
Absatz%
}

Test: \quelle{www.wikipedia.de}

Test: \quelle{www.wikipedia.de, sometext}

\end{document}
`