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?
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?
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: updated to load the lua file just once instead of loading it with each macro invocation.
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)
Update 3: make the lua code more compact, and make sure next character is always using a different font.
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 08:09
\lipsum[1] for example). So, IMO, the pre_linebreak_filter approach would be superior.
– mpg
Oct 31 '10 at 13:53
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\fontb{TeX Gyre Adventor}
\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.
\everyletterhook would make this easy. Could such a thing be done in Luatex? – Charles Stewart Oct 27 '10 at 09:00pre_linebreak_filterthis 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. – خالد حسني Oct 27 '10 at 09:19