7

I want to make a command that has as inputs $X,t$ and outputs E[X_t] if t is given and outputs E[X] if t is missing.


So far

If I don't have the condition on t then

\newcommand{\e}[1]{E[#1]}

works, but otherwise... I'm stumpted.

8

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}
  • I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0 – AIM_BLB Sep 8 '18 at 15:15
  • 1
    @AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say \(\CmdE {X}[t[t]]\) (note the two pairs of []). The third option would produce weird output with \(\CmdE [t[t]]{X}\). – Phelype Oleinik Sep 8 '18 at 15:19
  • It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :) – AIM_BLB Sep 8 '18 at 15:39
7

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

  • Interesting! Mine breaks when there's nothing after the comma :) – Phelype Oleinik Sep 8 '18 at 19:52
2

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

  • With \aimblb@E from the classical implementation brace-stripping at the delimited arguments might occur. Besides this, \@nil is not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this. – Ulrich Diez Sep 9 '18 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.