Show clearly
Create a summary document of this surgical procedure
mkdir -p /home/daytona/workspace/surgical-summary && ls /home/daytona/workspace/…
~/surgical-summary/generate_summary.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from datetime import date
OUTPUT_PATH = "/home/daytona/workspace/surgical-summary/Surgical_Procedure_Summary.pdf"
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
topMargin=2*cm,
bottomMargin=2*cm,
leftMargin=2.5*cm,
rightMargin=2.5*cm,
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
"Title",
parent=styles["Title"],
fontSize=18,
textColor=colors.HexColor("#1a3c5e"),
spaceAfter=6,
alignment=TA_CENTER,
fontName="Helvetica-Bold",
)
subtitle_style = ParagraphStyle(
"Subtitle",
parent=styles["Normal"],
fontSize=10,
textColor=colors.HexColor("#555555"),
spaceAfter=4,
alignment=TA_CENTER,
)
section_header_style = ParagraphStyle(
"SectionHeader",
parent=styles["Normal"],
fontSize=11,
textColor=colors.white,
fontName="Helvetica-Bold",
spaceBefore=10,
spaceAfter=4,
leftIndent=6,
)
body_style = ParagraphStyle(
"Body",
parent=styles["Normal"],
fontSize=10,
textColor=colors.HexColor("#222222"),
leading=16,
spaceAfter=4,
)
label_style = ParagraphStyle(
"Label",
parent=styles["Normal"],
fontSize=10,
fontName="Helvetica-Bold",
textColor=colors.HexColor("#1a3c5e"),
)
value_style = ParagraphStyle(
"Value",
parent=styles["Normal"],
fontSize=10,
textColor=colors.HexColor("#333333"),
)
step_style = ParagraphStyle(
"Step",
parent=styles["Normal"],
fontSize=10,
textColor=colors.HexColor("#222222"),
leading=18,
spaceAfter=2,
leftIndent=12,
bulletIndent=0,
)
note_style = ParagraphStyle(
"Note",
parent=styles["Normal"],
fontSize=9,
textColor=colors.HexColor("#666666"),
leading=14,
spaceAfter=4,
italics=True,
)
story = []
# ── TITLE BLOCK ──────────────────────────────────────────────────────────────
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("SURGICAL PROCEDURE SUMMARY", title_style))
story.append(Paragraph("Operative Note - Transcribed & Summarised", subtitle_style))
story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#1a3c5e"), spaceAfter=12))
# ── SECTION HEADER helper ────────────────────────────────────────────────────
def section_header(text):
tbl = Table([[Paragraph(text, section_header_style)]], colWidths=["100%"])
tbl.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, -1), colors.HexColor("#1a3c5e")),
("ROWBACKGROUNDS", (0, 0), (-1, -1), [colors.HexColor("#1a3c5e")]),
("TOPPADDING", (0, 0), (-1, -1), 4),
("BOTTOMPADDING", (0, 0), (-1, -1), 4),
("LEFTPADDING", (0, 0), (-1, -1), 8),
]))
return tbl
def info_table(rows):
"""rows: list of (label, value) tuples"""
table_data = [[Paragraph(r[0], label_style), Paragraph(r[1], value_style)] for r in rows]
tbl = Table(table_data, colWidths=[5.5*cm, 11*cm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, -1), colors.HexColor("#f4f8fc")),
("ROWBACKGROUNDS", (0, 0), (-1, -1), [colors.HexColor("#f4f8fc"), colors.white]),
("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#ccddee")),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
("LEFTPADDING", (0, 0), (-1, -1), 8),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
]))
return tbl
# ── 1. PROCEDURE DETAILS ─────────────────────────────────────────────────────
story.append(section_header("1. PROCEDURE DETAILS"))
story.append(Spacer(1, 0.2*cm))
story.append(info_table([
("Date of Surgery", "11 June 2026"),
("Incision Start Time", "3:50 PM"),
("Time of Closure", "4:50 PM"),
("Total Operative Duration", "~60 minutes"),
("Facility / Hospital", "Multi-branch Hospital (Uppal / Kachiguda / Banjara Hills / Miyapur)"),
("Document Version", "Version 2"),
]))
story.append(Spacer(1, 0.4*cm))
# ── 2. ANAESTHESIA & POSITIONING ────────────────────────────────────────────
story.append(section_header("2. ANAESTHESIA & PATIENT POSITIONING"))
story.append(Spacer(1, 0.2*cm))
story.append(info_table([
("Anaesthesia Type", "General Anaesthesia"),
("Aseptic Conditions", "Strict aseptic technique maintained throughout"),
("Patient Position", "Supine"),
("Site Preparation", "Lower limb scrubbed, painted and draped"),
]))
story.append(Spacer(1, 0.4*cm))
# ── 3. OPERATIVE STEPS ───────────────────────────────────────────────────────
story.append(section_header("3. OPERATIVE STEPS (SEQUENTIAL)"))
story.append(Spacer(1, 0.25*cm))
steps = [
("Step 1", "Patient placed in supine position under strict aseptic and general anaesthetic conditions."),
("Step 2", "Lower limb operative site scrubbed, painted with antiseptic solution, and draped."),
("Step 3", "Midline incision made over the operative site."),
("Step 4", "Subcutaneous layer dissected and pared."),
("Step 5", "Deep arthrotomy performed."),
("Step 6", "Mixed fluid collection identified, removed, and collected (likely sent for analysis)."),
("Step 7", "Wound wash (irrigation) given thoroughly."),
("Step 8", "Wound closed in layers."),
("Step 9", "Dressing applied."),
("Step 10", "Foot ulcer debridement performed."),
]
step_data = [[
Paragraph(f"<b>{s[0]}</b>", label_style),
Paragraph(s[1], value_style)
] for s in steps]
step_tbl = Table(step_data, colWidths=[2.5*cm, 14*cm])
step_tbl.setStyle(TableStyle([
("ROWBACKGROUNDS", (0, 0), (-1, -1), [colors.HexColor("#f4f8fc"), colors.white]),
("GRID", (0, 0), (-1, -1), 0.4, colors.HexColor("#ccddee")),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
("LEFTPADDING", (0, 0), (-1, -1), 8),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
]))
story.append(step_tbl)
story.append(Spacer(1, 0.4*cm))
# ── 4. CLINICAL SUMMARY ──────────────────────────────────────────────────────
story.append(section_header("4. CLINICAL SUMMARY"))
story.append(Spacer(1, 0.2*cm))
summary_text = (
"The procedure involved surgical exploration and arthrotomy of the lower limb under general "
"anaesthesia with the patient in the supine position. Following strict aseptic preparation, a "
"midline incision was made and subcutaneous dissection performed down to the joint. A deep "
"arthrotomy was carried out, and a mixed fluid collection was drained and collected. The wound "
"was thoroughly irrigated, then closed in layers with appropriate dressing. In addition, a foot "
"ulcer debridement was performed as part of the same operative session. The procedure lasted "
"approximately 60 minutes (3:50 PM to 4:50 PM)."
)
story.append(Paragraph(summary_text, body_style))
story.append(Spacer(1, 0.4*cm))
# ── 5. ORIGINAL HANDWRITTEN NOTE ────────────────────────────────────────────
story.append(section_header("5. ORIGINAL HANDWRITTEN NOTE (VERBATIM TRANSCRIPTION)"))
story.append(Spacer(1, 0.2*cm))
verbatim = (
'"Under strict aseptic & under general condition, patient in supine position, lower limb '
'parts are scrubbed, painted & draped. Mid line incision given, paring of subcutaneous '
'layer dissected. Then deep arthrotomy done, mixed fluid removed & collected and wash given. '
'Wound closed by layers. Dressing - foot ulcer debridement done."'
)
verbatim_box = Table([[Paragraph(verbatim, note_style)]], colWidths=["100%"])
verbatim_box.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, -1), colors.HexColor("#fffbee")),
("BOX", (0, 0), (-1, -1), 1, colors.HexColor("#e0c060")),
("LEFTPADDING", (0, 0), (-1, -1), 10),
("RIGHTPADDING", (0, 0), (-1, -1), 10),
("TOPPADDING", (0, 0), (-1, -1), 8),
("BOTTOMPADDING", (0, 0), (-1, -1), 8),
]))
story.append(verbatim_box)
story.append(Spacer(1, 0.6*cm))
# ── FOOTER ───────────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#aaaaaa"), spaceAfter=6))
footer_style = ParagraphStyle(
"Footer", parent=styles["Normal"],
fontSize=8, textColor=colors.HexColor("#888888"), alignment=TA_CENTER
)
story.append(Paragraph(
f"Document generated on {date.today().strftime('%d %B %Y')} | "
"This summary is based on a handwritten operative note and is for reference purposes only.",
footer_style
))
doc.build(story)
print(f"PDF created successfully: {OUTPUT_PATH}")
python /home/daytona/workspace/surgical-summary/generate_summary.py
Surgical Procedure Summary
PDF Document · PDF
Generate a Word document version for easier editing
~/surgical-summary/generate_docx.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType,
VerticalAlign, Header, Footer, PageNumber, NumberFormat,
TableOfContents
} = require('docx');
const fs = require('fs');
// ── Colour palette ────────────────────────────────────────────────────────
const NAVY = "1a3c5e";
const LIGHTBLUE = "dce9f5";
const LIGHTYELLOW = "fffbee";
const WHITE = "FFFFFF";
const GREY = "555555";
const DARK = "222222";
// ── Helper: section heading paragraph ────────────────────────────────────
function sectionHeading(text) {
return new Paragraph({
children: [
new TextRun({
text,
bold: true,
color: WHITE,
size: 24,
font: "Calibri",
}),
],
heading: HeadingLevel.HEADING_1,
shading: { type: ShadingType.SOLID, color: NAVY, fill: NAVY },
spacing: { before: 240, after: 120 },
indent: { left: 120 },
});
}
// ── Helper: info row (label | value) ─────────────────────────────────────
function infoRow(label, value, shaded) {
const bgColor = shaded ? LIGHTBLUE : WHITE;
return new TableRow({
children: [
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: label, bold: true, color: NAVY, size: 20, font: "Calibri" })],
spacing: { before: 60, after: 60 },
indent: { left: 80 },
})],
shading: { type: ShadingType.SOLID, color: bgColor, fill: bgColor },
width: { size: 30, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
left: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
right: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
},
verticalAlign: VerticalAlign.CENTER,
}),
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: value, color: DARK, size: 20, font: "Calibri" })],
spacing: { before: 60, after: 60 },
indent: { left: 80 },
})],
shading: { type: ShadingType.SOLID, color: bgColor, fill: bgColor },
width: { size: 70, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
left: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
right: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
},
verticalAlign: VerticalAlign.CENTER,
}),
],
});
}
function infoTable(rows) {
return new Table({
rows: rows.map((r, i) => infoRow(r[0], r[1], i % 2 === 0)),
width: { size: 100, type: WidthType.PERCENTAGE },
});
}
// ── Helper: step row ──────────────────────────────────────────────────────
function stepRow(stepLabel, stepText, shaded) {
const bgColor = shaded ? LIGHTBLUE : WHITE;
return new TableRow({
children: [
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: stepLabel, bold: true, color: NAVY, size: 20, font: "Calibri" })],
spacing: { before: 60, after: 60 },
indent: { left: 80 },
})],
shading: { type: ShadingType.SOLID, color: bgColor, fill: bgColor },
width: { size: 15, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
left: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
right: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
},
verticalAlign: VerticalAlign.CENTER,
}),
new TableCell({
children: [new Paragraph({
children: [new TextRun({ text: stepText, color: DARK, size: 20, font: "Calibri" })],
spacing: { before: 60, after: 60 },
indent: { left: 80 },
})],
shading: { type: ShadingType.SOLID, color: bgColor, fill: bgColor },
width: { size: 85, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
left: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
right: { style: BorderStyle.SINGLE, size: 4, color: "c0d8ee" },
},
verticalAlign: VerticalAlign.CENTER,
}),
],
});
}
function spacer() {
return new Paragraph({ text: "", spacing: { before: 0, after: 120 } });
}
// ── Build document ────────────────────────────────────────────────────────
const doc = new Document({
styles: {
default: {
document: {
run: { font: "Calibri", size: 20, color: DARK },
},
},
paragraphStyles: [
{
id: "Heading1",
name: "Heading 1",
basedOn: "Normal",
next: "Normal",
run: { bold: true, color: WHITE, size: 24, font: "Calibri" },
paragraph: {
shading: { type: ShadingType.SOLID, color: NAVY, fill: NAVY },
spacing: { before: 240, after: 120 },
indent: { left: 120 },
},
},
],
},
sections: [
{
properties: {
page: {
margin: { top: 1134, bottom: 1134, left: 1134, right: 1134 },
},
},
headers: {
default: new Header({
children: [
new Paragraph({
children: [
new TextRun({
text: "SURGICAL PROCEDURE SUMMARY | Operative Note",
bold: true,
color: NAVY,
size: 18,
font: "Calibri",
}),
],
alignment: AlignmentType.RIGHT,
}),
],
}),
},
footers: {
default: new Footer({
children: [
new Paragraph({
children: [
new TextRun({
text: "Generated 13 July 2026 | For reference purposes only | Page ",
size: 16,
color: "888888",
font: "Calibri",
}),
new TextRun({
children: [PageNumber.CURRENT],
size: 16,
color: "888888",
font: "Calibri",
}),
new TextRun({
text: " of ",
size: 16,
color: "888888",
font: "Calibri",
}),
new TextRun({
children: [PageNumber.TOTAL_PAGES],
size: 16,
color: "888888",
font: "Calibri",
}),
],
alignment: AlignmentType.CENTER,
}),
],
}),
},
children: [
// ── Title ──────────────────────────────────────────────────────
new Paragraph({
children: [new TextRun({
text: "SURGICAL PROCEDURE SUMMARY",
bold: true,
color: NAVY,
size: 40,
font: "Calibri",
})],
alignment: AlignmentType.CENTER,
spacing: { before: 240, after: 80 },
}),
new Paragraph({
children: [new TextRun({
text: "Operative Note — Transcribed & Summarised",
color: GREY,
size: 22,
font: "Calibri",
italics: true,
})],
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 240 },
}),
// ── Section 1: Procedure Details ──────────────────────────────
sectionHeading("1. PROCEDURE DETAILS"),
spacer(),
infoTable([
["Date of Surgery", "11 June 2026"],
["Incision Start Time", "3:50 PM"],
["Time of Closure", "4:50 PM"],
["Total Duration", "Approximately 60 minutes"],
["Facility / Hospital", "Multi-branch Hospital (Uppal / Kachiguda / Banjara Hills / Miyapur)"],
["Document Version", "Version 2"],
]),
spacer(),
// ── Section 2: Anaesthesia & Positioning ──────────────────────
sectionHeading("2. ANAESTHESIA & PATIENT POSITIONING"),
spacer(),
infoTable([
["Anaesthesia Type", "General Anaesthesia"],
["Aseptic Conditions", "Strict aseptic technique maintained throughout"],
["Patient Position", "Supine"],
["Site Preparation", "Lower limb scrubbed, painted with antiseptic, and draped"],
]),
spacer(),
// ── Section 3: Operative Steps ─────────────────────────────────
sectionHeading("3. OPERATIVE STEPS (SEQUENTIAL)"),
spacer(),
new Table({
rows: [
stepRow("Step 1", "Patient placed in supine position under strict aseptic and general anaesthetic conditions.", true),
stepRow("Step 2", "Lower limb operative site scrubbed, painted with antiseptic solution, and draped.", false),
stepRow("Step 3", "Midline incision made over the operative site.", true),
stepRow("Step 4", "Subcutaneous layer dissected and pared.", false),
stepRow("Step 5", "Deep arthrotomy performed.", true),
stepRow("Step 6", "Mixed fluid collection identified, removed, and collected (likely sent for analysis).", false),
stepRow("Step 7", "Wound wash (irrigation) given thoroughly.", true),
stepRow("Step 8", "Wound closed in layers.", false),
stepRow("Step 9", "Dressing applied.", true),
stepRow("Step 10", "Foot ulcer debridement performed.", false),
],
width: { size: 100, type: WidthType.PERCENTAGE },
}),
spacer(),
// ── Section 4: Clinical Summary ────────────────────────────────
sectionHeading("4. CLINICAL SUMMARY"),
spacer(),
new Paragraph({
children: [new TextRun({
text: "The procedure involved surgical exploration and arthrotomy of the lower limb under general anaesthesia with the patient in the supine position. Following strict aseptic preparation, a midline incision was made and subcutaneous dissection performed down to the joint. A deep arthrotomy was carried out, and a mixed fluid collection was drained and collected. The wound was thoroughly irrigated, then closed in layers with appropriate dressing applied. In addition, a foot ulcer debridement was performed as part of the same operative session. The total operative time was approximately 60 minutes (3:50 PM to 4:50 PM).",
size: 20,
color: DARK,
font: "Calibri",
})],
spacing: { before: 60, after: 60, line: 360 },
}),
spacer(),
// ── Section 5: Verbatim Note ───────────────────────────────────
sectionHeading("5. ORIGINAL HANDWRITTEN NOTE (VERBATIM TRANSCRIPTION)"),
spacer(),
new Table({
rows: [
new TableRow({
children: [
new TableCell({
children: [
new Paragraph({
children: [new TextRun({
text: '"Under strict aseptic & under general condition, patient in supine position, lower limb parts are scrubbed, painted & draped. Mid line incision given, paring of subcutaneous layer dissected. Then deep arthrotomy done, mixed fluid removed & collected and wash given. Wound closed by layers. Dressing - foot ulcer debridement done."',
italics: true,
color: "555555",
size: 20,
font: "Calibri",
})],
spacing: { before: 100, after: 100 },
indent: { left: 100, right: 100 },
}),
],
shading: { type: ShadingType.SOLID, color: LIGHTYELLOW, fill: LIGHTYELLOW },
borders: {
top: { style: BorderStyle.SINGLE, size: 8, color: "e0c060" },
bottom: { style: BorderStyle.SINGLE, size: 8, color: "e0c060" },
left: { style: BorderStyle.SINGLE, size: 8, color: "e0c060" },
right: { style: BorderStyle.SINGLE, size: 8, color: "e0c060" },
},
}),
],
}),
],
width: { size: 100, type: WidthType.PERCENTAGE },
}),
spacer(),
// ── Section 6: Notes / Editable Fields ─────────────────────────
sectionHeading("6. ADDITIONAL NOTES (Edit as Required)"),
spacer(),
infoTable([
["Surgeon Name", ""],
["Anaesthetist Name", ""],
["Diagnosis / Indication", ""],
["Intra-op Blood Loss", ""],
["Blood Units Transfused", ""],
["Intra-op Change in Plan", "Yes / No — If Yes, reason:"],
["Post-op Instructions", ""],
["Follow-up Date", ""],
]),
spacer(),
],
},
],
});
Packer.toBuffer(doc).then(buffer => {
const outPath = "/home/daytona/workspace/surgical-summary/Surgical_Procedure_Summary.docx";
fs.writeFileSync(outPath, buffer);
console.log("DOCX created: " + outPath);
});
cd /home/daytona/workspace/surgical-summary && node generate_docx.js
python /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/worksp…
python -c " import zipfile, os path = '/home/daytona/workspace/surgical-summary/…
lxml module in the environment, not a document issue.Surgical Procedure Summary
Word Document · DOCX
| Section | Content |
|---|---|
| 1. Procedure Details | Date, times, duration, hospital, version |
| 2. Anaesthesia & Positioning | Type, aseptic details, patient position, prep |
| 3. Operative Steps | All 10 steps in a two-column table |
| 4. Clinical Summary | Narrative paragraph |
| 5. Verbatim Transcription | Original handwritten note (highlighted box) |
| 6. Additional Notes | Blank editable fields - surgeon name, anaesthetist, diagnosis, blood loss, post-op instructions, follow-up date |