Adding custom fonts to groff (+pandoc)
It's not easy, but it's easier than you might think! You'll need:
- TTF versions of the font you want to install (ideally in roman, italic, bold, and bold-italic varieties)
- ttf2pt1 to convert TTF to PostScript Type 1
- afmtodit (should come installed with groff)
The latest versions of groff and ttf2pt1 are available in package repositories, including homebrew.
Converting and installing a font
We need to take a TrueType (TTF) font and convert it to a groff font file. To do this, we use groff's
afmtodit utility. This won't convert from TTF directly, so we need to convert the TTF font to a PostScript Type 1 font first using Andrew Weeks et al.'s
You also need to locate your
groff/share directory, which contains
font/devps, the install directory. For a homebrew installation of groff, this will be
Suppose we have
IowanBoldItalic.ttf. We need to move them somewhere convenient, like the
mkdir -p ~/.fonts mv Iowan*.ttf ~/.fonts/.
Then convert each TTF to a PFA/AFM pair:
ttf2pt1 -a -e Iowan.ttf ttf2pt1 -a -e IowanItalic.ttf ttf2pt1 -a -e IowanBold.ttf ttf2pt1 -a -e IowanBoldItalic.ttf
Next, switch to the groff postscript font directory
(You may need to replace the directory name representing the version number.)
Then convert the AFM files to the native groff font format and store them in the
afmtodit -e text.enc ~/.fonts/Iowan.afm textmap IR afmtodit -e text.enc ~/.fonts/IowanItalic.afm textmap II afmtodit -e text.enc ~/.fonts/IowanBold.afm textmap IB afmtodit -e text.enc ~/.fonts/IowanBoldItalic.afm textmap IBI
Here is the naming convention: The prefix is up to you---I've chosen
Iowan, but it doesn't even need to be a single letter. The suffix is standardised:
R for regular/roman,
I for italic,
B for bold, and
BI for bold-italic. In this example, you should end up with four files:
IBI, all in your
.pfa files need to remain in your
~/.fonts directory, or the font must be otherwise installed in your system's font manager.
Note also: You might think we could leave everything in
~/.fonts instead of moving files into
groff/share/font/devps. Alas, setting the
GROFF_FONT_PATH environment variable to the local
.fonts directory also doesn't accomplish this for me, and I don't understand why. Mysteries.
Congratulations: your font is now available to groff and its macros using the short name you've just given it.
Using an installed font with
I use groff as the pdf engine for pandoc, a universal document format converter. So now, suppose I want my groff-typset PDFs to use Iowan as a font. Here's how to make that happen.
You can now set the font by passing
-M fontfamily=I as an argument to pandoc.
Alternatively, you can include this in your markdown manuscript's YAML header block:
--- ... fontfamily: I ---
Suppose you want all your documents to use your newly installe font of choice by default. Rather than specifying it in each document or each time you compile, you can (locally) modify pandoc's default
Pandoc looks for "custom" templates in two locations. If you have a
~/.local directory, it looks for
~/.local/pandoc/templates; and (only!) if you don't, it looks for
So let's create and populate the first directory with a modified
groff/ms macro template.
mkdir -p ~/.local/share/pandoc/templates pandoc -D ms > default.ms
default.ms using your editor of choice, changing this line (38):
I (Iowan) instead of
Now when you use pandoc to generate pdfs using the
-T ms option, it will be typeset using your font of choice!
Note: If you specify the font on the command line or in the YAML block, that will take precedence over any changes you've made to the default template.
Note also: If this breaks your groff>pdf documents after a pandoc update, you may need to repeat the steps in this subsection. (The default ms template may have importantly changed, but pandoc will still be using your old, modified version.) However, the template seems to be very stable; I've never encountered this issue in several years of using this system.