Renamed "manifest" to "files" in web templates.
manifest.tmpl is still used, so people having their own templates don't have
to change them. "cmd=manifest" still works, new style URLs are not affected,
because they already used "/file/".
"""
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, 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#'
# 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))
# 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