PageRenderTime 40ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/phpy/drafts/phpy_2.py

https://bitbucket.org/arosenthal/python
Python | 77 lines | 67 code | 6 blank | 4 comment | 0 complexity | 520046e34cf7b1f5ec900e136a856f19 MD5 | raw file
  1. #Python Hypertext Preprocessor (Second iteration: Not functional)
  2. #Author: Anson Rosenthal (anrosent)
  3. #10/2013
  4. #Figured out scheme for output capture using ast, but parsing still a pain
  5. import ast, sys
  6. code_start_delim = "<?"
  7. code_stop_delim = "?>"
  8. class TextNode():
  9. def __init__(self, string):
  10. self.string = string
  11. def capture_output(self):
  12. return self.string
  13. class CodeNode():
  14. def __init__(self, string):
  15. self.string = string
  16. self.capture = ''
  17. def self_node(self):
  18. return ast.Name('self')
  19. def write(self, string):
  20. self.capture += string
  21. def capture_output(self):
  22. tree = ast.parse(self.string)
  23. for node in ast.walk(tree):
  24. if isinstance(node, ast.Call):
  25. if node.func.id == 'print':
  26. node.keywords.append(ast.keyword('file',self.self_node()))
  27. exec(self.string)
  28. return self.capture
  29. def parse(string):
  30. nodes = []
  31. return parse_rec(iter(string.lstrip(code_start_delim)), nodes, string.startswith(code_start_delim))
  32. def parse_rec(string_iter, nodes, in_code):
  33. if in_code:
  34. nodes.append(get_code_node(string_iter))
  35. else:
  36. nodes.append(get_text_node(string_iter))
  37. return parse_rec(string_iter, nodes, not in_code)
  38. def get_code_node(string_iter):
  39. buf = []
  40. delim_match = 0
  41. while delim_match < len(code_stop_delimeter):
  42. c = string_iter.__next__()
  43. if c == code_stop_delimeter[delim_match]:
  44. delim_match += 1
  45. buf.append(c)
  46. return ''.join(buf[:-len(code_stop_delimeter)])
  47. def get_text_node(string_iter):
  48. buf = []
  49. delim_match = 0
  50. for c in string_iter:
  51. if c == code_start_delimeter[delim_match]:
  52. delim_match += 1
  53. el
  54. buf.append(c)
  55. return ''.join(buf[:-len(code_stop_delimeter)])
  56. def parse_full(string):
  57. return ''.join(node.capture_output() for node in parse(string))
  58. if __name__ == '__main__':
  59. with open(sys.argv[1]) as inputfile:
  60. print(parse_full(inputfile.read()))