# Color all vowels differently in a LaTeX document

Is it possible to give the letters a,e,i,o,u,y a different color in a piece of text? For instance, color all the a's red, the e's blue, the i's green, etc.

EDIT: Without doing it manually of course.

• How big is this piece of text? Can you be more precise about your need? – egreg Oct 13 '13 at 21:07
• Coloring all vowels is more difficult than just coloring a,e,i,o,u,y. For instance, y is a vowel in "tyre" but not in "hay". – Tim N Oct 14 '13 at 15:37
• Just want to link these two questions: tex.stackexchange.com/q/120397/17423 – Sean Allred Jul 4 '18 at 17:41

Requires xelatex:

\documentclass{article}
\usepackage{color}
\XeTeXinterchartokenstate = 1
\newXeTeXintercharclass \vowelsclass

\XeTeXcharclass \a \vowelsclass
\XeTeXcharclass \e \vowelsclass
\XeTeXcharclass \i \vowelsclass
\XeTeXcharclass \o \vowelsclass
\XeTeXcharclass \u \vowelsclass

\XeTeXcharclass \A \vowelsclass
\XeTeXcharclass \E \vowelsclass
\XeTeXcharclass \I \vowelsclass
\XeTeXcharclass \O \vowelsclass
\XeTeXcharclass \U \vowelsclass

\XeTeXinterchartoks 0 \vowelsclass = {\bgroup\color{blue}}
\XeTeXinterchartoks 1 \vowelsclass = {\bgroup\color{blue}}
\XeTeXinterchartoks 2 \vowelsclass = {\bgroup\color{blue}}
\XeTeXinterchartoks 3 \vowelsclass = {\bgroup\color{blue}}
\XeTeXinterchartoks 255 \vowelsclass = {\bgroup\color{blue}}
\XeTeXinterchartoks \vowelsclass 0 = {\egroup}
\XeTeXinterchartoks \vowelsclass 1 = {\egroup}
\XeTeXinterchartoks \vowelsclass 2 = {\egroup}
\XeTeXinterchartoks \vowelsclass 255 = {\egroup}

\begin{document}

One two three four five six seven eight.

\end{document}


This is just for practicing with LaTeX3 code.

\documentclass{article}
\usepackage{xparse,xcolor}
\ExplSyntaxOn
\NewDocumentCommand{\colorize}{mm}
{
\cs_set:cpn { maryjane_color_#1: } { \textcolor{#2}{#1} }
}
\tl_new:N \l_maryjane_text_tl
\NewDocumentCommand{\changecolors}{ O{aeiou} m }
{
\tl_set:Nn \l_maryjane_text_tl { #2 }
\tl_map_inline:nn { #1 }
{
\tl_replace_all:Nnn \l_maryjane_text_tl { ##1 } { \use:c { maryjane_color_##1: } }
}
\l_maryjane_text_tl
}
\ExplSyntaxOff

\colorize{a}{red}
\colorize{e}{blue}
\colorize{i}{green}
\colorize{o}{yellow}
\colorize{u}{blue!30}

\begin{document}

\changecolors{The quick brown fox jumped over the lazy dog}

\changecolors[a]{The quick brown fox jumped over the lazy dog}

\end{document}


In the optional argument you can specify a subset of the declared letters. If you specify an undeclared letter (with \colorize), it will be gobbled.

• Very nice. So this works in the style of \textbf{...} or \textcolor{...}. How would you modify this to make it work in the style of \bfseries or \color{...}? – A.Ellett Oct 13 '13 at 21:41
• @A.Ellett I need to get the text before starting to change the colors. – egreg Oct 13 '13 at 21:47

A luatex solution to the problem:

\RequirePackage{luatex85}
\documentclass[varwidth]{standalone}
\usepackage{luacode}
\begin{luacode}
vowels = {'a', 'e', 'i', 'o', 'u', 'y',
'A', 'E', 'I', 'O', 'U', 'Y'}

vowels_char = {}
for _, value in pairs(vowels) do
vowels_char[#vowels_char + 1] = string.byte(value)
end

function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end

for n in node.traverse_id(node.id("glyph"), head) do
if table.contains(vowels_char, n.char) then
local n1, n2
n1 = node.new(node.id("whatsit"), node.subtype("pdf_literal"))
n2 = node.new(node.id("whatsit"), node.subtype("pdf_literal"))
n1.data = "q 1 0 0 rg"
n1.mode = 1
n2.data = " Q"
n2.mode = 1
end
end
end
\end{luacode}

\begin{document}

The quick brown fox jumped Over the lazy dog

\hbox{The quick brown fox jumped Over the lazy dog}

$a^2$
\end{document}


A few notes about the code. string.byte returns the ASCII value of its argument. Color change is done at pdf level with a 'whatits' pdf_literal node (q is a kind of begin group and Q a kind of end group in pdf, rg is the rgb model for non stroking operations).

A final note: my method does not work with inline math.

• ...or more precisely works too good, even for inline math :) – cjorssen Oct 4 '16 at 21:25