Skip to content

Instantly share code, notes, and snippets.

@connordavenport
Last active September 27, 2022 10:05
Show Gist options
  • Save connordavenport/6be7fa6eb5d2a9f57c2ca449e4a13cbb to your computer and use it in GitHub Desktop.
Save connordavenport/6be7fa6eb5d2a9f57c2ca449e4a13cbb to your computer and use it in GitHub Desktop.
Command line tool for changing version of a sfnt
#!/usr/bin/env python
'''
A command-line script to update a version number inside a SFNT.
python Versioner.py -v 1.420 -i *.otf
'''
import os
from re import findall as extract
from fontTools.ttLib import TTFont
import argparse
import sys
parser = argparse.ArgumentParser(usage='Versioner.py [-v version] [-i inputFile(s)] [-s suffix] [-f minorFlip]')
parser.add_argument("-v", help="version")
parser.add_argument("-i", help="input file path", nargs='+')
parser.add_argument("-s", help="append path suffix")
parser.add_argument("-f", help="flip minor zero formatting", action='store_true')
args = parser.parse_args()
def main():
version = args.v
try:
float(version)
except ValueError:
print("Invalid input value")
sys.exit(1)
# add zfill button
# add override for <#>.<#>.<#>.<#> syntax
if "." not in version:
version = float(version)
verStr = str(version)
major = verStr.split(".")[0]
#-f only works on values that have less than _3_ minor digits, def is 100, -f will print 001
if args.f:
minor = str(int(verStr.split(".")[1])).zfill(3)
else:
minor = str(int(verStr.split(".")[1])).ljust(3,'0')
vers = f"{major}.{minor}"
fileTypes = ['.otf','.ttf','.woff','.woff2']
for tt in args.i:
# covers most cases at the moment -------
suffix = args.s
if suffix == None:
dest = tt
else:
if "." in suffix:
suffix = suffix.split(".")[1]
splitPath = tt.rsplit(".",1)
print(splitPath)
dest = splitPath[0] + f".{suffix}." + splitPath[1]
if os.path.splitext(tt)[-1] not in fileTypes:
print("File format not supported")
sys.exit(1)
f = TTFont(tt)
# Temporary Checks -----------------
if verStr.count(".") > 1:
print("Incorrect version formatting\nPlease input a valid version using the //<Major>.<Minor>// syntax")
sys.exit(1)
if int(verStr.split(".")[0]) < 1 and f["OS/2"].achVendID != "ABDE":
print("Invalid version major value, please make ≥1")
sys.exit(1)
if int(major) > 65535 or int(minor) > 65535:
print("Version value is too large, must be under 65,535")
sys.exit(1)
# ----------------------------------
# CFF Table (OpenType —CFF— fonts only)
if "CFF " in f.keys():
cff = f["CFF "].cff[0]
oldVers = cff.version
cff.version = vers
head = f["head"]
head.fontRevision = float(vers)
name = f["name"]
oldNameID3 = str(name.getName(3,1,0,0))
oldNameID5 = str(name.getName(5,1,0,0))
if ";" in oldNameID5:
id5 = f"Version {vers};{oldNameID5.split(';',1)[1]}"
else:
id5 = f"Version {vers}"
if ";" in oldNameID3:
id3 = f"{vers};{oldNameID3.split(';',1)[1]}"
else:
id3 = vers
# Mac
name.setName(id3,3,1,0,0)
name.setName(id5,5,1,0,0)
# windows
name.setName(id3,3,3,1,1033)
name.setName(id5,5,3,1,1033)
f.save(dest)
print(f"changing {name.getName(1,1,0,0)} {name.getName(2,1,0,0)} version from {oldVers} to {vers}...")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment