Paragraph, row, cell and run tags ({%p %}, {%tr %}, {%tc %}, {%r %}) fail when their Jinja expression contains a % (for example modulo) or a } (for example a dict literal). Rendering raises TemplateSyntaxError: Encountered unknown tag 'p'.
In docxtpl/template.py (line 186) the expression body is matched with [^}%]*:
r"<w:%(y)s[ >](?:(?!<w:%(y)s[ >]).)*({%%|{{)%(y)s ([^}%%]*(?:%%}|}})).*?</w:%(y)s>"
[^}%]* stops at the first } or %, so the tag is not matched and the surrounding <w:p> (or <w:tr>/<w:tc>/<w:r>) wrapper is not removed. The literal {%p ...%} is then passed to Jinja, which does not know the tag p.
Reproduction:
from docx import Document
from docxtpl import DocxTemplate
d = Document()
for line in ["{%p for i in range(4) %}", "{%p if i % 2 == 0 %}", "even: {{ i }}", "{%p endif %}", "{%p endfor %}"]:
d.add_paragraph(line)
d.save("modulo_tpl.docx")
tpl = DocxTemplate("modulo_tpl.docx")
tpl.render({}) # TemplateSyntaxError: Encountered unknown tag 'p'.
The same template with if i in [0, 2] (no %) renders fine, which isolates the cause.
Fix: match up to the closing %}/}} instead of excluding % and }. Related to #81. PR follows.
Paragraph, row, cell and run tags (
{%p %},{%tr %},{%tc %},{%r %}) fail when their Jinja expression contains a%(for example modulo) or a}(for example a dict literal). Rendering raisesTemplateSyntaxError: Encountered unknown tag 'p'.In
docxtpl/template.py(line 186) the expression body is matched with[^}%]*:r"<w:%(y)s[ >](?:(?!<w:%(y)s[ >]).)*({%%|{{)%(y)s ([^}%%]*(?:%%}|}})).*?</w:%(y)s>"[^}%]*stops at the first}or%, so the tag is not matched and the surrounding<w:p>(or<w:tr>/<w:tc>/<w:r>) wrapper is not removed. The literal{%p ...%}is then passed to Jinja, which does not know the tagp.Reproduction:
The same template with
if i in [0, 2](no%) renders fine, which isolates the cause.Fix: match up to the closing
%}/}}instead of excluding%and}. Related to #81. PR follows.