# Creating a macro that can selectively format capital letters

For a project my partner and I are working on, our text includes a great number of words in mixed lowercase and smallcaps:

We're currently doing this with a rather clunky macro:

\newcommand{\famword}[5]{%
#1\textsc{#2}#3\textsc{#4}#5}


This allows us to have two "clusters" of smallcaps within a word like this:

\famword{a}{k}{i}{l}{ulat}


which is just good enough to function without wasting too much of our time. However, since we're inputting a lot of words like this what we'd really like to do is have a macro where we could type the command like this:

\famword{aKiLulat}


and have it automatically convert the capital letters within the command to smallcaps in the document. We've searched for answers on this stack exchange and found a few solutions to adjacent issues, but none that addresses this particular problem.

As an addendum, some of these words contain the "Latin capital letter glottal stop" character Ɂ. Our existing macro deals with this character fine (as far as I can tell it just leaves it unaltered), but just in case any solution exists that would break on this non-ascii character, it won't do.

Does anybody know if this is doable?

• For those of us who aren't linguists: Could you give an example of a word that "contains the 'Latin capital letter glottal stop' character Ɂ"? – Mico Jan 13 '20 at 7:15
• for instance, there are words like eɁaɁa. – Sparksbet Jan 13 '20 at 7:34

When using modern fonts in conjunction with LuaLaTeX or XeLaTeX, one is (sometimes) able to delegate this this to the font, since OpenType Layout defines a font feature c2sc that translates capital letters to small cap letters. Unfortunately, Latin Modern does not contain this feature. When available, one can activate this via fontspec feature Letters=UppercaseSmallCaps. Example:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Stix Two Text} % Font with c2sc feature and italic SC

\begin{document}
\famword{aKiLulat}

\itshape \famword{aKiLulat}
\end{document}


• Nifty! I wasn't aware of the Letters=UppercaseSmallCaps option until I read your answer. – Mico Jan 13 '20 at 13:25
• Accepting this because it's what we ended up using -- it even puts the capital glottal stop in smallcaps, which our solution (or bare \textsc{}) wasn't doing! – Sparksbet Jan 13 '20 at 15:49

The tokcycle package (https://www.ctan.org/pkg/tokcycle) can be used for this.

\documentclass{article}
\usepackage{tokcycle}
\newcommand\famword[1]{%
\resettokcycle%
\Characterdirective{\ifcat A##1\ifnum##1<Z\addcytoks{%
\textsc{\char\numexpr32+##1\relax}}\else
\tokcyclexpress{#1}%
\the\cytoks%
}
\begin{document}
\famword{aKiLulat or even aK\textit{iLulat}!}
\end{document}


As I commented, to get italic small caps, you need a font that supports it, such as \usepackage{newtxtext}:

If one prefers an invocation that is more environment-based, rather than macro-based, there is this:

\documentclass{article}
\usepackage{tokcycle}
\tokcycleenvironment\famword%
{\ifcat A##1\ifnum##1<Z\addcytoks{%
\textsc{\char\numexpr32+##1\relax}}\else
{\processtoks{##1}}% <-GROUPS
\begin{document}
\famword aKiLulat or even aK\textit{iLulat}!\endfamword
\end{document}

• thanks so much for this answer! who knew there was a package that did this... is it possible to make the small caps also italicized when the rest is italicized? or is that just a matter of putting the scope of \textit{} over \famword rather than vice-versa? – Sparksbet Jan 13 '20 at 1:19
• @Sparksbet The problem is that with the default CM font, there is no version of italic small caps. If you use a font that supports it, it should properly italicize. As to my tokcycle package, its purpose is to provide a tool for cycling through a list of tokens, and "doing something." Here, the "something" I choose to do is to apply small caps to alphabetic letters that are initially capitalized. I have to first lowercase them, and then apply the \textsc. – Steven B. Segletes Jan 13 '20 at 2:58
• In the next latex version \textit + \textsc will combine to an italic small caps. The prerelease has just been uploaded and tomorrow it should be possible to test this with pdflatex-dev and similar dev-versions. – Ulrike Fischer Jan 13 '20 at 8:35

Here's a LuaLaTeX-based solution. It consists of (a) a main Lua function called uc2sc (short for "uppercase to smallcaps", I suppose) and an auxiliary Lua function called makesc which, together, do most of the work and (b) a LaTeX macro called \famword that acts as a wrapper for the uc2sc function. The Lua functions employ Lua's versatile built-in string.gsub and string.lower functions.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for "luacode" environment
\begin{luacode}

function makesc ( x )
return ( "\\textsc{" .. x:lower() .. "}" )
end
function uc2sc ( s )
return ( s:gsub ( "%u", makesc ) )
end

\end{luacode}
%% LaTeX wrapper macro:
\newcommand\famword[1]{\directlua{tex.sprint(uc2sc("#1"))}}

\usepackage{fontspec}
\setmainfont{Stix Two Text} % a font with italic-smallcap letters

\begin{document}
\famword{aKiLulat}

\itshape \famword{aKiLulat}
\end{document}


Using uppercase in the input to mean small caps in the output:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\famword}{m}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN { ([A-Z]+) } { \c{spark_lc:n}\cB\{\1\cE\} } \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Nn \spark_lc:n { \textsc { \text_lowercase:n { #1 } } }
\ExplSyntaxOff

\begin{document}

\famword{aKiLulat}

\end{document}


This only touches uppercase letters.