summaryrefslogtreecommitdiffstats
path: root/lib/silfont/scripts/psfsetkeys.py
blob: 2cee4ab7e4a198826102d38491cf6f5729add3a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python
__doc__ = '''Set keys with given values in a UFO plist file.'''
__url__ = 'http://github.com/silnrsi/pysilfont'
__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
__license__ = 'Released under the MIT License (http://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()