diff --git a/src/lib/docx-pleading.ts b/src/lib/docx-pleading.ts index a2fd1e9..062bc81 100644 --- a/src/lib/docx-pleading.ts +++ b/src/lib/docx-pleading.ts @@ -316,8 +316,16 @@ export function buildPleadingDoc(input: PleadingInput): Document { const bodyParagraphs: Paragraph[] = []; if (input.title) { + // Render title as one centered paragraph per manual line; underline only the last line. bodyParagraphs.push(emptyP()); - bodyParagraphs.push(p(input.title.toUpperCase(), { bold: true, align: AlignmentType.CENTER })); + const segments = input.title.toUpperCase().split("\n"); + const lastIdx = segments.length - 1; + segments.forEach((seg, i) => { + bodyParagraphs.push(new Paragraph({ + alignment: AlignmentType.CENTER, + children: [run(seg, { bold: true, underline: i === lastIdx })], + })); + }); bodyParagraphs.push(emptyP()); } if (input.bodyHtml && input.bodyHtml.trim()) { diff --git a/src/lib/pdf-pleading.ts b/src/lib/pdf-pleading.ts index f368e2f..afa29f9 100644 --- a/src/lib/pdf-pleading.ts +++ b/src/lib/pdf-pleading.ts @@ -258,10 +258,22 @@ export async function downloadPleadingPdf(input: PleadingInput, filename: string y = captionEndY + LINE_H; if (input.title) { - ensureSpace(LINE_H * 2); setFont(pdf, { bold: true }); - pdf.text(input.title.toUpperCase(), PAGE_W / 2, y, { align: "center" }); - y += LINE_H * 1.5; + const titleText = input.title.toUpperCase(); + const titleLines = pdf.splitTextToSize(titleText, CONTENT_W) as string[]; + ensureSpace(LINE_H * (titleLines.length + 2)); + y += LINE_H; // one blank line before title + titleLines.forEach((line, i) => { + const isLast = i === titleLines.length - 1; + pdf.text(line, PAGE_W / 2, y, { align: "center" }); + if (isLast) { + const tw = pdf.getTextWidth(line); + pdf.setLineWidth(0.6); + pdf.line((PAGE_W - tw) / 2, y + 1.5, (PAGE_W + tw) / 2, y + 1.5); + } + y += LINE_H; + }); + y += LINE_H; // one blank line after title } setFont(pdf, {}); // reset to non-bold for body