|
1 # highlight extension implementation file |
|
2 # |
|
3 # The original module was split in an interface and an implementation |
|
4 # file to defer pygments loading and speedup extension setup. |
|
5 |
|
6 from mercurial import demandimport |
|
7 demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__',]) |
|
8 |
|
9 from mercurial import util |
|
10 from mercurial.templatefilters import filters |
|
11 |
|
12 from pygments import highlight |
|
13 from pygments.util import ClassNotFound |
|
14 from pygments.lexers import guess_lexer, guess_lexer_for_filename, TextLexer |
|
15 from pygments.formatters import HtmlFormatter |
|
16 |
|
17 SYNTAX_CSS = ('\n<link rel="stylesheet" href="{url}highlightcss" ' |
|
18 'type="text/css" />') |
|
19 |
|
20 def pygmentize(field, fctx, style, tmpl): |
|
21 |
|
22 # append a <link ...> to the syntax highlighting css |
|
23 old_header = ''.join(tmpl('header')) |
|
24 if SYNTAX_CSS not in old_header: |
|
25 new_header = old_header + SYNTAX_CSS |
|
26 tmpl.cache['header'] = new_header |
|
27 |
|
28 text = fctx.data() |
|
29 if util.binary(text): |
|
30 return |
|
31 |
|
32 # To get multi-line strings right, we can't format line-by-line |
|
33 try: |
|
34 lexer = guess_lexer_for_filename(fctx.path(), text[:1024], |
|
35 encoding=util._encoding) |
|
36 except (ClassNotFound, ValueError): |
|
37 try: |
|
38 lexer = guess_lexer(text[:1024], encoding=util._encoding) |
|
39 except (ClassNotFound, ValueError): |
|
40 lexer = TextLexer(encoding=util._encoding) |
|
41 |
|
42 formatter = HtmlFormatter(style=style, encoding=util._encoding) |
|
43 |
|
44 colorized = highlight(text, lexer, formatter) |
|
45 # strip wrapping div |
|
46 colorized = colorized[:colorized.find('\n</pre>')] |
|
47 colorized = colorized[colorized.find('<pre>')+5:] |
|
48 coloriter = iter(colorized.splitlines()) |
|
49 |
|
50 filters['colorize'] = lambda x: coloriter.next() |
|
51 |
|
52 oldl = tmpl.cache[field] |
|
53 newl = oldl.replace('line|escape', 'line|colorize') |
|
54 tmpl.cache[field] = newl |