xmakefirstuc combined with MakeTextLowercase

I am trying to convert a string as in the example, with all lowercase characters except the first. However, xmakefirstuc does not like me that much. Here's my MWE:

% arara: pdflatex
\documentclass{book}
\usepackage{xstring}
\usepackage{textcase}
\usepackage{mfirstuc}
\newcommand{\howtodothis}[1]{%
\StrSubstitute{#1}{ }{-}[\mylong]%
\xmakefirstuc{\MakeTextLowercase{\mylong}}\\%
\xmakefirstuc\expandafter{\MakeTextLowercase{\mylong}}\\%
\xmakefirstuc{\expandafter\MakeTextLowercase{\mylong}}\\%
\xmakefirstuc{\MakeTextLowercase\expandafter{\mylong}}\\%
\xmakefirstuc{\MakeTextLowercase{\expandafter\mylong}}\\%
\xmakefirstuc\expandafter\relax{\MakeTextLowercase{\mylong}}\\%
\xmakefirstuc{\expandafter\relax\MakeTextLowercase{\mylong}}\\%
\xmakefirstuc{\MakeTextLowercase\expandafter\relax{\mylong}}\\%
\xmakefirstuc{\MakeTextLowercase{\expandafter\relax\mylong}}\\%
\expandafter\xmakefirstuc{\MakeTextLowercase{\mylong}}\\%
\expandafter\xmakefirstuc\expandafter{\MakeTextLowercase{\mylong}}\\%
\expandafter\xmakefirstuc{\expandafter\MakeTextLowercase{\mylong}}\\%
\expandafter\xmakefirstuc{\MakeTextLowercase\expandafter{\mylong}}\\%
\expandafter\xmakefirstuc{\MakeTextLowercase{\expandafter\mylong}}\\%
\expandafter\xmakefirstuc\expandafter\relax{\MakeTextLowercase{\mylong}}\\%
\expandafter\xmakefirstuc{\expandafter\relax\MakeTextLowercase{\mylong}}\\%
\expandafter\xmakefirstuc{\MakeTextLowercase\expandafter\relax{\mylong}}\\%
\expandafter\xmakefirstuc{\MakeTextLowercase{\expandafter\relax\mylong}}\\%
}
\begin{document}\noindent%
\howtodothis{First Letter Should Be Uppercase, All Others Lowercase.}
\end{document}

-
Have a look here. – Hackbard_C Aug 19 '14 at 13:11

\xmakefirstuc{\MakeTextLowercase{\mylong}}


is a shortcut for

\expandafter\makefirstuc\expandafter{\MakeTextLowercase{\mylong}}


which attempts to expand \MakeTextLowercase{\mylong}. Since \MakeTextLowercase is robust, no expansion is performed. The TeX primitive \lowercase also doesn't expand, so trying to expand to lowercase and then applying \makefirstuc won't work. However, it will work if you first expand \mylong. Like this:

\expandafter\makefirstuc\expandafter{\expandafter\MakeTextLowercase\expandafter{\mylong}}


Or using \xmakefirstuc:

\xmakefirstuc{\expandafter\MakeTextLowercase\expandafter{\mylong}}


Here's the MWE:

% arara: pdflatex
\documentclass{book}
\usepackage{xstring}
\usepackage{textcase}
\usepackage{mfirstuc}
\newcommand{\howtodothis}[1]{%
\StrSubstitute{#1}{ }{-}[\mylong]%
\xmakefirstuc{\expandafter\MakeTextLowercase\expandafter{\mylong}}%
}
\begin{document}\noindent%
\howtodothis{First Letter Should Be Uppercase, All Others Lowercase.}
\end{document}


This is the result:

Edit: This is actually equivalent to:

\MakeTextLowercase{\MakeUppercase{F}irst-Letter-Should-Be-Uppercase,-All-Others-Lowercase.}


This may seem a bit contradictory as logic suggests that the \MakeTextLowercase should counteract the \MakeUppercase, but this is a result of the way that TeX processes tokens (see @egreg's comment below). You can see this from:

\lowercase{\uppercase{f}}


which produces an uppercase F.

-
\lowercase{\uppercase{f}} simply passes \uppercase{f} to the next stage; the character tokens are transformed using the \lccode table and the resulting token list is placed back in the main input stream; then \uppercase{f} is processed in a similar way, which produces F. If you do \uppercase{\lowercase{f}} or \uppercase{\lowercase{F}}, you get f. – egreg Aug 19 '14 at 16:01
@egreg I think the point being made in the edit is that people might expect a 'functional' outcome (lowercase-of-uppercase-of-'f'), which as the TeX experts know is not what you get :-) – Joseph Wright Aug 19 '14 at 16:03
@JosephWright There is a functional outcome, but in the reverse order. – egreg Aug 19 '14 at 16:04
@egreg It's contrary to what most computer programmers would expect (as quite often happens with TeX). In most languages newString = lowercase(uppercase(orgString)) would result in a lowercase string. I'll edit my edit. – Nicola Talbot Aug 19 '14 at 16:45

Case changing use TeX primitives is not expandable, which is why trying to 'force the issue' isn't easy to get right here. Nicola has shown how to handle this using mfirstuc. A 'classical' approach to the same issue is to split the first token off from all of the rest, for example

\documentclass{book}
\usepackage{xstring}
\usepackage{textcase}
\newcommand\howtodothis[1]{%
\howtodothisaux#1\stop
}
\newcommand\howtodothisaux{}
\long\def\howtodothisaux#1#2\stop{%
\MakeTextUppercase{#1}%
\MakeTextLowercase{#2}%
}
\begin{document}\noindent%
\howtodothis{First Letter Should Be Uppercase, All Others Lowercase.}
\end{document}


With an up-to-date expl3, you can do this using the expandable (but experimental) \tl_mixed_case:n function and no need to split the input:

\documentclass{book}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand{\howtodothis}[1]{%
\tl_mixed_case:n {#1}%
}
\ExplSyntaxOff
\begin{document}\noindent%
\howtodothis{First Letter Should Be Uppercase, All Others Lowercase.}
\end{document}


Note that this will case change UTF-8 input if used with XeTeX/LuaTeX. Also note that as it's experimental the name and/or behaviour is not yet fixed (the general idea is good, it's the detail).

-