##// END OF EJS Templates
highlight: pass encoding to lexers and formatter...
Christian Ebert -
r5655:fe38b0a3 default
parent child Browse files
Show More
@@ -1,144 +1,147 b''
1 1 """
2 2 This is Mercurial extension for syntax highlighting in the file
3 3 revision view of hgweb.
4 4
5 5 It depends on the pygments syntax highlighting library:
6 6 http://pygments.org/
7 7
8 8 To enable the extension add this to hgrc:
9 9
10 10 [extensions]
11 11 hgext.highlight =
12 12
13 13 There is a single configuration option:
14 14
15 15 [web]
16 16 pygments_style = <style>
17 17
18 18 The default is 'colorful'. If this is changed the corresponding CSS
19 19 file should be re-generated by running
20 20
21 21 # pygmentize -f html -S <newstyle>
22 22
23 23
24 24 -- Adam Hupp <adam@hupp.org>
25 25
26 26
27 27 """
28 28
29 29 from mercurial import demandimport
30 30 demandimport.ignore.extend(['pkgutil',
31 31 'pkg_resources',
32 32 '__main__',])
33 33
34 34 import mimetypes
35 35
36 36 from mercurial.hgweb import hgweb_mod
37 37 from mercurial.hgweb.hgweb_mod import hgweb
38 38 from mercurial import util
39 39 from mercurial.hgweb.common import paritygen
40 40 from mercurial.node import hex
41 41
42 42 from pygments import highlight
43 43 from pygments.util import ClassNotFound
44 44 from pygments.lexers import guess_lexer_for_filename, TextLexer
45 45 from pygments.formatters import HtmlFormatter
46 46
47 47 SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" '
48 48 'type="text/css" />')
49 49
50 50 class StripedHtmlFormatter(HtmlFormatter):
51 51 def __init__(self, stripecount, *args, **kwargs):
52 52 super(StripedHtmlFormatter, self).__init__(*args, **kwargs)
53 53 self.stripecount = stripecount
54 54
55 55 def wrap(self, source, outfile):
56 56 yield 0, "<div class='highlight'>"
57 57 yield 0, "<pre>"
58 58 parity = paritygen(self.stripecount)
59 59
60 60 for n, i in source:
61 61 if n == 1:
62 62 i = "<div class='parity%s'>%s</div>" % (parity.next(), i)
63 63 yield n, i
64 64
65 65 yield 0, "</pre>"
66 66 yield 0, "</div>"
67 67
68 68
69 def pygments_format(filename, rawtext, forcetext, stripecount, style):
69 def pygments_format(filename, rawtext, forcetext, encoding,
70 stripecount, style):
71 etext = util.tolocal(rawtext)
70 72 if not forcetext:
71 73 try:
72 lexer = guess_lexer_for_filename(filename, rawtext)
74 lexer = guess_lexer_for_filename(filename, etext,
75 encoding=util._encoding)
73 76 except ClassNotFound:
74 lexer = TextLexer()
77 lexer = TextLexer(encoding=util._encoding)
75 78 else:
76 lexer = TextLexer()
79 lexer = TextLexer(encoding=util._encoding)
77 80
78 81 formatter = StripedHtmlFormatter(stripecount, style=style,
79 linenos='inline')
82 linenos='inline', encoding=encoding)
80 83
81 return highlight(rawtext, lexer, formatter)
84 return highlight(etext, lexer, formatter)
82 85
83 86
84 87 def filerevision_pygments(self, tmpl, fctx):
85 88 """Reimplement hgweb.filerevision to use syntax highlighting"""
86 89 f = fctx.path()
87 90
88 91 rawtext = fctx.data()
89 92 text = rawtext
90 93
91 94 fl = fctx.filelog()
92 95 n = fctx.filenode()
93 96
94 97 mt = mimetypes.guess_type(f)[0]
95 98
96 99 if util.binary(text):
97 100 mt = mt or 'application/octet-stream'
98 101 text = "(binary:%s)" % mt
99 102
100 103 # don't parse (binary:...) as anything
101 104 forcetext = True
102 105 else:
103 106 mt = mt or 'text/plain'
104 107 forcetext = False
105 108
106 109 def lines(text):
107 110 for line in text.splitlines(True):
108 111 yield {"line": line}
109 112
110 113 style = self.config("web", "pygments_style", "colorful")
111 114
112 text_formatted = lines(pygments_format(f, text, forcetext,
115 text_formatted = lines(pygments_format(f, text, forcetext, self.encoding,
113 116 self.stripecount, style))
114 117
115 118 # override per-line template
116 119 tmpl.cache['fileline'] = '#line#'
117 120
118 121 # append a <link ...> to the syntax highlighting css
119 122 old_header = ''.join(tmpl('header'))
120 123 if SYNTAX_CSS not in old_header:
121 124 new_header = old_header + SYNTAX_CSS
122 125 tmpl.cache['header'] = new_header
123 126
124 127 yield tmpl("filerevision",
125 128 file=f,
126 129 path=hgweb_mod._up(f), # fixme: make public
127 130 text=text_formatted,
128 131 raw=rawtext,
129 132 mimetype=mt,
130 133 rev=fctx.rev(),
131 134 node=hex(fctx.node()),
132 135 author=fctx.user(),
133 136 date=fctx.date(),
134 137 desc=fctx.description(),
135 138 parent=self.siblings(fctx.parents()),
136 139 child=self.siblings(fctx.children()),
137 140 rename=self.renamelink(fl, n),
138 141 permissions=fctx.manifest().flags(f))
139 142
140 143
141 144 # monkeypatch in the new version
142 145 # should be safer than overriding the method in a derived class
143 146 # and then patching the class
144 147 hgweb.filerevision = filerevision_pygments
General Comments 0
You need to be logged in to leave comments. Login now