Commit ef9f1868 authored by Stefan Behnel's avatar Stefan Behnel

fix code annotation for unicode source

parent cd9d08f3
...@@ -3,15 +3,17 @@ ...@@ -3,15 +3,17 @@
import os import os
import re import re
import time import time
import codecs
from StringIO import StringIO from StringIO import StringIO
import Version import Version
from Code import CCodeWriter from Code import CCodeWriter
from Cython import Utils
# need one-characters subsitutions (for now) so offsets aren't off # need one-characters subsitutions (for now) so offsets aren't off
special_chars = [('<', '\xF0', '&lt;'), special_chars = [(u'<', u'\xF0', u'&lt;'),
('>', '\xF1', '&gt;'), (u'>', u'\xF1', u'&gt;'),
('&', '\xF2', '&amp;')] (u'&', u'\xF2', u'&amp;')]
class AnnotationCCodeWriter(CCodeWriter): class AnnotationCCodeWriter(CCodeWriter):
...@@ -48,7 +50,7 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -48,7 +50,7 @@ class AnnotationCCodeWriter(CCodeWriter):
def save_annotation(self, filename): def save_annotation(self, filename):
self.mark_pos(None) self.mark_pos(None)
f = open(filename) f = Utils.open_source_file(filename)
lines = f.readlines() lines = f.readlines()
for k in range(len(lines)): for k in range(len(lines)):
line = lines[k] line = lines[k]
...@@ -76,10 +78,11 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -76,10 +78,11 @@ class AnnotationCCodeWriter(CCodeWriter):
line = lines[line_no] line = lines[line_no]
lines[line_no] = line[:col] + item + line[col:] lines[line_no] = line[:col] + item + line[col:]
f = open("%s.html" % filename, "w") f = codecs.open("%s.html" % filename, "w", encoding="UTF-8")
f.write('<html>\n') f.write(u'<html>\n')
f.write(""" f.write(u"""
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css"> <style type="text/css">
body { font-family: courier; font-size: 12; } body { font-family: courier; font-size: 12; }
...@@ -112,16 +115,16 @@ function toggleDiv(id) { ...@@ -112,16 +115,16 @@ function toggleDiv(id) {
</script> </script>
</head> </head>
""") """)
f.write('<body>\n') f.write(u'<body>\n')
f.write('<p>Generated by Cython %s on %s\n' % (Version.version, time.asctime())) f.write(u'<p>Generated by Cython %s on %s\n' % (Version.version, time.asctime()))
c_file = os.path.basename(filename)[:-3] + 'c' c_file = Utils.encode_filename(os.path.basename(filename)[:-3] + 'c')
f.write('<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file)) f.write(u'<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
k = 0 k = 0
py_c_api = re.compile('(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)') py_c_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)')
pyx_api = re.compile('(__Pyx[A-Za-z_]+)\(') pyx_api = re.compile(u'(__Pyx[A-Za-z_]+)\(')
py_marco_api = re.compile('(Py[A-Za-z]*_[A-Z][A-Z_]+)') py_marco_api = re.compile(u'(Py[A-Za-z]*_[A-Z][A-Z_]+)')
error_goto = re.compile(r'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})') error_goto = re.compile(ur'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})')
for line in lines: for line in lines:
...@@ -131,33 +134,33 @@ function toggleDiv(id) { ...@@ -131,33 +134,33 @@ function toggleDiv(id) {
except KeyError: except KeyError:
code = '' code = ''
code, c_api_calls = py_c_api.subn(r"<span class='py_api'>\1</span>", code) code, c_api_calls = py_c_api.subn(ur"<span class='py_api'>\1</span>", code)
code, pyx_api_calls = pyx_api.subn(r"<span class='pyx_api'>\1</span>(", code) code, pyx_api_calls = pyx_api.subn(ur"<span class='pyx_api'>\1</span>(", code)
code, macro_api_calls = py_marco_api.subn(r"<span class='py_macro_api'>\1</span>", code) code, macro_api_calls = py_marco_api.subn(ur"<span class='py_macro_api'>\1</span>", code)
code, error_goto_calls = error_goto.subn(r"<span class='error_goto'>\1</span>", code) code, error_goto_calls = error_goto.subn(ur"<span class='error_goto'>\1</span>", code)
code = code.replace("<span class='error_goto'>;", ";<span class='error_goto'>") code = code.replace(u"<span class='error_goto'>;", u";<span class='error_goto'>")
color = "FFFF%02x" % int(255/(1+(5*c_api_calls+2*pyx_api_calls+macro_api_calls)/10.0)) color = u"FFFF%02x" % int(255/(1+(5*c_api_calls+2*pyx_api_calls+macro_api_calls)/10.0))
f.write("<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k)) f.write(u"<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k))
f.write(" %d: " % k) f.write(u" %d: " % k)
for c, cc, html in special_chars: for c, cc, html in special_chars:
line = str(line).replace(cc, html) line = line.replace(cc, html)
f.write(line.rstrip()) f.write(line.rstrip())
f.write('</pre>\n') f.write(u'</pre>\n')
f.write("<pre id='line%s' class='code' style='background-color: #%s'>%s</pre>" % (k, color, code)) f.write(u"<pre id='line%s' class='code' style='background-color: #%s'>%s</pre>" % (k, color, code))
f.write('</body></html>\n') f.write(u'</body></html>\n')
f.close() f.close()
# TODO: make this cleaner # TODO: make this cleaner
def escape(raw_string): def escape(raw_string):
raw_string = raw_string.replace("\'", r"&#146;") raw_string = raw_string.replace(u"\'", ur"&#146;")
raw_string = raw_string.replace('\"', r'&quot;') raw_string = raw_string.replace(u'\"', ur'&quot;')
raw_string = raw_string.replace('\n', r'<br>\n') raw_string = raw_string.replace(u'\n', ur'<br>\n')
raw_string = raw_string.replace('\t', r'\t') raw_string = raw_string.replace(u'\t', ur'\t')
return raw_string return raw_string
...@@ -170,7 +173,7 @@ class AnnotationItem: ...@@ -170,7 +173,7 @@ class AnnotationItem:
self.size = size self.size = size
def start(self): def start(self):
return "<span class='tag %s' title='%s'>%s" % (self.style, self.text, self.tag) return u"<span class='tag %s' title='%s'>%s" % (self.style, self.text, self.tag)
def end(self): def end(self):
return self.size, "</span>" return self.size, u"</span>"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment