Rich Text Paragraph Formatting Update
This commit is contained in:
parent
b97fa32f10
commit
aa7b7a77e3
@ -9,6 +9,6 @@ __version__ = "0.19.1"
|
||||
# flake8: noqa
|
||||
from .inline_image import InlineImage
|
||||
from .listing import Listing
|
||||
from .richtext import RichText, R
|
||||
from .richtext import RichText, R, RichTextParagraph, RP
|
||||
from .subdoc import Subdoc
|
||||
from .template import DocxTemplate
|
||||
|
||||
@ -119,5 +119,50 @@ class RichText(object):
|
||||
def __html__(self):
|
||||
return self.xml
|
||||
|
||||
class RichTextParagraph(object):
|
||||
"""class to generate Rich Text Paragraphs when using templates variables
|
||||
|
||||
This is much faster than using Subdoc class,
|
||||
but this only for texts OUTSIDE an existing paragraph.
|
||||
"""
|
||||
|
||||
def __init__(self, text=None, **text_prop):
|
||||
self.xml = ""
|
||||
if text:
|
||||
self.add(text, **text_prop)
|
||||
|
||||
def add(
|
||||
self,
|
||||
text,
|
||||
parastyle=None,
|
||||
):
|
||||
|
||||
# If a RichText is added
|
||||
if not isinstance(text, RichText):
|
||||
text = RichText(text)
|
||||
|
||||
prop = ""
|
||||
if parastyle:
|
||||
prop += '<w:pStyle w:val="%s"/>' % parastyle
|
||||
|
||||
xml = "<w:p>"
|
||||
if prop:
|
||||
xml += "<w:pPr>%s</w:pPr>" % prop
|
||||
xml += text.xml
|
||||
xml += "</w:p>"
|
||||
self.xml += xml
|
||||
|
||||
def __unicode__(self):
|
||||
return self.xml
|
||||
|
||||
def __str__(self):
|
||||
return self.xml
|
||||
|
||||
def __html__(self):
|
||||
return self.xml
|
||||
|
||||
|
||||
|
||||
|
||||
R = RichText
|
||||
RP = RichTextParagraph
|
||||
|
||||
@ -160,7 +160,7 @@ class DocxTemplate(object):
|
||||
flags=re.DOTALL,
|
||||
)
|
||||
src_xml = re.sub(
|
||||
r"({{r\s.*?}}|{%r\s.*?%})",
|
||||
r"({{r.\s.*?}}|{%r.\s.*?%})",
|
||||
r'</w:t></w:r><w:r><w:t xml:space="preserve">\1</w:t></w:r><w:r><w:t xml:space="preserve">',
|
||||
src_xml,
|
||||
flags=re.DOTALL,
|
||||
@ -173,7 +173,7 @@ class DocxTemplate(object):
|
||||
r"-%}(?:(?!<w:t[ >]|{%|{{).)*?<w:t[^>]*?>", "%}", src_xml, flags=re.DOTALL
|
||||
)
|
||||
|
||||
for y in ["tr", "tc", "p", "r"]:
|
||||
for y in ["tr", "tc", "p"]:
|
||||
# replace into xml code the row/paragraph/run containing
|
||||
# {%y xxx %} or {{y xxx}} template tag
|
||||
# by {% xxx %} or {{ xx }} without any surrounding <w:y> tags :
|
||||
@ -184,6 +184,18 @@ class DocxTemplate(object):
|
||||
)
|
||||
src_xml = re.sub(pat, r"\1 \2", src_xml, flags=re.DOTALL)
|
||||
|
||||
for y in ["p", "r"]:
|
||||
# replace into xml paragraph or run containing
|
||||
# {%rp xxx %} or {{rp xxx}} template tag
|
||||
# by {% xxx %} or {{ xx }} without any surrounding <w:p> tags
|
||||
# This allow for inline {rr <var> }} and paragraph {rp <var> }) styling
|
||||
# This is mandatory to have jinja2 generating correct xml code
|
||||
pat = (
|
||||
r"<w:%(y)s[ >](?:(?!<w:%(y)s[ >]).)*({%%|{{)r%(y)s ([^}%%]*(?:%%}|}})).*?</w:%(y)s>"
|
||||
% {"y": y}
|
||||
)
|
||||
src_xml = re.sub(pat, r"\1 \2", src_xml, flags=re.DOTALL)
|
||||
|
||||
for y in ["tr", "tc", "p"]:
|
||||
# same thing, but for {#y xxx #} (but not where y == 'r', since that
|
||||
# makes less sense to use comments in that context
|
||||
|
||||
32
tests/richtextparagraph.py
Normal file
32
tests/richtextparagraph.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""
|
||||
Created : 2025-02-28
|
||||
|
||||
@author: Hannah Imrie
|
||||
"""
|
||||
|
||||
from docxtpl import DocxTemplate, RichText, RichTextParagraph
|
||||
|
||||
tpl = DocxTemplate("templates/richtext_paragraph_tpl.docx")
|
||||
|
||||
rtp = RichTextParagraph()
|
||||
rt = RichText()
|
||||
|
||||
rtp.add("The rich text paragraph function allows paragraph styles to be added to text",parastyle="myrichparastyle")
|
||||
|
||||
rtp.add("This allows for the use of")
|
||||
rtp.add("bullet\apoints.", parastyle="SquareBullet")
|
||||
|
||||
rt.add("This works with ")
|
||||
rt.add("Rich ", bold=True)
|
||||
rt.add("Text ", italic=True)
|
||||
rt.add("Strings", underline="single")
|
||||
rt.add(" too.")
|
||||
|
||||
rtp.add(rt, parastyle="SquareBullet")
|
||||
|
||||
context = {
|
||||
"example": rtp,
|
||||
}
|
||||
|
||||
tpl.render(context)
|
||||
tpl.save("output/richtext_paragraph.docx")
|
||||
BIN
tests/templates/richtext_paragraph_tpl.docx
Normal file
BIN
tests/templates/richtext_paragraph_tpl.docx
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user