Mercurial > hg
changeset 6193:2344da8eb9b4
highlight: support annotate, and reduce layering violations.
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Thu, 28 Feb 2008 21:35:27 -0800 |
parents | cd65a67aff31 |
children | fe54e7501de1 |
files | hgext/highlight.py |
diffstat | 1 files changed, 37 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/highlight.py Fri Feb 29 02:45:12 2008 +0100 +++ b/hgext/highlight.py Thu Feb 28 21:35:27 2008 -0800 @@ -38,6 +38,7 @@ from mercurial import util from mercurial.hgweb.common import paritygen from mercurial.node import hex +from mercurial.templatefilters import filters from pygments import highlight from pygments.util import ClassNotFound @@ -47,93 +48,50 @@ SYNTAX_CSS = ('\n<link rel="stylesheet" href="#staticurl#highlight.css" ' 'type="text/css" />') -class StripedHtmlFormatter(HtmlFormatter): - def __init__(self, stripecount, *args, **kwargs): - super(StripedHtmlFormatter, self).__init__(*args, **kwargs) - self.stripecount = stripecount - - def wrap(self, source, outfile): - yield 0, "<div class='highlight'>" - yield 0, "<pre>" - parity = paritygen(self.stripecount) - - for n, i in source: - if n == 1: - i = "<div class='parity%s'>%s</div>" % (parity.next(), i) - yield n, i - - yield 0, "</pre>" - yield 0, "</div>" - - -def pygments_format(filename, text, forcetext, stripecount, style): - if not forcetext: - try: - lexer = guess_lexer_for_filename(filename, text, - encoding=util._encoding) - except ClassNotFound: - lexer = TextLexer(encoding=util._encoding) - else: - lexer = TextLexer(encoding=util._encoding) - - formatter = StripedHtmlFormatter(stripecount, style=style, - linenos='inline', encoding=util._encoding) - - return highlight(text, lexer, formatter) - - -def filerevision_pygments(self, tmpl, fctx): - """Reimplement hgweb.filerevision to use syntax highlighting""" - f = fctx.path() - text = fctx.data() - fl = fctx.filelog() - n = fctx.filenode() - - if util.binary(text): - mt = mimetypes.guess_type(f)[0] or 'application/octet-stream' - text = "(binary:%s)" % mt - # don't parse (binary:...) as anything - forcetext = True - else: - # encode to hgweb.encoding for lexers and formatter - util._encoding = self.encoding - text = util.tolocal(text) - forcetext = False - - def lines(text): - for line in text.splitlines(True): - yield {"line": line} - - style = self.config("web", "pygments_style", "colorful") - - text_formatted = lines(pygments_format(f, text, forcetext, - self.stripecount, style)) - - # override per-line template - tmpl.cache['fileline'] = '#line#' - +def pygmentize(self, tmpl, fctx, field): # append a <link ...> to the syntax highlighting css old_header = ''.join(tmpl('header')) if SYNTAX_CSS not in old_header: new_header = old_header + SYNTAX_CSS tmpl.cache['header'] = new_header - return tmpl("filerevision", - file=f, - path=hgweb_mod._up(f), # fixme: make public - text=text_formatted, - rev=fctx.rev(), - node=hex(fctx.node()), - author=fctx.user(), - date=fctx.date(), - desc=fctx.description(), - parent=self.siblings(fctx.parents()), - child=self.siblings(fctx.children()), - rename=self.renamelink(fl, n), - permissions=fctx.manifest().flags(f)) + style = self.config("web", "pygments_style", "colorful") + # To get multi-line strings right, we can't format line-by-line + text = fctx.data() + try: + lexer = guess_lexer_for_filename(fctx.path(), text, + encoding=util._encoding) + except ClassNotFound: + lexer = TextLexer(encoding=util._encoding) + + formatter = HtmlFormatter(style=style, encoding=util._encoding) + colorized = highlight(text, lexer, formatter) + # strip wrapping div + colorized = colorized[:colorized.find('\n</pre>')] + colorized = colorized[colorized.find('<span'):] + coloriter = (l for l in colorized.splitlines()) + + filters['colorize'] = lambda x: coloriter.next() + + oldl = tmpl.cache[field] + newl = oldl.replace('line|escape', 'line|colorize') + tmpl.cache[field] = newl + +def filerevision_highlight(self, tmpl, fctx): + pygmentize(self, tmpl, fctx, 'fileline') + + return realrevision(self, tmpl, fctx) + +def fileannotate_highlight(self, tmpl, fctx): + pygmentize(self, tmpl, fctx, 'annotateline') + + return realannotate(self, tmpl, fctx) # monkeypatch in the new version # should be safer than overriding the method in a derived class # and then patching the class -hgweb.filerevision = filerevision_pygments +realrevision = hgweb.filerevision +hgweb.filerevision = filerevision_highlight +realannotate = hgweb.fileannotate +hgweb.fileannotate = fileannotate_highlight