# Uppercase Smallcaps with LaTeX (not XeLaTeX)?

In XeLaTeX there is an UppercaseSmallCaps font option (as mentioned in this question for example) that will cause upper-case letters to be rendered in small-caps and lower-case letters to remain.

Question: How can UppercaseSmallCaps be implemented in plain LaTeX (or pdfLaTeX) so that text like \upsc{ABCdef} will be rendered as \textsc{abc}def?

-
Hmmm. Having a really hard time deciding between egreg and Joseph Wright's solutions! –  mforbes Jan 4 '12 at 5:53

Maybe a bit over the top, but you could use l3regex to achieve this

\documentclass{article}
\usepackage{l3regex,xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_rescan:nn { nV }
\NewDocumentCommand \upsc { m }
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:nnN { ([A-Z]+) }
{ \c{textsc} \cB\{ \c{lowercase} \cB\{ \1 \cE\} \cE\} } \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\upsc{ABCabcDEF}
\end{document}


This uses the latest experimental version of l3regex, which is on CTAN and which has an 'extended regex' system to allow the inclusion of category-code information in the search and replace text.

You could set up a search for upper-case letters in the same way using alternative methods (such as xstring).

Explanation of the code

The basic idea here is to store the text, do a replacement then print it again. I've chosen to replace each upper case <Letter> by

\textsc{\lowercase{<Letter>}}


The search part is a simple regex ([A-Z]+), which will capture the letter as \1 (in the replace part). There, \c{textsc} will create the control sequence \textsc in the updated text and \c{lowercase} creates \lowercase. \1 is the captured letter from the search part, while \cB\{ and \cE\} possibly need a bit of explanation. In the replacement text, \cB\{ creates the character { (which needs to be escaped) with category code 'Begin group'. Similarly, \cE\} creates the character } with category code 'End group'.

The final stage is to insert the result into the input stream. If you want to see what is happening, try adding \tl_show:N \l_tmpa_tl after the \tl_use:N line.

-
You can't use fontspec with pdfTeX, so UppercaseSmallCaps is not directly relevant. –  Joseph Wright Jan 2 '12 at 14:25
Support for accents would be more challenging (they'll work in the lower case part but not the upper case part). –  Joseph Wright Jan 2 '12 at 14:38
Nice demonstration of LaTeX3! Better than egreg's in that it works with spaces and paragraphs (with a small modification), but an order of magnitude slower, and disables kerning... –  mforbes Jan 4 '12 at 5:48
\documentclass[convert,border=1]{standalone}

\makeatletter
\newif\ifsc@active
\newif\ifnf@active
\def\upsc#1{{\sc@activefalse\nf@activetrue\@upsc#1\@nil}}
\def\@upsc#1{\ifx#1\@nil\else\@@upsc{#1}\expandafter\@upsc\fi}
\def\@@upsc#1{%
\ifnum\uccode#1=#1\relax
\ifsc@active\else\sc@activetrue\nf@activefalse\scshape\fi
\expandafter\@firstoftwo
\else
\ifsc@active\sc@activefalse\fi
\ifnf@active\else\nf@activetrue\normalfont\fi
\expandafter\@secondoftwo
\fi
{\lowercase{#1}}%
{#1}}
\makeatother

\begin{document}
\upsc{xABCdovff}
\end{document}


Doesn't work with accented letters, of course.

-
Isn't the point of the question that we're not allowed to use XeTeX? –  Joseph Wright Jan 2 '12 at 14:37
@JosephWright Now it works with pdflatex (and does ligatures and kerning when possible). –  egreg Jan 2 '12 at 15:49
Nice fast solution! Better than Joseph's solution in that it is an order of magnitude faster and does ligatures and kerning, but it does not allow for spaces, paragraphs etc. –  mforbes Jan 4 '12 at 5:53
@mforbes No, of course. But I believed it was for acronyms or abbreviations. –  egreg Jan 4 '12 at 9:41
\def\upsc#1{{...}} should have an enclosing group so that the smallcaps do not leak. Will fix later when I test more thoroughly. –  mforbes Jan 17 '12 at 6:07