From 2090c58c87c0d0f22f1791bc00a974f8fde2d40a Mon Sep 17 00:00:00 2001 From: Jens Kutilek Date: Fri, 19 Feb 2021 09:26:18 +0100 Subject: [PATCH 1/3] Add cmdline script --- Lib/extractor/__init__.py | 20 ++++++++++++++++++++ setup.py | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/Lib/extractor/__init__.py b/Lib/extractor/__init__.py index 3c9a602..0cdaf0f 100644 --- a/Lib/extractor/__init__.py +++ b/Lib/extractor/__init__.py @@ -66,3 +66,23 @@ def extractUFO( raise ExtractorError( "There was an error reading the %s file." % format ) + + +def cmdline(): + """ + Extract one ore more fonts to UFO. Installed as command line script + `extractufo`. + + Usage: extractufo font [font ...] + """ + from sys import argv, exit + from ufoLib2 import Font + + if len(argv) <= 1: + print("No font path supplied.\nUsage: extractufo font [font ...]") + exit(1) + + for font_path in argv[1:]: + ufo = Font() + extractUFO(font_path, ufo) + ufo.save(f"{font_path}.ufo", overwrite=True) diff --git a/setup.py b/setup.py index 57eec18..8e4cf7f 100644 --- a/setup.py +++ b/setup.py @@ -25,12 +25,18 @@ license="MIT", package_dir={"": "Lib"}, packages=find_packages("Lib"), + entry_points={ + "console_scripts": [ + "extractufo = extractor:cmdline", + ] + }, setup_requires=pytest_runner + wheel, tests_require=[ 'pytest>=2.8', ], install_requires=[ "fonttools[ufo,lxml,woff,unicode,type1]>=4.17.0", + "ufoLib2", ], classifiers=[ "Development Status :: 4 - Beta", From 29fc2ec3bd64ccc27b659687236d873952560e0e Mon Sep 17 00:00:00 2001 From: Rimas Kudelis Date: Thu, 26 Sep 2024 14:20:56 +0300 Subject: [PATCH 2/3] Better cmdline script - make ufoLib2 an optional dependency - attempt to fall back to defcon if ufoLib2 is not installed - output status messages when running the script --- Lib/extractor/__init__.py | 18 ++++++++++++++++-- setup.py | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Lib/extractor/__init__.py b/Lib/extractor/__init__.py index f0cf41e..9dec481 100644 --- a/Lib/extractor/__init__.py +++ b/Lib/extractor/__init__.py @@ -85,13 +85,27 @@ def cmdline(): Usage: extractufo font [font ...] """ from sys import argv, exit - from ufoLib2 import Font + try: + from ufoLib2 import Font + library = "ufoLib2" + except ImportError: + try: + from defcon import Font + library = "defcon" + except ImportError: + print("Either ufoLib2 or defcon library is required for this command to work.\nPlease install one of them.") + exit(1) if len(argv) <= 1: print("No font path supplied.\nUsage: extractufo font [font ...]") exit(1) + print(f"Will use {library} library for UFO output.") + for font_path in argv[1:]: + ufo_path = f"{font_path}.ufo" + print(f"Extracting {ufo_path}... ", end="") ufo = Font() extractUFO(font_path, ufo) - ufo.save(f"{font_path}.ufo", overwrite=True) + ufo.save(ufo_path, overwrite=True) + print("done.") diff --git a/setup.py b/setup.py index e76ed8e..3faca15 100755 --- a/setup.py +++ b/setup.py @@ -41,10 +41,10 @@ install_requires=[ "fonttools[ufo,lxml,woff,unicode,type1]>=4.17.0", "fontFeatures", - "ufoLib2", ], extras_require={ "vfb": ["vfbLib>=0.7.1"], + "script": ["ufoLib2"], }, classifiers=[ "Development Status :: 4 - Beta", From e5c15404a17cee77e8980ccd28971fc7720f81ea Mon Sep 17 00:00:00 2001 From: Rimas Kudelis Date: Thu, 26 Sep 2024 22:01:00 +0300 Subject: [PATCH 3/3] Improve the cmdline script to accept more options --- Lib/extractor/__init__.py | 61 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/Lib/extractor/__init__.py b/Lib/extractor/__init__.py index 9dec481..84fe2ed 100644 --- a/Lib/extractor/__init__.py +++ b/Lib/extractor/__init__.py @@ -84,28 +84,57 @@ def cmdline(): Usage: extractufo font [font ...] """ - from sys import argv, exit - try: - from ufoLib2 import Font - library = "ufoLib2" - except ImportError: + import os + from sys import exit + from argparse import ArgumentParser + + parser = ArgumentParser( + description="Extract data from font binaries and build UFO objects from them.", + epilog="Each resulting UFO will be saved as FONT_FILE.ufo(z) in the same directory as the original FONT_FILE. " + "If destination file or directory already exists, conversion for that source file will be skipped and the application exit code will indicate an error.", + ) + parser.add_argument('FONT_FILE', help='Input font path', nargs="+") + parser.add_argument('-m', '--ufo-module', choices=['ufoLib2', 'defcon'], + help='Select the default library for writing UFOs (default: autodetect, prefer ufoLib2)') + parser.add_argument('-z', '--zip', action="store_true", help="Output UFO ZIP") + + args = parser.parse_args() + if args.ufo_module is None: + try: + from ufoLib2 import Font + print("Will use ufoLib2 for UFO output.") + except ImportError: + try: + from defcon import Font + print("Will use defcon for UFO output.") + except ImportError: + print("Either ufoLib2 or, alternatively, defcon library is required to run this command.\nPlease install one of them.") + exit(1) + elif args.ufo_module == 'ufoLib2': + try: + from ufoLib2 import Font + except ImportError: + print("Can't find ufoLib2 installed. Please install it or specify a different UFO library.") + exit(1) + else: try: from defcon import Font - library = "defcon" except ImportError: - print("Either ufoLib2 or defcon library is required for this command to work.\nPlease install one of them.") + print("Can't find defcon installed. Please install it or specify a different UFO library.") exit(1) - if len(argv) <= 1: - print("No font path supplied.\nUsage: extractufo font [font ...]") - exit(1) - - print(f"Will use {library} library for UFO output.") - - for font_path in argv[1:]: - ufo_path = f"{font_path}.ufo" + structure = "zip" if args.zip else "package" + had_write_errors = False + for font_path in args.FONT_FILE: + ufo_path = f"{font_path}.ufo" if not args.zip else f"{font_path}.ufoz" print(f"Extracting {ufo_path}... ", end="") + if os.path.exists(ufo_path): + print("path already exists, skipping.") + had_write_errors = True + continue ufo = Font() extractUFO(font_path, ufo) - ufo.save(ufo_path, overwrite=True) + ufo.save(ufo_path, structure=structure) print("done.") + + exit(had_write_errors)