465 lines
22 KiB
Python
465 lines
22 KiB
Python
"""
|
||
Website Taal-, Consistentie- & LLM-analyse — PDF Rapport Generator
|
||
====================================================================
|
||
Gebruik dit script als startpunt. Vervang de inhoud van BEVINDINGEN
|
||
met de werkelijk gevonden actiepunten. De stijlfuncties en layoutlogica
|
||
hoef je niet aan te passen.
|
||
|
||
Gebruik:
|
||
pip install reportlab --break-system-packages -q
|
||
python rapport_generator.py
|
||
"""
|
||
|
||
from reportlab.lib.pagesizes import A4
|
||
from reportlab.lib.styles import ParagraphStyle
|
||
from reportlab.lib.units import cm
|
||
from reportlab.lib import colors
|
||
from reportlab.platypus import (
|
||
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
|
||
HRFlowable, KeepTogether, PageBreak
|
||
)
|
||
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
|
||
from datetime import date
|
||
import os
|
||
|
||
# ── Configuratie — pas dit aan per opdracht ───────────────────────────────────
|
||
MERKNAAM = "HelloPrint" # Merknaam van de geanalyseerde site
|
||
DOMEINNAAM = "helloprint.com/nl-nl" # Domein / pad
|
||
DOELGROEP = "B2B klein zakelijk (tot 10 medewerkers)"
|
||
LOCALE = "nl-NL"
|
||
OUTPUT = f"/mnt/user-data/outputs/{MERKNAAM}_Taal_Consistentie_LLM_{date.today().strftime('%Y%m%d')}.pdf"
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
doc = SimpleDocTemplate(
|
||
OUTPUT, pagesize=A4,
|
||
rightMargin=2.2*cm, leftMargin=2.2*cm,
|
||
topMargin=2.5*cm, bottomMargin=2.5*cm,
|
||
)
|
||
|
||
# ── Kleurenpalet ──────────────────────────────────────────────────────────────
|
||
GROEN = colors.HexColor("#1a6b2f")
|
||
GROEN_L = colors.HexColor("#eaf5ec")
|
||
BLAUW = colors.HexColor("#1a3a6b")
|
||
BLAUW_L = colors.HexColor("#e8eef5")
|
||
PAARS = colors.HexColor("#5b2d8e")
|
||
PAARS_L = colors.HexColor("#f3eefb")
|
||
TEAL = colors.HexColor("#0e6b5e")
|
||
TEAL_L = colors.HexColor("#e6f4f2")
|
||
ROOD = colors.HexColor("#b03030")
|
||
ROOD_L = colors.HexColor("#fdf0ee")
|
||
ORANJE = colors.HexColor("#c05c00")
|
||
ORANJE_L = colors.HexColor("#fef5e7")
|
||
DONKER = colors.HexColor("#1a1a1a")
|
||
GRIJS = colors.HexColor("#f4f4f4")
|
||
GRIJS2 = colors.HexColor("#e8e8e8")
|
||
LICHT = colors.HexColor("#777777")
|
||
WIT = colors.white
|
||
|
||
# ── Stijlen ───────────────────────────────────────────────────────────────────
|
||
def ps(name, **kw):
|
||
return ParagraphStyle(name, **kw)
|
||
|
||
BODY = ps("B", fontSize=9.5, leading=14, fontName="Helvetica", textColor=DONKER, spaceAfter=4)
|
||
SMALL = ps("S", fontSize=8.5, leading=12, fontName="Helvetica", textColor=LICHT)
|
||
H1 = ps("H1", fontSize=13, leading=17, fontName="Helvetica-Bold", textColor=BLAUW, spaceBefore=16, spaceAfter=5)
|
||
H2 = ps("H2", fontSize=10.5,leading=14, fontName="Helvetica-Bold", textColor=DONKER, spaceBefore=8, spaceAfter=3)
|
||
|
||
# ── Thema- en prioriteitsconfiguratie ─────────────────────────────────────────
|
||
THEMA = {
|
||
"TAAL": (BLAUW, BLAUW_L, "T"),
|
||
"CONSISTENTIE": (GROEN, GROEN_L, "C"),
|
||
"LLM": (PAARS, PAARS_L, "L"),
|
||
"NAV": (TEAL, TEAL_L, "N"),
|
||
}
|
||
PRIO = {
|
||
"HOOG": ROOD,
|
||
"MIDDEL": ORANJE,
|
||
"LAAG": GROEN,
|
||
}
|
||
_tellers = {k: 0 for k in THEMA}
|
||
|
||
|
||
def omslagrij(tekst, stijlkw, achtergrond):
|
||
"""Eén gekleurde rij voor het omslagblok."""
|
||
t = Table([[Paragraph(tekst, ps(f"omslag_{hash(tekst)}", **stijlkw))]], colWidths=[17*cm])
|
||
t.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,-1), achtergrond),
|
||
("TOPPADDING", (0,0), (-1,-1), 6),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 6),
|
||
("LEFTPADDING", (0,0), (-1,-1), 20),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 20),
|
||
]))
|
||
return t
|
||
|
||
|
||
def actiepunt(thema, prio, titel, probleem, vindplaats, actie):
|
||
"""
|
||
Geeft een opgemaakte actiepunt-blok terug als ReportLab Flowable.
|
||
|
||
Parameters
|
||
----------
|
||
thema : "TAAL" | "CONSISTENTIE" | "LLM" | "NAV"
|
||
prio : "HOOG" | "MIDDEL" | "LAAG"
|
||
titel : Korte probleemtitel (string)
|
||
probleem : Uitleg van het probleem (mag HTML-tags bevatten)
|
||
vindplaats : Exacte locatie op de pagina
|
||
actie : Concreet advies (mag HTML-tags bevatten)
|
||
"""
|
||
_tellers[thema] += 1
|
||
nr = _tellers[thema]
|
||
tk, tl, afk = THEMA[thema]
|
||
pk = PRIO[prio]
|
||
|
||
uid = f"{thema}{nr}"
|
||
|
||
def badge(tekst, breedte, achtergrond):
|
||
t = Table([[Paragraph(f"<b>{tekst}</b>",
|
||
ps(f"bdg_{uid}_{tekst}", fontSize=8, fontName="Helvetica-Bold",
|
||
textColor=WIT, leading=10, alignment=TA_CENTER))]],
|
||
colWidths=[breedte])
|
||
t.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,-1), achtergrond),
|
||
("TOPPADDING", (0,0), (-1,-1), 4),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 4),
|
||
("LEFTPADDING", (0,0), (-1,-1), 2),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 2),
|
||
("ROUNDEDCORNERS", [3]),
|
||
]))
|
||
return t
|
||
|
||
labels = Table([[badge(f"{afk}{nr}", 0.9*cm, tk),
|
||
Spacer(0.25*cm, 1),
|
||
badge(prio, 1.4*cm, pk)]],
|
||
colWidths=[1*cm, 0.35*cm, 1.5*cm])
|
||
labels.setStyle(TableStyle([
|
||
("TOPPADDING", (0,0), (-1,-1), 0),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 0),
|
||
("LEFTPADDING", (0,0), (-1,-1), 0),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 0),
|
||
]))
|
||
|
||
inhoud = [
|
||
Paragraph(f"<b>{titel}</b>",
|
||
ps(f"ti_{uid}", fontSize=10.5, fontName="Helvetica-Bold",
|
||
textColor=DONKER, leading=14, spaceAfter=3)),
|
||
Paragraph(f"<b>Probleem:</b> {probleem}",
|
||
ps(f"pr_{uid}", fontSize=9, fontName="Helvetica",
|
||
textColor=DONKER, leading=13, spaceAfter=2)),
|
||
Paragraph(f"<b>Vindplaats:</b> {vindplaats}",
|
||
ps(f"vp_{uid}", fontSize=8.5, fontName="Helvetica",
|
||
textColor=LICHT, leading=12, spaceAfter=3)),
|
||
Paragraph(f"\u25B8 <b>Actie:</b> {actie}",
|
||
ps(f"ac_{uid}", fontSize=9, fontName="Helvetica-Bold",
|
||
textColor=tk, leading=13)),
|
||
]
|
||
|
||
blok = Table([[labels, inhoud]], colWidths=[3.1*cm, 13.9*cm])
|
||
blok.setStyle(TableStyle([
|
||
("VALIGN", (0,0), (-1,-1), "TOP"),
|
||
("BACKGROUND", (0,0), (-1,-1), tl),
|
||
("TOPPADDING", (0,0), (-1,-1), 10),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 10),
|
||
("LEFTPADDING", (0,0), (-1,-1), 10),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 10),
|
||
("ROUNDEDCORNERS", [5]),
|
||
]))
|
||
return KeepTogether([blok, Spacer(1, 7)])
|
||
|
||
|
||
def nav_tabel(items, kolombreedtes=(3.2*cm, 1.3*cm, 12.5*cm)):
|
||
"""
|
||
Geeft een opgemaakte navigatiebeoordelingstabel terug.
|
||
|
||
items = lijst van tuples:
|
||
(nav_naam, symbool, kleur, toelichting)
|
||
symbool: "✓" | "△" | "✗"
|
||
kleur: GROEN | ORANJE | ROOD
|
||
"""
|
||
data = [[
|
||
Paragraph("<b>Menu-item</b>",
|
||
ps("nv_h1", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12)),
|
||
Paragraph("<b>Oordeel</b>",
|
||
ps("nv_h2", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
Paragraph("<b>Toelichting</b>",
|
||
ps("nv_h3", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12)),
|
||
]]
|
||
for naam, symbool, kleur, toelichting in items:
|
||
uid = naam.replace(" ", "_")
|
||
data.append([
|
||
Paragraph(f"<b>{naam}</b>",
|
||
ps(f"nv_naam_{uid}", fontSize=9, fontName="Helvetica-Bold", textColor=DONKER, leading=12)),
|
||
Paragraph(symbool,
|
||
ps(f"nv_sym_{uid}", fontSize=11, fontName="Helvetica-Bold",
|
||
textColor=kleur, leading=14, alignment=TA_CENTER)),
|
||
Paragraph(toelichting,
|
||
ps(f"nv_toe_{uid}", fontSize=8.5, fontName="Helvetica", textColor=DONKER, leading=12)),
|
||
])
|
||
t = Table(data, colWidths=list(kolombreedtes))
|
||
t.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,0), BLAUW),
|
||
("ROWBACKGROUNDS", (0,1), (-1,-1), [WIT, GRIJS]),
|
||
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#dddddd")),
|
||
("TOPPADDING", (0,0), (-1,-1), 7),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 7),
|
||
("LEFTPADDING", (0,0), (-1,-1), 8),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 8),
|
||
("VALIGN", (0,0), (-1,-1), "TOP"),
|
||
]))
|
||
return t
|
||
|
||
|
||
def mapping_tabel(rijen, header_kleur=TEAL):
|
||
"""
|
||
Vergelijkingstabel nav-item vs. pagina-naam vs. status.
|
||
|
||
rijen = lijst van tuples:
|
||
(nav_naam, pagina_naam, status_tekst, status_kleur)
|
||
"""
|
||
data = [[
|
||
Paragraph("<b>Nav-item</b>",
|
||
ps("mp_h1", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12)),
|
||
Paragraph("<b>Naam op overzichtspagina</b>",
|
||
ps("mp_h2", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12)),
|
||
Paragraph("<b>Status</b>",
|
||
ps("mp_h3", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
]]
|
||
for nav, pagina, status, kleur in rijen:
|
||
uid = nav.replace(" ", "_")
|
||
data.append([
|
||
Paragraph(nav, ps(f"mp_n_{uid}", fontSize=9, fontName="Helvetica-Bold", textColor=DONKER, leading=12)),
|
||
Paragraph(pagina, ps(f"mp_p_{uid}", fontSize=9, fontName="Helvetica", textColor=DONKER, leading=12)),
|
||
Paragraph(status, ps(f"mp_s_{uid}", fontSize=8.5, fontName="Helvetica-Bold",
|
||
textColor=kleur, leading=12, alignment=TA_CENTER)),
|
||
])
|
||
t = Table(data, colWidths=[3.5*cm, 7.5*cm, 6*cm])
|
||
t.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,0), header_kleur),
|
||
("ROWBACKGROUNDS", (0,1), (-1,-1), [WIT, GRIJS]),
|
||
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#dddddd")),
|
||
("TOPPADDING", (0,0), (-1,-1), 7),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 7),
|
||
("LEFTPADDING", (0,0), (-1,-1), 8),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 8),
|
||
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
|
||
]))
|
||
return t
|
||
|
||
|
||
def prioriteitsmatrix(acties):
|
||
"""
|
||
Slottabel met alle actiepunten, thema, impact en doorlooptijd.
|
||
|
||
acties = lijst van tuples:
|
||
(nr, omschrijving, thema_label, impact_kleur, doorlooptijd)
|
||
"""
|
||
data = [[
|
||
Paragraph("<b>#</b>", ps("pm_h0", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
Paragraph("<b>Actie</b>", ps("pm_h1", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12)),
|
||
Paragraph("<b>Thema</b>", ps("pm_h2", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
Paragraph("<b>Impact</b>", ps("pm_h3", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
Paragraph("<b>Doorlooptijd</b>", ps("pm_h4", fontSize=9, textColor=WIT, fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)),
|
||
]]
|
||
for nr, omschr, thema_lbl, impact_kleur, tijd in acties:
|
||
data.append([
|
||
Paragraph(str(nr), ps(f"pm_nr_{nr}", fontSize=9, fontName="Helvetica-Bold", textColor=DONKER, leading=12, alignment=TA_CENTER)),
|
||
Paragraph(omschr, ps(f"pm_om_{nr}", fontSize=9, fontName="Helvetica", textColor=DONKER, leading=13)),
|
||
Paragraph(thema_lbl, ps(f"pm_th_{nr}", fontSize=8.5, fontName="Helvetica", textColor=LICHT, leading=12, alignment=TA_CENTER)),
|
||
Paragraph("■", ps(f"pm_ic_{nr}", fontSize=12, fontName="Helvetica-Bold", textColor=impact_kleur, leading=14, alignment=TA_CENTER)),
|
||
Paragraph(tijd, ps(f"pm_ti_{nr}", fontSize=8.5, fontName="Helvetica", textColor=LICHT, leading=12, alignment=TA_CENTER)),
|
||
])
|
||
t = Table(data, colWidths=[0.8*cm, 9.2*cm, 2.4*cm, 1.8*cm, 2.8*cm])
|
||
t.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,0), BLAUW),
|
||
("ROWBACKGROUNDS", (0,1), (-1,-1), [WIT, GRIJS]),
|
||
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#e0e0e0")),
|
||
("TOPPADDING", (0,0), (-1,-1), 6),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 6),
|
||
("LEFTPADDING", (0,0), (-1,-1), 7),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 7),
|
||
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
|
||
]))
|
||
return t
|
||
|
||
|
||
# ══════════════════════════════════════════════════════════════════════════════
|
||
# RAPPORT — pas de inhoud hieronder aan per opdracht
|
||
# ══════════════════════════════════════════════════════════════════════════════
|
||
|
||
story = []
|
||
|
||
# ── Omslag ────────────────────────────────────────────────────────────────────
|
||
story.append(omslagrij(
|
||
"Analyse rapport",
|
||
dict(fontSize=9.5, fontName="Helvetica", textColor=colors.HexColor("#a8c0e0"), leading=14),
|
||
BLAUW))
|
||
story.append(omslagrij(
|
||
"Taal • Consistentie • LLM-vindbaarheid",
|
||
dict(fontSize=24, fontName="Helvetica-Bold", textColor=WIT, leading=30),
|
||
BLAUW))
|
||
story.append(omslagrij(
|
||
f"{DOMEINNAAM} | Doelgroep: {DOELGROEP} | Locale: {LOCALE}",
|
||
dict(fontSize=10, fontName="Helvetica", textColor=colors.HexColor("#9ab8d8"), leading=14),
|
||
BLAUW))
|
||
|
||
story.append(Spacer(1, 4))
|
||
|
||
meta = Table([[
|
||
Paragraph(f"Datum: {date.today().strftime('%d %B %Y')}", SMALL),
|
||
Paragraph(f"Pagina: {DOMEINNAAM}", SMALL),
|
||
Paragraph("Opgesteld door: Claude (Anthropic)", SMALL),
|
||
]], colWidths=[5.5*cm, 6.5*cm, 5*cm])
|
||
meta.setStyle(TableStyle([
|
||
("BACKGROUND", (0,0), (-1,-1), GRIJS),
|
||
("TOPPADDING", (0,0), (-1,-1), 7),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 7),
|
||
("LEFTPADDING", (0,0), (-1,-1), 8),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 8),
|
||
]))
|
||
story.append(meta)
|
||
story.append(Spacer(1, 14))
|
||
|
||
story.append(Paragraph(
|
||
f"Dit rapport analyseert {DOMEINNAAM} op taal, consistentie en LLM-vindbaarheid. "
|
||
f"De primaire doelgroep is {DOELGROEP.lower()}. "
|
||
"Elk knelpunt heeft een concreet actiepunt met vindplaats en aanbeveling.",
|
||
BODY))
|
||
story.append(Spacer(1, 10))
|
||
|
||
# ── SECTIE 1 — TAAL ───────────────────────────────────────────────────────────
|
||
story.append(Paragraph("1 Taal — zuiverheid en geschiktheid voor de doelgroep", H1))
|
||
story.append(HRFlowable(width="100%", thickness=1.5, color=BLAUW, spaceAfter=8))
|
||
story.append(Paragraph(
|
||
"Vul hier een korte inleiding in over de algemene taalstijl van de geanalyseerde pagina.",
|
||
BODY))
|
||
story.append(Spacer(1, 8))
|
||
|
||
# Voeg hier actiepunten toe met de actiepunt()-functie:
|
||
story.append(actiepunt(
|
||
"TAAL", "HOOG",
|
||
"Titel van het taalprobleem",
|
||
"Beschrijving van het probleem. Waarom is dit een probleem voor de doelgroep?",
|
||
"Exacte locatie op de pagina (bijv. 'Hoofdnavigatie — item 3', '<title>-tag', 'H1-heading')",
|
||
"Concreet advies. Geef bij voorkeur een voorbeeldtekst: 'Vervang X door Y.'"))
|
||
|
||
# ── SECTIE 2 — MENUNAMEN ──────────────────────────────────────────────────────
|
||
story.append(Paragraph("2 Menunamen — helderheid voor de bezoeker", H1))
|
||
story.append(HRFlowable(width="100%", thickness=1.5, color=BLAUW, spaceAfter=8))
|
||
story.append(Paragraph(
|
||
"Beoordeling van elk navigatie-item vanuit het perspectief van de doelgroep.",
|
||
BODY))
|
||
story.append(Spacer(1, 8))
|
||
|
||
# Voorbeeld nav_tabel() — pas items aan op basis van de geanalyseerde navigatie:
|
||
story.append(nav_tabel([
|
||
("Menu-item 1", "✓", GROEN, "Helder en herkenbaar."),
|
||
("Menu-item 2", "△", ORANJE, "Dubbelzinnig of te vaag. Toelichting."),
|
||
("Menu-item 3", "✗", ROOD, "Problematisch. Reden + aanbeveling."),
|
||
]))
|
||
|
||
story.append(Spacer(1, 10))
|
||
|
||
# ── SECTIE 3 — CONSISTENTIE ───────────────────────────────────────────────────
|
||
story.append(Paragraph("3 Consistentie — toon, aanspreekvorm en categorienamen", H1))
|
||
story.append(HRFlowable(width="100%", thickness=1.5, color=BLAUW, spaceAfter=8))
|
||
story.append(Paragraph("Inleiding consistentie.", BODY))
|
||
story.append(Spacer(1, 8))
|
||
|
||
story.append(actiepunt(
|
||
"CONSISTENTIE", "HOOG",
|
||
"Consistentieprobleem",
|
||
"Beschrijving.", "Vindplaats.", "Actie."))
|
||
|
||
# ── SECTIE 4 — LLM-VINDBAARHEID ───────────────────────────────────────────────
|
||
story.append(Paragraph("4 LLM-vindbaarheid", H1))
|
||
story.append(HRFlowable(width="100%", thickness=1.5, color=BLAUW, spaceAfter=8))
|
||
story.append(Paragraph("Inleiding LLM.", BODY))
|
||
story.append(Spacer(1, 8))
|
||
|
||
story.append(actiepunt(
|
||
"LLM", "HOOG",
|
||
"LLM-probleem",
|
||
"Beschrijving.", "Vindplaats.", "Actie."))
|
||
|
||
# ── SECTIE 5 — NAVIGATIESTRUCTUUR (optioneel) ─────────────────────────────────
|
||
# Voeg deze sectie toe als je ook een overzichts-/categoriepagina hebt geanalyseerd.
|
||
#
|
||
# story.append(PageBreak())
|
||
# story.append(Paragraph("5 Navigatiestructuur — nav vs. overzichtspagina", H1))
|
||
# story.append(HRFlowable(width="100%", thickness=1.5, color=TEAL, spaceAfter=8))
|
||
# story.append(Paragraph("5.1 Naamvergelijking", H2))
|
||
# story.append(mapping_tabel([
|
||
# ("Nav-item 1", "Paginanaam 1", "✓ Consistent", GROEN),
|
||
# ("Nav-item 2", "Andere naam op pagina", "✗ Mismatch", ROOD),
|
||
# ("Nav-item 3", "Subcategorie onder 'Overig'", "△ Inconsistent", ORANJE),
|
||
# ]))
|
||
|
||
# ── SECTIE 6 — PRIORITEITSOVERZICHT ──────────────────────────────────────────
|
||
story.append(PageBreak())
|
||
story.append(Paragraph("Prioriteitsoverzicht — wat als eerste aanpakken", H1))
|
||
story.append(HRFlowable(width="100%", thickness=1.5, color=BLAUW, spaceAfter=10))
|
||
|
||
# Vul aan met alle actiepunten uit het rapport:
|
||
story.append(prioriteitsmatrix([
|
||
("1", "Omschrijving actie 1", "TAAL", ROOD, "1 dag"),
|
||
("2", "Omschrijving actie 2", "CONS", ROOD, "1 dag"),
|
||
("3", "Omschrijving actie 3", "LLM", ROOD, "1–2 wkn"),
|
||
("4", "Omschrijving actie 4", "NAV", ORANJE, "1 week"),
|
||
("5", "Omschrijving actie 5", "LLM", GROEN, "Doorlopend"),
|
||
]))
|
||
|
||
story.append(Spacer(1, 8))
|
||
|
||
# Legenda
|
||
legenda_impact = Table([[
|
||
Paragraph("■ Hoog — direct zichtbaar, groot effect",
|
||
ps("leg1", fontSize=8.5, fontName="Helvetica", textColor=ROOD, leading=12)),
|
||
Paragraph("■ Middel — merkbaar effect, planbaar",
|
||
ps("leg2", fontSize=8.5, fontName="Helvetica", textColor=ORANJE, leading=12)),
|
||
Paragraph("■ Laag — finetuning / continu",
|
||
ps("leg3", fontSize=8.5, fontName="Helvetica", textColor=GROEN, leading=12)),
|
||
]], colWidths=[6*cm, 6*cm, 5*cm])
|
||
legenda_impact.setStyle(TableStyle([
|
||
("TOPPADDING", (0,0), (-1,-1), 0),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 0),
|
||
("LEFTPADDING", (0,0), (-1,-1), 0),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 0),
|
||
]))
|
||
story.append(legenda_impact)
|
||
story.append(Spacer(1, 10))
|
||
|
||
legenda_thema = Table([[
|
||
Paragraph("T = Taal", ps("lt1", fontSize=8.5, fontName="Helvetica", textColor=BLAUW, leading=12)),
|
||
Paragraph("C = Consistentie", ps("lt2", fontSize=8.5, fontName="Helvetica", textColor=GROEN, leading=12)),
|
||
Paragraph("L = LLM", ps("lt3", fontSize=8.5, fontName="Helvetica", textColor=PAARS, leading=12)),
|
||
Paragraph("N = Navigatie", ps("lt4", fontSize=8.5, fontName="Helvetica", textColor=TEAL, leading=12)),
|
||
]], colWidths=[4*cm, 4*cm, 4*cm, 5*cm])
|
||
legenda_thema.setStyle(TableStyle([
|
||
("TOPPADDING", (0,0), (-1,-1), 0),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 0),
|
||
("LEFTPADDING", (0,0), (-1,-1), 0),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 0),
|
||
]))
|
||
story.append(legenda_thema)
|
||
story.append(Spacer(1, 20))
|
||
|
||
# ── Footer ────────────────────────────────────────────────────────────────────
|
||
story.append(HRFlowable(width="100%", thickness=0.8, color=GRIJS2, spaceAfter=8))
|
||
footer_t = Table([[
|
||
Paragraph(f"{MERKNAAM} — Taal, Consistentie & LLM-vindbaarheid — Vertrouwelijk", SMALL),
|
||
Paragraph(f"Opgesteld {date.today().strftime('%d-%m-%Y')} | Claude (Anthropic)",
|
||
ps("footer_r", fontSize=8, textColor=LICHT, fontName="Helvetica",
|
||
leading=11, alignment=TA_RIGHT)),
|
||
]], colWidths=[9*cm, 8*cm])
|
||
footer_t.setStyle(TableStyle([
|
||
("TOPPADDING", (0,0), (-1,-1), 0),
|
||
("BOTTOMPADDING", (0,0), (-1,-1), 0),
|
||
("LEFTPADDING", (0,0), (-1,-1), 0),
|
||
("RIGHTPADDING", (0,0), (-1,-1), 0),
|
||
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
|
||
]))
|
||
story.append(footer_t)
|
||
|
||
# ── Bouw PDF ──────────────────────────────────────────────────────────────────
|
||
doc.build(story)
|
||
print(f"PDF klaar: {OUTPUT}")
|