Merge branch 'development' of github.com:christopher-ramirez/secretary into development
This commit is contained in:
commit
4bebfbcbcb
3 changed files with 24 additions and 13 deletions
15
README.md
15
README.md
|
|
@ -16,7 +16,7 @@ Rendered documents are produced in ODT format, and can then be converted to PDF,
|
||||||
## Rendering a Template
|
## Rendering a Template
|
||||||
|
|
||||||
from secreatary import Render
|
from secreatary import Render
|
||||||
|
|
||||||
engine = Render(template)
|
engine = Render(template)
|
||||||
result = engine.render(foo=foo, bar=bar)
|
result = engine.render(foo=foo, bar=bar)
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ To render a template create an instance of class `Render` and call the instance'
|
||||||
Before rendering a template, you can configure the internal templating engine using the `Render` instance's variable `environment`, which is an instance of jinja2 **[Environment][3]** class. For example, to declare a custom filter use:
|
Before rendering a template, you can configure the internal templating engine using the `Render` instance's variable `environment`, which is an instance of jinja2 **[Environment][3]** class. For example, to declare a custom filter use:
|
||||||
|
|
||||||
from secreatary import Render
|
from secreatary import Render
|
||||||
|
|
||||||
engine = Render(template)
|
engine = Render(template)
|
||||||
|
|
||||||
# Configure custom application filters
|
# Configure custom application filters
|
||||||
|
|
@ -76,7 +76,7 @@ Most of the time secretary will handle the internal composing of XML when you in
|
||||||
> YOU HAVEN'T PAID
|
> YOU HAVEN'T PAID
|
||||||
> `{% endif %}`
|
> `{% endif %}`
|
||||||
|
|
||||||
The last example could had been simplified into a single paragraph in Writer like:
|
The last example could had been simplified into a single paragraph in Writer like:
|
||||||
|
|
||||||
> `{% if already_paid %}`YOU ALREADY PAID`{% else %}`YOU HAVEN'T PAID`{% endif %}`
|
> `{% if already_paid %}`YOU ALREADY PAID`{% else %}`YOU HAVEN'T PAID`{% endif %}`
|
||||||
|
|
||||||
|
|
@ -101,15 +101,18 @@ Although most of the time the automatic handling of control flow in secretary ma
|
||||||
* `after::cell`: Same as `after::row` but for a table cell.
|
* `after::cell`: Same as `after::row` but for a table cell.
|
||||||
> Field content is the control flow tag you insert with the Writer *input field*
|
> Field content is the control flow tag you insert with the Writer *input field*
|
||||||
|
|
||||||
|
### Features of jinja2 not supported
|
||||||
|
Secretary supports most of the jinja2 control structure/flow tags. But please avoid using the following tags since they are not supported: `block`, `extends`, `macro`, `call`, `include` and `import`.
|
||||||
|
|
||||||
### Builtin Filters
|
### Builtin Filters
|
||||||
Secretary includes some predefined *jinja2* filters. Included filters are:
|
Secretary includes some predefined *jinja2* filters. Included filters are:
|
||||||
|
|
||||||
- **markdown(value)**
|
- **markdown(value)**
|
||||||
Convert the value, a markdown formated string, into a ODT formated text. Example:
|
Convert the value, a markdown formated string, into a ODT formated text. Example:
|
||||||
|
|
||||||
{{ invoice.description|markdown }}
|
{{ invoice.description|markdown }}
|
||||||
|
|
||||||
- **pad(value, length)**
|
- **pad(value, length)**
|
||||||
Pad zeroes to `value` to the left until output value's length be equal to `length`. Default length if 5. Example:
|
Pad zeroes to `value` to the left until output value's length be equal to `length`. Default length if 5. Example:
|
||||||
|
|
||||||
{{ invoice.number|pad(6) }}
|
{{ invoice.number|pad(6) }}
|
||||||
|
|
|
||||||
22
secretary.py
22
secretary.py
|
|
@ -180,27 +180,35 @@ class Render(object):
|
||||||
Unpack and render the internal template and
|
Unpack and render the internal template and
|
||||||
returns the rendered ODF document.
|
returns the rendered ODF document.
|
||||||
"""
|
"""
|
||||||
|
def unescape_gt_lt(text):
|
||||||
|
# unescape XML entities gt and lt
|
||||||
|
unescape_entities = {
|
||||||
|
r'({[{|%].*)(>)(.*[%|}]})': r'\1>\3',
|
||||||
|
r'({[{|%].*)(<)(.*[%|}]})': r'\1<\3',
|
||||||
|
}
|
||||||
|
for pattern, repl in unescape_entities.iteritems():
|
||||||
|
text = re.sub(pattern, repl, text, flags=re.IGNORECASE or re.DOTALL)
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
self.unpack_template()
|
self.unpack_template()
|
||||||
|
|
||||||
# Render content.xml
|
# Render content.xml
|
||||||
self.prepare_template_tags(self.content)
|
self.prepare_template_tags(self.content)
|
||||||
# print(self.content.toprettyxml())
|
template = self.environment.from_string(unescape_gt_lt(self.content.toxml()))
|
||||||
template = self.environment.from_string(self.content.toxml())
|
|
||||||
result = template.render(**kwargs)
|
result = template.render(**kwargs)
|
||||||
result = result.replace('\n', '<text:line-break/>')
|
result = result.replace('\n', '<text:line-break/>')
|
||||||
|
|
||||||
# Replace original body with rendered body
|
# Replace original body with rendered body
|
||||||
original_body = self.content.getElementsByTagName('office:body')[0]
|
original_body = self.content.getElementsByTagName('office:body')[0]
|
||||||
rendered_body = parseString(result.encode('ascii', 'xmlcharrefreplace')) \
|
rendered_body = parseString(result.encode('ascii', 'xmlcharrefreplace')).getElementsByTagName('office:body')[0]
|
||||||
.getElementsByTagName('office:body')[0]
|
|
||||||
|
|
||||||
document = self.content.getElementsByTagName('office:document-content')[0]
|
document = self.content.getElementsByTagName('office:document-content')[0]
|
||||||
document.replaceChild(rendered_body, original_body)
|
document.replaceChild(rendered_body, original_body)
|
||||||
|
|
||||||
# Render style.xml
|
# Render style.xml
|
||||||
self.prepare_template_tags(self.styles)
|
self.prepare_template_tags(self.styles)
|
||||||
template = self.environment.from_string(self.styles.toxml())
|
template = self.environment.from_string(unescape_gt_lt(self.styles.toxml()))
|
||||||
result = template.render(**kwargs)
|
result = template.render(**kwargs)
|
||||||
result = result.replace('\n', '<text:line-break/>')
|
result = result.replace('\n', '<text:line-break/>')
|
||||||
self.styles = parseString(result.encode('ascii', 'xmlcharrefreplace'))
|
self.styles = parseString(result.encode('ascii', 'xmlcharrefreplace'))
|
||||||
|
|
@ -332,7 +340,7 @@ class Render(object):
|
||||||
# Avoid removing whole container, just original text:p parent
|
# Avoid removing whole container, just original text:p parent
|
||||||
field = self.node_parents(keep_field, 'text:p')
|
field = self.node_parents(keep_field, 'text:p')
|
||||||
parent = field.parentNode
|
parent = field.parentNode
|
||||||
|
|
||||||
parent.removeChild(field)
|
parent.removeChild(field)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -494,7 +502,7 @@ if __name__ == "__main__":
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
render = Render('a.odt')
|
render = Render('simple_template.odt')
|
||||||
result = render.render(countries=countries, document=document)
|
result = render.render(countries=countries, document=document)
|
||||||
|
|
||||||
output = open('rendered.odt', 'wb')
|
output = open('rendered.odt', 'wb')
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue