0

I was reading the following post Different command definitions with and without optional argument on how to implement Different command definitions with and without optional argument. The example mentioned in this link covers the case of one optional argument. Following the same guidelines, I have been trying to do the same with two optional arguments using the following code without any luck:

\makeatletter
\@ifundefined{myDummy}
{

\def\myDummy
{
    \@ifnextchar[
    {\@WithAtLeastParam}{\@WithoutParam}
}
\def\@WithoutParam#1{x_{#1}}
\def\@WithAtLeastParam[#1]
{
    \@ifnextchar[
    {\@WithTwoParam}{\@WithOneParam}
}
\def\@WithTwoParam#1[#2]#3{x_{#1\rightarrow #2,#3}}

\def\@WithOneParam#1#2{x_{#1\rightarrow #2}}
}
\makeatother

Could any one please tell me what I have been doing wrong?

3
  • Welcome to TeX.SX! I have removed the LaTeX3 tag since your code example does not use LaTeX3. If you are interested in a LaTeX3/xparse solution, you may want to look into tex.stackexchange.com/a/2925/35864
    – moewe
    May 18, 2018 at 13:51
  • BTW: This code could cause unwanted white space because the line ends are not commented with % (see tex.stackexchange.com/q/7453/35864). If it is a math command, the spaces may not be problematic, but it is a good idea to keep this in mind in case one decides to write text mode macros.
    – moewe
    May 18, 2018 at 13:55
  • Note quite in this case, but the general idea is correct. \def\@WithoutParam#1{x_{#1}} does not end in a control sequence name that would gobble the space. And it actually has a space after it, but that is irrelevant because it is used in the preamble. If used in the document that becomes apparent, have a look at gist.github.com/moewew/bf2c7bda7be3a0bc1c189bde61916b26
    – moewe
    May 18, 2018 at 16:22

1 Answer 1

2

You need to comment out the newline after \def\@WithAtLeastParam[#1], else the argument must be followed by a space and TeX will fail to parse the macro arguments if there is no space. This is not necessary for \def\myDummy because of TeX's rules for spaces following control sequences, but behind each \def which's line ends with something that is not a control sequence the line ending should be commented. I also commented each parasitic space which could sneak into the macro (though those won't matter as the macro is used in math mode).

Also \@WithAtLeastParam grabs the first parameter, which is why you have to forward the grabbed argument to both \@WithTwoParam and \@WithOneParam.

I removed the \@ifundefined test for simplicity, you might add it again.

\documentclass[]{article}

\makeatletter
\def\myDummy%
  {%
    \@ifnextchar[
      {\@WithAtLeastParam}
      {\@WithoutParam}%
  }
\def\@WithoutParam#1{x_{#1}}
\def\@WithAtLeastParam[#1]%
  {%
    \@ifnextchar[
      {\@WithTwoParam{#1}}
      {\@WithOneParam{#1}}%
  }
\def\@WithTwoParam#1[#2]#3%
  {%
    x_{#1\rightarrow #2,#3}%
  }
\def\@WithOneParam#1#2%
  {%
    x_{#1\rightarrow #2}%
  }
\makeatother

\begin{document}
$\myDummy{1} \myDummy[1]{2} \myDummy[1][2]{3}$
\end{document}

The same behaviour but implemented using xparse:

\documentclass[]{article}

\usepackage{xparse}
\NewDocumentCommand \myDummy { o o m }
  {%
    x_{\IfValueT{#1}{#1\rightarrow}\IfValueT{#2}{#2,}#3}%
  }

\begin{document}
$\myDummy{1} \myDummy[1]{2} \myDummy[1][2]{3}$
\end{document}
2
  • Thanks for clarifying this issue. So there reason\def\@WithoutParam#1{x_{#1}} is not required to ended in a % is because it ends with a control sequence, where as \def\@WithAtLeastParam[#1]% needs the % because it doesn't end with a control sequence?
    – Yashar Z
    May 18, 2018 at 16:17
  • @YasharZ no, \def\@WithoutParam#1{x_{#1}} doesn't need the trailing %, because the argument of \def ends with the last closing bracket and since it is used before \begin{document} there is no whitespace inserted. \def\@WithAtLeastParam[#1]% needs the %, because the argument of \def which is specifying the arguments available to the defined macro (\@WithAtLeastParam) begins after the marco's name and ends at the opening {. This would contain a space prior to {, so the macro's arguments would be defined as [#1] where a space must follow the closing ].
    – Skillmon
    May 18, 2018 at 18:17

You must log in to answer this question.

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