#!/usr/bin/env python3 __doc__ = '''Set keys with given values in a UFO plist file.''' __url__ = 'https://github.com/silnrsi/pysilfont' __copyright__ = 'Copyright (c) 2018 SIL International (https://www.sil.org)' __license__ = 'Released under the MIT License (https://opensource.org/licenses/MIT)' __author__ = 'Bobby de Vos' from silfont.core import execute from xml.etree import ElementTree as ET import codecs suffix = "_setkeys" argspec = [ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}), ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}), ('--plist',{'help': 'Select plist to modify'}, {'def': 'fontinfo'}), ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': None}), ('-k','--key',{'help': 'Name of key to set'},{}), ('-v','--value',{'help': 'Value to set key to'},{}), ('--file',{'help': 'Use contents of file to set key to'},{}), ('--filepart',{'help': 'Use contents of part of the file to set key to'},{}), ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}) ] def doit(args) : font = args.ifont logger = args.logger plist = args.plist if plist is None: plist = "fontinfo" if plist not in ("lib", "fontinfo"): logger.log("--plist must be either fontinfo or lib", "S") else: if plist not in font.__dict__: font.addfile(plist) logger.log("Adding keys to " + plist, "I") font_plist = getattr(font, plist) # Ensure enough options were specified value = args.value or args.file or args.filepart if args.key and not value: logger.log('Value needs to be specified', "S") if not args.key and value: logger.log('Key needs to be specified', "S") # Use a one line string to set the key if args.key and args.value: set_key_value(font_plist, args.key, args.value) # Use entire file contents to set the key if args.key and args.file: fh = codecs.open(args.file, 'r', 'utf-8') contents = ''.join(fh.readlines()) set_key_value(font_plist, args.key, contents) fh.close() # Use some of the file contents to set the key if args.key and args.filepart: fh = codecs.open(args.filepart, 'r', 'utf-8') lines = list() for line in fh: if line == '\n': break lines.append(line) contents = ''.join(lines) set_key_value(font_plist, args.key, contents) fh.close() # Set many keys if args.input: incsv = args.input incsv.numfields = 2 for line in incsv: key = line[0] value = line[1] set_key_value(font_plist, key, value) return font def set_key_value(font_plist, key, value): """Set key to value in font.""" # Currently setval() only works for integer, real or string. # For other items you need to construct an elementtree element and use setelem() if value == 'true' or value == 'false': # Handle boolean values font_plist.setelem(key, ET.Element(value)) else: try: # Handle integers values number = int(value) font_plist.setval(key, 'integer', number) except ValueError: # Handle string (including multi-line strings) values font_plist.setval(key, 'string', value) font_plist.font.logger.log(key + " added, value: " + str(value), "I") def cmd() : execute("UFO",doit, argspec) if __name__ == "__main__": cmd()