# ifx macro not behaving as expected

I am trying the following code

\documentclass{article}
\usepackage{etoolbox,xstring}

\begin{document}

\def\FormatName#1{
\def\myname{My Name}
\def\name{#1}
\ifx\name\myname
\textbf{#1}
\else
#1
\fi
}

\FormatName{My Name}

\FormatName{My Name*}

\end{document}


The first call creates My Name in bold font, but not the second. Therefore, if I modify the definition of \name as

\def\name{\StrDel{#1}{*}}


But this does not work for either first or second call. I am not sure what I am doing wrong here. Any thoughts?

In order to see whether

\ifx<csnameA><csnameB>
<true>
\else
<false>
\fi


will follow the <true> or <false> branch, it's always a good idea to issue \show<csnameA> and \show<csnameB> before to see what they evaluate to. Let's use your first example:

\documentclass{article}

\begin{document}

\def\FormatName#1{%
\def\myname{My Name}%
\def\name{#1}%
\show\myname\show\name
\ifx\name\myname
\textbf{#1}%
\else
#1%
\fi
}

\FormatName{My Name}

\FormatName{My Name*}

\end{document}


The .log file shows

> \myname=macro:
->My Name.

> \name=macro:
->My Name.


These are clearly the same. Then it also shows:

> \myname=macro:
->My Name.

> \name=macro:
->My Name*.


These are clearly difference. Hence, the output is as expected. Now look at your updated setup that uses xstring:

\documentclass{article}
\usepackage{xstring}

\begin{document}

\def\FormatName#1{%
\def\myname{My Name}%
\def\name{\StrDel{#1}{*}}%
\show\myname\show\name
\ifx\name\myname
\textbf{#1}%
\else
#1%
\fi
}

\FormatName{My Name}

\FormatName{My Name*}

\end{document}


The .log shows

> \myname=macro:
->My Name.

> \name=macro:
->\StrDel {My Name}{*}.

> \myname=macro:
->My Name.

> \name=macro:
->\StrDel {My Name*}{*}.


In both cases, it's clear these entries don't match. Now (again), the output is expected.

If you want to delete a * from \name, you need to fully expand the deletion and use that in the comparison. xstring provides this expansion-and-storage as part of most of its string manipulation macros. Specifically for \StrDel, add an optional [<csname>] at the end:

\documentclass{article}
\usepackage{xstring}

\begin{document}

\def\FormatName#1{%
\def\myname{My Name}%
\StrDel{#1}{*}[\name]%
\show\myname\show\name
\ifx\name\myname
\textbf{#1}%
\else
#1%
\fi
}

\FormatName{My Name}

\FormatName{My Name*}

\end{document}


You can also use etoolbox to remove (the first) *:

\documentclass{article}
\usepackage{etoolbox}

\begin{document}

\def\FormatName#1{%
\def\myname{My Name}%
\def\name{#1}%
\patchcmd{\name}{*}{}{}{}%
\show\myname\show\name
\ifx\name\myname
\textbf{#1}%
\else
#1%
\fi
}

\FormatName{My Name}

\FormatName{My Name*}

\end{document}


If you want to remove all *, one can use regexpatch.

• Many thanks for such a useful answer! If I may ask a follow up question, is it possible to check the argument against a list/array of strings? For example if I want to highlight several names. If it is a question that deserves a new question, I will be happy to do that. – Ankush Dec 7 '16 at 2:13
• @Ankush: I don't understand. Perhaps a follow-up question is in order. – Werner Dec 7 '16 at 4:24

\def does not interpret the replacement text, so testing My Name against \StrDel{My Name*}{*} will obviously fail.

You can use expl3 (via xparse) and get much more:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\setspecialnames}{m}
{
\seq_gset_from_clist:Nn \g_ankush_specialnames_seq { #1 }
}

\seq_new:N \g_ankush_specialnames_seq
\tl_new:N \l_ankush_testname_tl

\NewDocumentCommand{\FormatName}{m}
{
\tl_set:Nn \l_ankush_testname_tl { #1 }
\tl_remove_all:Nn \l_ankush_testname_tl { * }
\seq_if_in:NVTF \g_ankush_specialnames_seq \l_ankush_testname_tl
{
\textbf{#1}
}
{
#1
}
}
\ExplSyntaxOff

\setspecialnames{My Name, A. Uthor}

\begin{document}

\FormatName{My Name} \FormatName{My Name*}

\FormatName{A. Uthor} \FormatName{A. Uthor*}

\FormatName{W. Riter}

\end{document}