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.

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?

share|improve this question
    
Hmmm. Having a really hard time deciding between egreg and Joseph Wright's solutions! –  mforbes Jan 4 '12 at 5:53
add comment

2 Answers

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.

share|improve this answer
    
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
add comment
\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.

enter image description here

share|improve this answer
    
Isn't the point of the question that we're not allowed to use XeTeX? –  Joseph Wright Jan 2 '12 at 14:37
1  
@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
show 1 more comment

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.