Mercurial > hg
view hgext/highlight.py @ 5532:40a06e39f010
extension for synax highlighting in the hgweb file revision view
Depends on the pygments syntax highlighting library:
http://pygments.org/
author | Adam Hupp <adam@hupp.org> |
---|---|
date | Sat, 10 Nov 2007 17:54:57 -0500 |
parents | |
children | 6cf7d7fe7d3d |
line wrap: on
line source
""" This is Mercurial extension for syntax highlighting in the file revision view of hgweb. It depends on the pygments syntax highlighting library: http://pygments.org/ To enable the extension add this to hgrc: [extensions] hgext.highlight = There is a single configuration option: [web] pygments_style = <style> The default is 'colorful'. If this is changed the corresponding CSS file should be re-generated by running # pygmentize -f html -S <newstyle> -- Adam Hupp <adam@hupp.org> """ from mercurial import demandimport demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__',]) import mimetypes from mercurial.hgweb import hgweb_mod from mercurial.hgweb.hgweb_mod import hgweb from mercurial import util from mercurial.hgweb.common import paritygen from mercurial.node import hex from pygments import highlight from pygments.util import ClassNotFound from pygments.lexers import guess_lexer_for_filename, TextLexer from pygments.formatters import HtmlFormatter 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, rawtext, forcetext=False, stripecount=1, style='colorful'): if not forcetext: try: lexer = guess_lexer_for_filename(filename, rawtext) except ClassNotFound: lexer = TextLexer() else: lexer = TextLexer() formatter = StripedHtmlFormatter(stripecount, style=style, linenos='inline') return highlight(rawtext, lexer, formatter) """ This reimplements hgweb.filerevision to use syntax highlighting """ def filerevision_pygments(self, fctx): filename = fctx.path() rawtext = fctx.data() text = rawtext mt = mimetypes.guess_type(filename)[0] if util.binary(text): mt = mt or 'application/octet-stream' text = "(binary:%s)" % mt # don't parse (binary:...) as anything forcetext = True else: mt = mt or 'text/plain' 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(filename, text, forcetext=forcetext, stripecount=self.stripecount, style=style)) # override per-line template self.t.cache['fileline'] = '#line#' # append a <link ...> to the syntax highlighting css old_header = ''.join(self.t('header')) if SYNTAX_CSS not in old_header: new_header = old_header + SYNTAX_CSS self.t.cache['header'] = new_header yield self.t("filerevision", file=filename, path=hgweb_mod._up(filename), # fixme: make public text=text_formatted, raw=rawtext, mimetype=mt, 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(fctx.filelog(), fctx.filenode()), permissions=fctx.manifest().flags(filename)) # 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