Permit XML entities to be escaped in template output.
authorJesse Glick <jesse.glick@sun.com>
Mon, 28 Jan 2008 22:19:12 -0500
changeset 6174 434139080ed4
parent 6173 963000ed8cac
child 6175 7f9f3233a2c6
Permit XML entities to be escaped in template output. Useful for creating XML documents directly from Hg logging. Can also be used for HTML. For use in content, will escape '&', '<', and for completeness '>' (although it is not strictly necessary). For use in attributes, will also escape ' and ". Will also replace nonprinting (ASCII) control characters with spaces, since these are illegal in XML.
mercurial/templatefilters.py
tests/test-command-template
tests/test-command-template.out
--- a/mercurial/templatefilters.py	Sun Feb 24 17:58:55 2008 +0100
+++ b/mercurial/templatefilters.py	Mon Jan 28 22:19:12 2008 -0500
@@ -121,6 +121,15 @@
         return "-rwxr-xr-x"
     return "-rw-r--r--"
 
+def xmlescape(text):
+    text = (text
+            .replace('&', '&amp;')
+            .replace('<', '&lt;')
+            .replace('>', '&gt;')
+            .replace('"', '&quot;')
+            .replace("'", '&#39;')) # &apos; invalid in HTML
+    return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
+
 filters = {
     "addbreaks": nl2br,
     "basename": os.path.basename,
@@ -147,5 +156,6 @@
     "urlescape": lambda x: urllib.quote(x),
     "user": lambda x: util.shortuser(x),
     "stringescape": lambda x: x.encode('string_escape'),
+    "xmlescape": xmlescape,
     }
 
--- a/tests/test-command-template	Sun Feb 24 17:58:55 2008 +0100
+++ b/tests/test-command-template	Mon Jan 28 22:19:12 2008 -0500
@@ -106,6 +106,7 @@
 hg log --template '{date|rfc822date}\n'
 hg log --template '{desc|firstline}\n'
 hg log --template '{node|short}\n'
+hg log --template '<changeset author="{author|xmlescape}"/>\n'
 
 echo '# formatnode filter works'
 echo '#  quiet'
--- a/tests/test-command-template.out	Sun Feb 24 17:58:55 2008 +0100
+++ b/tests/test-command-template.out	Mon Jan 28 22:19:12 2008 -0500
@@ -541,6 +541,14 @@
 97054abb4ab8
 b608e9d1a3f0
 1e4e1b8f71e0
+<changeset author="User Name &lt;user@hostname&gt;"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="other@place"/>
+<changeset author="A. N. Other &lt;other@place&gt;"/>
+<changeset author="User Name &lt;user@hostname&gt;"/>
 # formatnode filter works
 #  quiet
 1e4e1b8f71e0