From a0c9478e72958473a748d8d7a47796e13b5392f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 11:09:44 -0600 Subject: [PATCH 1/9] Implement href for links and fix issues with preformated text in markdown filter. --- markdown_map.py | 3 ++- secretary.py | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/markdown_map.py b/markdown_map.py index c09ce68..5e480e9 100644 --- a/markdown_map.py +++ b/markdown_map.py @@ -51,7 +51,8 @@ transform_map = { 'a': { 'replace_with': 'text:a', 'attributes': { - 'xlink:type': 'simple' + 'xlink:type': 'simple', + 'xlink:href': '' } }, diff --git a/secretary.py b/secretary.py index 8568538..492bd5d 100644 --- a/secretary.py +++ b/secretary.py @@ -232,7 +232,7 @@ class Render(object): continue field_description = field.getAttribute('text:description') - + if re.findall(r'\|markdown', field_content): # a markdown should take the whole paragraph field_description = 'text:p' @@ -259,10 +259,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): @@ -283,7 +283,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) @@ -309,7 +309,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) @@ -358,12 +358,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): """ From b1d781441c94ea7e1b7e20adbb91f41025dd85ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 11:25:09 -0600 Subject: [PATCH 2/9] Updated READMED with documentation about builtin filters. --- README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 51197a4..c6b452a 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,23 @@ Secretary will handle multiline variable values replacing the line breaks with a ### Control Flow -To be documented... +To be documented... + + +### Builtin Filters +Secretary includes some predefined *jinja2* filters. Included filters are: + +- **markdown(value)** +Convert the value, a markdown formated string, into a ODT formated text. Example: + + {{ invoice.description|markdown }} + +- **pad(value, length)** +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) }} [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 From a2885f398db67338e8433d3a9f4241faf168d668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 11:28:37 -0600 Subject: [PATCH 3/9] Update version number in setup.py. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f7fc066..99dfb01 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ class PyTest(TestCommand): setup( name='secretary', - version='0.0.1', + version='0.0.2', url='https://github.com/christopher-ramirez/secretary', license='BSD', author='Christopher Ramírez', From 4d6a7669a68cc4ec277f8480a00844b185fe377d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 11:45:05 -0600 Subject: [PATCH 4/9] Fixing typos in readme. --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6b452a..1bef237 100644 --- a/README.md +++ b/README.md @@ -58,15 +58,17 @@ To be documented... ### Builtin Filters -Secretary includes some predefined *jinja2* filters. Included filters are: +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: + 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 value's length be equal to `length`. Default length if 5. Example: + 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) }} From 10b05017b5b565168aa25c75eb77620e8f74141e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 11:48:06 -0600 Subject: [PATCH 5/9] Removing useless deepcopy import. --- secretary.py | 1 - 1 file changed, 1 deletion(-) diff --git a/secretary.py b/secretary.py index 492bd5d..507706d 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 From 32b7f8f42f6b725800521844596550602dfe7d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 12:09:15 -0600 Subject: [PATCH 6/9] Adding support for ul and ol convertion. --- markdown_map.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/markdown_map.py b/markdown_map.py index 5e480e9..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' @@ -104,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 From 7b81a294bdbfbcc825c944977099efa9d81b0b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Thu, 24 Oct 2013 15:28:36 -0600 Subject: [PATCH 7/9] Adding markdown_map to dist setup. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 99dfb01..e60833b 100644 --- a/setup.py +++ b/setup.py @@ -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' From 2f76982c38cae7d752e5694377689e0596594a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Mon, 3 Feb 2014 16:39:27 -0600 Subject: [PATCH 8/9] fix #5. --- secretary.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/secretary.py b/secretary.py index 507706d..6373045 100644 --- a/secretary.py +++ b/secretary.py @@ -300,6 +300,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 From 09d2b9bd57b3db159733311781e75e7d55390f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Ram=C3=ADrez?= Date: Mon, 3 Feb 2014 16:52:17 -0600 Subject: [PATCH 9/9] Updated version number. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e60833b..8e7be1c 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ class PyTest(TestCommand): setup( name='secretary', - version='0.0.2', + version='0.1.0', url='https://github.com/christopher-ramirez/secretary', license='BSD', author='Christopher Ramírez',