Tx · LaTeX & TikZ

How Can You Define a LaTeX Command with a Variable Number of Arguments?

Published By the 9to5Science editorial team

At a glance

  1. 1. Know the limit

    The standard \newcommand syntax defines a fixed number of arguments, with at most one optional argument.

  2. 2. Choose a representation

    For a variable-length collection, pass one list argument or use a repeated-group parser with an explicit terminator.

  3. 3. Process the items

    Map over the list, or make the parser consume one braced group at a time.

  4. 4. Test edge cases

    Check empty input, grouped items, special characters, and how the command behaves in moving arguments.

LaTeX commands defined with \newcommand have a fixed argument specification. Without an optional argument, you can define a command with zero through nine mandatory arguments; with classic optional-argument syntax, the first of at most nine argument slots is optional. It does not provide a built-in “take as many arguments as follow” option.

For a collection whose length varies, pass the collection as one argument and process it as a list. If you specifically need consecutive braced arguments such as \cmd{a}{b}{c}, you can write a recursive parser, but it needs a clear stopping rule.

What \newcommand supports

The ordinary form is \newcommand{\name}[n]{definition}, where n is the fixed number of mandatory arguments. Inside the definition, refer to them as #1, #2, and so on. With optional-argument syntax, n counts the optional first argument as one of the argument slots, so there can be at most eight mandatory arguments in that case.

For example, this command always has one mandatory argument and optionally accepts a greeting as its first argument:

\newcommand{\greet}[2][Hello]{#1, #2!}

You can write \greet{Sam} to get “Hello, Sam!” or \greet[Welcome]{Sam} to get “Welcome, Sam!” The optional argument means the command may receive either one or two arguments in use, but it does not make the command variadic: its argument structure is fixed.

The newer \NewDocumentCommand interface offers more ways to specify fixed arguments, including optional and delimited arguments. It still does not mean “repeat this argument type until there are no more.” TeX needs a rule for deciding whether the next tokens belong to the command or to the text that follows it.

For a variable number of items, a single list argument is generally easier to read and maintain. This complete example uses LaTeX’s built-in expl3 list-mapping function:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\showitems}{m}
  {
    \clist_map_inline:nn {#1}
      { \textbf{##1}\par }
  }
\ExplSyntaxOff

\begin{document}
\showitems{red, green, blue}
\end{document}

Here \showitems has exactly one mandatory argument, but that argument can contain as many comma-separated items as needed. The mapping function processes each item in turn. The doubled ##1 is required because it refers to the item parameter inside a definition that is itself inside another definition.

This approach is convenient when the items are naturally a comma-separated list. If an item itself contains a comma, protect it with braces and check the list parser’s grouping rules for your intended input. For arbitrary text, a custom list syntax or an environment may be clearer than commas.

If you need \cmd{a}{b}{c} syntax

A sequence of braced groups can be parsed recursively if you append a private end marker and stop when the parser reaches it. For example:

\makeatletter
\newcommand{\showgroups}[1]{\showgroups@loop#1\showgroups@stop}
\def\showgroups@loop{%
  \@ifnextchar\showgroups@stop
    {\showgroups@finish}
    {\showgroups@item}%
}
\def\showgroups@item#1{%
  \textbf{#1}\par
  \showgroups@loop
}
\def\showgroups@finish\showgroups@stop{}
\makeatother

Use it as \showgroups{{red}{green}{blue}}. The outer braces provide the command’s one mandatory argument; inside it, each item is a separate braced group. The command appends \showgroups@stop, processes groups one at a time, and finishes when it sees that marker. With an empty argument, it reaches the marker immediately and produces no items.

This parser is deliberately narrow: each item must be braced, and it formats each item as text. More elaborate content, nesting, or use in section titles and other moving arguments may require a more robust design. Keep the marker private and avoid putting it into user input, or the parser may stop early.

Common mistakes

  • Expecting an omitted argument count to mean “any number.” \newcommand requires a fixed count; a list or a parser is needed for variable-length input.
  • Assuming optional arguments repeat automatically. The classic optional-argument syntax gives one optional first argument, not an arbitrary sequence of optional arguments.
  • Leaving the parser without an end condition. Without a delimiter or terminator, TeX cannot reliably distinguish more arguments from following document text.
  • Forgetting the item braces. In the repeated-group example, \showgroups{{red}{blue}} supplies two groups. Unbraced input is not parsed as one whole item.
  • Using the wrong parameter marker in nested definitions. In the expl3 example, ##1 refers to the mapped item; a single # would be interpreted as the enclosing command’s parameter marker.

When users can choose how many items to provide, a single list argument is usually the best interface. Use repeated-group parsing only when that syntax is important and its stopping convention is explicit.

References

  1. The LaTeX3 Interfaces: `xparse` documentation
  2. The LaTeX2e Sources

Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.