2

What I have

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\newcommand\foo[2]{%
  \ifnum\pdf@strcmp{\unexpanded{#2}}{}=0 %
     \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
    {TRUE}
    {FALSE}%
}
\makeatother
\begin{document}

\foo{1}{}

\end{document}

It results True if and only if \foo{someargument}{} is called. What I need: It should return True if and only if \foo{someargument} is called (so someone left the second parameter out). In the end I will replace True and False with two different function calls.

How can I do this?

5
  • 3
    TeX always grabs two arguments if you set up a macro with two parameters: are you trying to make an 'optional group' argument? That's not really recommended (it's not in line with how TeX works in general), but it is doable.
    – Joseph Wright
    Jul 13 at 11:20
  • I am trying to do something like this: \entry{x}{y} registers glossary entry (x,y). \entry{x} prints the glossary entry. It has some advantages for me if I can implement it like this since I got used to using the command in the way it was used before (I decided to use the glossary package)
    – Natan
    Jul 13 at 14:04
  • but if you declare mandatory arguments it is not possible to omit them \entry{X} \entry{Y} then #2 of the first \entry is not missing, it is the second \entry. Jul 13 at 15:47
  • in your example, if you delete the {} then the second argument is not missing it is \par (from the blank line) Jul 13 at 15:50
  • Thanks @DavidCarlisle this gives me a deeper understanding on why my attempt has failed. I personally thought it was a null "" error, but your explanation really helped.
    – Natan
    Jul 13 at 16:01
3

You can trick TeX into doing something like this, but I strongly discourage from it. This isn't common (La)TeX syntax and in the long run it will likely cause more problems than it solves.

\documentclass{article}

\usepackage{amsgen}% for \new@ifnextchar

\makeatletter
\newcommand\foo[1]{%
   \new@ifnextchar\bgroup{\fooB{#1}}{\fooA{#1}}%
}
\newcommand{\fooA}[1]{Only one: `#1'.}
\newcommand{\fooB}[2]{You've got two: `#1' and `#2'.}
\makeatother

\begin{document}

\foo{1}

\foo{a}{b}

However: \foo{a}{}

\foo{a} {\bfseries This shouldn't do any harm.}

\end{document}

enter image description here

2
  • 2
    this is basically what the deprecated xparse g parameter does. Jul 13 at 15:49
  • @DavidCarlisle I know, but since I don't use xparse I do it the dumb way ;-)
    – campa
    Jul 13 at 18:29
5

If you declare a command with arguments, you can omit the {} but you can not omit the argument.

enter image description here

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\newcommand\foo[2]{%
  \ifnum\pdf@strcmp{\detokenize{#2}}{\noexpand\par}=0 %
     \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
    {TRUE}
    {FALSE}%
}
\makeatother
\begin{document}

\foo{1}{2}

\foo34

\foo{1}

\end{document}

In the third call here, the second argument is not missing, it is the blank line, which is reported as \par.

If you omit the blank line the second argument is \end then latex will typeset document and wait at the * prompt for you to type \end{document} to stop the run.

You could of course detect \end in your macro and return \end to the input in that case, but input such as {\foo{1}} will always give a low level error

! Argument of \foo has an extra }.

You could avoid the issue by not declaring the command has two arguments, as shown in the other answer, but this is taking you a long way from standard LaTeX syntax, where optional arguments are delimited by [] not {}.

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.