"""
PySummary
A PySummary instance reads a python file and creates a summary of the file which you can access by using it as a string (e.g., %s or str()).
The notion of a "category" is recognized. A category is simply a group of methods with a given name. The default prefix for denoting a category is ##.
"""
import string
from string import find, join, replace, strip
from types import *
import os
class PySummary:
## Init ##
def __init__(self):
self._filename = None
self._lines = []
self.invalidateCache()
if os.path.exists('PySummary.config'):
self.readConfig('PySummary.config')
## Config ##
def readConfig(self, filename):
self._settings = eval(open(filename).read())
assert type(self._settings) is DictType
## Reading files ##
def readFileNamed(self, filename):
self._filename = filename
file = open(filename)
self.readFile(file)
file.close()
def readFile(self, file):
self.invalidateCache()
for line in file.readlines():
if line and line[-1]=='\n':
line = line[:-1]
sline = strip(line)
if not sline:
continue
try:
if sline[:6]=='class ' and sline[6]!='_':
self._lines.append(Line('class', line))
elif sline[:4]=='def ' and (sline[4]!='_' or sline[5]=='_'):
self._lines.append(Line('def', line))
elif sline[:3]=='## ':
self._lines.append(Line('category', line))
except IndexError:
pass
## Reports ##
def text(self):
return self.render('text')
def html(self):
return self.render('html')
def render(self, format):
filename = self._filename
span = format=='html'
settings = self._settings[format]
res = []
res.append(settings['file'][0] % locals())
for line in self._lines:
type = line.type()
res.append(settings[type][0])
if span:
res.append('' % type)
res.append(apply(getattr(line, format))) # e.g., line.format()
if span:
res.append('')
res.append('\n')
res.append(settings[type][1])
res.append(settings['file'][1] % locals())
res = join(res, '')
res = replace(res, '\t', settings['tabSubstitute'])
return res
## As strings ##
def __repr__(self):
return self.text()
def __str__(self):
return self.html()
## Self utility ##
def invalidateCache(self):
self._text = None
self._html = None
class Line:
def __init__(self, type, contents):
self._type = type
self._text = contents
self._html = None
def type(self):
return self._type
def text(self):
return self._text
def html(self):
if self._html is None:
if self._type=='class' or self._type=='def':
delimiters = {'class': ':', 'def': '('}
delimiter = delimiters[self._type]
ht = self._text
start = find(ht, self._type) + len(self._type) + 1
end = find(ht, delimiter, start)
ht = '%s%s%s' % (
ht[:start], ht[start:end], ht[end:])
else:
ht = self._text
self._html = ht
return self._html
def __str__(self):
return self.contents()
def test():
print 'Testing on self...'
sum = PySummary()
sum.readFileNamed('PySummary.py')
open('PySummary.py.sum.text', 'w').write(sum.text())
open('PySummary.py.sum.html', 'w').write(sum.html())
print 'Wrote PySummary.py.sum.* files.'
print 'Finished.'
if __name__=='__main__':
test()