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')
47 def renderHtml(text
, highlights
, sourceFileName
, outputFileName
):
48 splittedText
= highlightSplit(text
, highlights
)
50 file = open(outputFileName
, 'a')
51 file.write("<hr/><p><b>" + sourceFileName
+ "</b></p>")
53 # insert highlight tags in a temp buffer
56 for slice in splittedText
:
58 temp
+= escape(slice) + '<span class="highlight tooltip">'
60 temp
+= escape(slice) + "<em>" + highlights
[(count
- 1) / 2][2] \
64 temp
+= "</span>" # close the superfluous last highlight
66 file.write('<table><tr><td><pre class="code"><span class="linenumber">')
68 for line
in temp
.split('\n'):
69 file.write(str(count
).rjust(4)+"<br/>")
72 file.write('</span></pre></td><td><pre class="code">')
74 for line
in temp
.split('\n'):
75 file.write('<span class="linehead"> </span>' + line
.replace('\r', ' ') \
78 file.write("</pre></td></tr></table>")
83 # highlight overlap check
84 def highlightOverlaps(highlight1
, highlight2
):
85 #print "hl1", highlight1, "hl2", highlight2
86 return not(highlight2
[0] > highlight1
[1] or highlight1
[0] > highlight2
[1])
89 # splits the string in three parts before, between and after the highlight
90 def splitByHighlight(string
, highlight
):
91 return (string
[:highlight
[0]], string
[highlight
[0]:highlight
[1]], \
92 string
[highlight
[1]:])
95 # splits the source text on highlights boundaries so that we can escape to html
96 # without the need to recalculate the highlights positions
97 def highlightSplit(string
, highlights
):
102 for (start
, end
, name
) in highlights
:
104 (before
, between
, after
) = splitByHighlight( \
105 text
, (start
- offset
, end
- offset
))
106 splittedString
.append(before
)
107 splittedString
.append(between
)
110 offset
+= len(before
+ between
)
112 print "overlap ", (start
, end
, name
)
113 splittedString
.append(text
)
114 return splittedString
117 # checkHighlights() checks for highlights overlaps
118 def checkHighlights(highlights
):
122 lastHighlight
= (-2, -1, '')
124 # merge overlapping highlights
125 for highlight
in highlights
:
126 if highlightOverlaps(highlight
, lastHighlight
):
128 newStart
= min(lastHighlight
[0], highlight
[0])
129 newEnd
= max(lastHighlight
[1], highlight
[1])
130 newComment
= lastHighlight
[2]
132 if (newComment
.find(highlight
[2]) == -1):
133 newComment
+= " + " + highlight
[2]
135 highlight
= (newStart
, newEnd
, newComment
)
136 highlights
[index
] = highlight
138 # mark highlight to be deleted
139 highlights
[index
- 1] = (0, 0, "")
141 lastHighlight
= highlight
144 # remove "to be deleted" highlights
145 return [ (start
, end
, comment
) for (start
, end
, comment
) in highlights \
146 if (start
, end
, comment
) != (0, 0, "") ]
161 .highlight .linehead {
162 background: #ffff00;;
181 font-family: monospace;
192 text-decoration:none;
203 border: 1px solid #bbb;