How to make a command with default if missing

To allow that syntax you can use \@ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:

\documentclass{article}

% Option 1:
\makeatletter
\newcommand{\CmdE}[1]{%
  E[#1%
  \@ifnextchar,{\grab@sub}]}
\def\grab@sub,#1{%
  _{#1}]}
\makeatother

\begin{document}
\pagenumbering{gobble}

\begin{tabular}{ll}
\(\CmdE X\)      & \(\CmdE {XX}\)      \\
\(\CmdE X,t\)    & \(\CmdE {XX},t\)    \\
\(\CmdE X,{tt}\) & \(\CmdE {XX},{tt}\) \\
\end{tabular}

\end{document}

produces:

enter image description here

I propose a clearer (and more robust) syntax, using xparse:

\documentclass{article}

% Option 2:
\usepackage{xparse}
\NewDocumentCommand\CmdE{mo}
  {%
    E[#1\IfValueT{#2}{_{#2}}]%
  }

\begin{document}

\begin{tabular}{ll}
\(\CmdE {X}\)     & \(\CmdE {XX}\)     \\
\(\CmdE {X}[t]\)  & \(\CmdE {XX}[t]\)  \\
\(\CmdE {X}[tt]\) & \(\CmdE {XX}[tt]\) \\
\end{tabular}

\end{document}

the result is the same for both approaches.

Ooh, yes, there's plain LaTeX syntax too:

\documentclass{article}

% Option 3:
\newcommand{\CmdE}[2][]
  {%
    E[#2%
    \if\relax\detokenize{#1}\relax
    \else
      _{#1}%
    \fi]%
  }

\begin{document}

\begin{tabular}{ll}
\(\CmdE {X}\)     & \(\CmdE {XX}\)     \\
\(\CmdE [t]{X}\)  & \(\CmdE [t]{XX}\)  \\
\(\CmdE [tt]{X}\) & \(\CmdE [tt]{XX}\) \\
\end{tabular}

\end{document}

With the example below, \CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.

Use \CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.

\documentclass{article}

\makeatletter
\newcommand\CheckWhetherArgBlank[1]{%
  \if\relax\detokenize\expandafter{\@firstoftwo#1{}.}\relax
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
\newcommand\gobbletocomma{}\long\def\gobbletocomma#1,{}%
\newcommand\removecomma{}\long\def\removecomma#1,{#1}%
\newcommand\gobbledot{}\def\gobbledot.{}%
\newcommand\firsttoSelDoM{}\long\def\firsttoSelDoM#1,#2\SelDoM{{#1},}%
\newcommand\keeptillcomma[1]{%
   \expandafter\CheckWhetherArgBlank\expandafter{\gobbletocomma#1}{%
     \expandafter\gobbledot\removecomma#1%
   }{%
    \expandafter\keeptillcomma\expandafter{\firsttoSelDoM#1}%
   }%
}%
\newcommand\CmdE[1]{%
  \expandafter\CheckWhetherArgBlank\expandafter{\gobbletocomma#1,}%
  {E[#1]}% no comma
  {\expandafter\CheckWhetherArgBlank\expandafter{\gobbletocomma#1}%
    {\removecomma E[#1]}% comma but only blankness behind it.
    {E[{\keeptillcomma{.#1\SelDoM}}_{\gobbletocomma#1}]}% comma and something other than blankness behind it
  }%
}%
% Blankness = Either only explicit space tokens or no tokens at all.
\makeatother

\begin{document}

\begin{verbatim}
\begin{tabular}{ll}
\(\CmdE{X}\)          & \(\CmdE{{XX}}\)          \\
\(\CmdE{X,t}\)        & \(\CmdE{{XX},t}\)        \\
\(\CmdE{X, t}\)       & \(\CmdE{{XX}, t}\)       \\
\(\CmdE{X,{tt}}\)     & \(\CmdE{{XX},{tt}}\)     \\
\(\CmdE{X, tt}\)      & \(\CmdE{XX, tt}\)        \\
\(\CmdE{[XX], [tt]}\) & \(\CmdE{[XX], [tt],u}\)  \\
\(\CmdE{X,}\)         & \(\CmdE{{[XX], [tt]},u}\)\\
\end{tabular}
\end{verbatim}

\begin{tabular}{ll}
\(\CmdE{X}\)          & \(\CmdE{{XX}}\)          \\
\(\CmdE{X,t}\)        & \(\CmdE{{XX},t}\)        \\
\(\CmdE{X, t}\)       & \(\CmdE{{XX}, t}\)       \\
\(\CmdE{X,{tt}}\)     & \(\CmdE{{XX},{tt}}\)     \\
\(\CmdE{X, tt}\)      & \(\CmdE{XX, tt}\)        \\
\(\CmdE{[XX], [tt]}\) & \(\CmdE{[XX], [tt],u}\)  \\
\(\CmdE{X,}\)         & \(\CmdE{{[XX], [tt]},u}\)\\
\end{tabular}

\end{document}

enter image description here


A different expl3 implementation:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\E}{m}
 {
  \clist_set:Nn \l_aimblb_e_clist { #1 }
  \clist_pop:NN \l_aimblb_e_clist \l_aimblb_e_main_tl
  E[ \l_aimblb_e_main_tl % print the main
     \clist_if_empty:NF \l_aimblb_e_clist
      {
       \sb{ \clist_use:Nn \l_aimblb_e_clist { , } }
      }
  ]
 }
\clist_new:N \l_aimblb_e_clist
\tl_new:N \l_aimblb_e_main_tl
\ExplSyntaxOff

\begin{document}

Simple: $\E{X}$

With subscript: $\E{X,t}$

More subscripts: $\E{X,t,u}$

\end{document}

This supports more subscripts; since it is for free, I added them. You may have different usages for them.

enter image description here

A classical implementation:

\documentclass{article}

\makeatletter
\newcommand{\E}[1]{\aimblb@E#1,,\@nil}
\def\aimblb@E#1,#2,#3\@nil{%
  E[#1\if\relax\detokenize{#2}\relax\else_{#2}\fi]
}

\begin{document}

$\E{X}$

$\E{X,t}$

$\E{X,abcdef}$

Comparing with Ulrich's:

\begin{verbatim}
\begin{tabular}{ll}
\(\E{X}\)          & \(\E{{XX}}\)          \\
\(\E{X,t}\)        & \(\E{{XX},t}\)        \\
\(\E{X, t}\)       & \(\E{{XX}, t}\)       \\
\(\E{X,{tt}}\)     & \(\E{{XX},{tt}}\)     \\
\(\E{X, tt}\)      & \(\E{XX, tt}\)        \\
\(\E{[XX], [tt]}\) & \(\E{[XX], [tt],u}\)  \\
\(\E{X,}\)         & \(\E{{[XX], [tt]},u}\)\\
\end{tabular}
\end{verbatim}

\begin{tabular}{ll}
\(\E{X}\)          & \(\E{{XX}}\)          \\
\(\E{X,t}\)        & \(\E{{XX},t}\)        \\
\(\E{X, t}\)       & \(\E{{XX}, t}\)       \\
\(\E{X,{tt}}\)     & \(\E{{XX},{tt}}\)     \\
\(\E{X, tt}\)      & \(\E{XX, tt}\)        \\
\(\E{[XX], [tt]}\) & \(\E{[XX], [tt],u}\)  \\
\(\E{X,}\)         & \(\E{{[XX], [tt]},u}\)\\
\end{tabular}

\end{document}

enter image description here

Tags:

Macros