1

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?

1

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:

enter image description here

\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
0

\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}

enter image description here

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.