run tests
This commit is contained in:
commit
fe7362f4d4
@ -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 %}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
13
tests/escape_auto.py
Normal 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.
BIN
tests/test_files/escape_auto.docx
Normal file
BIN
tests/test_files/escape_auto.docx
Normal file
Binary file not shown.
BIN
tests/test_files/escape_tpl_auto.docx
Normal file
BIN
tests/test_files/escape_tpl_auto.docx
Normal file
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.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user