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