Fix merge conflict.
This commit is contained in:
commit
f3e5923737
4 changed files with 66 additions and 18 deletions
24
README.md
24
README.md
|
|
@ -16,7 +16,7 @@ Rendered documents are produced in ODT format, and can then be converted to PDF,
|
|||
## Rendering a Template
|
||||
|
||||
from secreatary import Render
|
||||
|
||||
|
||||
engine = Render(template)
|
||||
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:
|
||||
|
||||
from secreatary import Render
|
||||
|
||||
|
||||
engine = Render(template)
|
||||
|
||||
# Configure custom application filters
|
||||
|
|
@ -54,9 +54,25 @@ Secretary will handle multiline variable values replacing the line breaks with a
|
|||
|
||||
### Control Flow
|
||||
|
||||
To be documented...
|
||||
To be documented...
|
||||
|
||||
|
||||
### Builtin Filters
|
||||
Apart of the available Jinja2 filters. Secretary includes some additionals filters. These are:
|
||||
|
||||
- **markdown(value)**
|
||||
Convert the value, a markdown formated string, into a ODT formated text. Example:
|
||||
|
||||
{{ invoice.description|markdown }}
|
||||
|
||||
**Output value will take the whole paragraph** so be aware of loosing text which is on the same paragraph of the markdown field.
|
||||
|
||||
- **pad(value, length)**
|
||||
Pad zeroes to `value` to the left until output's length will equal to `length`. Default output length is 5. Example:
|
||||
|
||||
{{ invoice.number|pad(6) }}
|
||||
|
||||
|
||||
[1]: http://jinja.pocoo.org/docs/templates/
|
||||
[2]: https://github.com/mirkonasato/pyodconverter
|
||||
[3]: http://jinja.pocoo.org/docs/api/#jinja2.Environment
|
||||
[3]: http://jinja.pocoo.org/docs/api/#jinja2.Environment
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from random import randint
|
||||
|
||||
# Transform map used by the markdown filter. transform_map have
|
||||
# instructions of how to transform a HTML style tag into a ODT document
|
||||
# styled tag. Some ODT tags may need extra attributes; these are defined
|
||||
|
|
@ -39,7 +41,7 @@ common_styles = {
|
|||
}
|
||||
},
|
||||
|
||||
'p': {
|
||||
'p': {
|
||||
'replace_with': 'text:p',
|
||||
'style_attributes': {
|
||||
'style-name': 'Standard'
|
||||
|
|
@ -51,7 +53,8 @@ transform_map = {
|
|||
'a': {
|
||||
'replace_with': 'text:a',
|
||||
'attributes': {
|
||||
'xlink:type': 'simple'
|
||||
'xlink:type': 'simple',
|
||||
'xlink:href': ''
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -103,4 +106,22 @@ transform_map = {
|
|||
'style-name': 'Preformatted_20_Text'
|
||||
}
|
||||
},
|
||||
|
||||
'ul': {
|
||||
'replace_with': 'text:list',
|
||||
'attributes': {
|
||||
'xml:id': 'list' + str(randint(100000000000000000,900000000000000000))
|
||||
}
|
||||
},
|
||||
|
||||
'ol': {
|
||||
'replace_with': 'text:list',
|
||||
'attributes': {
|
||||
'xml:id': 'list' + str(randint(100000000000000000,900000000000000000))
|
||||
}
|
||||
},
|
||||
|
||||
'li': {
|
||||
'replace_with': 'text:list-item'
|
||||
},
|
||||
}
|
||||
31
secretary.py
31
secretary.py
|
|
@ -38,7 +38,6 @@ import re
|
|||
import sys
|
||||
import zipfile
|
||||
import io
|
||||
from copy import deepcopy
|
||||
from xml.dom.minidom import parseString
|
||||
from jinja2 import Environment, Undefined
|
||||
|
||||
|
|
@ -252,7 +251,7 @@ class Render(object):
|
|||
|
||||
keep_field = field
|
||||
field_reference = field.getAttribute('text:description')
|
||||
|
||||
|
||||
if re.findall(r'\|markdown', field_content):
|
||||
# a markdown should take the whole paragraph
|
||||
field_reference = 'text:p'
|
||||
|
|
@ -295,10 +294,10 @@ class Render(object):
|
|||
"""
|
||||
|
||||
auto_styles = self.content.getElementsByTagName('office:automatic-styles')[0]
|
||||
|
||||
|
||||
if not auto_styles.hasChildNodes():
|
||||
return None
|
||||
|
||||
|
||||
for style_node in auto_styles.childNodes:
|
||||
if style_node.hasAttribute('style:name') and \
|
||||
(style_node.getAttribute('style:name') == style_name):
|
||||
|
|
@ -319,7 +318,7 @@ class Render(object):
|
|||
style_node.setAttribute('style:name', style_name)
|
||||
style_node.setAttribute('style:family', 'text')
|
||||
style_node.setAttribute('style:parent-style-name', 'Standard')
|
||||
|
||||
|
||||
if attributes:
|
||||
for k, v in attributes.iteritems():
|
||||
style_node.setAttribute('style:%s' % k, v)
|
||||
|
|
@ -337,6 +336,10 @@ class Render(object):
|
|||
"""
|
||||
Convert a markdown text into a ODT formated text
|
||||
"""
|
||||
|
||||
if not isinstance(markdown_text, basestring):
|
||||
return ''
|
||||
|
||||
from xml.dom import Node
|
||||
from markdown_map import transform_map
|
||||
|
||||
|
|
@ -345,7 +348,7 @@ class Render(object):
|
|||
except ImportError:
|
||||
raise SecretaryError('Could not import markdown2 library. Install it using "pip install markdown2"')
|
||||
|
||||
styles_cache = {} # cache styles searching
|
||||
styles_cache = {} # cache styles searching
|
||||
html_text = markdown(markdown_text)
|
||||
xml_object = parseString('<html>%s</html>' % html_text)
|
||||
|
||||
|
|
@ -394,12 +397,20 @@ class Render(object):
|
|||
|
||||
html_node.parentNode.replaceChild(odt_node, html_node)
|
||||
|
||||
def node_to_string(node):
|
||||
result = node.toxml()
|
||||
|
||||
result = ''.join(c.toxml() for c in xml_object.getElementsByTagName('html')[0].childNodes)
|
||||
# A double linebreak should be replacece with an empty paragraph
|
||||
result = result.replace('\n\n', '<text:p text:style-name="Standard"/>')
|
||||
return result
|
||||
# linebreaks in preformated nodes should be converted to <text:line-break/>
|
||||
if (node.__class__.__name__ != 'Text') and \
|
||||
(node.getAttribute('text:style-name') == 'Preformatted_20_Text'):
|
||||
result = result.replace('\n', '<text:line-break/>')
|
||||
|
||||
# All double linebreak should be replaced with an empty paragraph
|
||||
return result.replace('\n\n', '<text:p text:style-name="Standard"/>')
|
||||
|
||||
|
||||
return ''.join(node_as_str for node_as_str in map(node_to_string,
|
||||
xml_object.getElementsByTagName('html')[0].childNodes))
|
||||
|
||||
def render_template(template, **kwargs):
|
||||
"""
|
||||
|
|
|
|||
4
setup.py
4
setup.py
|
|
@ -24,7 +24,7 @@ class PyTest(TestCommand):
|
|||
|
||||
setup(
|
||||
name='secretary',
|
||||
version='0.0.1',
|
||||
version='0.1.0',
|
||||
url='https://github.com/christopher-ramirez/secretary',
|
||||
license='BSD',
|
||||
author='Christopher Ramírez',
|
||||
|
|
@ -32,7 +32,7 @@ setup(
|
|||
description=('Take the power of Jinja2 templates to OpenOffice and '
|
||||
'LibreOffice and create reports and letters in your web applications'),
|
||||
long_description=read('README.md'),
|
||||
py_modules=['secretary'],
|
||||
py_modules=['secretary', 'markdown_map'],
|
||||
platforms='any',
|
||||
install_requires=[
|
||||
'Jinja2', 'markdown2'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue