zulip/tools/get-handlebar-vars

116 lines
2.9 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):
# type: (Any) -> None
print(json.dumps(obj, indent=4))
def parse_file(fn):
# type: (str) -> Dict[str, Any]
with open(fn, 'r') 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, val):
# type: (str, 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):
# type: (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()