diff --git a/secretary.py b/secretary.py index 8041a5e..272c43c 100644 --- a/secretary.py +++ b/secretary.py @@ -26,6 +26,7 @@ from os import path from mimetypes import guess_type, guess_extension from uuid import uuid4 from xml.dom.minidom import parseString +from xml.parsers.expat import ExpatError from jinja2 import Environment, Undefined # Test python versions and normalize calls to basestring, unicode, etc. @@ -313,18 +314,16 @@ class Renderer(object): and unescapes HTML codes for >, <, & and " """ unescape_rules = { - r'(?is)({[{|%].*)(<.?text:s.*?>)(.*[%|}]})': r'\1\3', - r'(?is)({[{|%].*)(>)(.*[%|}]})': r'\1>\3', r'(?is)({[{|%].*)(<)(.*[%|}]})': r'\1<\3', r'(?is)({[{|%].*)(&)(.*[%|}]})': r'\1&\3', r'(?is)({[{|%].*)(")(.*[%|}]})': r'\1"\3' } - for p, r in unescape_rules.items(): - count = None - while count != 0: - xml_text, count = re.subn(p, r, xml_text) + for regexp, replacement in unescape_rules.items(): + subs_made = True + while subs_made: + xml_text, subs_made = re.subn(regexp, replacement, xml_text) return xml_text @@ -451,17 +450,21 @@ class Renderer(object): try: self.template_images = dict() self._prepare_template_tags(xml_document) - template_string = Renderer._unescape_entities(xml_document.toxml()) + template_string = self._unescape_entities(xml_document.toxml()) jinja_template = self.environment.from_string(template_string) result = jinja_template.render(**kwargs) - result = Renderer._encode_escape_chars(result) + result = self._encode_escape_chars(result) final_xml = parseString(result.encode('ascii', 'xmlcharrefreplace')) if self.template_images: self.replace_images(final_xml) return final_xml + except ExpatError as e: + near = result.split('\n')[e.lineno -1][e.offset-50:e.offset+50] + raise ExpatError('ExpatError at line %d, column %d\nNear of: "[...]%s[...]"' % \ + (e.lineno, e.offset, near)) except: self.log.error('Error rendering template:\n%s', xml_document.toprettyxml(), exc_info=True)