git » pygen » commit 6150fc9

Initial import.

author Alberto Bertogli
2006-03-07 07:12:15 UTC
committer Alberto Bertogli
2006-03-07 07:12:15 UTC

Initial import.

pygen +192 -0
samples/1/hdr.pgh +4 -0
samples/1/sample.html.pg +27 -0
samples/2/src/a/hdr.pgh +4 -0
samples/2/src/a/sample.html.pg +27 -0
samples/2/src/anyfile +0 -0
samples/2/src/b/b.html.pg +10 -0
samples/3/src/a.txt.pg +4 -0

diff --git a/pygen b/pygen
new file mode 100644
index 0000000..2a634fe
--- /dev/null
+++ b/pygen
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import shutil
+from optparse import OptionParser
+
+
+def printd(*args):
+	for i in args:
+		print >> sys.stderr, i,
+	print >> sys.stderr
+
+def is_newer_than(new, old):
+	"""Determine if "new" is newer than "old"."""
+	if not os.path.exists(new):
+		return False
+	if os.path.getmtime(new) >= os.path.getmtime(old):
+		return True
+	return False
+
+
+def gen_from(src, dst, environ = None, incpath = None):
+	"Process src and generate dst."
+
+	# open files if necessary
+	if not isinstance(src, file):
+		src = open(src)
+	if not isinstance(dst, file):
+		dst = open(dst, 'w')
+
+	# set up the environment for execution
+	preout = sys.stdout
+	if not environ:
+		sys.stdout = dst
+		environ = {
+			'sys': sys,
+		}
+
+	# include path search
+	if not incpath:
+		incpath = options.include
+	base, reduced = os.path.split(src.name)
+	incpath.append(base)
+
+	# state variables
+	in_python = 0
+	in_python_code = ''
+
+	for line in src:
+
+		# state parsing
+		if in_python and not line.startswith('#endpy'):
+			in_python_code += line
+			continue
+
+		if line.startswith('#include '):
+			path = line.split()[1]
+			origpath = path
+			if not os.path.exists(path):
+				for p in incpath:
+					newpath = p + '/' + path
+					if os.path.exists(newpath):
+						path = newpath
+						break
+				else:
+					printd("Unable to find file to include")
+					printd("\tsrc: %s" % src.name)
+					printd("\tfile: %s" % origpath)
+					printd("\tincpath: %s" % str(incpath))
+					os.unlink(dst.name)
+					return
+
+			gen_from(path, dst, environ)
+
+		elif line.startswith('#py '):
+			code = line.split(' ', 1)[1]
+			exec code in environ
+
+		elif line.startswith('#py:'):
+			in_python = 1
+			in_python_code = ''
+
+		elif line.startswith('#endpy'):
+			exec in_python_code in environ
+			in_python = 0
+			in_python_code = ''
+
+		elif line.startswith('#print'):
+			s = line.split(' ', 1)[1]
+			s = 'print ' + s
+			exec s in environ
+
+		else:
+			dst.write(line)
+
+	# restore environment
+	sys.stdout = preout
+
+
+def autogen(src, dst):
+	"Generate automatically by walking src and storing results in dst."
+
+	srcroot = os.path.abspath(src)
+	base, reduced = os.path.split(srcroot)
+	tree = os.walk(srcroot)
+
+	if not os.path.isdir(dst):
+		print 'mkdir', dst
+		os.mkdir(dst)
+
+	for path, dirs, files in tree:
+		for d in dirs:
+			fulld = path + '/' + d
+			diff = fulld[len(srcroot):]
+			p = os.path.normpath(dst + '/' + diff)
+			if os.path.islink(fulld):
+				files.append(d)
+				continue
+			if not os.path.isdir(p):
+				print 'mkdir', p
+				os.mkdir(p)
+
+		for f in files:
+			fullf = path + '/' + f
+			diff = fullf[len(srcroot):]
+			if diff.endswith('.pgh'):
+				# header files are ignored
+				print 'ignored', diff
+				continue
+			elif diff.endswith('.pg'):
+				t = os.path.splitext(diff)[0]
+				t = os.path.normpath(dst + '/' + t)
+
+				if is_newer_than(t, fullf):
+					print 'skipped', diff
+					continue
+				print diff, '->', t
+				gen_from(fullf, t)
+			else:
+				t = os.path.normpath(dst + '/' + diff)
+				if is_newer_than(t, fullf):
+					print 'skipped', diff
+					continue
+				if os.path.islink(fullf):
+					dlink = os.readlink(fullf)
+					print 'symlink', diff, '->', dlink
+					os.symlink(dlink, t)
+				elif os.path.isfile(fullf):
+					print 'copy', diff
+					shutil.copy2(fullf, t)
+
+
+if __name__ == '__main__':
+
+	usage = "usage: %prog [options] {gen|autogen} [action_parameters]"
+
+	parser = OptionParser(usage)
+	parser.add_option("-I", "--include", action = "append", default = [],
+			help = "Include directory for .pgh files")
+	#parser.add_option("-v", "--verbose", action = "store_true",
+	#		help = "Show additional information")
+
+	options, args = parser.parse_args()
+
+	if len(args) < 1:
+		parser.error("Incorrect number of arguments")
+		sys.exit(1)
+
+	action = args[0]
+
+	if action == 'gen':
+		if len(args) < 2:
+			parser.error("Incorrect number of arguments")
+			sys.exit(1)
+		for src in args[1:]:
+			dst = os.path.splitext(src)[0]
+			print src, '->', dst
+			gen_from(src, dst)
+
+	elif action == 'autogen':
+		if len(args) < 3:
+			parser.error("Incorrect number of arguments")
+			sys.exit(1)
+		srcroot, dstroot = args[1:3]
+		autogen(srcroot, dstroot)
+
+	else:
+		parser.error("Unknown action")
+		sys.exit(1)
+
+
diff --git a/samples/1/hdr.pgh b/samples/1/hdr.pgh
new file mode 100644
index 0000000..4495334
--- /dev/null
+++ b/samples/1/hdr.pgh
@@ -0,0 +1,4 @@
+<head>
+#py print "<title>" + title + "</title>"
+</head>
+
diff --git a/samples/1/sample.html.pg b/samples/1/sample.html.pg
new file mode 100644
index 0000000..f52f154
--- /dev/null
+++ b/samples/1/sample.html.pg
@@ -0,0 +1,27 @@
+
+<html>
+#py title = "Title set dynamically"
+#include hdr.pgh
+
+<body>
+
+To generate an html file from this, run <tt>pygen genhtml sample.pg</tt>.<br>
+
+This is the main body<br>
+#py print "One-line python statement"
+<p>
+
+#print "Shortcut to print<br>"
+Some more static text.<p>
+
+#py:
+i = 1
+l = ['a', 2, 'b']
+print 'Some variables:', i, l
+#endpy
+
+The end!
+
+</body>
+</html>
+
diff --git a/samples/2/src/a/hdr.pgh b/samples/2/src/a/hdr.pgh
new file mode 100644
index 0000000..4495334
--- /dev/null
+++ b/samples/2/src/a/hdr.pgh
@@ -0,0 +1,4 @@
+<head>
+#py print "<title>" + title + "</title>"
+</head>
+
diff --git a/samples/2/src/a/sample.html.pg b/samples/2/src/a/sample.html.pg
new file mode 100644
index 0000000..f52f154
--- /dev/null
+++ b/samples/2/src/a/sample.html.pg
@@ -0,0 +1,27 @@
+
+<html>
+#py title = "Title set dynamically"
+#include hdr.pgh
+
+<body>
+
+To generate an html file from this, run <tt>pygen genhtml sample.pg</tt>.<br>
+
+This is the main body<br>
+#py print "One-line python statement"
+<p>
+
+#print "Shortcut to print<br>"
+Some more static text.<p>
+
+#py:
+i = 1
+l = ['a', 2, 'b']
+print 'Some variables:', i, l
+#endpy
+
+The end!
+
+</body>
+</html>
+
diff --git a/samples/2/src/anyfile b/samples/2/src/anyfile
new file mode 100644
index 0000000..e69de29
diff --git a/samples/2/src/b/b.html.pg b/samples/2/src/b/b.html.pg
new file mode 100644
index 0000000..53763b8
--- /dev/null
+++ b/samples/2/src/b/b.html.pg
@@ -0,0 +1,10 @@
+
+<html>
+
+<body>
+
+This is a file which lives in B
+
+</body>
+</html>
+
diff --git a/samples/3/src/a.txt.pg b/samples/3/src/a.txt.pg
new file mode 100644
index 0000000..4b991e4
--- /dev/null
+++ b/samples/3/src/a.txt.pg
@@ -0,0 +1,4 @@
+#py:
+print "Hello hello!"
+#endpy
+