Patient leaf let
/home/daytona/workspace
mkdir -p /home/daytona/workspace/patient-leaflet
~/patient-leaflet/create_leaflet.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
HeadingLevel, AlignmentType, LevelFormat, BorderStyle, WidthType,
ShadingType, VerticalAlign, PageNumber, UnderlineType
} = require('docx');
const fs = require('fs');
// ─── Colour palette ───────────────────────────────────────────────────────────
const TEAL = "0077A8"; // header / section title backgrounds
const LTBLUE = "E8F4FA"; // light info box background
const WHITE = "FFFFFF";
const DARK = "1A1A1A";
const ORANGE = "E05C00"; // warning highlight
// ─── Helper: bold coloured run ────────────────────────────────────────────────
const boldRun = (text, color = DARK, size = 24) =>
new TextRun({ text, bold: true, color, size, font: "Arial" });
const normalRun = (text, color = DARK, size = 22) =>
new TextRun({ text, color, size, font: "Arial" });
const italicRun = (text, color = "555555", size = 20) =>
new TextRun({ text, italics: true, color, size, font: "Arial" });
// ─── Helper: section heading paragraph ───────────────────────────────────────
const sectionHeading = (text) =>
new Paragraph({
spacing: { before: 200, after: 100 },
shading: { type: ShadingType.SOLID, color: TEAL, fill: TEAL },
indent: { left: 200, right: 200 },
children: [
new TextRun({ text: " " + text + " ", bold: true, color: WHITE, size: 26, font: "Arial" })
]
});
// ─── Helper: bullet paragraph ────────────────────────────────────────────────
const bullet = (text, bold_part = "", rest = "") =>
new Paragraph({
numbering: { reference: "bullets", level: 0 },
spacing: { before: 60, after: 60 },
children: bold_part
? [boldRun(bold_part), normalRun(rest)]
: [normalRun(text)]
});
// ─── Helper: plain paragraph ─────────────────────────────────────────────────
const para = (text, align = AlignmentType.LEFT, spacing_after = 120) =>
new Paragraph({
alignment: align,
spacing: { before: 60, after: spacing_after },
children: [normalRun(text)]
});
// ─── Helper: info box (shaded table) ─────────────────────────────────────────
const infoBox = (heading, lines) =>
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
margins: { top: 80, bottom: 80, left: 160, right: 160 },
borders: {
top: { style: BorderStyle.SINGLE, size: 8, color: TEAL },
bottom: { style: BorderStyle.SINGLE, size: 8, color: TEAL },
left: { style: BorderStyle.SINGLE, size: 8, color: TEAL },
right: { style: BorderStyle.SINGLE, size: 8, color: TEAL },
},
rows: [
new TableRow({ children: [
new TableCell({
shading: { type: ShadingType.SOLID, color: LTBLUE, fill: LTBLUE },
verticalAlign: VerticalAlign.CENTER,
children: [
new Paragraph({ spacing: { before: 60, after: 80 }, children: [
boldRun(heading, TEAL, 24)
]}),
...lines.map(l =>
new Paragraph({ spacing: { before: 40, after: 40 }, children: [normalRun(l)] })
)
]
})
]})
]
});
// ─── Helper: warning box ─────────────────────────────────────────────────────
const warningBox = (heading, lines) =>
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 8, color: ORANGE },
bottom: { style: BorderStyle.SINGLE, size: 8, color: ORANGE },
left: { style: BorderStyle.THICK, size: 16, color: ORANGE },
right: { style: BorderStyle.SINGLE, size: 8, color: ORANGE },
},
rows: [
new TableRow({ children: [
new TableCell({
shading: { type: ShadingType.SOLID, color: "FFF3EC", fill: "FFF3EC" },
children: [
new Paragraph({ spacing: { before: 60, after: 80 }, children: [
new TextRun({ text: "⚠ " + heading, bold: true, color: ORANGE, size: 24, font: "Arial" })
]}),
...lines.map(l =>
new Paragraph({ spacing: { before: 40, after: 40 }, children: [normalRun(l)] })
)
]
})
]})
]
});
// ─── Spacer ───────────────────────────────────────────────────────────────────
const spacer = (pts = 80) =>
new Paragraph({ spacing: { before: pts, after: 0 }, children: [new TextRun("")] });
// ─── Document ─────────────────────────────────────────────────────────────────
const doc = new Document({
numbering: {
config: [
{
reference: "bullets",
levels: [{
level: 0, format: LevelFormat.BULLET, text: "\u2022",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 480, hanging: 240 } } }
}]
}
]
},
styles: {
default: {
document: { run: { font: "Arial", size: 22, color: DARK } }
}
},
sections: [{
properties: {
page: {
margin: { top: 720, bottom: 720, left: 900, right: 900 }
}
},
children: [
// ── TITLE BANNER ──────────────────────────────────────────────────────
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.NONE },
bottom: { style: BorderStyle.NONE },
left: { style: BorderStyle.NONE },
right: { style: BorderStyle.NONE },
insideH:{ style: BorderStyle.NONE },
insideV:{ style: BorderStyle.NONE },
},
rows: [
new TableRow({ children: [
new TableCell({
shading: { type: ShadingType.SOLID, color: TEAL, fill: TEAL },
verticalAlign: VerticalAlign.CENTER,
children: [
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 160, after: 60 },
children: [
new TextRun({ text: "PATIENT INFORMATION LEAFLET", bold: true, color: WHITE, size: 40, font: "Arial" })
]
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 160 },
children: [
new TextRun({ text: "[Condition / Medication / Procedure Name]", color: "CCEEFF", size: 26, font: "Arial", italics: true })
]
})
]
})
]})
]
}),
spacer(120),
// ── INTRO ─────────────────────────────────────────────────────────────
para(
"This leaflet has been written to help you understand your condition and what to expect. " +
"Please read it carefully and keep it for future reference. If you have any questions, " +
"do not hesitate to speak to your doctor, nurse, or pharmacist.",
AlignmentType.LEFT, 160
),
// ── SECTION 1: WHAT IS IT? ────────────────────────────────────────────
sectionHeading("1. What is [Condition / Medication / Procedure]?"),
spacer(60),
para(
"[Provide a clear, jargon-free explanation of what this condition, medication, or procedure " +
"is. Use simple language — aim for a reading age of around 12 years old.]"
),
para(
"Key facts:"
),
bullet("", "How common it is: ", "[e.g. It affects approximately 1 in 100 people in the UK.]"),
bullet("", "Who is affected: ", "[e.g. It can occur at any age, but is most common in adults over 40.]"),
bullet("", "Is it serious? ", "[e.g. It is usually a manageable condition with the right treatment.]"),
spacer(80),
// ── SECTION 2: CAUSES ─────────────────────────────────────────────────
sectionHeading("2. Causes and Risk Factors"),
spacer(60),
para("[Describe the known causes or contributing factors. List risk factors where relevant.]"),
bullet("Risk factor 1"),
bullet("Risk factor 2"),
bullet("Risk factor 3"),
spacer(80),
// ── SECTION 3: SYMPTOMS ───────────────────────────────────────────────
sectionHeading("3. Symptoms"),
spacer(60),
para(
"Common symptoms include:"
),
bullet("Symptom 1"),
bullet("Symptom 2"),
bullet("Symptom 3"),
spacer(80),
warningBox(
"When to seek urgent medical help",
[
"Call 999 or go to your nearest A&E immediately if you experience:",
" \u2022 [Urgent symptom 1 — e.g. sudden severe chest pain]",
" \u2022 [Urgent symptom 2 — e.g. difficulty breathing]",
" \u2022 [Urgent symptom 3 — e.g. signs of severe allergic reaction]",
]
),
spacer(120),
// ── SECTION 4: DIAGNOSIS ──────────────────────────────────────────────
sectionHeading("4. Diagnosis"),
spacer(60),
para("[Explain how the condition is diagnosed — tests, examinations, imaging, etc.]"),
bullet("Test / examination 1"),
bullet("Test / examination 2"),
bullet("Test / examination 3"),
spacer(80),
// ── SECTION 5: TREATMENT ──────────────────────────────────────────────
sectionHeading("5. Treatment Options"),
spacer(60),
para("[Summarise the main treatment options available.]"),
spacer(40),
infoBox(
"Treatment Option 1 — [e.g. Medication]",
[
"How it works: [Brief explanation]",
"How to take it: [Dosage, frequency]",
"How long: [Duration of treatment]",
]
),
spacer(80),
infoBox(
"Treatment Option 2 — [e.g. Lifestyle changes]",
[
"What to do: [Specific advice]",
"Why it helps: [Brief explanation]",
]
),
spacer(80),
// ── SECTION 6: SIDE EFFECTS ───────────────────────────────────────────
sectionHeading("6. Side Effects and Risks"),
spacer(60),
para("Common side effects (affecting more than 1 in 10 people):"),
bullet("Side effect 1"),
bullet("Side effect 2"),
spacer(40),
para("Less common side effects (affecting 1 in 10 to 1 in 100 people):"),
bullet("Side effect 3"),
bullet("Side effect 4"),
spacer(80),
// ── SECTION 7: SELF-CARE ──────────────────────────────────────────────
sectionHeading("7. Self-Care and Lifestyle Advice"),
spacer(60),
bullet("Stay hydrated and maintain a balanced diet."),
bullet("Exercise regularly as advised by your healthcare team."),
bullet("Avoid smoking and limit alcohol intake."),
bullet("[Add condition-specific self-care advice here.]"),
spacer(80),
// ── SECTION 8: FOLLOW-UP ──────────────────────────────────────────────
sectionHeading("8. Follow-Up Appointments"),
spacer(60),
para(
"[Explain the follow-up schedule — when the patient should return, what will be checked, " +
"and who to contact if they have concerns before their next appointment.]"
),
spacer(80),
// ── SECTION 9: FURTHER INFORMATION ───────────────────────────────────
sectionHeading("9. Further Information and Support"),
spacer(60),
bullet("", "Your GP: ", "Contact your GP surgery for advice and referrals."),
bullet("", "NHS Helpline: ", "Call 111 for non-emergency medical advice (UK)."),
bullet("", "Support groups: ", "[Name of relevant patient charity / organisation, website URL]"),
bullet("", "NHS website: ", "www.nhs.uk — search for your condition."),
spacer(80),
// ── FOOTER INFO ───────────────────────────────────────────────────────
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "AAAAAA" },
bottom: { style: BorderStyle.NONE },
left: { style: BorderStyle.NONE },
right: { style: BorderStyle.NONE },
insideH:{ style: BorderStyle.NONE },
insideV:{ style: BorderStyle.NONE },
},
rows: [
new TableRow({ children: [
new TableCell({
children: [
new Paragraph({
spacing: { before: 80, after: 40 },
children: [italicRun("Produced by: [Department / Organisation Name]")]
}),
new Paragraph({
spacing: { before: 0, after: 40 },
children: [italicRun("Date produced: [Month Year] | Review date: [Month Year] | Ref: [Reference number]")]
}),
new Paragraph({
spacing: { before: 0, after: 40 },
children: [italicRun(
"This leaflet is for informational purposes only and does not replace professional medical advice. " +
"Always consult a qualified healthcare professional for diagnosis and treatment."
)]
}),
]
})
]})
]
}),
]
}]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync("/home/daytona/workspace/patient-leaflet/Patient_Information_Leaflet_Template.docx", buffer);
console.log("Done — file written.");
});
cd /home/daytona/workspace/patient-leaflet && node create_leaflet.js 2>&1
python /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/workspace/patient-leaflet/Patient_Information_Leaflet_Template.docx 2>&1
python -c "import zipfile; z = zipfile.ZipFile('/home/daytona/workspace/patient-leaflet/Patient_Information_Leaflet_Template.docx'); print('Valid ZIP. Contents:'); [print(' ', n) for n in z.namelist()]"
Patient Information Leaflet Template
Word Document · DOCX
| Section | Content |
|---|---|
| Title banner | Teal header with leaflet title and condition/medication name placeholder |
| 1. What is it? | Plain-language explanation, key facts |
| 2. Causes & Risk Factors | Bullet list |
| 3. Symptoms | Bullet list + orange warning box for urgent symptoms |
| 4. Diagnosis | Tests and examinations |
| 5. Treatment Options | Colour-coded info boxes per treatment option |
| 6. Side Effects | Categorised by frequency |
| 7. Self-Care | Lifestyle advice bullets |
| 8. Follow-Up | Appointment guidance |
| 9. Further Info & Support | NHS resources, charities, helpline |
| Footer | Department, date, review date, disclaimer |
[bracketed placeholders] with your specific content. If you'd like a version for a specific condition, medication, or procedure — just let me know.