Skip to content

Instantly share code, notes, and snippets.

@hhatto
Last active October 18, 2021 21:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hhatto/42b0abf615b374080952cd7e3ac47544 to your computer and use it in GitHub Desktop.
Save hhatto/42b0abf615b374080952cd7e3ac47544 to your computer and use it in GitHub Desktop.
create magic file of font type list(type.mgk) for GraphicsMagick.
#
# about
# -----
# create magic file of font type list(type.mgk) for GraphicsMagick.
# use only on macOS.
#
# output file format
# ------------------
#
# <?xml version="1.0"?>
# <typemap>
# <type
# name="Arial"
# fullname="Arial"
# family="Arial"
# weight="400"
# style="normal"
# stretch="normal"
# glyphs="/Library/Fonts/Arial.ttf"
# />
# </typemap>
#
# usage
# -----
#
# (If Language Setting is not English in System Preference, please set it to English.)
# $ system_profiler -xml SPFontsDataType > fontset.xml
# $ python mgkgen fontset.xml > type.mgk
# copy to Your GraphicsMagick config path
# ex.)
# $ cp type.mgk /usr/local/Cellar/graphicsmagick/1.3.25/lib/GraphicsMagick/config/
#
import copy
import sys
from subprocess import Popen, PIPE
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import Element, SubElement
import xml.dom.minidom as minidom
WEIGHT_DEFAULT = 400
WEIGHT_STRING_SET = {
'Extrabold': 800,
'Extra Bold': 800,
'Bold': 700,
'Demi': 600, # high priority
'Regular': 400,
'Light': 300,
'Extralight': 200,
'Extra Light': 200,
}
STYLE_DEFAULT = "normal"
STYLE_STRING_SET = {
'Oblique': 'oblique',
'Italic': 'italic',
}
def get_style(line):
# from fullname text
tmp = line.split()
for s, style in STYLE_STRING_SET.items():
if s in tmp:
return style
return STYLE_DEFAULT
def get_weight(line):
# from style text
if 'demi' in line.lower():
return WEIGHT_STRING_SET['Demi']
for k, weight in WEIGHT_STRING_SET.items():
if k in line.lower():
return weight
return WEIGHT_DEFAULT
def main():
xmlstr = ""
if len(sys.argv) == 1:
# from system_profiler
with Popen(["system_profiler", "-xml", "SPFontsDataType"], stdout=PIPE) as proc:
xmlstr = proc.stdout.read()
else:
xmlstr = open(sys.argv[1]).read()
root = etree.fromstring(xmlstr)
result = []
for elm in root.findall("./array/dict/array/dict"):
# find glyphs
d = {"stretch": "normal"} # NOTE: stretch is only 'normal'
found_path = False
for child in elm.getchildren():
if found_path:
d["glyphs"] = child.text
found_path = False
# find key
if child.tag == "key":
if child.text == "path":
found_path = True
# find name, fullname, family, style
for elm in elm.findall("./array/dict"):
dd = copy.copy(d)
found_name = False
found_family = False
found_fullname = False
found_style = False
for child in elm.getchildren():
if found_name:
dd["name"] = child.text
found_name = False
elif found_family:
dd["family"] = child.text
found_family = False
elif found_fullname:
dd["fullname"] = child.text
found_fullname = False
elif found_style:
dd["style"] = child.text
found_style = False
# find key
if child.tag == "key":
if child.text == "_name":
found_name = True
elif child.text == "family":
found_family = True
elif child.text == "fullname":
found_fullname = True
elif child.text == "style":
found_style = True
# fix style and weight
dd["weight"] = str(get_weight(dd["style"]))
dd["style"] = get_style(dd["fullname"])
result.append(dd)
top = Element("typemap")
for r in result:
child = SubElement(top, "type", r)
print(minidom.parseString(etree.tostring(top, "utf-8")).toprettyxml())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment