import textwrap
import fluent.syntax.ast as FTL
from fluent.syntax.parser import FluentParser, FluentParserStream
fluent_parser = FluentParser(with_spans=False)
def parse(Parser, string):
if Parser is FluentParser:
return fluent_parser.parse(string)
parser = Parser()
parser.readContents(string.encode("utf8"))
return {ent.key: ent for ent in parser}
def ftl_resource_to_ast(code):
return fluent_parser.parse(ftl(code))
def ftl_resource_to_json(code):
return fluent_parser.parse(ftl(code)).to_json()
def ftl_pattern_to_json(code):
ps = FluentParserStream(ftl(code))
return fluent_parser.maybe_get_pattern(ps).to_json()
def to_json(merged_iter):
return {path: resource.to_json() for path, resource in merged_iter}
LOCALIZABLE_ENTRIES = (FTL.Message, FTL.Term)
def get_message(body, ident):
for entity in body:
if isinstance(entity, LOCALIZABLE_ENTRIES) and entity.id.name == ident:
return entity
def get_transform(body, ident):
for transform in body:
if transform.id.name == ident:
return transform
def skeleton(node):
if isinstance(node, LOCALIZABLE_ENTRIES):
return type(node)(id=node.id.clone(), value=None)
return node.clone()
def ftl(code):
code = code.lstrip("\n")
return textwrap.dedent(code)
def fold(fun, node, init):
def fold_(vals, acc):
if not vals:
return acc
head = list(vals)[0]
tail = list(vals)[1:]
if isinstance(head, FTL.BaseNode):
acc = fold(fun, head, acc)
if isinstance(head, list):
acc = fold_(head, acc)
if isinstance(head, dict):
acc = fold_(head.values(), acc)
return fold_(tail, fun(acc, head))
return fold_(vars(node).values(), init)