Building a TTF to UFO Converter with Argparse
January 23, 2018
If you have used command line software before you are probably familiar with flags, for example --help
for help or -v
for version. In this tutorial, I will demonstrate using the module Argparse to add flags to a Python script.
The script will convert a TTF font file to a UFO directory, UFO is an XML based format used for uncompiled fonts. To start, open a terminal and navigate to a directory where you want to work. To keep dependencies contained, make a virtual environment by entering the following commands:
python3 -m venv venv
source venv/bin/activate
Runnging source venv/bin/activate
activates the virtual environment, to deactivate just type deactivate
. Now that we are in the venv
we need to install the packages needed for the script, argparse, defcon and, ufo-extractor:
ufo-extractor: Extracts UFO files from defcon font objects.
defcon: Creates a Python object from a given TTF.
argparse: Command line interface tool, gets input and output location.
Install these dependencies with pip:
pip install --upgrade ufo-extractor defcon argparse
Now we have everything installed and are ready to write the script, in any directory, make a new Python file and open it with a text editor (I'm using Vim here):
touch ttf-to-ufo.py
vi ttf-to-ufo.py
Now start the script by importing argparse
, make a new argparse object called parser and call parser.parse_args()
.
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
Save the script an run it from the command line:
python3 ttf-to-ufo.py
Nothing happens... try running it with a --help
flag:
python3 ttf-to-ufo.py --help
usage: test.py [-h]
optional arguments:
-h, --help show this help message and exit
It works, great. Help is the only built-in flag that works without additional code, so let’s add -i
for input path and -o
for output path:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-i", help = "input file path")
parser.add_argument("-o", help = "output file path")
args = parser.parse_args()
print('inputfile:', args.i)
print('outputfile:', args.o)
Now if we run the script with a help flag again, we should get something like this:
python3 ttf-to-ufo.py --help
usage: test.py [-h] [-i I] [-o O]
optional arguments:
-h, --help show this help message and exit
-i I input file path
-o O output file path
Next, let’s try using the flags, replace ~/.fonts/test.ttf
with the path to a TTF you want to use:
python3 ttf-to-ufo.py -i ~/.fonts/test.ttf -o test.ufo
inputfile: /home/user/.fonts/test.ttf
outputfile: test.ufo
Now import defcon and ufo-extractor. Please note that even though ufo-extractor is imported with pip install ufo-extractor
, it needs to be imported in python with import extractor
, confusing, I know. Move the argparse code into a function that returns args and move the script part into a conditional statement. if __name__ == "__main__":
tells Python to only run the script part when you are running the script from the command line, and ignore it if you are importing create_arg_parser
into another Python program:
import argparse
import defcon
import extractor
def create_arg_parser():
parser = argparse.ArgumentParser()
parser.add_argument("-i", help = "input filename")
parser.add_argument("-o", help = "output filename")
args = parser.parse_args()
return args
if __name__ == "__main__":
args = create_arg_parser()
ttf_path = args.i
ufo_path = args.o
print('ttf_path: ', ttf_path)
print('ufo_path:', ufo_path)
# Make UFO
print('Generating UFO...', ufo_path)
ufo = defcon.Font()
extractor.extractUFO(ttf_path, ufo)
ufo.save(ufo_path)
print('Done.')
If you run this script with -i
and -o
a UFO directory should be generated. If you don’t give a full file path for -o
and just enter a file name like this test.ufo
, a ufo directory will be created in the same directory as the script:
python3 ttf-to-ufo.py -i ~/.fonts/test.ttf -o ~/test.ufo
ttf_path: /home/eli/.fonts/test.ttf
ufo_path: /home/eli/test.ufo
Generating UFO... /home/eli/test.ufo
Done.