# Ifthenelse fails if is part of argument

I have followed very simple tutorial to create own listof. Link is https://texblog.org/2008/07/13/define-your-own-list-of/

It worked great, I just wanted to add optional parameter. If this optional is given, to the custom ToC it will send this optional parametr. But I get error, which I don't understand.

\usepackage{tocloft}
...
\newcommand{\listTMname}{List of TMs}
\newlistof{TM}{tms}{\listTMname}

\newcommand{\TM}[2][]{%
\refstepcounter{TM}
\par\noindent\textbf{TM \theTM. #2}
}\par}


I wanted to use it as follows: \TM{To text and ToC} and \TM[to ToC]{To text} But I get error calling is on line 94:

Illegal parameter number in definition of \reserved@a. l.94 \TM{Test...}

What I did wrong? If in \addcontentsline... command I remove ifthenelse and put it into \textbf 2 line above it works, but not opposite way.

• Have you tried enclosing the whole \ifthenelse in braces? – TeXnician Apr 30 '17 at 15:10
• Welcome to TeX - LaTeX! To good to get useful answers it usually best to collect your code snippets in to minimal compilable document demonstrating the problem. – Andrew Swann Apr 30 '17 at 15:28
• @TeXnician yes I tried, did not help, Andrew Swann thanks, next time I will know – Arxeiss Apr 30 '17 at 18:22

The command \ifthenelse is fragile and so is the whole construction

\ifthenelse{\equal{#1}{}}{#2}{#1}


Use an expandable test, such as

\newcommand{\TM}[2][]{%
\par\noindent
\refstepcounter{TM}% <--- don't forget %
\protect\numberline{\theTM}%
\if\relax\detokenize{#1}\relax#2\else#1\fi
}%
\textbf{TM \theTM. #2}% <--- don't forget %
\par\nopagebreak
}


Alternatively, with \usepackage{xparse}:

\NewDocumentCommand{\TM}{om}{%
\par\noindent
\refstepcounter{TM}% <--- don't forget %

I changed the position of the various items for placing the anchor (in case you use hyperref) in the right place.
• Works perfectly, thank you. Glad that you pointed version with and withou package xparse – Arxeiss Apr 30 '17 at 18:35