diff --git a/example.pyh b/example.pyh new file mode 100644 index 0000000..9dddcb5 --- /dev/null +++ b/example.pyh @@ -0,0 +1,51 @@ + + + + + + + + <?= title ?> + + +

+

+ + + + + + + + + + +
+ + diff --git a/pyhi.sh b/pyhi.sh new file mode 100644 index 0000000..710ef96 --- /dev/null +++ b/pyhi.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [ -z "$PYHP" ]; then + PYHP=""$(dirname "$0")"/pyhp.py" +fi + +PYH="$1" +shift + +HYPERTEXT=$("$PYHP" "$PYH" | python3 - "$@") + +# check for headers, if present assume the pyh file is going to handle them +if head -n1 <<< "$HYPERTEXT" | grep "[A-Za-z][A-Za-z0-9\-]*: "; then + ; +else + echo -ne "Content-type: text/html\\n\\n" +fi diff --git a/pyhp.py b/pyhp.py new file mode 100644 index 0000000..ea40bb7 --- /dev/null +++ b/pyhp.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 + +# This is a naive implementation of the Python Hypertext preprocessor. +# For example, we just assume that we can hold the entire code in memory. +# Also, this is just the preprocessor, the resulting code will not be +# executed. + +# Yes, the comments were here first and I wrote the code after writing them and then adjusted them to reality. + +import sys + +fd = open(sys.argv[1], "r") +lines = fd.read().split("\n") +fd.close() + +# start text +output = "print(\"\"\"" +# while not end of file +while len(lines)>0: + # grab a line to process + line = lines.pop(0) + # iterate over line + i=0 + while i < len(line): + # attempt to grab the next few characters + try: + # variable(s) or code + if line[i:i+3] in [" or a line break + while True: + # if line break, attempt to go to next line + if len(line[i:])<2: + variable_list = variable_list + line[i:] + i = -1 + try: + line = lines.pop(0) + except IndexError: + print("Unexpected end of file: No closing ?> found.", file=sys.stderr) + sys.exit(1) + else: + if line[i:i+2]=="?>": + i = i+1 + break + else: + # add to variable list + variable_list = variable_list + line[i] + i = i+1 + # split at comma and add the variables + output = output + ") + str(".join(variable_list.split(",")) + ") + " + # code + elif line[i:i+4] == "" in line: + # fix indent + line = indent*" "+line[unindent_length:] + # add code line + output = output + line + "\n" + # grab next code line + line = lines.pop(0) + # checking for end of code failed + except IndexError: + print("Unexpected end of file: No closing ?> found.", file=sys.stderr) + sys.exit(1) + # attempt to determine indent after end of code + indent = 0 + try: + if not line[:line.find("?>")].strip()=="": + indent = int(line[:line.find("?>")]) + except ValueError: + print("Invalid indent: \""+line[:line.find("?>")]+"\"\n" + line, file=sys.stderr) + sys.exit(1) + # add indent after end of code + output = output + " "*indent + "print(" + # set i accordingly to add rest of line after code + # block end + i = line.find("?>")+2 + # assume accidental match + else: + # start text + output = output + " + \"" + # add text + output = output + line[i] + # end text + output = output + "\" + " + # start text + output = output + "\"\"\"" + else: + # add text + output = output + line[i] + # handle last characters of line + except IndexError: + # add text + output = output + line[i] + i = i+1 + output = output + "\n" +# end text +output = output + "\"\"\", end=\"\")\n" + +print(output)