Merge branch 'refs/heads/ST-Imrie-master'

This commit is contained in:
Eric Lapouyade 2025-05-02 16:08:08 +02:00
commit a48a6a96b2
6 changed files with 102 additions and 2 deletions

View File

@ -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

View File

@ -128,5 +128,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

View File

@ -161,7 +161,7 @@ class DocxTemplate(object):
flags=re.DOTALL,
)
src_xml = re.sub(
r"({{r\s.*?}}|{%r\s.*?%})",
r"({{[rq]\s.*?}}|{%[rq].\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,
@ -184,6 +184,18 @@ class DocxTemplate(object):
% {"y": y}
)
src_xml = re.sub(pat, r"\1 \2", src_xml, flags=re.DOTALL)
# For paragraph level richtext
# replace into xml paragraph containing
# {%q xxx %} or {{q xxx}} template tag
# by {% xxx %} or {{ xx }} without any surrounding <w:p> tags
# This allow for inline {r <var> }} and paragraph {q <var> }) styling
# This is mandatory to have jinja2 generating correct xml code
pat = (
r"<w:p[ >](?:(?!<w:p[ >]).)*({%%|{{)q ([^}%%]*(?:%%}|}})).*?</w:p>"
)
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

View File

@ -0,0 +1,43 @@
"""
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("Any built in paragraph style can be used", parastyle="IntenseQuote")
rtp.add("or you can add your own, unlocking all style options", parastyle="createdStyle")
rtp.add("To use, just create a style in your template word doc with the formatting you want and call it in the code.", parastyle="normal")
rtp.add("This allows for the use of")
rtp.add("custom bullet\apoints", parastyle="SquareBullet")
rtp.add("Numbered Bullet Points", parastyle="BasicNumbered")
rtp.add("and Alpha Bullet Points.", parastyle="alphaBracketNumbering")
rtp.add("You can", parastyle="normal")
rtp.add("set the", parastyle="centerAlign")
rtp.add("text alignment", parastyle="rightAlign")
rtp.add("as well as the spacing between lines of text. Like this for example, this text has very tight spacing between the lines.\aIt also has no space between paragraphs of the same style.", parastyle="TightLineSpacing")
rtp.add("Unlike this one, which has extra large spacing between lines for when you want to space things out a bit or just write a little less.", parastyle="WideLineSpacing")
rtp.add("You can also set the background colour of a line.", parastyle="LineShadingGreen")
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")

Binary file not shown.

Binary file not shown.