1
1
mirror of https://github.com/rsms/inter.git synced 2024-12-13 12:14:53 +03:00
inter/misc/tools/fixup-diacritics.py

168 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python
# encoding: utf8
from __future__ import print_function
import os, sys, plistlib, re
from collections import OrderedDict
from ConfigParser import RawConfigParser
from argparse import ArgumentParser
from robofab.objects.objectsRF import OpenFont
# Regex matching "default" glyph names, like "uni2043" and "u01C5"
uniNameRe = re.compile(r'^u(?:ni)([0-9A-F]{4,8})$')
def unicodeForDefaultGlyphName(glyphName):
m = uniNameRe.match(glyphName)
if m is not None:
try:
return int(m.group(1), 16)
except:
pass
return None
def canonicalGlyphName(glyphName, uc2names):
uc = unicodeForDefaultGlyphName(glyphName)
if uc is not None:
names = uc2names.get(uc)
if names is not None and len(names) > 0:
return names[0]
return glyphName
def parseGlyphComposition(composite):
c = composite.split("=")
d = c[1].split("/")
glyphName = d[0]
if len(d) == 1:
offset = [0, 0]
else:
offset = [int(i) for i in d[1].split(",")]
accentString = c[0]
accents = accentString.split("+")
baseName = accents.pop(0)
accentNames = [i.split(":") for i in accents]
return (glyphName, baseName, accentNames, offset)
def fmtGlyphComposition(glyphName, baseName, accentNames, offset):
# glyphName = 'uni03D3'
# baseName = 'uni03D2'
# accentNames = [['tonos', 'top'], ['acute', 'top']]
# offset = [100, 0]
# => "uni03D2+tonos:top+acute:top=uni03D3/100,0"
s = baseName
for accentNameTuple in accentNames:
s += '+' + accentNameTuple[0]
if len(accentNameTuple) > 1:
s += ':' + accentNameTuple[1]
s += '=' + glyphName
if offset[0] != 0 or offset[1] != 0:
s += '/%d,%d' % tuple(offset)
return s
def loadGlyphCompositions(filename): # { glyphName => (baseName, accentNames, offset) }
compositions = OrderedDict()
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if len(line) > 0 and line[0] != '#':
glyphName, baseName, accentNames, offset = parseGlyphComposition(line)
compositions[glyphName] = (baseName, accentNames, offset)
return compositions
def loadAGL(filename): # -> { 2126: 'Omega', ... }
m = {}
with open(filename, 'r') as f:
for line in f:
# Omega;2126
# dalethatafpatah;05D3 05B2 # higher-level combinations; ignored
line = line.strip()
if len(line) > 0 and line[0] != '#':
name, uc = tuple([c.strip() for c in line.split(';')])
if uc.find(' ') == -1:
# it's a 1:1 mapping
m[int(uc, 16)] = name
return m
def loadFontGlyphs(font):
uc2names = {} # { 2126: ['Omega', ...], ...}
name2ucs = {} # { 'Omega': [2126, ...], '.notdef': [], ...}
for g in font:
name = g.name
ucs = g.unicodes
name2ucs[name] = ucs
for uc in ucs:
names = uc2names.setdefault(uc, [])
if name not in names:
names.append(name)
return uc2names, name2ucs
def main():
argparser = ArgumentParser(description='Fixup diacritic names')
argparser.add_argument(
'-dry', dest='dryRun', action='store_const', const=True, default=False,
help='Do not modify anything, but instead just print what would happen.')
argparser.add_argument(
'fontPaths', metavar='<ufofile>', type=str, nargs='+', help='UFO fonts')
args = argparser.parse_args()
dryRun = args.dryRun
uc2names = {}
name2ucs = {}
for fontPath in args.fontPaths:
font = OpenFont(fontPath)
_uc2names, _name2ucs = loadFontGlyphs(font)
for uc, _names in _uc2names.iteritems():
names = uc2names.setdefault(uc, [])
for name in _names:
if name not in names:
names.append(name)
for name, _ucs in _name2ucs.iteritems():
ucs = name2ucs.setdefault(name, [])
for uc in _ucs:
if uc not in ucs:
ucs.append(uc)
agl = loadAGL('src/glyphlist.txt') # { 2126: 'Omega', ... }
diacriticsFilename = 'src/diacritics.txt'
diacriticComps = loadGlyphCompositions(diacriticsFilename) # {glyphName => (baseName, a, o)}
for glyphName, comp in list(diacriticComps.items()):
if glyphName not in name2ucs:
uc = unicodeForDefaultGlyphName(glyphName)
if uc is not None:
aglName = agl.get(uc)
if aglName is not None:
if aglName in diacriticComps:
raise Exception('composing same glyph with different names:', aglName, glyphName)
print('rename', glyphName, '->', aglName, '(U+%04X)' % uc)
del diacriticComps[glyphName]
diacriticComps[aglName] = comp
lines = []
for glyphName, comp in diacriticComps.iteritems():
lines.append(fmtGlyphComposition(glyphName, *comp))
# print('\n'.join(lines))
print('Write', diacriticsFilename)
if not dryRun:
with open(diacriticsFilename, 'w') as f:
for line in lines:
f.write(line + '\n')
main()