# Package for changing font with each letter?

I want to write a text in which each letter uses a different font. It is rather short. I guess I could make it letter by letter, selecting the font I want for each of them.

Are there easier ways?

-
Do you care at all which fonts the package chooses? This is possible (make all letters active!) but weird and I guess more trouble to write the package than to do this by hand. – Charles Stewart Oct 27 '10 at 8:59
An \everyletter hook would make this easy. Could such a thing be done in Luatex? – Charles Stewart Oct 27 '10 at 9:00
@Charles: It should not be hard to write a macro that gives a piece of text certain attribute (luatex attributes) and a function at pre_linebreak_filter this assigns nodes with that attribute a random font from a predefined set. But it might be too much work for a one use only feature. – Khaled Hosny Oct 27 '10 at 9:19
If the document itself is the text, I'd rather write a Python script that creates the TeX source file (then again, I'm more proficient in Python than in TeX, so YMMV). – Martin Tapankov Oct 27 '10 at 9:58
why would you want to do this? – Seamus Oct 31 '10 at 11:49

Right, I'm sure that this could be vastly improved. In particular, it doesn't like spaces and it doesn't like being fed an argument (so using the lipsum package to demonstrate it didn't work). Of course, the kerning is completely messed up, but then I'd be amazed at a solution that got that right!

It uses the fontspec package, and for some reason unknown to me, to use the proper names of the fonts required me to use lualatex instead of xelatex.

Without further ado, here's the code:

\documentclass{article}

\usepackage{fontspec}
\pagestyle{empty}

\newfontfamily\fonta{TeX Gyre Bonum}
\newfontfamily\fontc{TeX Gyre Chorus}
\newfontfamily\fontd{TeX Gyre Heros}
\newfontfamily\fonte{TeX Gyre Pagella}
\newfontfamily\fontf{TeX Gyre Schola}
\newfontfamily\fontg{TeX Gyre Termes}
\newfontfamily\fonth{GFS Artemisia}
\newfontfamily\fonti{GFS Bodoni}
\newfontfamily\fontj{Iwona}
\newfontfamily\fontk{GFS Didot}
\newfontfamily\fontl{GFS Neohellenic}
\newfontfamily\fontm{Kurier}
\newfontfamily\fontn{Free Mono}
\newfontfamily\fonto{Free Sans}
\newfontfamily\fontp{Free Serif}
\newfontfamily\fontq{Inconsolata}
\newfontfamily\fonts{Linux Libertine O}
\newfontfamily\fontt{Cyklop}
\newfontfamily\fontu{Old Standard}
\newfontfamily\fontv{Antykwa Poltawskiego}
\newfontfamily\fontw{STIX General}
\newfontfamily\fontx{Punknova}
\newfontfamily\fonty{Semafor}
\newfontfamily\fontz{UM Typewriter}

\makeatletter
\edef\my@relax{\relax}
\newcommand{\do@font}[1]{%
\edef\my@arg{#1}%
\ifx\my@arg\my@relax
\else
\@ifundefined{font#1}{}{%
\csname font#1\endcsname}%
\my@arg
\expandafter\do@font
\fi}

\newcommand{\dofont}[1]{%
\edef\my@arg{#1}%
\expandafter\do@font\my@arg\relax}
\makeatother

\begin{document}
\Large
\dofont{the quick brown fox jumped over the lazy dog}

\dofont{abcdefghijklmnopqrstuvwxyz}

\end{document}


All the fonts are ones that I found in my TeXLive2010 distribution.

-
XeLaTeX fonts can only be loaded by name if they are installed in the operating system (Mac) or with fontconfig (Windows/Linux). – Will Robertson Oct 28 '10 at 0:20
@Will: Thanks! That's cleared that up for me. – Loop Space Oct 28 '10 at 10:41

Here is a different approach than what I proposed above, The following lua code is to be saved in a file randomfont.lua:

function randomfonts(fonts, text)
local list = { }
local last, new

for s in string.gmatch(fonts,"([^, ]+)") do
list[#list+1] = s
end

for c in string.utfcharacters(text) do
if c:is_empty() then
tex.sprint(c)
else
while last==new do
new = math.random(#list)
end
tex.sprint(luatexbase.catcodetables.latex,
string.format([[{\%s %s}]], list[new], c))
last = new
end
end
end


And a test file:

\documentclass{article}
\usepackage{xcolor,fontspec}
\newfontfamily\one[Color=red]{TeX Gyre Termes}
\newfontfamily\two[Color=blue]{TeX Gyre Pagella}
\newfontfamily\three[Color=yellow]{TeX Gyre Heros}
\newfontfamily\four[Color=green]{TeX Gyre Bonum}

\directlua{dofile("randomfont.lua")} % load the lua file

\newcommand\randomfonts[2]{%
\directlua{randomfonts("#1", "#2")}%
}

\begin{document}
% can take text strings
\randomfonts{one, two, three, four}{abcdef ghijk lmn o}

% or even macros
\def\sometext{the quick brown fox jumps over the lazy dog}
\randomfonts{one, two, three, four}{\sometext}
\end{document}


Update 2: now using string.utfcharacters(text) instead of unicode.utf8.gmatch(text,".") as the former looks better (it is a luatex extension to lua string library)
Also you seem to be generating (and parsing) the list of fonts t each time you produce a single letter. Could you do this only once in the code of randomfonts? – Juan A. Navarro Oct 31 '10 at 8:09
Nice, but it won't work if the argument isn't purely expandable (say, \lipsum[1] for example). So, IMO, the pre_linebreak_filter approach would be superior. – mpg Oct 31 '10 at 13:53