# Macro that capitalizes word if first in sentence

In a document I want to parametrize a pronoun so the document is easier to change when we change the person.

\newcommand\personname[0]{Joanna Smith}
\newcommand\personpronoun[0]{she}


This is great,

If \personname{} wants a second cookie, \personpronoun{} may ask for one.

But it gets awkward at the beginning of a sentence, because we'd like it to be capitalized.

\personpronoun is expected to use a napkin to wipe excess chocolate from fingers.

Is there a better way than defining two commands?

\newcommand\personpronounlc[0]{she}
\newcommand\personpronounuc[0]{She}

• No, not really. The only other thing you could do is using a * after \personpronoun to indicate this, This could be done with \makeatletter\newcommand\personpronoun{\@ifstar{She}{she}}\makeatother. Doing this in an automatic way is really tricky and there are too many exceptions to get it right. This would only result in you having to check each usage in the output to see whether everything went right, a manual approach like yours is preferable. Oct 4 '20 at 8:29

The reasonable solution adopted in some packages is indeed to define two commands, but using capitalization to distinguish them, so

\newcommand\personpronoun{she}
\newcommand\Personpronoun{She}


A more automatic method could be built on \spacefactor

\everypar{\spacefactor3000\relax}% beginning of paragraphs
% normally after sentences, the spacefactor is 3000
\DeclareRobustCommand\personpronoun{\leavevmode\ifnum\spacefactor<3000 she\else She\fi}


But I can't really recommend that, because the frequent unusual situations make it too unreliable, and much more trouble than simply capitalizing the commands as you type them.

Under the following conditions you can probably try to automatize things a bit:

• The macro \personpronoun is only used in normal paragraphs of text. (I.e., the game is only about (internal) vertical mode and horizontal mode. Not about restricted horizontal mode or whatsoever mathmode.)
• Punctuation-marks ., :, ?, ! have space-factor-codes/\sfcodes which can be distinguished from the \sfcodes of all other characters. Thus:
• The macro \personpronoun is only used with fonts/settings where this is the case.
• The macro \personpronoun is only used while \nonfrenchspacing is in effect.

Under these conditions you can have TeX check whether it is in \vmode and—if not—whether the current spacefactor equals the \sfcode of one of the punctuation-marks.

But this is not all too reliable. A lot of situations can occur where this kind of checking is not sufficient/is outmaneuvered.

\documentclass{article}

\makeatletter
\@ifdefinable\CheckVmodeOrPunctuationSpaceFactor{%
\DeclareRobustCommand\CheckVmodeOrPunctuationSpaceFactor{%
\ifvmode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode\.=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode\!=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode\?=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode\:=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{\@firstoftwo}%
}%
}%
}%
}%
}%
}%
\makeatother

\newcommand\personname{Joanna Smith}
\newcommand\personpronoun{\CheckVmodeOrPunctuationSpaceFactor{s}{S}he}

% \frenchspacing % <---Don't do this!
\nonfrenchspacing

\begin{document}

If \personname{} wants a second cookie, \personpronoun{} may ask for one. \personpronoun{} is expected to use a napkin to wipe excess chocolate from fingers.

\personpronoun{} is expected to use a napkin to wipe excess chocolate from fingers.

\end{document}


Due to the inherent unreliability of this approach I would prefer a different approach:

As \personpronoun is followed by an empty group to get the spacing behind the control-word-token right, you can define \personpronoun to take a mandatory argument which can be used for choosing between lowercase- and uppercase-variant.

In the following example if the argument of \personpronoun is empty, then the lowercased variant is used. Otherwise the uppercased variant is used:

\documentclass{article}

\makeatletter
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \CheckWhetherNull{<Argument which is to be checked>}%
%%                  {<Tokens to be delivered in case that argument
%%                    which is to be checked is empty>}%
%%                  {<Tokens to be delivered in case that argument
%%                    which is to be checked is not empty>}%
%%
%% If you don't have eTeX-extensions, then do:
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%%
%%\newcommand\CheckWhetherNull[1]{%
%%  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
%%  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
%%  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
%%  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
%%  {\@firstoftwo\expandafter{} \@firstoftwo}%
%%}%
%% If you have eTeX-extensions, then do:
\newcommand\CheckWhetherNull[1]{%
\romannumeral0\ifcat$\detokenize{#1}$%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@firstoftwo\expandafter{} \@firstoftwo}%
{\@firstoftwo\expandafter{} \@secondoftwo}%
}%
\makeatother

\newcommand\personname{Joanna Smith}
\newcommand\personpronoun[1]{\CheckWhetherNull{#1}{s}{S}he}

\begin{document}

If \personname{} wants a second cookie, \personpronoun{} may ask for one. \personpronoun{UC} is expected to use a napkin to wipe excess chocolate from fingers.

\personpronoun{UC} is expected to use a napkin to wipe excess chocolate from fingers.

\end{document}


But this is still cumbersome.

Better just define \personpronoun and \Personpronoun as suggested by Donald Arseneau.

You may wish to load the package xspace and to append an \xspace to the pronoun. In many situations \xspace correctly inserts a space token when one is needed but the space-character in the corresponding .tex-input-file was eaten during tokenization due to occurring right behind something that got tokenized as a control-word-token which caused TeX to switch the reading-apparatus to state S(skipping blanks).

\documentclass{article}
\usepackage{xspace}

\newcommand\personname{Joanna Smith\xspace}
\newcommand\personpronoun{she\xspace}
\newcommand\Personpronoun{She\xspace}

\begin{document}

If \personname wants a second cookie, \personpronoun may ask for one. \Personpronoun is expected to use a napkin to wipe excess chocolate from fingers.

\Personpronoun is expected to use a napkin to wipe excess chocolate from fingers.

\end{document}