Can TeX do ugly typesetting (with poor kerning)?

An approach with XeTeX and \XeTeXinterchartoks (i.e. compile the below with xelatex):

\documentclass{article}
\usepackage{lipsum}
\input{random}

\newcount\randnum
\newcommand{\randkern}{%
  \setrannum{\randnum}{-30}{30}%
  \kern \dimexpr(\randnum pt/10)\relax
}

\XeTeXinterchartokenstate = 1
\XeTeXinterchartoks 0 0 = {\randkern}

\begin{document}
\lipsum[1]
\end{document}

output

You can make the range smaller if you'd like less aggressive miskerning, e.g. changing {-30}{30} to {-10}{20} gives:

less miskerning

The idea is simply to insert a random kern between any two characters. For example, if we typed something like:

L\kern 0.4pt o\kern 1.3pt r\kern -1.0pt e\kern -0.4pt m

and so on, we'd have the result from the image above. The above code just does this, with two shortcuts:

  • Defines a \randkern, using package random to generate random numbers, and the \dimexpr primitive introduced in e-TeX).
  • Uses \XeTeXinterchartoks (documented in the XeTeX reference guide). Setting \XeTeXinterchartoks 0 0 to \randkern inserts the token \randkern between any two characters of class 0 (most characters are of class 0 by default). For example, when our text contains the character L followed by the character o, XeTeX treats it as if you had typed the token \randkern between them (like typing L\randkern o).

With LuaTeX, there’s a kerning callback provided, which we can use for exactly this purpose. There is no built-in equivalent of \XeTeXinterchartoks, but the appeal of LuaTeX is that a lot of such functionality we can implement ourselves, in Lua. We can get:

output

with (compile the below with lualatex)

\documentclass{article}
\usepackage{lipsum}
\directlua{dofile('randomkern.lua')}
\begin{document}
\lipsum[1]
\end{document}

where randomkern.lua is:

function rekern(head)
   local i = head
   while i~=nil do
      j = i.next
      -- Skip over discretionary (hyphen) nodes
      while j~=nil and node.type(j.id)=='disc' do
         j = j.next
      end
      -- Insert a kern node between successive glyph nodes
      if node.type(i.id)=='glyph' and j~=nil and node.type(j.id)=='glyph' then
         k = node.new(node.id('kern'))
         head, i = node.insert_after(head, i, k)
         assert(node.type(i.id)=='kern')
      end
      -- Tweak existing kerns (including ones we inserted) by a random amount
      if node.type(i.id)=='kern' then
         i.kern = i.kern + math.random(65536*-1, 65536*2)
      end
      i = i.next
   end
end

luatexbase.add_to_callback('kerning', rekern, 'Introduce random kern nodes')

The idea is that the kerning callback gets a list of nodes: for example,

  temp 
  local_par 
  hlist  indent {}
  glyph  L
  glyph  o
  glyph  r
  glyph  e
  glyph  m
  glue  <spaceskip: 218235 plus 109117^0 minus 72745^0>
  glyph  i
  glyph  p
  disc 
  glyph  s
  glyph  u
  glyph  m
  glue  <spaceskip: 218235 plus 109117^0 minus 72745^0>
  glyph  d
  glyph  o
  disc 
  glyph  l
  glyph  o
  glyph  r
  glue  <spaceskip: 218235 plus 109117^0 minus 72745^0>
  glyph  s
  glyph  i
  glyph  t

and so on. We simply traverse this list, and between every two consecutive glyph nodes (possibly with a disc node between them), we insert a kern node, and give it a random value. (TeX stores all dimensions (lengths, etc.) internally in scaled points, where 65536 sp = 1 pt.)

Note that this version handles hyphenation automatically: only the kerning changes; the set of valid hyphenation or line-break points remains the same.