I would like to bold-face occurrences of strings conditionally on them occurring within longer strings, using the \IfSubStr and \StrSubstitute macros from the xstring package. The issue that I'm running into is related to expansion of the \makebold macro, which depends on the work of the \surnamefirst and \surnamelast macros. How can I get the \makebold macro to work correctly?
\documentclass{article}
\usepackage{xstring}
\newcommand{\name}{John Doe}
\makeatletter
% Macro to extract and store "last name" from full-name string
\newcommand{\lastname}{%
\IfSubStr{\name}{.}%
{\StrBehind{\name}{. }}%
{\StrBehind{\name}{ }}%
[\@lastname]
}
% Extract and store first name from full-name string
\newcommand{\firstname}{%
\StrBefore{\name}{ }[\@firstname]
}
% Extract first initial from full-name string
\newcommand{\firstinitial}{%
\StrLeft{\name}{1}[\@firstinitial]
}
% Extract middle initial (if any) from full-name string
\newcommand{\middleinitial}{%
\StrBetween{\name}{ }{.}[\@middleinitial]
}
\newcommand{\testxstring}{%
\middleinitial % Find middle initial
\IfStrEq{\@middleinitial}{}%
{No middle initial!}%
{Middle initial: \@middleinitial}
}
% Surname first
\newcommand{\surnamefirst}{%
\firstinitial
\middleinitial % Find middle initial
\lastname
\IfStrEq{\@middleinitial}{}%
{\@lastname, \@firstinitial.}%
{\@lastname, \@firstinitial.~\@middleinitial.}
}
% Surname last
\newcommand{\surnamelast}{%
\firstinitial
\middleinitial % Find middle initial
\lastname
\IfStrEq{\@middleinitial}{}%
{\@firstinitial.~\@lastname}%
{\@firstinitial.~\@middleinitial.~\@lastname}
}
% Render full name in bold
\newcommand{\makeboldname}[1]{%
\expandarg
\IfSubStr{#1}{\getvalue{name}}%
{\StrSubstitute{#1}{\name}{\textbf{\name}}\par}%
{#1}
}
% Render only last name in bold
\newcommand{\makeboldlastname}[1]{%
\lastname
\expandarg
\IfSubStr{#1}{\@lastname}%
{\StrSubstitute{#1}{\@lastname}{\textbf{\@lastname}}\par}%
{#1}
}
% Render surname-first and surname-last in bold
\newcommand{\makebold}[1]{%
\expandarg
\IfSubStr{#1}{\surnamefirst}%
{\StrSubstitute{#1}{\surnamefirst}{\textbf{\surnamefirst}}\par}%
{\IfSubStr{#1}{\surnamelast}%
{\StrSubstitute{#1}{\surnamelast}{\textbf{\surnamelast}}\par}%
{#1}%
}
}
\makeatother
\begin{document}
\name
\surnamefirst
\surnamelast
\makeboldname{His name was John Doe.}
\makeboldlastname{Again, Doe was his last name.}
\makebold{I heard that Doe, J. was from Kentucky.}
\makebold{There was also a J. Doe from New York.}
\end{document}
Expected output:
John Doe
Doe, J.
J. Doe
His name was John Doe.
Again, Doe was his last name.
I heard that Doe, J. was from Kentucky.
There was also a J. Doe from New York.

\makebolddoes not work due to expansion issues with its use of\IfSubStrfor calling\surnamefirstor\surnamelast. How can I store the result of\IfSubStrfor use in\makebold? – Adam Erickson Jan 17 '19 at 17:31\surnamelastand\surnamefirst. – Adam Erickson Jan 17 '19 at 17:45\makeboldname{His name was John Doe.}– egreg Jan 17 '19 at 23:29