From: Robert Bradshaw Date: Sun, 18 Nov 2007 08:16:43 +0000 (-0800) Subject: Add annotate file for html output X-Git-Tag: 0.9.6.14~29^2~93 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=7c2bc88cbc09c2d1b6856858470fc352c60a504e;p=cython.git Add annotate file for html output --- diff --git a/Cython/Compiler/Annotate.py b/Cython/Compiler/Annotate.py new file mode 100644 index 00000000..278ca8e6 --- /dev/null +++ b/Cython/Compiler/Annotate.py @@ -0,0 +1,163 @@ +# Note: Work in progress + + +import re +from StringIO import StringIO + + +from Code import CCodeWriter + + +class AnnotationCCodeWriter(CCodeWriter): + + def __init__(self, f): + CCodeWriter.__init__(self, self) + self.buffer = StringIO() + self.real_f = f + self.annotations = [] + self.last_pos = None + self.code = {} + + def getvalue(self): + return self.real_f.getvalue() + + def write(self, s): + self.real_f.write(s) + self.buffer.write(s) + + def mark_pos(self, pos): +# if pos is not None: +# CCodeWriter.mark_pos(self, pos) +# return + print "marking", pos + if self.last_pos: + try: + code = self.code[self.last_pos[1]] + except KeyError: + code = "" + self.code[self.last_pos[1]] = code + self.buffer.getvalue() + self.buffer = StringIO() + self.last_pos = pos + + def annotate(self, pos, item): + self.annotations.append((pos, item)) + + def save_annotation(self, filename): + self.mark_pos(None) + f = open(filename) + lines = f.readlines() + for k in range(len(lines)): + # there has to be a better way to do this + lines[k] = lines[k].replace(' ','\t ') + lines[k] = lines[k].replace(' ','\t\t') + # TODO: this is incorrect + lines[k] = lines[k].replace('<', '~') + lines[k] = lines[k].replace('>', '~') + f.close() + all = [] + for pos, item in self.annotations: + if pos[0] == filename: + start = item.start() + size, end = item.end() + if size: + all.append((pos, start)) + all.append(((filename, pos[1], pos[2]+size), end)) + else: + all.append((pos, start+end)) + + all.sort() + all.reverse() + for pos, item in all: + _, line_no, col = pos + line_no -= 1 + col += 1 + line = lines[line_no] + lines[line_no] = line[:col] + item + line[col:] + + f = open("%s.html" % filename, "w") + f.write('\n') + f.write(""" + + + + + """) + f.write('\n') + k = 0 + + py_c_api = re.compile('(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)') + pyx_api = re.compile('(__Pyx[A-Za-z_]+)\(') + py_marco_api = re.compile('(Py[A-Za-z]*_[A-Z][A-Z_]+)') + + for line in lines: + + k += 1 + try: + code = self.code[k] + except KeyError: + code = '' + + code, c_api_calls = py_c_api.subn(r"\1", code) + code, pyx_api_calls = pyx_api.subn(r"\1(", code) + code, macro_api_calls = py_marco_api.subn(r"\1", code) + + color = "FFFF%02x" % int(255/(1+(5*c_api_calls+2*pyx_api_calls+macro_api_calls)/10.0)) + f.write("
" % (color, k)) + + f.write(" %d: " % k) + line = line.replace('\t', ' ') + f.write(line) + + f.write('
\n') + f.write("
%s
" % (k, color, code.replace('\n', '\n
'))) + f.write('\n') + f.close() + + +# TODO: make this cleaner +def escape(raw_string): + raw_string = raw_string.replace("\'", r"’") + raw_string = raw_string.replace('\"', r'"') + raw_string = raw_string.replace('\n', r'
\n') + raw_string = raw_string.replace('\t', r'\t') + return raw_string + + +class AnnotationItem: + + def __init__(self, style, text, tag="", size=0): + self.style = style + self.text = text + self.tag = tag + self.size = size + + def start(self): + return "%s" % (self.style, self.text, self.tag) + + def end(self): + return self.size, ""