aboutsummaryrefslogtreecommitdiffstats
path: root/tools/json2hash
blob: ae2505fb28bfb62201d38d1526c0861f86a89fd1 (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
101
102
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import json
import sys
import os
import re
import argparse

python2 = sys.version_info[0] == 2
python3 = sys.version_info[0] == 3

if python2:
    from cStringIO import StringIO
if python3:
    from io import StringIO



class ApplicationException(Exception):
    pass

def pystr2elstrexp(s):
    s = re.sub(r'^(u\'|\'|u\"|\")(.*)(\'|\")$', r'\2', repr(s))
    output = re.sub(r'("|\\")', '\\"', s)
    return u'"' + output + u'"'

class Processor(object):

    def __init__(self):
        self.out = StringIO()

    def _print(self, data):
        _type = type(data)
        if _type is dict:
            self.out.write('(let ((tbl (make-hash-table :test \'equal)))\n')
            for k, v in sorted(data.items(), key=lambda x: x[0]):
                self.out.write('(puthash ')
                self.out.write(pystr2elstrexp(k))
                self.out.write(' ')
                self._print(v)
                self.out.write(' tbl)\n')
            self.out.write('tbl)')
        elif _type is list:
            self.out.write('(vector\n')
            for v in data:
                self._print(v)
                self.out.write('\n')
            self.out.write(')\n')
        elif _type is bool:
            self.out.write('t' if data else 'nil')
        elif (_type is str or _type is unicode):
            self.out.write(pystr2elstrexp(data))
        else: # number ?
            self.out.write(str(data))

    def read(self, file):
        data = json.load(file)
        self._print(data)

    def write(self, out):
        out.write(self.out.getvalue())

def main():
    argparser = argparse.ArgumentParser()
    argparser.add_argument('-o', type=str)
    argparser.add_argument('--defvar', type=str)
    argparser.add_argument('file', nargs='+', type=str)
    options = argparser.parse_args()
    if options.o:
        out = open(options.o, 'w')
    else:
        out = sys.stdout
    try:
        p = Processor()
        for file in options.file:
            try:
                f = open(os.path.abspath(file))
                p.read(f)
            finally:
                f.close()
        out.write(';; ' + str(options.o) + '\n')
        out.write(';; This file is generated from ' + ','.join(options.file) + '\n')
        out.write(';; Don\'t edit.\n')
        if options.defvar:
            out.write(u'(emmet-defparameter ' + options.defvar + u'\n')
        p.write(out)
        if options.defvar:
            out.write(')\n')
    except:
        if options.o:
            out.close()
            os.unlink(options.o)
        raise
    if options.o:
        out.close()

if __name__ == '__main__':
    try:
        main()
    except ApplicationException as e:
        print(e.message, file=sys.stderr)