Is there a LaTeX recommended standard for commands with optional arguments?
Even standard latex commands have optional arguments before or after the mandatory arguments, for example
\usepackage{zzzz}[1884/01/01]
what is true is that the simple interface to defining optional arguments provided by \newcommand
only lets you define one optional argument and it has to be first.
There are disadvantages to having a mandatory argument last if there is any possibility of the following text having a [
so for example
\title{TITLE}
[the opening remarks are in square brackets]
would take the parenthetic remark as the optional argument so would requrire
\title{TITLE}\relax
[the opening remarks are in square brackets]
or similar constructs to hide the [
from the argument scanner.
Note that that is not an issue for the trailing optional argument of \usepackage
as you can not have free text in the preamble.
With the fontspec and/or unicode-math packages (which, in turn, require the use of either LuaLaTeX or XeLaTeX), it's permissible to place the optional argument either before or after the mandatory argument in instructions such as \fontspec
, \setmainfont
, \setsansfont
, \setmonofont
, \setmathfont
, \newfontfamily
, \newfontface
etc.
Otherwise, the general LaTeX standard is that if a macro is defined via \newcommand
, any optional argument must come before the mandatory argument(s).
With LaTeX3 and xparse, the optional argument(s) can be essentially wherever you want (and user-defined macros may have more than one), except in particular cases where arguments are parsed “expandably”, such as when using \NewExpandableDocumentCommand
and friends.
Here is an example where we define a \printStuff
macro whose syntax is:
\printStuff[global style]{arg1}[style1][color1]{arg2}[style2][color2]
. This macro prints the two arguments separated by a vertical bar. It applies global style to both arguments (default: \bfseries
), then style1 plus color1 to the first argument, and style2 plus color2 to the second argument.
As customary in LaTeX3, we keep the implementation and user interface separate. The main logic is implemented in the internal function \my_print_stuff:nnnnnnn
, while the user-level macro \printStuff
merely defines the “public interface” (including default values) and calls \my_print_stuff:nnnnnnn
with the appropriate parameters. Of course, it is technically possible to do everything inside the public macro \printStuff
defined with \NewDocumentCommand
, but this way, one loses the benefits of separation between interface and implementation.
\documentclass[a4paper,12pt]{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{expl3}
\usepackage{xparse}
\usepackage[svgnames]{xcolor}
\ExplSyntaxOn
% Implementation (internal)
\cs_new:Nn \my_print_stuff:nnnnnnn
{
\noindent
{
#1 #3 % apply global and local “style”
#4 % optional color switch
#2 % first thing to print
}
\nobreakspace | \nobreakspace
{
#1 #6 % apply global and local “style”
#7 % optional color switch
#5 % second thing to print
}
\par \bigskip
}
% Public interface (user-accessible)
\NewDocumentCommand \printStuff { O{\bfseries} m O{} o m O{} o }
{
\my_print_stuff:nnnnnnn
{#1}
{#2} {#3}
{
\IfValueT {#4} { \color {#4} }
}
{#5} {#6}
{
\IfValueT {#7} { \color {#7} }
}
}
\ExplSyntaxOff
\begin{document}
\printStuff{first arg}{second arg}%
\printStuff[\itshape]{first arg}{second arg}%
\printStuff[\mdseries]{first arg}[\slshape]%
{second arg}[\scshape]%
\printStuff[\mdseries]{first arg}[\slshape][DarkRed]%
{second arg}[\scshape][DarkBlue]%
\end{document}