2

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
    Add the default value of the optional argument to tell LaTeX that it is optional: \newcommand{\s}[1][]{...} – Phelype Oleinik Apr 30 '18 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. – Phelype Oleinik Apr 30 '18 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. – Phelype Oleinik Apr 30 '18 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}). – Steven B. Segletes Apr 30 '18 at 14:50
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}
| improve this answer | |
  • 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?

| improve this answer | |

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.