')
+ entete = html[deb:html.index("
Dear ")]
+ html = html[:deb] + entete + f"
Dear {o.prenom},
\n\n" + corps + "\n\n" + html[fin:]
+
+ tmp = pathlib.Path(o.sortie).with_suffix(".html")
+ tmp.write_text(html, encoding="utf-8")
+ r = subprocess.run(["weasyprint", str(tmp), o.sortie])
+ if r.returncode == 0 and not o.garder_html:
+ tmp.unlink()
+ if r.returncode == 0:
+ pages = subprocess.run(["pdfinfo", o.sortie], capture_output=True, text=True).stdout
+ n = next((l.split()[1] for l in pages.splitlines() if l.startswith("Pages")), "?")
+ print(f"ok — {o.sortie} ({n} page(s))")
+ if n not in ("1", "2"):
+ print(" ATTENTION : au-delà de deux pages, une lettre d'affaires se lit mal. "
+ "Resserrer le corps plutôt que la typographie.", file=sys.stderr)
+ return r.returncode
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/correspondance/lettre.template.html b/correspondance/lettre.template.html
new file mode 100644
index 0000000..f1b47c7
--- /dev/null
+++ b/correspondance/lettre.template.html
@@ -0,0 +1,102 @@
+
+
{{TITRE}} — Arcodange
+
+
+
+
+
+ SARL au capital de 1 000 € — SIREN 999 657 455 R.C.S. Évry
+ 73 boulevard de l'Yerres, 91000 Évry-Courcouronnes, France
+ VAT FR00 999 657 455 — gabrielradureau@arcodange.fr
+
+
+
+
+ To
+ {{DESTINATAIRE}} — {{FONCTION}}, {{SOCIETE}}
+ {{ADRESSE}}
+ cc {{COPIE}}
+
+
+
{{TITRE}}
+
{{DATE}}
+
+
Dear {{PRENOM}},
+
+
+
+
1 — Une section
+
+
Corps de texte en Charter. Les montants et les points qui
+portent la décision se mettent en gras ; les citations en italique.
+
+
+
Une question posée franchement se met dans
+un encadré gris — elle ne doit pas se noyer dans un paragraphe.
+
+
+
+
L'encadré rouge sourd est réservé à ce qui doit être lu
+même en diagonale. Un par lettre, pas deux.
+
+
+
+
Gabriel
Radureau
+
Gérant — Arcodange
+
+
+
diff --git a/test/emoji2png.ts b/test/emoji2png.ts
new file mode 100644
index 0000000..5430865
--- /dev/null
+++ b/test/emoji2png.ts
@@ -0,0 +1,16 @@
+// Rend un emoji en PNG transparent via Chromium, qui sait lire Apple Color
+// Emoji là où weasyprint échoue (format bitmap sbix, non géré).
+import { chromium } from "playwright";
+const [outDir, ...emojis] = Deno.args;
+const b = await chromium.launch({ headless: true });
+const p = await (await b.newContext({ deviceScaleFactor: 8 })).newPage();
+for (const [i, e] of emojis.entries()) {
+ await p.setContent(
+ `
${e}`);
+ const el = p.locator("#g");
+ const f = `${outDir}/emoji-${i + 1}.png`;
+ await el.screenshot({ path: f, omitBackground: true });
+ console.log(` ${e} -> ${f}`);
+}
+await b.close();