[Tex/LaTex] Use LaTeX to simulate old typewriter written texts

fontsfuntypewritertypography

This question led to a new package:
typewriter

I'm giving my students an old exam and barely remembered to change the date at the top. A colleague and I joked about how long we could reuse the same exam, and it made me wonder if I could use LaTeX to create an exam that looked like it was written in 1963 on a typewriter.

Here's what I'd like to see:

  1. Typewriter font even in math mode. (Several ways to accomplish this; is there a "best" way?)

  2. Slight inconsistencies in the printing of each letter. I attempt this below adapting code taken from here. Each word has a random vertical shift, though I'd like to see it reduced to each letter having its own vertical shift. Other typewriter-like irregularities would be great.

  3. It would be great if math-mode delimeters \left(, \right}, etc., can be created in a piece-meal fashion as they did in days of old.

  4. Fraction bars, tops of square-root symbols — any horizontal line, really — is made up of a series of en-dashes that don't quite match up.

Here is what I've come up with so far:

\documentclass[10pt]{article}% This is a document class providing more font size options
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage[textwidth=7.5in,textheight=9.5in]{geometry}
\pagestyle{empty}

% thanks to Bruno Le Floch: https://tex.stackexchange.com/q/9331/4012
% and in his comments to https://tex.stackexchange.com/a/29458/4012
\usepackage[first=-1,last=1]{lcg}% you can play around with these values
\makeatletter
\newcommand{\globalrand}{\rand\global\cr@nd\cr@nd}
\makeatother

\newcommand{\randomvshift}[1]{\globalrand\raisebox{\value{rand}pt}{#1}}

%%% thanks to Martin Scharrer: https://tex.stackexchange.com/q/11598/4012
\makeatletter
\def\typewriter#1{%
    \@typewriter#1 \@empty
}
\def\@typewriter#1 #2{%
   \randomvshift{#1}\space
   \ifx #2\@empty\else
    \expandafter\@typewriter
   \fi
   #2%
}
\makeatother
\begin{document}\tt

\typewriter{Math 101 Fall 1963}

\begin{enumerate}
\item   \typewriter{$\frac{\texttt{d}}{\texttt{dx}}\texttt{(x)}^2$}

\item \typewriter{State the Fundamental Theorem of Calculus.}

\end{enumerate}

\end{document}

Best Answer

This is now available as the typewriter package on ctan and texlive etc


Improved version with some Greek and mathematics, and avoiding small numbers being written using 2e-5 notation into the pdf (and crashing the pdf reader) This version assumes that the CM Unicode opentype fonts are available.

2nd update now works with texlive 2016 stable release, and also a texlive 2015 updated to luatex 0.95 (Previous version only seemed to work in a texlive 2017 test release).

Slightly updated code available as a package here

https://github.com/davidcarlisle/dpctex/tree/master/typewriter

enter image description here

\documentclass{article}

% luaotfload exlicitly loaded for latex formats before 2017/01/01
\usepackage{luaotfload}

% load cmuntt here not from lua (for everyone except me, it seems)
\font\cmuntt = cmuntt at 12pt \cmuntt
\edef\cmunttid{\fontid\cmuntt}


\expandafter\let\expandafter\%\csname @percentchar\endcsname
\directlua{
    local cbl = luatexbase.callback_descriptions('define_font')
    % print('\string\n======' .. cbl[1] .. '===\string\n')
    original_fontloader = luatexbase.remove_from_callback('define_font', cbl[1])
    luatexbase.add_to_callback(
        'define_font',
        function(name, size, i)
            if (name=='cmtt10x') then
                % this works in my dev version but for older setups
                % make sure cmuntt.otf has been loaded before we mess
                % up the font loader.
                % f = original_fontloader('cmuntt.otf',size)
                f = font.getfont(\cmunttid)
                f.name = 'cmtt10x'
                f.type = 'virtual'
                f.fonts = {{name = 'cmuntt', size = size}}
                for j, v in pairs(f.characters) do
                    local gr  = 0.4*math.random()
                    local gr2 = 0.4*math.random()
                    v.commands = {
                        {
                            'lua',
                            'r1 = 0.01*math.random(-10, 10)
                            pdf.print(string.format(
                                " q \%f \%f \%f \%f 0 0 cm ",
                                math.cos(r1), - math.sin(r1), 
                                math.sin(r1),   math.cos(r1)
                            ))'
                        },
                        {'special', 'pdf: ' .. gr2 .. ' g'},
                        {'push'},
                        {'right', math.random(-20000,20000)},
                        {'down', math.random(-20000,20000)},
                        {'char', j},
                        {'pop'},
                        {'lua', 'pdf.print(" Q ")'},
                        {'down', math.random(-20000,20000)},
                        {'special', 'pdf: ' .. gr .. ' g'},
                        {'char', j},
                        {'special', 'pdf: 0 g'}
                    }
                end  % end of for
                return f
            else
                return original_fontloader(name, size, i)
            end  % end of if
        end,  % end of function
        'define font'
    )  % end of add_to_callback
}

\def\sqrt#1{^^^^221a\overline{#1}}


\begin{document}
$\relax$

\font\myfont= cmtt10x at 12pt \myfont
\font\myfonts= cmtt10x at 7pt
\let\selectfont\relax

\textfont0=\myfont
\scriptfont0=\myfonts 
\scriptscriptfont0=\myfonts 
\textfont1=\myfont
\textfont2=\myfont
\textfont3=\myfont

\section{Introduction}

ABCD one two theee four five

TTTTTTTooooooWWWWW

\begin{enumerate}
\item red yellow blue green
\item black blue purple
\end{enumerate}

[some greek text θ]

and in math $x^2-\cos θ$


\[\left(\frac{x^2}{\sqrt{1+y}}\right)\]

\raggedleft
typeset by egreg design services
\end{document}

Original:

enter image description here

This introduces randomness on every use of each letter of the document. It requires luatex. (math is possible but not yet)

\documentclass{article}

\directlua {
    local cbl = luatexbase.callback_descriptions('define_font')
    original_fontloader = luatexbase.remove_from_callback('define_font', cbl[1])
    luatexbase.add_to_callback(
        'define_font',
        function(name, size, i)
            if (name=='cmtt10x') then
                f = font.read_tfm('cmtt10', size)
                f.name = 'cmtt10x'
                f.type = 'virtual'
                f.fonts = {{name = 'cmtt10', size = size}}
                for j, v in pairs(f.characters) do
                    local gr  = 0.4*math.random()
                    local gr2 = 0.4*math.random()
                    v.commands = {
                        {'lua',
                         '
                            r1 = 0.05+0.1*math.random()
                            pdf.print
                            (" q "
                                .. math.cos(r1) .. " "
                                .. - math.sin(r1) .. " "
                                .. math.sin(r1) .. " "
                                .. math.cos(r1) .. " 0 0 "
                                .. " cm "
                            )
                          '
                        },
                        {'special', 'pdf: ' .. gr2 .. ' g'},
                        {'push'},
                        {'right', math.random(-30000,30000)},
                        {'down', math.random(-30000,30000)},
                        {'char', j},
                        {'pop'},
                        {'lua', 'pdf.print(" Q ")'},
                        {'down', math.random(-30000,30000)},
                        {'special', 'pdf: ' .. gr .. ' g'},
                        {'char', j},
                        {'special','pdf: 0 g'}
                    }
                end  % end of for
                return f
            else
                return original_fontloader(name, size, i)
            end  % end of if
        end,  % end of function
        'define font'
    )
}


\begin{document}

\font\myfont= cmtt10x at 12pt \myfont
\let\selectfont\relax

\section{Introduction}

ABCD one two theee four five

TTTTTTTooooooWWWWW

\begin{enumerate}
\item red yellow blue green
\item black blue purple
\end{enumerate}


\raggedleft
typeset by egreg design services
\end{document}

This emulates a really poor typewriter with dodgy print hammers that wobble and move around as each key is hit:-)