4

I am trying to write a function which takes only one optional argument. How do I do this with \newcommand?

Here is my attempt:

\newcommand{\s}[1]{%
    \ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}%
}

but it fails when I don't specify the argument.

edit: \newcommand{\s}[1][] does not work, as then the output is not as desired:

\s{2} -> S(Theta)2
John
  • 528
Grants
  • 41

2 Answers2

2

Edit:

In your edit you said:

edit: \newcommand{\s}[1][] does not work, as then the output is not as desired:

\s{2} -> S(Theta)2

So your definition of the command \s is incorrect. I propose you use this definition of \s:

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\s}{o}{% S(\Theta)\IfValueT{#1}{^{#1}}% }

\begin{document} $\s$

$\s[2]$ \end{document}

enter image description here

Using xparse to define the command and, as egreg suggested in the comments, using \IfValueT to check the presence of the optional argument and write the superscript.

You have to call \s[2], though. Defining an optional argument delimited by braces it not a good idea.

My previous answer:

You must add a default value to tell LaTeX that the argument is optional, like this:

%                 ↓ default value to the optional argument
\newcommand{\s}[1][]{...}

Or you could use xparse to have more control over the arguments:

\documentclass{article}

\usepackage{xparse}

\usepackage{ifthen}

% "usual" way \newcommand{\s}[1][]{% \ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}% }

% Exactly the same as above. The O{} tells xparse that the first argument % is optional and the default value is empty \NewDocumentCommand{\xxs}{O{}}{% \ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}% }

% This one also tells xparse that the first argument is optional, but % the presence of the optional argument can be tested with \IfNoValueTF \NewDocumentCommand{\xs}{o}{% \IfNoValueTF{#1}% {S(\Theta)}% {S^{#1}(\Theta)}% }

\begin{document} $\s$

$\s[a]$

$\xxs$

$\xxs[a]$

$\xs$

$\xs[a]$ \end{document}

  • The last example is not good, because an empty superscript triggers the insertion of \scriptspace. The second example can be written more compactly: S\IfValueT{#1}{^{#1}}(\Theta) – egreg Apr 30 '18 at 14:23
  • @egreg Thanks. I noticed the empty superscript later. I didn't know about \IfValueT. Many thanks again :) – Phelype Oleinik Apr 30 '18 at 14:25
0

An alternative approach using \@ifnextchar:

\documentclass{article}
\begin{document}
  \makeatletter
    \newcommand\@s{S(\theta)}
    \newcommand\s@opt[1]{S^{#1}(\theta)}
    \newcommand\s{\@ifnextchar\bgroup\s@opt\@s}
  \makeatother
  \[ \s\s{2} \]
\end{document}

Whats going on here is that when you do \s, then \@ifnextchar checks the next character.

If it is an opening bracket (or any \bgroup), then it executes \s@opt, if not it executes \@s. \s@opt expects one argument, but \@sdoes not.

That is: if the next character is a \bgroup (opening brace*) then LaTeX replaces \s with the \s@opt, else with the \@s.


Below this point at your own risk.


Down the rabbit hole we go:

You can do even more fancy stuff here, like make \s^{2} -> S^{2}(\theta) like so**:

\documentclass{article}
\begin{document}
  \makeatletter
    \newcommand\@s{S(\theta)}
    \def\s@pow^#1{S^{#1}(\theta)}
    \newcommand\s{\@ifnextchar^\s@pow\@s}
  \makeatother
  \[ \s \]     %<- prints S(\theta)
  \[ \s^{2} \] %<- prints S^2(\theta)
\end{document}

OR you could do an optional squaring, like \s{\theta}^{2} -> S^{2}(\theta) whilst \s{\theta} -> S(\theta):

\documentclass{article}
\begin{document}
  \makeatletter
    \def\s#1{\def\res@a{#1}\@ifnextchar^\s@pow\@s}
    \def\@s{S(\res@a)}
    \def\s@pow^#1{S^{#1}(\res@a)}
  \makeatother
  \[ \s{\theta} \]    %<- S(\theta)
  \[ \s{\theta}^{2} \]%<- S^{2}(\theta)
\end{document}

*:unless otherwise defined, which it's usually not.

**: This is probably not recommended because of some reasons. I do not know these reasons, but I feel like I'm doing something hacky?