changeset 10843:b91c1804008e

templater: directly parse templates, no regexes
author Matt Mackall <mpm@selenic.com>
date Mon, 05 Apr 2010 14:33:41 -0500
parents 6514935e223d
children 6722ba3bf80b
files mercurial/templater.py
diffstat 1 files changed, 22 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/templater.py	Mon Apr 05 14:33:41 2010 -0500
+++ b/mercurial/templater.py	Mon Apr 05 14:33:41 2010 -0500
@@ -6,7 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import re, sys, os
+import sys, os
 import util, config, templatefilters
 
 path = ['templates', '../templates']
@@ -42,8 +42,6 @@
     filter uses function to transform value. syntax is
     {key|filter1|filter2|...}.'''
 
-    template_re = re.compile(r'{([\w\|%]+)}')
-
     def __init__(self, loader, filters={}, defaults={}):
         self.loader = loader
         self.filters = filters
@@ -113,19 +111,29 @@
                 v = v(**map)
             return v
 
-        while tmpl:
-            m = self.template_re.search(tmpl)
-            if not m:
-                yield tmpl
+        pos, stop = 0, len(tmpl)
+        while pos < stop:
+            n = tmpl.find('{', pos)
+            if n < 0:
+                yield tmpl[pos:stop]
+                break
+            if n > 0 and tmpl[n - 1] == '\\':
+                # escaped
+                yield tmpl[pos:n + 1]
+                pos = n + 1
+                continue
+            if n > pos:
+                yield tmpl[pos:n]
+
+            pos = n
+            n = tmpl.find('}', pos)
+            if n < 0:
+                # no closing
+                yield tmpl[pos:stop]
                 break
 
-            start, end = m.span(0)
-            variants = m.groups()
-            expr = variants[0] or variants[1]
-
-            if start:
-                yield tmpl[:start]
-            tmpl = tmpl[end:]
+            expr = tmpl[pos + 1:n]
+            pos = n + 1
 
             if '%' in expr:
                 yield self._format(expr, get, map)