run tests

This commit is contained in:
Eric Lapouyade 2018-11-08 12:11:59 +01:00
commit fe7362f4d4
26 changed files with 59 additions and 4 deletions

View File

@ -1,3 +1,7 @@
0.5.7 (2018-11-07)
------------------
- Render can now autoescape context dict
0.5.6 (2018-10-18)
------------------
- Fix invalid xml parse because using {% vm %}

View File

@ -159,11 +159,12 @@ Escaping, newline, new paragraph, Listing
-----------------------------------------
When you use a ``{{ <var> }}``, you are modifying an **XML** word document, this means you cannot use all chars,
especially ``<``, ``>`` and ``&``. In order to use them, you must escape them. There are 3 ways :
especially ``<``, ``>`` and ``&``. In order to use them, you must escape them. There are 4 ways :
* ``context = { 'var':R('my text') }`` and ``{{r <var> }}`` in the template (note the ``r``),
* ``context = { 'var':'my text'}`` and ``{{ <var>|e }}`` in your word template
* ``context = { 'var':escape('my text')}`` and ``{{ <var> }}`` 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
text, they will be converted accordingly.

View File

@ -5,7 +5,7 @@ Created : 2015-03-12
@author: Eric Lapouyade
'''
__version__ = '0.5.6'
__version__ = '0.5.7'
from lxml import etree
from docx import Document
@ -15,7 +15,7 @@ from docx.opc.constants import RELATIONSHIP_TYPE as REL_TYPE
from jinja2 import Template
from jinja2.exceptions import TemplateError
try:
from html import escape
from html import escape, unescape
except ImportError:
# cgi.escape is deprecated in python 3.7
from cgi import escape
@ -24,6 +24,7 @@ import six
import binascii
import os
import zipfile
import sys
NEWLINE_XML = '</w:t><w:br/><w:t xml:space="preserve">'
NEWPARAGRAPH_XML = '</w:t></w:r></w:p><w:p><w:r><w:t xml:space="preserve">'
@ -169,7 +170,43 @@ class DocxTemplate(object):
def map_headers_footers_xml(self, relKey, xml):
self.docx._part._rels[relKey]._target._blob = xml
def render(self,context,jinja_env=None):
@staticmethod
def escape_values(context):
"""Escape strings for an XML Word document
which may contain <, >, &, ', and ".
"""
def escape_recursively(d):
"""Escape string values of the passed :dict: `d` in-place
including nested dictionaries.
"""
nonlocal hash_values
for k, v in d.items():
if isinstance(v, dict):
hash_value = id(v)
if hash_value not in hash_values:
hash_values.add(hash_value)
escape_recursively(v)
else:
# Avoid dict, Listing, InlineImage, RichText, etc. classes
# by comparing v to str. Do not use try-except.
if isinstance(v, str):
# Unescape at first to avoid secondary escaping
d[k] = escape(unescape(v))
# Avoid RecursionError (if back edges, i.e. cycles, exist)
# by using a set of hash values of iterated dictionaries.
hash_values = {id(context), }
escape_recursively(context)
def render(self, context, jinja_env=None, autoescape=False):
if sys.version_info >= (3, 0) and autoescape:
self.escape_values(context)
else:
# Sorry folk, use awesome Python3 such as 3.6
pass
# Body
xml_src = self.build_xml(context,jinja_env)

13
tests/escape_auto.py Normal file
View File

@ -0,0 +1,13 @@
from docxtpl import *
tpl = DocxTemplate("test_files/escape_tpl_auto.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'),
'mylisting': Listing('the listing\nwith\nsome\nlines\nand special chars : <>&'),
'autoescape': """These string should be auto escaped for an XML Word document which may contain <, >, &, ", and '."""
}
tpl.render(context, autoescape=True)
tpl.save("test_files/escape_auto.docx")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.