Skip to content

Instantly share code, notes, and snippets.

@samuelharmer
Created June 17, 2020 11:13
Show Gist options
  • Save samuelharmer/598b3a532f7c3869a376c3d1a84f2571 to your computer and use it in GitHub Desktop.
Save samuelharmer/598b3a532f7c3869a376c3d1a84f2571 to your computer and use it in GitHub Desktop.
Custom formatting of reportlab lists
#!/usr/bin/env python3
import unicodedata
from pathlib import Path
from reportlab.platypus import SimpleDocTemplate, Paragraph, ListFlowable, Spacer
from reportlab.lib.styles import getSampleStyleSheet
output = Path.cwd() / Path(__file__).with_suffix(".pdf").name
doc = SimpleDocTemplate(str(output))
styles = getSampleStyleSheet()
normal = styles["Normal"]
body = styles["BodyText"]
h2 = styles["Heading2"]
def second_tetration(value: str):
try:
n = int(value)
try:
# Only works up to 9 (i.e. single digits)
exponent = unicodedata.lookup(unicodedata.name(str(n)).replace("DIGIT", "SUPERSCRIPT"))
except KeyError:
exponent = None
if exponent is None:
return f"{n}^{n} = {n ** n}"
else:
return f"{n}{exponent} = {n ** n}"
except ValueError:
return value
story = [
Paragraph("Plain", h2),
ListFlowable(
[Paragraph(s, normal) for s in ["One", "Two", "Three"]]
),
Paragraph("With a Full Stop (Period)", h2),
ListFlowable(
[Paragraph(s, normal) for s in [
"First element",
"This is the second element",
]],
bulletFormat="%s.", # ←
),
Paragraph("With a Right Parenthesis", h2),
ListFlowable(
[Paragraph(s, normal) for s in [
"First item",
"Second one",
]],
bulletType="a",
bulletFormat="%s)", # ←
),
Paragraph(
"Note that we must also change the bulletType here to get a sequence using "
"letters instead of numbers.",
body,
),
Paragraph("Second Tetration", h2),
ListFlowable(
[Paragraph(s, normal) for s in [
"One to the power one",
"Two to the power two",
"Three to the power three",
]],
leftIndent=48,
bulletFormat=second_tetration, # ←
),
Paragraph(
"""
Here the bullet is changed to its second tetration; which is to say 'n to
the power n'. Unlikely you want this, but a demonstration that your imagination
is the limit here. Note that to really make use of this functionality you
will have to play about with fonts and styles to ensure whatever characters
you're returning have glyphs that can be rendered. Hint: grab a copy of
<link href="https://www.gnu.org/software/freefont/">GNU FreeFont</link>.
""",
body,
),
]
doc.build(story)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment