mirror of https://github.com/zulip/zulip.git
112 lines
2.8 KiB
Python
Executable File
112 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
import re
|
|
import json
|
|
|
|
# check for the venv
|
|
from lib import sanity_check
|
|
sanity_check.check_venv(__file__)
|
|
|
|
from typing import Any, Dict, List
|
|
|
|
def debug(obj: Any) -> None:
|
|
print(json.dumps(obj, indent=4))
|
|
|
|
def parse_file(fn: str) -> Dict[str, Any]:
|
|
with open(fn) as f:
|
|
text = f.read()
|
|
tags = re.findall(r'{+\s*(.*?)\s*}+', text)
|
|
root = {} # type: Dict[str, Any]
|
|
context = root
|
|
stack = [] # type: List[Dict[str, Any]]
|
|
|
|
def set_var(var: str, val: Any) -> None:
|
|
num_levels_up = len(re.findall(r'\.\.', var))
|
|
if num_levels_up:
|
|
var = var.split('/')[-1]
|
|
stack[-1 * num_levels_up][var] = val
|
|
else:
|
|
context[var] = val
|
|
|
|
for tag in tags:
|
|
if tag.startswith('! '):
|
|
continue
|
|
|
|
if tag == 'else':
|
|
continue
|
|
|
|
if tag[0] in '#^' and ' ' not in tag:
|
|
var = tag[1:]
|
|
set_var(var, True)
|
|
stack.append(context)
|
|
continue
|
|
|
|
if tag.startswith('#if'):
|
|
vars = tag.split()[1:]
|
|
for var in vars:
|
|
set_var(var, True)
|
|
stack.append(context)
|
|
continue
|
|
|
|
if tag.startswith('/if'):
|
|
context = stack.pop()
|
|
continue
|
|
|
|
if tag.startswith('#with '):
|
|
var = tag.split()[1]
|
|
new_context = {} # type: Dict[str, Any]
|
|
context[var] = new_context
|
|
stack.append(context)
|
|
context = new_context
|
|
continue
|
|
|
|
if tag.startswith('/with'):
|
|
context = stack.pop()
|
|
continue
|
|
|
|
if tag.startswith('#unless '):
|
|
var = tag.split()[1]
|
|
set_var(var, True)
|
|
stack.append(context)
|
|
continue
|
|
|
|
if tag.startswith('/unless'):
|
|
context = stack.pop()
|
|
continue
|
|
|
|
if tag.startswith('#each '):
|
|
var = tag.split()[1]
|
|
new_context = {}
|
|
context[var] = [new_context]
|
|
stack.append(context)
|
|
context = new_context
|
|
continue
|
|
|
|
if tag.startswith('/each'):
|
|
context = stack.pop()
|
|
continue
|
|
|
|
if tag.startswith('/'):
|
|
context = stack.pop()
|
|
continue
|
|
|
|
set_var(tag, '')
|
|
|
|
def clean_this(obj: Any) -> Any:
|
|
if isinstance(obj, list):
|
|
return [clean_this(item) for item in obj]
|
|
if isinstance(obj, dict):
|
|
if len(obj) == 1 and 'this' in obj:
|
|
return clean_this(obj['this'])
|
|
return {k: clean_this(v) for k, v in obj.items()}
|
|
return obj
|
|
root = clean_this(root)
|
|
return root
|
|
|
|
if __name__ == '__main__':
|
|
for fn in sys.argv[1:]:
|
|
print('===', fn)
|
|
root = parse_file(fn)
|
|
debug(root)
|
|
print()
|