3

I'd like to define similar commands one with underscore the other — without. However such an approach throws me an error

\def\Fix#1{\mathrm{Fix}(#1)}
\def\Fix_#1#2{\mathrm{Fix}_{\,#1}(#2)}

I tried to change the catcode of the underscore and set it back, but \Fix_ seemed to work exactly like \Fix

\def\Fix#1{\mathrm{Fix}(#1)}
\catcode`\_=11
\def\Fix_#1#2{\mathrm{Fix}_{\,#1}(#2)}
\catcode`\_=8

What is the right way to do that?

4

Your first approach doesn't work because TeX can't have two definitions for the same command, so the second definition overwrites the first. Your second approach kind-of works because you have two commands, \Fix and \Fix_, but you cannot access \Fix_ normally.

You have to define \Fix to look ahead for an optional _. For example, with \@ifnextchar:

\documentclass{article}
\makeatletter
\DeclareRobustCommand\Fix{\@ifnextchar_{\@FixU}{\@Fix}}
\def\@Fix#1{\mathrm{Fix}(#1)}
\def\@FixU_#1#2{\mathrm{Fix}_{\,#1}(#2)}
\makeatother
\begin{document}
$\Fix{a}$ and $\Fix_{b}{a}$
\end{document}

Or, much easier (and robust), with xparse:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\Fix { e{_} m }
  {\mathrm{Fix}\IfValueT{#1}{_{\,#1}}(#2)}
\begin{document}
$\Fix{a}$ and $\Fix_{b}{a}$
\end{document}

Both documents produce:

enter image description here

2
  • Thank you for the detailed explanation why my attempts didn't work and for your solutions. I do especially like the xparse one. – antshar May 4 at 15:15
  • @antshar You're welcome! The e argument type for xparse is especially powerful if you have two tokens, for example _ and ^ (for example \NewDocumentCommand\Fix { e{_^} m }{\mathrm{Fix}\IfValueT{#1}{_{\,#1}}\IfValueT{#2}{^{\,#2}}(#3)}) then when you use the command you can have the arguments in any order (you could use the command above with $\Fix^{c}_{b}{a}$ or $\Fix_{b}^{c}{a}$). – Phelype Oleinik May 4 at 15:19

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.