Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
Have a look here. –  Hackbard_C Aug 19 at 13:11

2 Answers 2

up vote 4 down vote accepted
\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:

First-letter-should-be-uppercase-all-others-lowercase

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.

share|improve this answer
2  
\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 at 16:01
1  
@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 at 16:03
    
@JosephWright There is a functional outcome, but in the reverse order. –  egreg Aug 19 at 16:04
1  
@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 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).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.