# Text transforming functions

Generally, I tend to see LaTeX commands as subroutines rather than functions. I was wondering if LaTeX allows the definition of functions for, say, transforming text by replacing substrings.

I suppose that feature is something possible, because some packages let the user to use functions, real functions, to transform text. Even MakeUppercase does it.

If I wanted to make a function that replaces all "U"s for "V"s, and all "W"s for "VV"s, what would it be the anatomy of that function?

• While slow and inefficient in many ways (it was my first package), the stringstrings package can do some neat things: ctan.org/pkg/stringstrings. There are other better options for standard tasks. – Steven B. Segletes Apr 15 '16 at 18:46
• There's the xesearch package, but it is specific to the XeTeX engine. For LuaTeX, there's the more expansive chickenize package. – jon Apr 15 '16 at 19:41
• – Mico Apr 16 '16 at 21:01

\documentclass{article}
\usepackage{stringstrings}
\newcommand\latinify[1]{%
\convertchar[q]{#1}{U}{V}%
\convertchar{\thestring}{W}{VV}%
}
\begin{document}
\def\myphrase{CUSTWINIUS}
\myphrase{} versus \latinify{\myphrase}
\end{document}


And now for some sleight of hand:

\documentclass{article}
\usepackage{stringstrings}
\newcommand\latinify[1]{%
\encodetoken{\kern}%
\encodetoken[2]{\footnotesize}%
\encodetoken[3]{\normalsize}%
\convertchar[e]{#1}{U}{\footnotesize V\normalsize}%
\convertchar[e]{\thestring}{W}{V\kern-5pt\footnotesize V\normalsize}%
\retokenize{\thestring}\thestring%
\decodetoken{\kern}%
\decodetoken[2]{\footnotesize}%
\decodetoken[3]{\normalsize}%
}
\begin{document}
\def\myphrase{UNCLE CUSTWINIUS WABBLEWAUSER}
\myphrase{} versus

\latinify{\myphrase}
\end{document}


• UNCLE CUSTWINIUS WABBLEWAUSER... he has a cousin, you know? – Steven B. Segletes Apr 15 '16 at 19:11
• Release Roderick? – Ian Thompson Apr 15 '16 at 20:13
• @IanThompson Slightly off in my recollection: "He has a wife, you know. You know what she's called? She's called... 'Incontinentia'... " imdb.com/title/tt0079470/quotes – Steven B. Segletes Apr 15 '16 at 20:17
• Yes, he has a German cousin. – egreg Apr 15 '16 at 20:33

The \replacestrings from OPmac can be used. It is implemented by few lines of TeX code:

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\bgroup \catcode!=3 \catcode?=3
\gdef\replacestrings#1#2{\long\def\replacestringsA##1#1##2!{%
\edef\tmpb{\expandafter}\expandafter\replacestringsA\tmpb?#1!%
\long\def\replacestringsA##1?{\def\tmpb{##1}}\expandafter\replacestringsA\tmpb
}
\egroup

\def\cnvUVW#1{\def\tmpb{#1}%
\replacestrings{U}{V}\replacestrings{W}{V\kern-.5emV}\tmpb}

\cnvUVW{UNCLE CUSTWINIUS WABBLEWAUSER}


Edit I am surprised that nobody suggested usage of active characters here. I repair it:

\def\adef#1{\catcode#1=13 \begingroup \lccode\~=#1\lowercase{\endgroup\def~}}

{\setUW UNCLE CUSTWINIUS WABBLEWAUSER}


A pure LuaLaTeX solution: A Lua function (named u2v_w2vv) and a LaTeX macro (named \uvwvv) that invokes the Lua function.

\documentclass{article}

%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function u2v_w2vv ( s )
s = string.gsub ( s , "U" , "V" )
s = string.gsub ( s , "W" , "VV" )
return tex.sprint ( s )
end
\end{luacode}

%% LaTeX-side code
\newcommand\uvwvv[1]{\directlua{u2v_w2vv(\luastring{#1})}}

\begin{document}
UNCLE CUSTWINIUS WABBLEWAUSER vs.

\uvwvv{UNCLE CUSTWINIUS WABBLEWAUSER}
\end{document}


Transformations like \MakeUppercase are not really text manipulations, because they rely on a predefined one-to-one mapping. With LuaTeX it's certainly possible to modify the input stream before typesetting it in fairly general ways. With legacy engines one can just make substitutions to the argument of a macro (like for \MakeUppercase).

Here's a way with l3regex; the example involves the German cousin of Uncle Custwinius, who spells his name with an Ä and wants his surname in italics.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\useV}{m}
{
\tl_set:Nn \l_corbal_withuw_tl { #1 }
\regex_replace_all:nnN { U } { V } \l_corbal_withuw_tl
\regex_replace_all:nnN { W } { VV } \l_corbal_withuw_tl
\tl_use:N \l_corbal_withuw_tl
}
\ExplSyntaxOff

\begin{document}

\useV{UNCLE CUSTWINIUS \textit{WABBLEWÄUSER}}

\end{document}


This answer addresses the letter replacements by a OpenType feature file for LuaTeX:

\documentclass{article}

\usepackage{filecontents}
\usepackage{fontspec}

\begin{filecontents*}{uw2v.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;

feature uw2v {
lookup U_TO_V {
sub U by V;
} U_TO_V;
lookup W_TO_VV {
sub W by V V;
} W_TO_VV;
} uw2v;
\end{filecontents*}

\DeclareRobustCommand*{\textuwtov}[1]{%
\begingroup
FeatureFile=uwtovs.fea,
RawFeature=+uw2v,
}%
#1%
\endgroup
}
\setmainfont[FeatureFile=uwtovs.fea]{latinmodernroman}
\setsansfont[FeatureFile=uwtovs.fea]{latinmodernsans}

\begin{document}

\noindent
UNCLE CUSTWINIUS WABBLEWAUSER\\
\textuwtov{UNCLE CUSTWINIUS WABBLEWAUSER}

\bigskip
\noindent
\textsf{UNCLE CUSTWINIUS WABBLEWAUSER\\
\textuwtov{UNCLE CUSTWINIUS WABBLEWAUSER}}
\end{document}
`