[doc] Add help options to fonttools CLI (#1920)
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.
This commit is contained in:
parent
b299bfb389
commit
2cef07af80
@ -5,8 +5,6 @@ def main(args=None):
|
|||||||
if args is None:
|
if args is None:
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
|
|
||||||
# TODO Add help output, --help, etc.
|
|
||||||
|
|
||||||
# TODO Handle library-wide options. Eg.:
|
# TODO Handle library-wide options. Eg.:
|
||||||
# --unicodedata
|
# --unicodedata
|
||||||
# --verbose / other logging stuff
|
# --verbose / other logging stuff
|
||||||
@ -20,6 +18,10 @@ def main(args=None):
|
|||||||
# can be added. Should we just try importing the fonttools
|
# can be added. Should we just try importing the fonttools
|
||||||
# module first and try without if it fails?
|
# 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]
|
mod = 'fontTools.'+sys.argv[1]
|
||||||
sys.argv[1] = sys.argv[0] + ' ' + sys.argv[1]
|
sys.argv[1] = sys.argv[0] + ' ' + sys.argv[1]
|
||||||
del sys.argv[0]
|
del sys.argv[0]
|
||||||
|
@ -146,12 +146,8 @@ def optimizeWidths(widths):
|
|||||||
|
|
||||||
return default, nominal
|
return default, nominal
|
||||||
|
|
||||||
|
def main():
|
||||||
if __name__ == '__main__':
|
"""Calculate optimum defaultWidthX/nominalWidthX values"""
|
||||||
import sys
|
|
||||||
if len(sys.argv) == 1:
|
|
||||||
import doctest
|
|
||||||
sys.exit(doctest.testmod().failed)
|
|
||||||
for fontfile in sys.argv[1:]:
|
for fontfile in sys.argv[1:]:
|
||||||
font = TTFont(fontfile)
|
font = TTFont(fontfile)
|
||||||
hmtx = font['hmtx']
|
hmtx = font['hmtx']
|
||||||
@ -160,3 +156,10 @@ if __name__ == '__main__':
|
|||||||
print("glyphs=%d default=%d nominal=%d byteCost=%d" % (len(widths), default, nominal, byteCost(widths, default, nominal)))
|
print("glyphs=%d default=%d nominal=%d byteCost=%d" % (len(widths), default, nominal, byteCost(widths, default, nominal)))
|
||||||
#default, nominal = optimizeWidthsBruteforce(widths)
|
#default, nominal = optimizeWidthsBruteforce(widths)
|
||||||
#print("glyphs=%d default=%d nominal=%d byteCost=%d" % (len(widths), default, nominal, byteCost(widths, default, nominal)))
|
#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()
|
||||||
|
@ -59,6 +59,7 @@ def _copytree(input_path, output_path):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Convert a UFO font from cubic to quadratic curves"""
|
||||||
parser = argparse.ArgumentParser(prog="cu2qu")
|
parser = argparse.ArgumentParser(prog="cu2qu")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--version", action="version", version=fontTools.__version__)
|
"--version", action="version", version=fontTools.__version__)
|
||||||
|
@ -13,6 +13,7 @@ log = logging.getLogger("fontTools.feaLib")
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Add features from a feature file (.fea) into a OTF font"""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Use fontTools to compile OpenType feature files (*.fea).")
|
description="Use fontTools to compile OpenType feature files (*.fea).")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
34
Lib/fontTools/help.py
Normal file
34
Lib/fontTools/help.py
Normal file
@ -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()
|
@ -2,9 +2,6 @@
|
|||||||
#
|
#
|
||||||
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader
|
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader
|
||||||
|
|
||||||
"""Font merger.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.misc.timeTools import timestampNow
|
from fontTools.misc.timeTools import timestampNow
|
||||||
from fontTools import ttLib, cffLib
|
from fontTools import ttLib, cffLib
|
||||||
@ -1136,6 +1133,7 @@ __all__ = [
|
|||||||
|
|
||||||
@timer("make one with everything (TOTAL TIME)")
|
@timer("make one with everything (TOTAL TIME)")
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Merge multiple fonts into one"""
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
if args is None:
|
if args is None:
|
||||||
|
@ -1151,6 +1151,7 @@ def build(f, font, tableTag=None):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None, font=None):
|
def main(args=None, font=None):
|
||||||
|
"""Convert a FontDame OTL file to TTX XML"""
|
||||||
import sys
|
import sys
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
from fontTools.misc.testTools import MockFont
|
from fontTools.misc.testTools import MockFont
|
||||||
|
@ -2778,6 +2778,7 @@ def usage():
|
|||||||
|
|
||||||
@timer("make one with everything (TOTAL TIME)")
|
@timer("make one with everything (TOTAL TIME)")
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""OpenType font subsetter and optimizer"""
|
||||||
from os.path import splitext
|
from os.path import splitext
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
|
@ -2,5 +2,6 @@ from fontTools.misc.py23 import *
|
|||||||
import sys
|
import sys
|
||||||
from fontTools.subset import main
|
from fontTools.subset import main
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
@ -1390,6 +1390,7 @@ def decompress(input_file, output_file):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Compress and decompress WOFF2 fonts"""
|
||||||
import argparse
|
import argparse
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
from fontTools.ttx import makeOutputFileName
|
from fontTools.ttx import makeOutputFileName
|
||||||
@ -1404,7 +1405,7 @@ def main(args=None):
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="fonttools ttLib.woff2",
|
prog="fonttools ttLib.woff2",
|
||||||
description="Compress and decompress WOFF2 fonts",
|
description=main.__doc__
|
||||||
)
|
)
|
||||||
|
|
||||||
parser_group = parser.add_subparsers(title="sub-commands")
|
parser_group = parser.add_subparsers(title="sub-commands")
|
||||||
|
@ -384,6 +384,7 @@ def waitForKeyPress():
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Convert OpenType fonts to XML and back"""
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
if args is None:
|
if args is None:
|
||||||
|
@ -1007,6 +1007,7 @@ class MasterFinder(object):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Build a variable font from a designspace file and masters"""
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
from fontTools.varLib import main
|
from fontTools.varLib import main
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
@ -1375,6 +1375,7 @@ def parseArgs(args):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Partially instantiate a variable font."""
|
||||||
infile, axisLimits, options = parseArgs(args)
|
infile, axisLimits, options = parseArgs(args)
|
||||||
log.info("Restricting axes: %s", axisLimits)
|
log.info("Restricting axes: %s", axisLimits)
|
||||||
|
|
||||||
|
@ -158,6 +158,7 @@ def test(glyphsets, glyphs=None, names=None):
|
|||||||
# print(x)
|
# print(x)
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
|
"""Test for interpolatability issues between fonts"""
|
||||||
filenames = args
|
filenames = args
|
||||||
glyphs = None
|
glyphs = None
|
||||||
#glyphs = ['uni08DB', 'uniFD76']
|
#glyphs = ['uni08DB', 'uniFD76']
|
||||||
|
@ -58,6 +58,7 @@ def interpolate_layout(designspace, loc, master_finder=lambda s:s, mapped=False)
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Interpolate GDEF/GPOS/GSUB tables for a point on a designspace"""
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
@ -423,6 +423,7 @@ def piecewiseLinearMap(v, mapping):
|
|||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
|
"""Normalize locations on a given designspace"""
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
|
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
@ -399,6 +399,7 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True):
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Instantiate a variation font"""
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
@ -545,6 +545,7 @@ ot.VarStore.optimize = VarStore_optimize
|
|||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
|
"""Optimize a font's GDEF variation store"""
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from fontTools import configLogger
|
from fontTools import configLogger
|
||||||
from fontTools.ttLib import TTFont
|
from fontTools.ttLib import TTFont
|
||||||
|
Loading…
x
Reference in New Issue
Block a user