Show More
@@ -38,6 +38,7 b' from mercurial.hgweb.hgweb_mod import hg' | |||||
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 |
|
42 | |||
42 | from pygments import highlight |
|
43 | from pygments import highlight | |
43 | from pygments.util import ClassNotFound |
|
44 | from pygments.util import ClassNotFound | |
@@ -47,93 +48,50 b' from pygments.formatters import HtmlForm' | |||||
47 | SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" ' |
|
48 | SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" ' | |
48 | 'type="text/css" />') |
|
49 | 'type="text/css" />') | |
49 |
|
50 | |||
50 | class StripedHtmlFormatter(HtmlFormatter): |
|
51 | def pygmentize(self, tmpl, fctx, field): | |
51 | def __init__(self, stripecount, *args, **kwargs): |
|
|||
52 | super(StripedHtmlFormatter, self).__init__(*args, **kwargs) |
|
|||
53 | self.stripecount = stripecount |
|
|||
54 |
|
||||
55 | def wrap(self, source, outfile): |
|
|||
56 | yield 0, "<div class='highlight'>" |
|
|||
57 | yield 0, "<pre>" |
|
|||
58 | parity = paritygen(self.stripecount) |
|
|||
59 |
|
||||
60 | for n, i in source: |
|
|||
61 | if n == 1: |
|
|||
62 | i = "<div class='parity%s'>%s</div>" % (parity.next(), i) |
|
|||
63 | yield n, i |
|
|||
64 |
|
||||
65 | yield 0, "</pre>" |
|
|||
66 | yield 0, "</div>" |
|
|||
67 |
|
||||
68 |
|
||||
69 | def pygments_format(filename, text, forcetext, stripecount, style): |
|
|||
70 | if not forcetext: |
|
|||
71 | try: |
|
|||
72 | lexer = guess_lexer_for_filename(filename, text, |
|
|||
73 | encoding=util._encoding) |
|
|||
74 | except ClassNotFound: |
|
|||
75 | lexer = TextLexer(encoding=util._encoding) |
|
|||
76 | else: |
|
|||
77 | lexer = TextLexer(encoding=util._encoding) |
|
|||
78 |
|
||||
79 | formatter = StripedHtmlFormatter(stripecount, style=style, |
|
|||
80 | linenos='inline', encoding=util._encoding) |
|
|||
81 |
|
||||
82 | return highlight(text, lexer, formatter) |
|
|||
83 |
|
||||
84 |
|
||||
85 | def filerevision_pygments(self, tmpl, fctx): |
|
|||
86 | """Reimplement hgweb.filerevision to use syntax highlighting""" |
|
|||
87 | f = fctx.path() |
|
|||
88 | text = fctx.data() |
|
|||
89 | fl = fctx.filelog() |
|
|||
90 | n = fctx.filenode() |
|
|||
91 |
|
||||
92 | if util.binary(text): |
|
|||
93 | mt = mimetypes.guess_type(f)[0] or 'application/octet-stream' |
|
|||
94 | text = "(binary:%s)" % mt |
|
|||
95 | # don't parse (binary:...) as anything |
|
|||
96 | forcetext = True |
|
|||
97 | else: |
|
|||
98 | # encode to hgweb.encoding for lexers and formatter |
|
|||
99 | util._encoding = self.encoding |
|
|||
100 | text = util.tolocal(text) |
|
|||
101 | forcetext = False |
|
|||
102 |
|
||||
103 | def lines(text): |
|
|||
104 | for line in text.splitlines(True): |
|
|||
105 | yield {"line": line} |
|
|||
106 |
|
||||
107 | style = self.config("web", "pygments_style", "colorful") |
|
|||
108 |
|
||||
109 | text_formatted = lines(pygments_format(f, text, forcetext, |
|
|||
110 | self.stripecount, style)) |
|
|||
111 |
|
||||
112 | # override per-line template |
|
|||
113 | tmpl.cache['fileline'] = '#line#' |
|
|||
114 |
|
||||
115 | # append a <link ...> to the syntax highlighting css |
|
52 | # append a <link ...> to the syntax highlighting css | |
116 | old_header = ''.join(tmpl('header')) |
|
53 | old_header = ''.join(tmpl('header')) | |
117 | if SYNTAX_CSS not in old_header: |
|
54 | if SYNTAX_CSS not in old_header: | |
118 | new_header = old_header + SYNTAX_CSS |
|
55 | new_header = old_header + SYNTAX_CSS | |
119 | tmpl.cache['header'] = new_header |
|
56 | tmpl.cache['header'] = new_header | |
120 |
|
57 | |||
121 | return tmpl("filerevision", |
|
58 | style = self.config("web", "pygments_style", "colorful") | |
122 | file=f, |
|
59 | # To get multi-line strings right, we can't format line-by-line | |
123 | path=hgweb_mod._up(f), # fixme: make public |
|
60 | text = fctx.data() | |
124 | text=text_formatted, |
|
61 | try: | |
125 | rev=fctx.rev(), |
|
62 | lexer = guess_lexer_for_filename(fctx.path(), text, | |
126 | node=hex(fctx.node()), |
|
63 | encoding=util._encoding) | |
127 | author=fctx.user(), |
|
64 | except ClassNotFound: | |
128 | date=fctx.date(), |
|
65 | lexer = TextLexer(encoding=util._encoding) | |
129 | desc=fctx.description(), |
|
66 | ||
130 | parent=self.siblings(fctx.parents()), |
|
67 | formatter = HtmlFormatter(style=style, encoding=util._encoding) | |
131 | child=self.siblings(fctx.children()), |
|
|||
132 | rename=self.renamelink(fl, n), |
|
|||
133 | permissions=fctx.manifest().flags(f)) |
|
|||
134 |
|
68 | |||
|
69 | colorized = highlight(text, lexer, formatter) | |||
|
70 | # strip wrapping div | |||
|
71 | colorized = colorized[:colorized.find('\n</pre>')] | |||
|
72 | colorized = colorized[colorized.find('<span'):] | |||
|
73 | coloriter = (l for l in colorized.splitlines()) | |||
|
74 | ||||
|
75 | filters['colorize'] = lambda x: coloriter.next() | |||
|
76 | ||||
|
77 | oldl = tmpl.cache[field] | |||
|
78 | newl = oldl.replace('line|escape', 'line|colorize') | |||
|
79 | tmpl.cache[field] = newl | |||
|
80 | ||||
|
81 | def filerevision_highlight(self, tmpl, fctx): | |||
|
82 | pygmentize(self, tmpl, fctx, 'fileline') | |||
|
83 | ||||
|
84 | return realrevision(self, tmpl, fctx) | |||
|
85 | ||||
|
86 | def fileannotate_highlight(self, tmpl, fctx): | |||
|
87 | pygmentize(self, tmpl, fctx, 'annotateline') | |||
|
88 | ||||
|
89 | return realannotate(self, tmpl, fctx) | |||
135 |
|
90 | |||
136 | # monkeypatch in the new version |
|
91 | # monkeypatch in the new version | |
137 | # should be safer than overriding the method in a derived class |
|
92 | # should be safer than overriding the method in a derived class | |
138 | # and then patching the class |
|
93 | # and then patching the class | |
139 | hgweb.filerevision = filerevision_pygments |
|
94 | realrevision = hgweb.filerevision | |
|
95 | hgweb.filerevision = filerevision_highlight | |||
|
96 | realannotate = hgweb.fileannotate | |||
|
97 | hgweb.fileannotate = fileannotate_highlight |
General Comments 0
You need to be logged in to leave comments.
Login now