/buildtime/py/pde2py.py

http://github.com/jdf/processing.py · Python · 126 lines · 100 code · 21 blank · 5 comment · 19 complexity · a04ff6894d9d66ebe58224c43269120c MD5 · raw file

  1. #!/usr/bin/python
  2. """
  3. Utility to do whatever mechanical work can be done in converting
  4. PDE examples to Python ones.
  5. """
  6. from __future__ import with_statement
  7. from optparse import OptionParser
  8. import os
  9. import re
  10. import shutil
  11. import sys
  12. def usage():
  13. print >> sys.stderr, 'Usage: pde2py [-f|--force] srcdir destdir'
  14. sys.exit(1)
  15. parser = OptionParser()
  16. parser.add_option("-f", "--force",
  17. action="store_true", dest="force", default=False,
  18. help="overwrite existing files")
  19. (opts, args) = parser.parse_args()
  20. if len(args) < 2:
  21. usage()
  22. src, dest = args
  23. if not (os.path.exists(src) and os.path.isdir(src)):
  24. usage()
  25. if not os.path.exists(dest):
  26. os.makedirs(dest)
  27. def copy_dir(s, d):
  28. if not os.path.exists(d):
  29. os.mkdir(d)
  30. for f in os.listdir(s):
  31. if f[0] == '.':
  32. continue
  33. copy(os.path.join(s, f), os.path.join(d, f))
  34. def copy_file(s, d, xform=None):
  35. with open(s, 'rb') as f:
  36. text = f.read()
  37. if xform:
  38. (d, text) = xform(d, text)
  39. if os.path.exists(d):
  40. if opts.force:
  41. print >> sys.stderr, 'Overwriting %s.' % d
  42. else:
  43. print >> sys.stderr, 'Not overwriting %s.' % d
  44. return
  45. else:
  46. print >> sys.stderr, 'Writing %s.' % d
  47. with open(d, 'wb') as f:
  48. f.write(text)
  49. def to_python_case(name):
  50. s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
  51. return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
  52. def xform_py(d, text):
  53. text = re.sub('(?<!:)//', '#', text)
  54. text = text.replace(' ', ' ')
  55. text = re.sub(r'for *\((?: *int *)?(\w+) *= *0 *; * \1 *< *([^;]+); *\1\+\+ *\)', r'for \1 in range(\2):', text)
  56. text = re.sub(r'for *\((?: *int *)?(\w+) *= *(\d+) *; * \1 *< *([^;]+); *\1\+\+ *\)', r'for \1 in range(\2, \3):', text)
  57. text = re.sub(r'for *\((?: *int *)?(\w+) *= *(\d+) *; * \1 *< *([^;]+); *\1 *\+= *([^\)]+)\)', r'for \1 in range(\2, \3, \4):', text)
  58. text = re.sub(r'(?m)^(\s*)(?:public *)?(?:void|int|float|String)\s+([a-zA-Z0-9]+)\s*\(([^\)]*)\)',
  59. r'\1def \2(\3):',
  60. text)
  61. text = re.sub(r'(?:int|float|String|double|Object)\s+([a-zA-Z0-9]+)\s*([,\)])',
  62. r'\1\2',
  63. text)
  64. text = re.sub(r'(?:int|float|String|double|Object)\s+([a-zA-Z0-9]+)\s*=',
  65. r'\1 =',
  66. text)
  67. text = re.sub(
  68. r'(?:abstract +)?class +(\w+)', r'class \1(object):', text)
  69. text = re.sub(
  70. r'(?m)^\s*(?:abstract\s+)?class\s+(\S+)\s*extends\s*(\S+)\s*$', r'class \1(\2):', text)
  71. text = re.sub(r'(?m)^(\s*)(?:void|int|float|String)\s+', r'\1', text)
  72. text = re.sub(r'[{};] *', '', text)
  73. text = re.sub(r'\n\n+', '\n', text)
  74. text = re.sub(r'(?m)^(\s*)if\s*\((.+?)\)\s*$', r'\1if \2:', text)
  75. text = re.sub(r'(?m)^(\s*)else\s+if\s*\((.+?)\)\s*$', r'\1elif \2:', text)
  76. text = re.sub(r'(?m)^(\s*)else\s*$', r'\1else:', text)
  77. text = re.sub(r'/\*+| *\*+/', '"""', text)
  78. text = re.sub(r'(?m)^ *\* *', '', text)
  79. text = text.replace('new ', '')
  80. text = text.replace('true', 'True')
  81. text = text.replace('false', 'False')
  82. text = text.replace('this.', 'self.')
  83. text = text.replace('||', 'or')
  84. text = text.replace('&&', 'and')
  85. text = re.sub(r'(\w+)\+\+', r'\1 += 1', text)
  86. text = re.sub(r'(\w+)--', r'\1 -= 1', text)
  87. text = re.sub(r'(\w+)\.length\b', r'len(\1)', text)
  88. parent = os.path.dirname(d)
  89. parent_name = os.path.basename(parent)
  90. name, ext = os.path.splitext(os.path.basename(d))
  91. if name == parent_name:
  92. newext = '.pyde'
  93. else:
  94. newext = '.py'
  95. name = to_python_case(name)
  96. d = parent + '/' + name + newext
  97. return (d, text)
  98. def copy(s, d):
  99. if os.path.isdir(s):
  100. copy_dir(s, d)
  101. elif s.endswith(".pde"):
  102. copy_file(s, d, xform_py)
  103. else:
  104. copy_file(s, d)
  105. copy(src, dest)