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
4
  • 4
    Add the default value of the optional argument to tell LaTeX that it is optional: \newcommand{\s}[1][]{...} Apr 30, 2018 at 14:13
  • It looks like you've got two separate accounts, which means you cannot edit your original post or leave comments. The Stack Exchange staff can merge them together for you. Apr 30, 2018 at 14:38
  • I edited my answer to solve the problem you stated in your edit. Next time, leave a comment instead. People don't get notified of edits. You were lucky the edit fell in my review queue. Apr 30, 2018 at 14:46
  • 1
    With an optional argument, the syntax is \s[2] with square brackets. Then, the optional argument works as desired (i.e., producing S^2(\Theta}). Apr 30, 2018 at 14:50

2 Answers 2

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}
2
  • 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, 2018 at 14:23
  • @egreg Thanks. I noticed the empty superscript later. I didn't know about \IfValueT. Many thanks again :) Apr 30, 2018 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?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .