Skip to content

Commit d205f76

Browse files
committed
add pdf download and correct editor function
1 parent 87ee523 commit d205f76

5 files changed

Lines changed: 164 additions & 6 deletions

File tree

bun.lock

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"class-variance-authority": "^0.7.1",
3737
"clsx": "^2.1.1",
3838
"form-data": "4.0.5",
39+
"jspdf": "^3.0.4",
3940
"lucide-react": "^0.563.0",
4041
"next-themes": "^0.4.6",
4142
"react": "^19.1.1",

frontend/src/lib/pdf.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
function sanitizeFilename(input: string): string {
2+
return input
3+
.trim()
4+
.replace(/[\\/:*?"<>|]+/g, "-")
5+
.replace(/\s+/g, " ")
6+
.slice(0, 80)
7+
}
8+
9+
export async function downloadTextAsPdf(params: {
10+
title: string
11+
body: string
12+
subtitle?: string
13+
}) {
14+
const { jsPDF } = await import("jspdf")
15+
const { title, body, subtitle } = params
16+
const doc = new jsPDF({ unit: "pt", format: "a4" })
17+
18+
const marginX = 48
19+
const marginTop = 56
20+
const marginBottom = 48
21+
const pageWidth = doc.internal.pageSize.getWidth()
22+
const pageHeight = doc.internal.pageSize.getHeight()
23+
const usableWidth = pageWidth - marginX * 2
24+
const maxY = pageHeight - marginBottom
25+
26+
let y = marginTop
27+
28+
const ensureSpace = (height: number) => {
29+
if (y + height <= maxY) {
30+
return
31+
}
32+
doc.addPage()
33+
y = marginTop
34+
}
35+
36+
doc.setFont("helvetica", "bold")
37+
doc.setFontSize(16)
38+
ensureSpace(22)
39+
doc.text(title || "Generation", marginX, y)
40+
y += 24
41+
42+
if (subtitle) {
43+
doc.setFont("helvetica", "normal")
44+
doc.setFontSize(10)
45+
doc.setTextColor(100)
46+
ensureSpace(14)
47+
doc.text(subtitle, marginX, y)
48+
y += 20
49+
doc.setTextColor(0)
50+
}
51+
52+
doc.setFont("helvetica", "normal")
53+
doc.setFontSize(11)
54+
55+
const paragraphs = body.split(/\r?\n/)
56+
for (const paragraph of paragraphs) {
57+
if (!paragraph.trim()) {
58+
ensureSpace(12)
59+
y += 12
60+
continue
61+
}
62+
63+
const lines = doc.splitTextToSize(paragraph, usableWidth) as string[]
64+
for (const line of lines) {
65+
ensureSpace(14)
66+
doc.text(line, marginX, y)
67+
y += 14
68+
}
69+
ensureSpace(6)
70+
y += 6
71+
}
72+
73+
const filenameBase =
74+
sanitizeFilename(title || "generation-output") || "generation-output"
75+
doc.save(`${filenameBase}.pdf`)
76+
}

0 commit comments

Comments
 (0)