Skip to content

Commit

Permalink
[doc] Add help options to fonttools CLI (#1920)
Browse files Browse the repository at this point in the history
This adds a `help` verb (and `--help` option) to the `fonttools` command line tool. Submodules will be listed in the help text if they have an importable `main` function with a docstring, and `main`'s docstring will be used as the one-line description for the help text.
  • Loading branch information
simoncozens committed May 12, 2020
1 parent b299bfb commit 2cef07a
Show file tree
Hide file tree
Showing 19 changed files with 64 additions and 12 deletions.
6 changes: 4 additions & 2 deletions Lib/fontTools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ def main(args=None):
if args is None:
args = sys.argv[1:]

# TODO Add help output, --help, etc.

# TODO Handle library-wide options. Eg.:
# --unicodedata
# --verbose / other logging stuff
Expand All @@ -20,6 +18,10 @@ def main(args=None):
# can be added. Should we just try importing the fonttools
# module first and try without if it fails?

if len(sys.argv) < 2:
sys.argv.append("help")
if sys.argv[1] == "-h" or sys.argv[1] == "--help":
sys.argv[1] = "help"
mod = 'fontTools.'+sys.argv[1]
sys.argv[1] = sys.argv[0] + ' ' + sys.argv[1]
del sys.argv[0]
Expand Down
15 changes: 9 additions & 6 deletions Lib/fontTools/cffLib/width.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,8 @@ def optimizeWidths(widths):

return default, nominal


if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
import doctest
sys.exit(doctest.testmod().failed)
def main():
"""Calculate optimum defaultWidthX/nominalWidthX values"""
for fontfile in sys.argv[1:]:
font = TTFont(fontfile)
hmtx = font['hmtx']
Expand All @@ -160,3 +156,10 @@ def optimizeWidths(widths):
print("glyphs=%d default=%d nominal=%d byteCost=%d" % (len(widths), default, nominal, byteCost(widths, default, nominal)))
#default, nominal = optimizeWidthsBruteforce(widths)
#print("glyphs=%d default=%d nominal=%d byteCost=%d" % (len(widths), default, nominal, byteCost(widths, default, nominal)))

if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
import doctest
sys.exit(doctest.testmod().failed)
main()
1 change: 1 addition & 0 deletions Lib/fontTools/cu2qu/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def _copytree(input_path, output_path):


def main(args=None):
"""Convert a UFO font from cubic to quadratic curves"""
parser = argparse.ArgumentParser(prog="cu2qu")
parser.add_argument(
"--version", action="version", version=fontTools.__version__)
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/feaLib/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@


def main(args=None):
"""Add features from a feature file (.fea) into a OTF font"""
parser = argparse.ArgumentParser(
description="Use fontTools to compile OpenType feature files (*.fea).")
parser.add_argument(
Expand Down
34 changes: 34 additions & 0 deletions Lib/fontTools/help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pkgutil
import sys
import fontTools
import importlib
import os
from pathlib import Path


def main():
"""Show this help"""
path = fontTools.__path__
descriptions = {}
for pkg in sorted(
mod.name
for mod in pkgutil.walk_packages([fontTools.__path__[0]], prefix="fontTools.")
):
try:
imports = __import__(pkg, globals(), locals(), ["main"])
except ImportError as e:
continue
try:
description = imports.main.__doc__
if description:
pkg = pkg.replace("fontTools.", "").replace(".__main__", "")
descriptions[pkg] = description
except AttributeError as e:
pass
for pkg, description in descriptions.items():
print("fonttools %-12s %s" % (pkg, description), file=sys.stderr)


if __name__ == "__main__":
print("fonttools v%s\n" % fontTools.__version__, file=sys.stderr)
main()
4 changes: 1 addition & 3 deletions Lib/fontTools/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
#
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader

"""Font merger.
"""

from fontTools.misc.py23 import *
from fontTools.misc.timeTools import timestampNow
from fontTools import ttLib, cffLib
Expand Down Expand Up @@ -1136,6 +1133,7 @@ def _postMerge(self, font):

@timer("make one with everything (TOTAL TIME)")
def main(args=None):
"""Merge multiple fonts into one"""
from fontTools import configLogger

if args is None:
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/mtiLib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ def build(f, font, tableTag=None):


def main(args=None, font=None):
"""Convert a FontDame OTL file to TTX XML"""
import sys
from fontTools import configLogger
from fontTools.misc.testTools import MockFont
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/subset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2778,6 +2778,7 @@ def usage():

@timer("make one with everything (TOTAL TIME)")
def main(args=None):
"""OpenType font subsetter and optimizer"""
from os.path import splitext
from fontTools import configLogger

Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/subset/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
import sys
from fontTools.subset import main


if __name__ == '__main__':
sys.exit(main())
3 changes: 2 additions & 1 deletion Lib/fontTools/ttLib/woff2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,7 @@ def decompress(input_file, output_file):


def main(args=None):
"""Compress and decompress WOFF2 fonts"""
import argparse
from fontTools import configLogger
from fontTools.ttx import makeOutputFileName
Expand All @@ -1404,7 +1405,7 @@ def __call__(self, parser, namespace, values, option_string=None):

parser = argparse.ArgumentParser(
prog="fonttools ttLib.woff2",
description="Compress and decompress WOFF2 fonts",
description=main.__doc__
)

parser_group = parser.add_subparsers(title="sub-commands")
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/ttx.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ def waitForKeyPress():


def main(args=None):
"""Convert OpenType fonts to XML and back"""
from fontTools import configLogger

if args is None:
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,7 @@ def __call__(self, src_path):


def main(args=None):
"""Build a variable font from a designspace file and masters"""
from argparse import ArgumentParser
from fontTools import configLogger

Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
from fontTools.varLib import main


if __name__ == '__main__':
sys.exit(main())
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/instancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,7 @@ def parseArgs(args):


def main(args=None):
"""Partially instantiate a variable font."""
infile, axisLimits, options = parseArgs(args)
log.info("Restricting axes: %s", axisLimits)

Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/interpolatable.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def test(glyphsets, glyphs=None, names=None):
# print(x)

def main(args):
"""Test for interpolatability issues between fonts"""
filenames = args
glyphs = None
#glyphs = ['uni08DB', 'uniFD76']
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/interpolate_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def interpolate_layout(designspace, loc, master_finder=lambda s:s, mapped=False)


def main(args=None):
"""Interpolate GDEF/GPOS/GSUB tables for a point on a designspace"""
from fontTools import configLogger

import sys
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ def piecewiseLinearMap(v, mapping):


def main(args):
"""Normalize locations on a given designspace"""
from fontTools import configLogger

args = args[1:]
Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True):


def main(args=None):
"""Instantiate a variation font"""
from fontTools import configLogger
import argparse

Expand Down
1 change: 1 addition & 0 deletions Lib/fontTools/varLib/varStore.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ def VarStore_optimize(self):


def main(args=None):
"""Optimize a font's GDEF variation store"""
from argparse import ArgumentParser
from fontTools import configLogger
from fontTools.ttLib import TTFont
Expand Down

0 comments on commit 2cef07a

Please sign in to comment.