interhg: allow more flexible pattern specification (fixes 2/3 of issue699)
authorEdward Lee <edward.lee@engineering.uiuc.edu>
Fri, 07 Sep 2007 16:35:43 +0200
changeset 5288 18091102a633
parent 5287 c6f932d3e0f6
child 5290 05889b6b1468
interhg: allow more flexible pattern specification (fixes 2/3 of issue699) - something else than "pat" followed by a number can be used as key - something else than "/" can be used as delimiter - "ilmsux" flags (e.g. "i" for case insensitive) can be used
hgext/interhg.py
--- a/hgext/interhg.py	Fri Sep 07 16:14:51 2007 +0200
+++ b/hgext/interhg.py	Fri Sep 07 16:35:43 2007 +0200
@@ -2,6 +2,9 @@
 #
 # Copyright 2007 OHASHI Hideya <ohachige@gmail.com>
 #
+# Contributor(s):
+#   Edward Lee <edward.lee@engineering.uiuc.edu>
+#
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 #
@@ -13,15 +16,14 @@
 #   [extensions]
 #   interhg =
 #
-# This is an example to link to a bug tracking system.
+# These are some example patterns (link to bug tracking, etc.)
 #
 #   [interhg]
-#   pat1 = s/issue(\d+)/ <a href="http:\/\/bts\/issue\1">issue\1<\/a> /
+#   issues = s!issue(\d+)!<a href="http://bts/issue\1">issue\1<\/a>!
+#   bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!<a..=\2">\1</a>!i
+#   boldify = s/(^|\s)#(\d+)\b/ <b>#\2<\/b>/
 #
-# You can add patterns to use pat2, pat3, ...
-# For exapmle.
-#
-#   pat2 = s/(^|\s)#(\d+)\b/ <b>#\2<\/b> /
+# Add any number of names and patterns to match
 
 import re
 from mercurial.hgweb import hgweb_mod
@@ -33,9 +35,7 @@
 
 def interhg_escape(x):
     escstr = orig_escape(x)
-    for pat in interhg_table:
-        regexp = pat[0]
-        format = pat[1]
+    for regexp, format in interhg_table:
         escstr = regexp.sub(format, escstr)
     return escstr
 
@@ -45,20 +45,39 @@
 
 def interhg_refresh(self):
     interhg_table[:] = []
-    num = 1
-    while True:
-        key = 'pat%d' % num
-        pat = self.config('interhg', key)
-        if pat == None:
-            break
-        pat = pat[2:-1]
-        span = re.search(r'[^\\]/', pat).span()
-        regexp = pat[:span[0] + 1]
-        format = pat[span[1]:]
-        format = re.sub(r'\\/', '/', format)
-        regexp = re.compile(regexp)
-        interhg_table.append((regexp, format))
-        num += 1
+    for key, pattern in self.repo.ui.configitems('interhg'):
+        # grab the delimiter from the character after the "s"
+        unesc = pattern[1]
+        delim = re.escape(unesc)
+
+        # identify portions of the pattern, taking care to avoid escaped
+        # delimiters. the replace format and flags are optional, but delimiters
+        # are required.
+        match = re.match(r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
+                         % (delim, delim, delim), pattern)
+        if not match:
+            self.repo.ui.warn("interhg: invalid pattern for %s: %s\n"
+                              % (key, pattern))
+            continue
+
+        # we need to unescape the delimiter for regexp and format
+        delim_re = re.compile(r'(?<!\\)\\%s' % delim)
+        regexp = delim_re.sub(unesc, match.group(1))
+        format = delim_re.sub(unesc, match.group(2))
+
+        # the pattern allows for 6 regexp flags, so set them if necessary
+        flagin = match.group(3)
+        flags = 0
+        if flagin:
+            for flag in flagin.upper():
+                flags |= re.__dict__[flag]
+
+        try:
+            regexp = re.compile(regexp, flags)
+            interhg_table.append((regexp, format))
+        except re.error:
+            self.repo.ui.warn("interhg: invalid regexp for %s: %s\n"
+                              % (key, regexp))
     return orig_refresh(self)
 
 hgweb_mod.hgweb.refresh = interhg_refresh