[PATCH] Permit XML entities to be escaped in template output

Jesse Glick Jesse.Glick at Sun.COM
Mon Jan 28 21:30:36 CST 2008


# HG changeset patch
# User Jesse Glick <jesse.glick at sun.com>
# Date 1201576752 18000
# Node ID 94376877f34cee0bd37b0416faaf9fe4ae61067d
# Parent  f8ad3b76e92327b551c5dd78f2848b24cfb1664f
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.

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -206,6 +206,14 @@ def obfuscate(text):
     text = unicode(text, util._encoding, 'replace')
     return ''.join(['&#%d;' % ord(c) for c in text])
 
+def xmlescape(text):
+    text = text.replace('&', '&amp;')
+    text = text.replace('<', '&lt;')
+    text = text.replace('>', '&gt;')
+    text = text.replace('"', '&quot;')
+    text = text.replace("'", '&#39;') # &apos; invalid in HTML
+    return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
+
 def domain(author):
     '''get domain of author, or empty string if none.'''
     f = author.find('@')
@@ -278,6 +286,7 @@ common_filters = {
     "urlescape": lambda x: urllib.quote(x),
     "user": lambda x: util.shortuser(x),
     "stringescape": lambda x: x.encode('string_escape'),
+    "xmlescape": xmlescape,
     }
 
 def templatepath(name=None):
diff --git a/tests/test-command-template b/tests/test-command-template
--- a/tests/test-command-template
+++ b/tests/test-command-template
@@ -106,6 +106,7 @@ hg log --template '{date|rfc822date}\n'
 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'
diff --git a/tests/test-command-template.out b/tests/test-command-template.out
--- a/tests/test-command-template.out
+++ b/tests/test-command-template.out
@@ -541,6 +541,14 @@ 97054abb4ab8
 97054abb4ab8
 b608e9d1a3f0
 1e4e1b8f71e0
+<changeset author="User Name &lt;user at hostname&gt;"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="person"/>
+<changeset author="other at place"/>
+<changeset author="A. N. Other &lt;other at place&gt;"/>
+<changeset author="User Name &lt;user at hostname&gt;"/>
 # formatnode filter works
 #  quiet
 1e4e1b8f71e0


More information about the Mercurial-devel mailing list