--- 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