How to simulate old typewriter?

bad typewriter

I've generated a lookup table of macros to print characters with a vertical offset that's random but consistent for each character. This covers all printable ascii characters except those that have to be escaped in LaTeX.

A few letters are used as examples of special cases for how the characters can be further modified:

  • T has a 50% chance of a double hit (with the underneath hit in grey).
  • e is so worn it's fake bold.
  • t has a bent arm, tilting it to the right
  • w has a wobbly arm resulting in a random tilt to the left

A similar approach could be used to make compound symbols (like {'\hspace{-0.5em}.} instead of !, but this doesn't work very well in cmtt).

\documentclass{article}
\renewcommand{\familydefault}{cmtt}
\renewcommand{\rmdefault}{cmtt}
\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\usepackage{xstring}
\usepackage[first=0, last=10,counter=rnd]{lcg}
\usepackage{fp}
\usepackage{calc}
\usepackage{rotating}
\usepackage{ulem}
\newlength{\charwidth}

\makeatletter
\newcommand{\BTsetupchar}[3]{\csdef{BT#1}{{\raisebox{#2 pt}{#3}}}}
\newcommand{\BTchar}[1]{\ifcsdef{BT\expandafter#1}{\csuse{BT#1}}{#1}}
\def\BTtype#1{%
    \@BTtype#1 \@empty
}
\def\@BTtype#1 #2{%
   \zz{#1}\space  
   \ifx #2\@empty\else
    \expandafter\@BTtype
   \fi
   #2%
}
\def\zz#1{\def\zzsep{}\zzz#1\relax}
\def\zzz#1{\ifx\relax#1\else\BTchar{#1}\expandafter\zzz\fi}
\makeatother

\newcommand{\rnddoublehit}[2]{%first arg is character, second is probability (expressed as 0...10 out of 10)
\rand%
\ifnum\value{rnd}<#2{%
    \settowidth{\charwidth}{#1}%
    \makebox[0 pt]{\textcolor{DarkGrey}{#1}\hspace{-0.9\charwidth}}%
}\fi%
#1%
}
\newcommand{\fakebold}[1]{%
\hspace{0.25em}\makebox[0pt]{#1}\hspace{-0.01em}\makebox[0pt]{#1}\raisebox{0.01em}{\makebox[0pt]{#1}{\hspace{-0.01em}\makebox[0pt]{#1}}}\hspace{0.25em}%
}

\newcommand{\randomrotate}[1]{%
\rand\turnbox{\value{rnd}}{#1}\phantom{#1}%
}
\newcommand{\fixedrotate}[2]{%
\turnbox{#2}{#1}\phantom{#1}%
}

\BTsetupchar{!}{0.959552631912}{!}
\BTsetupchar{"}{-0.572568292908}{"}
\BTsetupchar{'}{-0.42445901612}{'}
\BTsetupchar{(}{0.691721871811}{(}
\BTsetupchar{)}{0.446192095977}{)}
\BTsetupchar{*}{0.668289632872}{*}
\BTsetupchar{+}{0.21316900542}{+}
\BTsetupchar{,}{0.910994324343}{,}
\BTsetupchar{-}{-0.0643612216322}{-}
\BTsetupchar{.}{0.630916143844}{.}
\BTsetupchar{/}{-0.208079854503}{/}
\BTsetupchar{0}{-0.959606455046}{0}
\BTsetupchar{1}{-0.656692744652}{1}
\BTsetupchar{2}{0.715910870838}{2}
\BTsetupchar{3}{0.801503738677}{3}
\BTsetupchar{4}{-0.32605935154}{4}
\BTsetupchar{5}{-0.675172696056}{5}
\BTsetupchar{6}{0.751559563665}{6}
\BTsetupchar{7}{0.976916884466}{7}
\BTsetupchar{8}{-0.975884092147}{8}
\BTsetupchar{9}{-0.283530490249}{9}
\BTsetupchar{:}{0.883460953498}{:}
\BTsetupchar{;}{-0.157194078996}{;}
\BTsetupchar{<}{-0.856089720103}{<}
\BTsetupchar{=}{-0.462380899054}{=}
\BTsetupchar{>}{-0.127783763665}{>}
\BTsetupchar{?}{0.340250629436}{?}
\BTsetupchar{@}{0.0681232531923}{@}
\BTsetupchar{A}{-0.28199357967}{A}
\BTsetupchar{B}{-0.908136793624}{B}
\BTsetupchar{C}{0.876151420093}{C}
\BTsetupchar{D}{-0.562459892016}{D}
\BTsetupchar{E}{0.447753032908}{E}
\BTsetupchar{F}{0.949806536361}{F}
\BTsetupchar{G}{-0.83022989235}{G}
\BTsetupchar{H}{0.237512188109}{H}
\BTsetupchar{I}{0.97859690646}{I}
\BTsetupchar{J}{-0.403375721451}{J}
\BTsetupchar{K}{0.96981128078}{K}
\BTsetupchar{L}{0.796113416346}{L}
\BTsetupchar{M}{-0.366049268456}{M}
\BTsetupchar{N}{0.198166324344}{N}
\BTsetupchar{O}{-0.100789626885}{O}
\BTsetupchar{P}{-0.183992646309}{P}
\BTsetupchar{Q}{0.173168897111}{Q}
\BTsetupchar{R}{0.480851283624}{R}
\BTsetupchar{S}{-0.614801263924}{S}
\BTsetupchar{T}{0.232244730499}{\rnddoublehit{T}{5}}
\BTsetupchar{U}{-0.841735743114}{U}
\BTsetupchar{V}{0.331678931812}{V}
\BTsetupchar{W}{0.49613372548}{W}
\BTsetupchar{X}{0.845697981975}{X}
\BTsetupchar{Y}{-0.482183997158}{Y}
\BTsetupchar{Z}{0.193975227977}{Z}
\BTsetupchar{[}{0.537571176714}{[}
\BTsetupchar{]}{-0.158672666173}{]}
\BTsetupchar{`}{-0.88025147726}{`}
\BTsetupchar{a}{0.78692076979}{a}
\BTsetupchar{b}{0.649368560189}{b}
\BTsetupchar{c}{0.902390617527}{c}
\BTsetupchar{d}{0.531144863033}{d}
\BTsetupchar{e}{0.236409401365}{\fakebold{e}}
\BTsetupchar{f}{0.643224218751}{f}
\BTsetupchar{g}{-0.0139542454465}{g}
\BTsetupchar{h}{-0.147690280772}{h}
\BTsetupchar{i}{0.58033164118}{i}
\BTsetupchar{j}{-0.795721708264}{j}
\BTsetupchar{k}{0.0175291953771}{k}
\BTsetupchar{l}{0.148103630735}{l}
\BTsetupchar{m}{-0.0330127123047}{m}
\BTsetupchar{n}{0.965120551956}{n}
\BTsetupchar{o}{-0.782274884983}{o}
\BTsetupchar{p}{-0.912884787628}{p}
\BTsetupchar{q}{-0.737446301979}{q}
\BTsetupchar{r}{-0.035564484607}{r}
\BTsetupchar{s}{0.980692209771}{s}
\BTsetupchar{t}{-0.195345192206}{\fixedrotate{t}{-5}}
\BTsetupchar{u}{-0.900370841615}{u}
\BTsetupchar{v}{0.88405712738}{v}
\BTsetupchar{w}{-0.235893592391}{\randomrotate{w}}
\BTsetupchar{x}{0.529953305453}{x}
\BTsetupchar{y}{-0.494754361551}{y}
\BTsetupchar{z}{-0.861855138219}{z}
\BTsetupchar{|}{0.058513536895}{|}


\begin{document}\pagestyle{empty}
\BTtype{This text was typed by a monkey on the world's worst typewriter.  This text was typed by a monkey on the world's worst typewriter.  This text was typed by a monkey on the world's worst typewriter.  This text was typed by a monkey on the world's worst typewriter.}

\emph{\BTtype{This text is underlined using the ulem package}}
\end{document}

The lookup table was generated using python:

import random
for i in range (33,127):
    c=chr(i)
    if not c in "&%$#_{}~^\\": 
        print "\BTsetupchar{"+c+"}{"+str((random.random()-0.5)*2)+"}{"+c+"}"

I haven't tried to handle maths mode or accented letters -- in fact any control sequence or escaped special character few to the macro breaks. It is possible (as demonstrated) to emphasise the text, but the \emph{} must be on the outide.

A few more ideas:

  • Implement underlining with a load of \textunderscores
  • Fake-bold one or more characters for emphasis
  • Basic maths (using a handwriting font for characters not on the a standard typewriter would be a bonus)

Important sources:

  • Davids Carlisle's answer to What's the best way to explode a string into characters, process each character individually, and join them back?
  • Martin Scharrer's answer to Iterate over space-separated list

Regarding the questions about memoir: if you don't want chapters numbered then put setsecnumdepth{part} in your preamble or, for all classes with \chapter use \chapter* to have an unnumbered title.

To make memoir output similar to that of the article class use the article option:

\documentclass[...,article]{memoir}

With this option \chapter behaves as \section, \section as \subsection and so on. This ability was introduced to help those (many) authors (or their supervisors) who could not decide between report or book class type output and an article style document without having to do extensive rewrites.