diff --git a/docs/index.rst b/docs/index.rst index b2a802b..89defe2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -189,12 +189,12 @@ especially ``<``, ``>`` and ``&``. In order to use them, you must escape them. T * ``context = { 'var':escape('my text')}`` and ``{{ }}`` in the template. * enable autoescaping when calling render method: ``tpl.render(context, autoescape=True)`` (default is autoescape=False) -The ``RichText()`` or ``R()`` offers newline and new paragraph feature : just use ``\n`` or ``\a`` in the +The ``RichText()`` or ``R()`` offers newline, new paragraph, and page break features : just use ``\n``, ``\a``, or ``\f`` in the text, they will be converted accordingly. See tests/escape.py example for more informations. -Another solution, if you want to include a listing into your document, that is to escape the text and manage \n and \a, +Another solution, if you want to include a listing into your document, that is to escape the text and manage \n, \a, and \f you can use the ``Listing`` class : in your python code :: diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index a64ff85..2044eb8 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -32,6 +32,8 @@ import zipfile NEWLINE_XML = '' NEWPARAGRAPH_XML = '' TAB_XML = '' +PAGE_BREAK = '' + class DocxTemplate(object): """ Class for managing docx files as they were jinja2 templates """ @@ -582,6 +584,7 @@ class Subdoc(object): def __html__(self): return self._get_xml() + class RichText(object): """ class to generate Rich Text when using templates variables @@ -612,10 +615,11 @@ class RichText(object): text = six.text_type(text) if not isinstance(text, six.text_type): text = text.decode('utf-8',errors='ignore') - text = ( escape(text) - .replace('\n', NEWLINE_XML) - .replace('\a', NEWPARAGRAPH_XML) - .replace('\t',TAB_XML) ) + text = (escape(text) + .replace('\n', NEWLINE_XML) + .replace('\a', NEWPARAGRAPH_XML) + .replace('\t', TAB_XML) + .replace('\f', PAGE_BREAK)) prop = u'' @@ -670,8 +674,10 @@ class RichText(object): def __html__(self): return self.xml + R = RichText + class Listing(object): r"""class to manage \n and \a without to use RichText, by this way you keep the current template styling @@ -683,9 +689,11 @@ class Listing(object): # If not a string : cast to string (ex: int, dict etc...) if not isinstance(text, (six.text_type, six.binary_type)): text = six.text_type(text) - self.xml = ( escape(text) - .replace('\n', NEWLINE_XML) - .replace('\a', NEWPARAGRAPH_XML) ) + self.xml = (escape(text) + .replace('\n', NEWLINE_XML) + .replace('\a', NEWPARAGRAPH_XML) + .replace('\t', TAB_XML) + .replace('\f', PAGE_BREAK)) def __unicode__(self): return self.xml diff --git a/tests/escape.py b/tests/escape.py index 9f12654..2addc87 100644 --- a/tests/escape.py +++ b/tests/escape.py @@ -3,9 +3,10 @@ from docxtpl import * tpl = DocxTemplate('templates/escape_tpl.docx') 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 : < ', - 'nlnp' : R('Here is a multiple\nlines\nstring\aand some\aother\aparagraphs\aNOTE: the current character styling is removed'), + 'myescvar': 'It can be escaped with a "|e" jinja filter in the template too : < ', + 'nlnp': R('Here is a multiple\nlines\nstring\aand some\aother\aparagraphs\aNOTE: the current character styling is removed'), 'mylisting': Listing('the listing\nwith\nsome\nlines\nand special chars : <>&'), + 'page_break': R('\f'), } tpl.render(context) diff --git a/tests/templates/escape_tpl.docx b/tests/templates/escape_tpl.docx index 6a97756..eb0cfe3 100644 Binary files a/tests/templates/escape_tpl.docx and b/tests/templates/escape_tpl.docx differ