2 # Copyright 2009, Alexandre Deckner, alex@zappotek.com
3 # Distributed under the terms of the MIT License.
8 # prints match to stdout
9 def printMatch(name
, match
, source
):
12 startLine
= source
.count('\n', 0, start
)
13 startColumn
= start
- source
.rfind('\n', 0, start
)
14 print name
+ " (line " + str(startLine
+ 1) + ", " + str(startColumn
) \
15 + "): '" + match
.group().replace('\n','\\n') + "'"
18 def openHtml(fileList
, outputFileName
):
19 file = open(outputFileName
, 'w')
21 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
22 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
23 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
25 <title>Style violations</title>
26 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
27 <style type="text/css">""" + cssStyle() + """</style>
30 <p><b>File list:</b><br>""")
31 for fileName
in fileList
:
32 file.write(fileName
+ "<br>")
37 def closeHtml(outputFileName
):
38 file = open(outputFileName
, 'a')
48 def renderHtml(text
, highlights
, sourceFileName
, outputFileName
):
49 splittedText
= highlightSplit(text
, highlights
)
51 file = open(outputFileName
, 'a')
52 file.write("<hr/><p><b>" + sourceFileName
+ "</b></p>")
54 # insert highlight tags in a temp buffer
57 for slice in splittedText
:
59 temp
+= escape(slice) + '<span class="highlight tooltip">'
61 temp
+= escape(slice) + "<em>" + highlights
[(count
- 1) / 2][2] \
65 temp
+= "</span>" # close the superfluous last highlight
67 file.write('<table><tr><td><pre class="code"><span class="linenumber">')
69 for line
in temp
.split('\n'):
70 file.write(str(count
).rjust(4)+"<br>")
73 file.write('</span></pre></td><td><pre class="code">')
75 for line
in temp
.split('\n'):
76 file.write('<span class="linehead"> </span>' + line
.replace('\r', ' ') \
79 file.write("</pre></td></tr></table>")
84 # highlight overlap check
85 def highlightOverlaps(highlight1
, highlight2
):
86 #print "hl1", highlight1, "hl2", highlight2
87 return not(highlight2
[0] > highlight1
[1] or highlight1
[0] > highlight2
[1])
90 # splits the string in three parts before, between and after the highlight
91 def splitByHighlight(string
, highlight
):
92 return (string
[:highlight
[0]], string
[highlight
[0]:highlight
[1]], \
93 string
[highlight
[1]:])
96 # splits the source text on highlights boundaries so that we can escape to html
97 # without the need to recalculate the highlights positions
98 def highlightSplit(string
, highlights
):
103 for (start
, end
, name
) in highlights
:
105 (before
, between
, after
) = splitByHighlight( \
106 text
, (start
- offset
, end
- offset
))
107 splittedString
.append(before
)
108 splittedString
.append(between
)
111 offset
+= len(before
+ between
)
113 print "overlap ", (start
, end
, name
)
114 splittedString
.append(text
)
115 return splittedString
118 # checkHighlights() checks for highlights overlaps
119 def checkHighlights(highlights
):
123 lastHighlight
= (-2, -1, '')
125 # merge overlapping highlights
126 for highlight
in highlights
:
127 if highlightOverlaps(highlight
, lastHighlight
):
129 newStart
= min(lastHighlight
[0], highlight
[0])
130 newEnd
= max(lastHighlight
[1], highlight
[1])
131 newComment
= lastHighlight
[2]
133 if (newComment
.find(highlight
[2]) == -1):
134 newComment
+= " + " + highlight
[2]
136 highlight
= (newStart
, newEnd
, newComment
)
137 highlights
[index
] = highlight
139 # mark highlight to be deleted
140 highlights
[index
- 1] = (0, 0, "")
142 lastHighlight
= highlight
145 # remove "to be deleted" highlights
146 return [ (start
, end
, comment
) for (start
, end
, comment
) in highlights \
147 if (start
, end
, comment
) != (0, 0, "") ]
162 .highlight .linehead {
163 background: #ffff00;;
182 font-family: monospace;
193 text-decoration:none;
204 border: 1px solid #bbb;