Use TTF, OTF or Type1 fonts with Groff (Castellano)

At the bottom you'll find a shell script to convert and install TTF, OTF, or Type1 fonts, making them available for use with Groff. The script uses fontforge fontforge to perform the conversion.

Motivation

I fully edited my three novels using GNU roff, including graphics and covers (the cover in the HTML version in my web site and the doble-sided one I uploaded to amazon.)  The only exception is the drawings on the covers, which are handmade (also by me) with paper and pencil.

I used plain roff, I wrote my own macros, which I've been perfecting over the years.  As an example this is the tmac file I made to format my novels.  (I also wrote a shell script to convert my roff file to HTML, you already saw the result.)

I'm not necessarily an aesthete, but lately, bored with the Times font, the one that comes in groff and its used by default with postscript output, I wanted to try Georg Duffner's EBGaramond, which I think is more pleasant for a novel, and what's more important, being rounder and not having the vertical strokes too highlighted, as is the case of the Times, it better hides the gaps in justified text.

Searching the web for how to convert and install new fonts in groff I found three shell scripts.  A first, from Peter Schaffter (the author of groff mom macros,) which comes with a detailed explanation, a second one which is an understandable attempt to simplify Schaffter's script, and a third one from which I don't include a linke since it doesn't even deserve you to take a look.

From all that information I distilled what I found effective in my own script (pasted at bottom.)

What my script does that others don't do

Here you are

Download the script

#!/bin/sh
# groff-install-font.sh - (c) 2023 Walter Alejandro Iglesias
#
# Convert and install OTF, TTF or PFA font to use it with Groff.  You need
# fontforge installed.

# Directory where you want the font installed (a custom path needs to
# be added to GROFF_FONT_PATH).  To install the font in the default
# system wide groff location just leave this empty (you'll need to run
# this script as root in this case).
sitefont=$XDG_DATA_HOME/groff/site-font

prefix=/usr/local/share/groff

if [ "`uname`" = "Linux" ]; then
	prefix=/usr/share/groff
fi
if [ "$sitefont" = "" ]; then
	sitefont=$prefix/site-font
	if [ "`whoami`" != "root" ]; then
		echo "You must be root to install the font in $sitefont"
		exit 1
	fi
elif [ ! -d $sitefont/devps ] || [ ! -d $sitefont/devpdf ]; then
	mkdir -p $sitefont/dev{ps,pdf}
fi
if ! echo $1 | grep -E '.*(R|I|B|BI)+$' ||
   ! echo $2 | grep -E '\.(otf|ttf|pfb)$'; then
	echo "Usage: `basename $0` <groffname> <fontfile>.(otf|ttf|pfb)"
	echo "  groffname must be <name>(R|I|B|BI)"
	exit 1
fi
which fontforge >/dev/null 2>&1 || {
	echo "This script uses fontforge to convert fonts"
	exit 1
}
textmap=$prefix/current/font/devps/generate/textmap
enc=$prefix/current/font/devps/text.enc
groffname=$1
font=$2
name=`basename "$font" | sed -E 's/\.(otf|ttf|pfb)$//'`

fontforge -lang=ff -c "Open(\"$font\");Generate(\"$name.pfa\");"
fontforge -lang=ff -c "Open(\"$font\");Generate(\"$name.t42\");"
afmtodit -e $enc $name.afm $textmap $groffname
if ! grep -q '^ligatures' $groffname ; then
	sed -i '/kernpairs/i\
ligatures fi fl 0\
\
' $groffname
fi
mv $name.t42 $groffname $sitefont/devps
mv $name.pfa $sitefont/devpdf
rm $name.afm
ln -s $sitefont/devps/$groffname $sitefont/devpdf/$groffname
printf "$name\t$name.t42\n" >> $sitefont/devps/download
printf "\t$name\t$name.pfa\n" >> $sitefont/devpdf/download

# End of groff-install-font.sh

GO BACK HOME