Implemented {% paragraph_tag %} tag. When this tag is present in a paragraph, the XML source of the paragraph will be replaced with an additional tag ex. {% if varname %} in the same paragraph.

This commit is contained in:
Christopher Ramírez 2012-07-19 18:45:40 -06:00
parent 374a6fcb40
commit 394867c694
2 changed files with 122 additions and 39 deletions

View file

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"><office:scripts/><office:font-face-decls><style:font-face style:name="Lohit Hindi1" svg:font-family="&apos;Lohit Hindi&apos;"/><style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="Lohit Hindi" svg:font-family="&apos;Lohit Hindi&apos;" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="WenQuanYi Micro Hei" svg:font-family="&apos;WenQuanYi Micro Hei&apos;" style:font-family-generic="system" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles/><office:body><office:text><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="Standard">Hello {{ name }}</text:p></office:text></office:body></office:document-content> <office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"><office:scripts/><office:font-face-decls><style:font-face style:name="Lohit Hindi1" svg:font-family="&apos;Lohit Hindi&apos;"/><style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="Lohit Hindi" svg:font-family="&apos;Lohit Hindi&apos;" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="WenQuanYi Micro Hei" svg:font-family="&apos;WenQuanYi Micro Hei&apos;" style:font-family-generic="system" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles/><office:body><office:text><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="Standard">Hello {{ record.name }}</text:p><text:p text:style-name="Standard"/><text:p text:style-name="Standard">You are from {{ record.country }}</text:p><text:p text:style-name="Standard"/><text:p text:style-name="Standard">{% if record.age %}{{ record.age }}{% else %}Unknow age{% endif %}</text:p></office:text></office:body></office:document-content>

View file

@ -34,58 +34,141 @@ import re
import os import os
import zipfile import zipfile
import xml.dom.minidom import xml.dom.minidom
from jinja2 import Template as TemplateEngine
try:
from jinja2 import Template as TemplateEngine
except ImportError:
from django.template import Template as TemplateEngine
PARAGRAPH_TAG = '{% paragraph_tag %}'
class BaseRender(): class BaseRender():
""" """
Prapares a XML string or file to be processed by a templating system. Prapares a XML string or file to be processed by a templating system.
Use example: Use example:
render = BaseRender('content/xml', var1, var2.. varN) render = BaseRender('content/xml', var1, var2.. varN)
render.render render.render
""" """
def __init__(self, xml_doc, **template_args): def __init__(self, xml_doc, **template_args):
self.template_vars = template_args self.template_vars = template_args
self.xml_document = xml.dom.minidom.parse(xml_doc) self.xml_document = xml.dom.minidom.parse(xml_doc)
body = self.xml_document.getElementsByTagName('office:body') body = self.xml_document.getElementsByTagName('office:body')
self.content_body = body and body[0] self.content_body = body and body[0]
# ------------------------------------------------------------------------@ # ------------------------------------------------------------------------@
def render_with_engine(self):
"""
Once the XML have been prepared, this routine is called
to do the actual rendering.
"""
template = TemplateEngine(self.content_body.toxml())
return template.render(**self.template_vars)
def render(self): def get_paragraph_parent(self, node):
""" """
render prepares the XML and the call render_with_engine Returns the first node's parent with name "text:p"
to parse template engine tags If parent "text:p" is not found, returns None.
""" """
# TODO:
# Prepare {% blocks|if|for|etc %} for rendering
return self.render_with_engine()
if hasattr(node, 'parentNode'):
if node.parentNode.nodeName.lower() == 'text:p':
return node.parentNode
else:
return get_paragraph_parent(node.parentNode)
else:
return None
# ------------------------------------------------------------------------@
def render_with_engine(self):
"""
Once the XML have been prepared, this routine is called
to do the actual rendering.
"""
template = TemplateEngine(self.xml_document.toxml())
return template.render(**self.template_vars)
# -----------------------------------------------------------------------
def scan_child_nodes(self, nodes):
"""
"""
if nodes.hasChildNodes():
child_nodes = nodes.childNodes
for node in child_nodes:
if node.nodeType == node.TEXT_NODE:
node_text = node.data.lower()
# replace a paragraph node with contained tags
# if tag PARAGRAPH_TAG is in paragraph content.
if node_text.find(PARAGRAPH_TAG) > -1:
# Get this node text:p parent
paragraph_node = self.get_paragraph_parent(node)
paragraph_parent = paragraph_node.parentNode
# Discar PARAGRAPH_TAG
pgraph_node_text = \
paragraph_node.toxml().replace(PARAGRAPH_TAG, '')
# replace text:p node's XML with its contained templates tags.
new_node_text = \
' '.join(re.findall('(\{.*?\})', pgraph_node_text))
new_node = xml_document.createTextNode(new_node_text)
paragraph_parent.replaceChild(new_node, paragraph_node)
else:
if node.hasChildNodes():
scan_child_nodes(node)
# -----------------------------------------------------------------------
def handle_special_tags(self):
"""
"""
paragraphs = self.content_body.getElementsByTagName('text:p')
for paragraph in paragraphs:
self.scan_child_nodes(paragraph)
# -----------------------------------------------------------------------
def render(self):
"""
render prepares the XML and the call render_with_engine
to parse template engine tags
"""
self.handle_special_tags()
return self.render_with_engine()
# -----------------------------------------------------------------------
if __name__ == "__main__": if __name__ == "__main__":
print 'Testing with content.xml\n'
render = BaseRender('content.xml', name='Christopher') data = {
print render.render() 'name': u'Christopher Ramirez',
'country': 'Nicaragua'
}
# xml_document = xml.dom.minidom.parse('content.xml') render = BaseRender('content.xml', record=data)
# doc_body = xml_document.getElementsByTagName('office:body') print render.render()
# doc_body = doc_body and doc_body[0]
# template = Template(doc_body.toprettyxml()) # xml_document = xml.dom.minidom.parse('content.xml')
# doc_body = xml_document.getElementsByTagName('office:body')
# doc_body = doc_body and doc_body[0]
# print template.render( name='Christopher :)' ) # template = Template(doc_body.toprettyxml())
# print template.render( name='Christopher :)' )