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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
class FTLSerializer():
def serialize(self, ast):
body = ast['body']
comment = ast['comment']
string = u''
if comment is not None:
string += self.dumpComment(comment) + u'\n\n'
for entry in body:
string += self.dumpEntry(entry)
return string
def dumpEntry(self, entry):
if entry['type'] == 'Entity':
return self.dumpEntity(entry) + u'\n'
elif entry['type'] == 'Comment':
return self.dumpComment(entry) + u'\n\n'
elif entry['type'] == 'Section':
return self.dumpSection(entry) + u'\n'
elif entry['type'] == 'JunkEntry':
return u''
else:
print(entry)
raise Exception('Unknown entry type.')
return u''
def dumpEntity(self, entity):
str = u''
if entity['comment']:
str += u'\n' + self.dumpComment(entity['comment']) + u'\n'
id = self.dumpIdentifier(entity['id'])
value = self.dumpPattern(entity['value'])
if len(entity['traits']):
traits = self.dumpMembers(entity['traits'], 2)
str += u'{} = {}\n{}'.format(id, value, traits)
else:
str += u'{} = {}'.format(id, value)
return str
def dumpComment(self, comment):
return u'# {}'.format(comment['content'].replace('\n', u'\n# '))
def dumpSection(self, section):
comment = u'{}\n'.format(self.dumpComment(
section['comment'])) if section['comment'] else u''
sec = self.dumpKeyword(section['key'])
str = u'\n\n{}[[ {} ]]\n\n'.format(comment, sec)
for entry in section['body']:
str += self.dumpEntry(entry)
return str
def dumpIdentifier(self, id):
return id['name']
def dumpKeyword(self, kw):
if kw['namespace']:
return u'{}/{}'.format(kw['namespace'], kw['name'])
return kw['name']
def dumpPattern(self, pattern):
if pattern is None:
return u''
if pattern['_quoteDelim']:
return u'"{}"'.format(pattern['source'])
str = u''
for elem in pattern['elements']:
if elem['type'] == 'TextElement':
if '\n' in elem['value']:
str += u'\n | {}'.format(
elem['value'].replace('\n', '\n | '))
else:
str += elem['value']
elif elem['type'] == 'Placeable':
str += self.dumpPlaceable(elem)
return str
def dumpPlaceable(self, placeable):
source = u', '.join(map(self.dumpExpression, placeable['expressions']))
if source.endswith('\n'):
return u'{{ {}}}'.format(source)
return u'{{ {} }}'.format(source)
def dumpExpression(self, exp):
if exp['type'] == 'Identifier' or \
exp['type'] == 'FunctionReference' or \
exp['type'] == 'EntityReference':
return self.dumpIdentifier(exp)
if exp['type'] == 'ExternalArgument':
return u'${}'.format(self.dumpIdentifier(exp))
elif exp['type'] == 'SelectExpression':
sel = self.dumpExpression(exp['expression'])
variants = self.dumpMembers(exp['variants'], 2)
return u'{} ->\n{}\n'.format(sel, variants)
elif exp['type'] == 'CallExpression':
id = self.dumpExpression(exp['callee'])
args = self.dumpCallArgs(exp['args'])
return u'{}({})'.format(id, args)
elif exp['type'] == 'Pattern':
return self.dumpPattern(exp)
elif exp['type'] == 'Number':
return exp['value']
elif exp['type'] == 'Keyword':
return self.dumpKeyword(exp)
elif exp['type'] == 'MemberExpression':
obj = self.dumpExpression(exp['object'])
key = self.dumpExpression(exp['keyword'])
return u'{}[{}]'.format(obj, key)
def dumpCallArgs(self, args):
return u', '.join(map(
lambda arg:
u'{}: {}'.format(arg['name'],
self.dumpExpression(arg['value']))
if arg['type'] == 'KeyValueArg' else self.dumpExpression(arg),
args))
def dumpMembers(self, members, indent):
return u'\n'.join(map(lambda member: u'{}[{}] {}'.format(
u' ' * (indent - 1) + u'*' if member['default'] else u' ' * indent,
self.dumpExpression(member['key']),
self.dumpPattern(member['value'])
), members))
|