patch for syntax highlighting in web interface

micha micha-1 at fantasymail.de
Wed May 16 16:21:20 CDT 2007


Hi,

I asked recently about how to integrate syntax highlighting in the
fileview of the web interface. One suggestion was to use Trac 0.11 to do it. 
I tried it and it works fine, only Trac 0.11 isn't released yet.
I never used python before, so it was a little execise to do it myself.
Here is how it works, (after reading many intros and tutorials and
source lines :-) with the patches.
First, you need pygments for it to work. (version > 0.7 supports ocaml)
then apply my patches to the mercurial source (version 0.9.3) and
configure pygments in the  [web] section of your .hgrc file, for
example:

-------------------------------
[web]
# first fileextensions comma separated, then a colon and the lexer
# than after semicolon more definitions:
pygments = ml,mli:ocaml;c,cpp,h:cpp
# the highlighting style (defaults to manni)
pygments-style = manni
-------------------------------

after that you should see colored source code in the fileview. 
I had to change the "fileline" entry in the templates/map file to get
the colored output, but you lose the default style on files which are
not highlighted by pygments. I didn't find how to do it otherwise.
Comments welcome, I hope someone will try it ...


cheers
 Michael



diff -r -u mercurial-0.9.3/mercurial/hgweb/hgweb_mod.py mercurial-0.9.3-pygments/mercurial/hgweb/hgweb_mod.py
--- mercurial-0.9.3/mercurial/hgweb/hgweb_mod.py	2006-12-18 02:02:33.000000000 +0100
+++ mercurial-0.9.3-pygments/mercurial/hgweb/hgweb_mod.py	2007-05-16 23:09:26.717195303 +0200
@@ -9,6 +9,10 @@
 import os
 import os.path
 import mimetypes
+from pygments import highlight
+from pygments.util import ClassNotFound
+from pygments.lexers import get_lexer_by_name 
+from pygments.formatters import HtmlFormatter
 from mercurial.demandload import demandload
 demandload(globals(), "re zlib ConfigParser mimetools cStringIO sys tempfile")
 demandload(globals(), 'urllib bz2')
@@ -107,6 +111,17 @@
             self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
             self.maxfiles = int(self.config("web", "maxfiles", 10))
             self.allowpull = self.configbool("web", "allowpull", True)
+            self.pygments_style = self.config("web", "pygments-style", "manni")
+            # MW
+            py = self.config("web", "pygments").split(';')
+            self.pygments = {}
+            try:
+                for el in py:
+                    ext,lex = el.split(':')
+                    for x in ext.split(','):
+                        self.pygments['.' + x] = lex
+            except ValueError:
+                self.pygments = {}
 
     def archivelist(self, nodeid):
         allowed = self.configlist("web", "allow_archive")
@@ -365,7 +380,19 @@
 
     def filerevision(self, fctx):
         f = fctx.path()
-        text = fctx.data()
+        # MW change begin
+        org_text = fctx.data()
+        text = org_text
+        root,ext = os.path.splitext(f)
+        try:
+            if ext in self.pygments:
+                lexer = get_lexer_by_name(self.pygments[ext])
+                formatter = HtmlFormatter(style=self.pygments_style, noclasses=True)
+                text = highlight(org_text, lexer, formatter )
+        except ClassNotFound:
+            print "lexer not found"
+
+    	# MW change end
         fl = fctx.filelog()
         n = fctx.filenode()
 
diff -r -u mercurial-0.9.3/templates/map mercurial-0.9.3-pygments/templates/map
--- mercurial-0.9.3/templates/map	2006-12-18 02:02:33.000000000 +0100
+++ mercurial-0.9.3-pygments/templates/map	2007-05-16 22:45:52.760903201 +0200
@@ -21,7 +21,8 @@
 fileannotate = fileannotate.tmpl
 filediff = filediff.tmpl
 filelog = filelog.tmpl
-fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>'
+#fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>'
+fileline = '#line#'
 filelogentry = filelogentry.tmpl
 annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
 difflineplus = '<span class="plusline">#line|escape#</span>'



More information about the Mercurial mailing list