diff --git a/CHANGES.rst b/CHANGES.rst
index 9ae35c1..1c53a79 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,7 @@
+0.10.3 (2020-10-15)
+-------------------
+- \n \t and \f are now accepted in simple context string (#307, #312)
+
0.10.1 (2020-08-23)
-------------------
- Remove extension testing (#297)
diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py
index aa1b1ee..4adb459 100644
--- a/docxtpl/__init__.py
+++ b/docxtpl/__init__.py
@@ -7,7 +7,7 @@ Created : 2015-03-12
import functools
import io
-__version__ = '0.10.2'
+__version__ = '0.10.3'
from lxml import etree
from docx import Document
@@ -27,6 +27,7 @@ import six
import binascii
import os
import zipfile
+from functools import partial
NEWLINE_XML = ''
NEWPARAGRAPH_XML = ''
@@ -234,8 +235,33 @@ class DocxTemplate(object):
.replace('}_}', '}}')
.replace('{_%', '{%')
.replace('%_}', '%}'))
+ dst_xml = self.resolve_listing(dst_xml)
return dst_xml
+ def resolve_listing(self, xml):
+ xml = xml.replace('\n', NEWLINE_XML)
+ xml = xml.replace('\f', PAGE_BREAK)
+
+ def resolve_run(paragraph_properties, m):
+ run_properties = re.search(r'.*', m[0])
+ run_properties = run_properties[0] if run_properties else ''
+ xml = m[0].replace('\t', ''
+ '%s'
+ '%s' % (run_properties, run_properties))
+ return xml.replace('\a', '%s%s' % (paragraph_properties, run_properties))
+
+ def resolve_paragraph(m):
+ paragraph_properties = re.search(r'.*', m[0])
+ paragraph_properties = paragraph_properties[0] if paragraph_properties else ''
+
+ p_resolve_run = partial(resolve_run, paragraph_properties)
+
+ return re.sub(r']*)?>.*?', p_resolve_run, m[0])
+
+ xml = re.sub(r']*)?>.*?', resolve_paragraph, xml)
+
+ return xml
+
def build_xml(self, context, jinja_env=None):
xml = self.get_xml()
xml = self.patch_xml(xml)
diff --git a/tests/escape.py b/tests/escape.py
index a18b926..c3d03fc 100644
--- a/tests/escape.py
+++ b/tests/escape.py
@@ -6,7 +6,7 @@ context = {
'myvar': R(
'"less than" must be escaped : <, this can be done with RichText() or R()'
),
- 'myescvar': 'It can be escaped with a "|e" jinja filter in the template too : < ',
+ 'myescvar': 'Without using Richtext, you can simply escape text with a "|e" jinja filter in the template : < ',
'nlnp': R(
'Here is a multiple\nlines\nstring\aand some\aother\aparagraphs\aNOTE: the current character styling is removed'
),
@@ -14,6 +14,11 @@ context = {
'the listing\nwith\nsome\nlines\nand special chars : <>&\f ... and a page break'
),
'page_break': R('\f'),
+ 'new_listing': """With the latest version of docxtpl,
+there is no need to use Listing objects anymore.
+Just use \\n for newline,\n\\t\t for tabulation and \\f for ...\f...page break
+One can also use special chars : <>& but you have then to add "|e" jinja filter in the template
+""",
}
tpl.render(context)
diff --git a/tests/templates/escape_tpl.docx b/tests/templates/escape_tpl.docx
index d676492..62592e4 100644
Binary files a/tests/templates/escape_tpl.docx and b/tests/templates/escape_tpl.docx differ