diff --git a/README.md b/README.md
index 51197a4..1bef237 100644
--- a/README.md
+++ b/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
\ No newline at end of file
diff --git a/markdown_map.py b/markdown_map.py
index c09ce68..77b4d24 100644
--- a/markdown_map.py
+++ b/markdown_map.py
@@ -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'
+ },
}
\ No newline at end of file
diff --git a/secretary.py b/secretary.py
index 860e026..209714d 100644
--- a/secretary.py
+++ b/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('%s' % 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', '')
- return result
+ # linebreaks in preformated nodes should be converted to
+ if (node.__class__.__name__ != 'Text') and \
+ (node.getAttribute('text:style-name') == 'Preformatted_20_Text'):
+ result = result.replace('\n', '')
+ # All double linebreak should be replaced with an empty paragraph
+ return result.replace('\n\n', '')
+
+
+ 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):
"""
diff --git a/setup.py b/setup.py
index f7fc066..8e7be1c 100644
--- a/setup.py
+++ b/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'