##// END OF EJS Templates
highlight: bail out if file is binary
Brendan Cully -
r6194:fe54e750 default
parent child Browse files
Show More
@@ -1,97 +1,100 b''
1 """
1 """
2 This is Mercurial extension for syntax highlighting in the file
2 This is Mercurial extension for syntax highlighting in the file
3 revision view of hgweb.
3 revision view of hgweb.
4
4
5 It depends on the pygments syntax highlighting library:
5 It depends on the pygments syntax highlighting library:
6 http://pygments.org/
6 http://pygments.org/
7
7
8 To enable the extension add this to hgrc:
8 To enable the extension add this to hgrc:
9
9
10 [extensions]
10 [extensions]
11 hgext.highlight =
11 hgext.highlight =
12
12
13 There is a single configuration option:
13 There is a single configuration option:
14
14
15 [web]
15 [web]
16 pygments_style = <style>
16 pygments_style = <style>
17
17
18 The default is 'colorful'. If this is changed the corresponding CSS
18 The default is 'colorful'. If this is changed the corresponding CSS
19 file should be re-generated by running
19 file should be re-generated by running
20
20
21 # pygmentize -f html -S <newstyle>
21 # pygmentize -f html -S <newstyle>
22
22
23
23
24 -- Adam Hupp <adam@hupp.org>
24 -- Adam Hupp <adam@hupp.org>
25
25
26
26
27 """
27 """
28
28
29 from mercurial import demandimport
29 from mercurial import demandimport
30 demandimport.ignore.extend(['pkgutil',
30 demandimport.ignore.extend(['pkgutil',
31 'pkg_resources',
31 'pkg_resources',
32 '__main__',])
32 '__main__',])
33
33
34 import mimetypes
34 import mimetypes
35
35
36 from mercurial.hgweb import hgweb_mod
36 from mercurial.hgweb import hgweb_mod
37 from mercurial.hgweb.hgweb_mod import hgweb
37 from mercurial.hgweb.hgweb_mod import hgweb
38 from mercurial import util
38 from mercurial import util
39 from mercurial.hgweb.common import paritygen
39 from mercurial.hgweb.common import paritygen
40 from mercurial.node import hex
40 from mercurial.node import hex
41 from mercurial.templatefilters import filters
41 from mercurial.templatefilters import filters
42
42
43 from pygments import highlight
43 from pygments import highlight
44 from pygments.util import ClassNotFound
44 from pygments.util import ClassNotFound
45 from pygments.lexers import guess_lexer_for_filename, TextLexer
45 from pygments.lexers import guess_lexer_for_filename, TextLexer
46 from pygments.formatters import HtmlFormatter
46 from pygments.formatters import HtmlFormatter
47
47
48 SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" '
48 SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" '
49 'type="text/css" />')
49 'type="text/css" />')
50
50
51 def pygmentize(self, tmpl, fctx, field):
51 def pygmentize(self, tmpl, fctx, field):
52 # append a <link ...> to the syntax highlighting css
52 # append a <link ...> to the syntax highlighting css
53 old_header = ''.join(tmpl('header'))
53 old_header = ''.join(tmpl('header'))
54 if SYNTAX_CSS not in old_header:
54 if SYNTAX_CSS not in old_header:
55 new_header = old_header + SYNTAX_CSS
55 new_header = old_header + SYNTAX_CSS
56 tmpl.cache['header'] = new_header
56 tmpl.cache['header'] = new_header
57
57
58 text = fctx.data()
59 if util.binary(text):
60 return
61
58 style = self.config("web", "pygments_style", "colorful")
62 style = self.config("web", "pygments_style", "colorful")
59 # To get multi-line strings right, we can't format line-by-line
63 # To get multi-line strings right, we can't format line-by-line
60 text = fctx.data()
61 try:
64 try:
62 lexer = guess_lexer_for_filename(fctx.path(), text,
65 lexer = guess_lexer_for_filename(fctx.path(), text,
63 encoding=util._encoding)
66 encoding=util._encoding)
64 except ClassNotFound:
67 except ClassNotFound:
65 lexer = TextLexer(encoding=util._encoding)
68 lexer = TextLexer(encoding=util._encoding)
66
69
67 formatter = HtmlFormatter(style=style, encoding=util._encoding)
70 formatter = HtmlFormatter(style=style, encoding=util._encoding)
68
71
69 colorized = highlight(text, lexer, formatter)
72 colorized = highlight(text, lexer, formatter)
70 # strip wrapping div
73 # strip wrapping div
71 colorized = colorized[:colorized.find('\n</pre>')]
74 colorized = colorized[:colorized.find('\n</pre>')]
72 colorized = colorized[colorized.find('<span'):]
75 colorized = colorized[colorized.find('<span'):]
73 coloriter = (l for l in colorized.splitlines())
76 coloriter = (l for l in colorized.splitlines())
74
77
75 filters['colorize'] = lambda x: coloriter.next()
78 filters['colorize'] = lambda x: coloriter.next()
76
79
77 oldl = tmpl.cache[field]
80 oldl = tmpl.cache[field]
78 newl = oldl.replace('line|escape', 'line|colorize')
81 newl = oldl.replace('line|escape', 'line|colorize')
79 tmpl.cache[field] = newl
82 tmpl.cache[field] = newl
80
83
81 def filerevision_highlight(self, tmpl, fctx):
84 def filerevision_highlight(self, tmpl, fctx):
82 pygmentize(self, tmpl, fctx, 'fileline')
85 pygmentize(self, tmpl, fctx, 'fileline')
83
86
84 return realrevision(self, tmpl, fctx)
87 return realrevision(self, tmpl, fctx)
85
88
86 def fileannotate_highlight(self, tmpl, fctx):
89 def fileannotate_highlight(self, tmpl, fctx):
87 pygmentize(self, tmpl, fctx, 'annotateline')
90 pygmentize(self, tmpl, fctx, 'annotateline')
88
91
89 return realannotate(self, tmpl, fctx)
92 return realannotate(self, tmpl, fctx)
90
93
91 # monkeypatch in the new version
94 # monkeypatch in the new version
92 # should be safer than overriding the method in a derived class
95 # should be safer than overriding the method in a derived class
93 # and then patching the class
96 # and then patching the class
94 realrevision = hgweb.filerevision
97 realrevision = hgweb.filerevision
95 hgweb.filerevision = filerevision_highlight
98 hgweb.filerevision = filerevision_highlight
96 realannotate = hgweb.fileannotate
99 realannotate = hgweb.fileannotate
97 hgweb.fileannotate = fileannotate_highlight
100 hgweb.fileannotate = fileannotate_highlight
General Comments 0
You need to be logged in to leave comments. Login now