Created
December 5, 2018 04:59
-
-
Save simplymathematics/5ddcb4c22baae95ef28f7cdf14e636fc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import re, sys, json | |
default_stream = \ | |
""" | |
"header": "Hello!" | |
"somearray": ["apple", "banana", "citrus", "dog"] | |
"footer": "That's it!" | |
"condition": "True" | |
"result": "You win!" | |
""" | |
default_template = \ | |
""" | |
First line. | |
{{header}} | |
{{#loop somearray item}} | |
This is a {{item}}. | |
{{#if condition result}} | |
This is {{result}}. | |
{{footer}} | |
Last line. | |
""" | |
def interpret(t, i): | |
""" | |
This function filters the layout according to the default template and outputs | |
it to stdout. It will strings, ints, and floats to the command line as printed text. | |
It loops through an array and prints out each elements using the specified notation. | |
{{#loop somearray item}} | |
Please note that this does | |
IT also takes a boolean condition and prints a result, both passed in from the stream. | |
""" | |
## Variables | |
template_add = {} | |
next_row_skip = [-1] | |
## v: stream by row. if by file, then use enumerate(v.splitlines(True)) | |
template = list(filter(None, list(t.split('\n')))) | |
for k,y in enumerate(i): | |
if 'header' in y.keys() \ | |
or 'footer' in y.keys(): | |
replace_with = str(list(y.values())[0]) | |
replace_this = str(list(y.keys())[0]) | |
template_add[replace_this] = replace_with | |
if 'condition' in y.keys(): | |
replace_with = str(y.values()) | |
replace_this = str(y.keys()) | |
template_add[replace_this] = replace_with | |
if 'result' in y.keys(): | |
replace_this = str(list(y.keys())[0]) | |
replace_with = list(y.values())[0] | |
template_add[replace_this] = replace_with | |
elif isinstance(list(y.values())[0], list) == True: | |
replace_this = str(list(y.keys())[0]) | |
replace_with = list(y.values())[0] | |
template_add[replace_this] = replace_with | |
elif isinstance(list(y.values())[0], int) == True: | |
replace_with = list(y.values())[0] | |
replace_this = str(list(y.keys())[0]) | |
template_add[replace_this] = replace_with | |
else: | |
## default type set: string | |
replace_with = str(list(y.values())[0]) | |
replace_this = str(list(y.keys())[0]) | |
template_add[replace_this] = replace_with | |
#print(":::::::::::::::::::::template") | |
#print(template) | |
# <!-- end: build template_add --> | |
for this_row_id, this_row_data in enumerate(template): | |
try: | |
## future: recursive functions for sections with nested loops | |
i=1 | |
now_this_row_id = this_row_id | |
if this_row_data == '{{header}}' \ | |
or this_row_data == '{{footer}}': | |
this_row_data = this_row_data.replace( | |
'{{header}}', template_add['header']).replace( | |
'{{footer}}', template_add['footer']) | |
if this_row_data == '{{condition}}' \ | |
or this_row_data == '{{result}}': | |
this_row_data = this_row_data.replace( | |
'{{condition}}', template_add['condition']).replace( | |
'{{result}}', template_add['result']) | |
#print("::::::::::::::::templating debug") | |
#print(this_row_id, this_row_data) | |
## {{#loop somearray item}} | |
## Note this does not handle nested functions. | |
rx = re.findall(r"^{{#loop (\w+) (\w+)", this_row_data) | |
if rx: | |
rx_key = rx[0][0] # somearray | |
rx_val = template_add[rx_key] # list() | |
tx_rex = rx[0][1] # item | |
tx_mex = "{{" + tx_rex + "}}" # {{item}} | |
this_row_data = "" | |
replace_next_row = template[now_this_row_id+1] | |
next_row_skip.append(now_this_row_id+i) | |
for abc,xyz in enumerate(rx_val): | |
this_row_data += replace_next_row.replace(tx_mex, str(xyz))+"\n" | |
#{{#if condition result}} | |
rx = re.findall("^{{#if (\w+) (\w+)", this_row_data) | |
if rx: | |
rx_key = rx[0][0] # condition | |
rx_val = template_add[str(rx_key)] # bool | |
tx_rex = rx[0][1] # result | |
tx_mex = "{{" + tx_rex + "}}" # {{result}} | |
this_row_data = "" | |
replace_next_row = template[now_this_row_id+1] | |
next_row_skip.append(now_this_row_id+i) | |
if eval(rx_val): | |
this_row_data += replace_next_row.replace(tx_mex, rx_val)+"\n" | |
## <!-- end: use template_add --> | |
except (IndexError) as e: | |
pass | |
## skip rows, strip dupe newlines, append to final output_result | |
try: | |
if this_row_id in next_row_skip: | |
# Row: Nothing appended to final output | |
next_row_skip.remove(this_row_id) | |
else: | |
# Row: Appending data to final output | |
if not this_row_data == "": | |
pass | |
output_result += this_row_data.rstrip("\n") + "\n" | |
except (NameError) as e: | |
if (next_row_skip == this_row_id): | |
# Row: Nothing appended to final output | |
continue | |
else: | |
# Row: Created row 1 | |
output_result = this_row_data + "\n" | |
# Idx: Removed placeholder -1 | |
next_row_skip.remove(-1) | |
return output_result | |
## <!-- end: filter_layout_template --> | |
def split_input_stream(x): | |
return filter(None, list(x.split('\n'))) | |
def json_input_stream(x): | |
return [ json.loads("{" + str(i) + "}") for i in x ] | |
def read_input_stream(): | |
input_stream = sys.stdin.read() | |
return input_stream | |
if __name__ == '__main__': | |
#input_stream = default_stream | |
input_stream = read_input_stream() | |
layout_template = default_template | |
input_stream_list = split_input_stream(input_stream) | |
input_stream_json = json_input_stream(input_stream_list) | |
layout_template_list = interpret(layout_template, | |
input_stream_json) | |
print(layout_template_list) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment