I'm trying to make uppercase the first letter in string and lowercase other letters. Example:
Input:eXample String and output Example string.
How can I do that?
- 173
4 Answers
\documentclass{article}
\newcommand\capmystring[1]{\capmystringaux#1\relax}
\def\capmystringaux#1#2\relax{\uppercase{#1}\lowercase{#2}}
\begin{document}
eXample String
\capmystring{eXample String}
\end{document}
In this case, \capmystring sends the argument to an auxiliary routine with an attached \relax token appended at the end. The auxiliary routine reads two arguments up to the \relax (one would hope and assume that the argument itself contains no \relax tokens). The way TeX absorbs arguments, the argument #1 will be a single token, whereas #2 will be all the remaining tokens up to (but not including) the originally supplied \relax. At that point it is as simple as applying \uppercase to the first token stored in #1, and \lowercase to the remaining tokens, all of which are stored in #2.
- 237,551
The expl3 language can do this using Unicode data:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \firstcap { m } { \text_titlecase:n {#1} }
\ExplSyntaxOff
\begin{document}
eXample String
\firstcap{eXample String}
\end{document}
(assuming a new enough LaTeX2e format; for older cases, add \usepackage[utf8]{inputenc} with pdfTeX.)
We might extend this approach to allow for language-specific case mappings
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \firstcap { O{} m }
{ \text_titlecase:nn {#1} {#2} }
\ExplSyntaxOff
\begin{document}
\firstcap{IJSSELMEER} % Ijsselmeer
\firstcap[nl]{IJSSELMEER} % IJsselmeer
\end{document}
- 259,911
- 34
- 706
- 1,036
-
Please be a bit more specific about the packages that need to be loaded to enable
\firstcapto operate on utf8-encoded characters such asö,ü,é,à,è,ł,ó, andż. – Mico Jul 13 '17 at 15:24 -
1@Mico I've updated the answer here: currently the pdfTeX version with direct input of Unicode chars needs the 'burning edge' version to avoid an error: CTAN update tomorrow. – Joseph Wright Jul 14 '17 at 21:51
-
Another solution using the stringstrings package:
\documentclass{article}
\usepackage{stringstrings}
\newcommand{\firstcap}[1]{\caselower[e]{#1}\capitalize{\thestring}}
\begin{document}
eXample String
\firstcap{eXample String}
\end{document}
Explanation:
\caselower makes the whole string lowercase, the option [e] saves the result in \thestring such that it can be further processed, finally \capitalize does what it says and outputs the result.
- 1,784
-
Is there a way to extend your code so that it can handle non-ASCII-encoded characters, such as
ä ö ü é à ê ł ó ż? (I picked these characters, more or less randomly, from German, French, and Polish keyboards...) – Mico Jul 15 '17 at 08:08 -
@Mico As far as I know the
stringstringspackage does not handle these special characters (please correct me if I am wrong). Thus I do not see a straight forward way to extend my solution. Sorry. – crixstox Jul 16 '17 at 12:21
Here's a LuaLaTeX-based solution that works with all UTF8-encoded characters. This approach can handle UTF8-encoded characters because it uses -- in place of the "standard" Lua string functions string.gsub, string.upper, and string.lower -- the functions unicode.utf8.gsub, unicode.utf8.upper, and unicode.utf8.lower. These functions are provided by the unicode.utf8 library, which is loade automatically by LuaTeX.
% !TeX program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function first_cap ( s )
s = unicode.utf8.gsub ( s , "(%a)(%a*)", function(x,y)
return ( unicode.utf8.upper(x) .. unicode.utf8.lower(y) )
end )
tex.sprint ( s )
end
\end{luacode}
\newcommand{\firstcap}[1]{\directlua{first_cap(\luastring{#1})}}
\begin{document}
\firstcap{eXample String}
\firstcap{Once upOn A tIMe i saw a BAT.}
\firstcap{ä ö ü é à è ł óÓÓÓ żĄĄĄ }
\end{document}
Addendum -- I just realized that I may have misinterpreted the OP's requirements: I had assumed that the uppercasing of the first letter in a word should apply to every word in the argument of \firstcap, not just the very first word. To make the uppercasing operation apply to the first word only (and thus applying the lowercasing operation to all other words in the argument of \firstcap), simply change the second argument of the Lua function unicode.utf8.gsub from "(%a)(%a*)" to "(%a)(.*)".
- 506,678
-
1One problem with the Lua UTF-8 support is it's not really clear what version of Unicode it is based on, and the treatment of contextual mappings is not documented. (Not a flaw in the answer, more a general frustration.) – Joseph Wright Jul 13 '17 at 15:22
-
@JosephWright - Thanks. So far, I've experienced only good results with the string functions of the
unicode.utf8library, which is loaded automatically by LuaTeX. (I don't know if this library is loaded by "plain" Lua5.2 or Lua5.3 as well, though.) I'll keep an eye out for potential problems. – Mico Jul 13 '17 at 15:28 -
1Not arguing with that: like I say, the issue isn't that it doesn't work but that it's not clear (to me) what exactly the detail is. As someone who has read the Unicode docs on case changing, I would feel happier knowing what has been implemented! – Joseph Wright Jul 13 '17 at 15:33


\relax, one could write something like\endcapmystringauxinstead of\relax. (Then the assumption would be that the argument contains no\endcapmystringaux… you have to draw the line somewhere!) – ShreevatsaR Jul 13 '17 at 17:14\expandafter\capmystring\expandafter{\mystr}. You could\newcommand\xcapmystring[1]{\expandafter\capmystring\expandafter{#1}}, to define a macro that expands the argument once before applying\capmystring. – Steven B. Segletes May 31 '21 at 13:55