| name | case-report |
| description | Convert clinical case data (medical records, IO sheets, lab data, imaging) into a professional, timeline-based PowerPoint presentation (PPTX) and interactive HTML website for M&M conference, case report, or morning conference presentation. |
| allowed-tools | Bash, Read, Write, Glob, Grep |
Case Report Presentation
Overview
When a user provides clinical case data and asks for a case report / M&M / morning conference presentation, use this skill to generate a timeline-based python-pptx presentation and an interactive HTML website. The input is typically a folder containing:
- Markdown medical records (
醫師記錄/): Admission note, Progress notes, Discharge note, Surgical records, Objective findings
- IO sheets (
IO/): PNG screenshots of fluid intake/output records by shift
- Lab data images (
LABS/): PNG screenshots of lab trend charts (CBC, SMAC, CRP, etc.)
- Chest X-rays / imaging (
CXR/): PNG images with date-based filenames
- Nursing records (
護理紀錄/): PDF files
- Medication records: PDF files at root level
The slide structure should be timeline-based — organized chronologically around the clinical course, with adaptive granularity (finer detail for the main focus period, coarser for secondary periods).
Prerequisites
pip3 install python-pptx pymupdf
Workflow
0a. Ask for Presenter Information & Presentation Type
Before starting, ask the user two things in a concise one-liner:
Presenter info: Who is presenting and who is the supervisor? (e.g., "R2 王大明 / VS 李教授") — press Enter to skip.
Presentation type: (1) M&M Conference (2) Case Report (3) Morning Conference — default: M&M
- M&M Conference → ending section uses "Learning Points / Take-home Messages"
- Case Report → ending section uses "Discussion" (literature comparison & analysis)
- Morning Conference → ending section uses "Summary & Key Points"
- If the user skips → check memory for saved user profile; default to M&M Conference
0b. Identify Input & Create Output Folder
Detect input type
The user provides a folder path containing clinical data organized in subdirectories:
import os, glob
user_input = "..."
records_dir = os.path.join(user_input, "醫師記錄")
io_dir = os.path.join(user_input, "IO")
labs_dir = os.path.join(user_input, "LABS")
cxr_dir = os.path.join(user_input, "CXR")
nursing_dir = os.path.join(user_input, "護理紀錄")
md_files = sorted(glob.glob(os.path.join(records_dir, "*.md"))) if os.path.isdir(records_dir) else []
io_images = sorted(glob.glob(os.path.join(io_dir, "*.png"))) if os.path.isdir(io_dir) else []
lab_images = sorted(glob.glob(os.path.join(labs_dir, "*.png"))) if os.path.isdir(labs_dir) else []
cxr_images = sorted(glob.glob(os.path.join(cxr_dir, "*.png"))) if os.path.isdir(cxr_dir) else []
nursing_pdfs = sorted(glob.glob(os.path.join(nursing_dir, "*.pdf"))) if os.path.isdir(nursing_dir) else []
root_pdfs = sorted(glob.glob(os.path.join(user_input, "*.pdf")))
Create output folder
{PatientName}_case_report/
├── figures/ ← CXR images, lab images copied here
├── images/ ← IO sheet images if embedded
├── presentation.pptx ← PPTX presentation
├── presentation.html ← HTML website (external images)
└── presentation_portable.html ← HTML website (self-contained base64)
1. Read & Parse All Clinical Records
Markdown records (primary data source)
Read each .md file using the Read tool and extract structured data:
| File | Extract |
|---|
Admission note.md | Demographics, chief complaint, present illness narrative, past history, allergies, initial vitals, initial labs, physical exam, assessment/impression, initial plan |
Progress note.md | Date-stamped entries (split by YYYY-MM-DD HH:MM:SS pattern); per entry: vitals, assessment changes, plan changes, clinical events |
手術紀錄.md | Procedure details, TBSA breakdown by region (for burns), operative findings, EBL |
Objective finding.md | Serial weights, serial lab data by date (structured), imaging findings — THIS IS THE PRIMARY LAB DATA SOURCE |
Discharge note.md | Final diagnoses, course summary, discharge condition, radiology reports, culture results |
IO sheets (PNG images)
IO sheets are PNG screenshots from the hospital's electronic medical system. Process them:
- Visually inspect each IO image using the Read tool to understand the format
- Extract numerical data by reading the values directly from the image:
- Per shift: 白班 (07:00-14:59), 小夜 (15:00-22:59), 大夜 (23:00-06:59)
- Categories: 輸液 (IV fluids), 血品 (blood products), 進食 (enteral), 排尿 (urine output), 總輸入/總排出/差值
- Structure into tables for the fluid resuscitation slides (Pattern G)
- If OCR is needed for hard-to-read values, use the macOS Vision OCR script from the
notebooklm-to-editable-pptx skill
Lab data strategy
- Primary source:
Objective finding.md — already has parsed, structured lab values by date
- Lab images (PNG): Use as visual verification and can be embedded as supplementary reference
- DO NOT recreate charts — use the structured data to build formatted tables
Medication records (PDF — 急診用藥紀錄, 住院後用藥簽用記錄)
Extract using PyMuPDF (fitz.open()). Key data to parse:
- IV fluids: LR, NS, D5W — with execution times (not order times). Multiple execution records under the same order number may represent either separate bags or multi-nurse sign-offs — cross-reference with nursing records to disambiguate.
- Blood products: FFP, FP, RBC — doses and execution times
- Antibiotics: Drug name, dose, frequency, start/stop dates, route
- Supportive medications: NaHCO₃, Albumin, diuretics, vasopressors, sedatives
CRITICAL: Use execution timestamps (執行時間), not order timestamps (開立時間), for fluid volume calculations. The same order number with multiple execution records may be the same bag signed by different nurses — verify with nursing records and IO sheets.
CXR and imaging
- Copy all CXR images to
figures/ directory with date-based filenames
- These will be used in serial comparison slides (Pattern I)
- Label by actual imaging location — check PACS header (institution name) in the image. Do NOT assume the first CXR is from an outside hospital.
Wound / clinical photos
- Check for existing PPTX files (e.g., trauma team presentations) that may contain clinical photos
- Extract images via
shape.image.blob from python-pptx
- Resize large images (>3MB) using
sips -Z 2000 -s format jpeg -s formatOptions 80 before embedding in PPTX
2. Build Clinical Timeline
Construct a chronological timeline from all parsed data. The timeline granularity should be adaptive:
Timeline structure (acute/critical care default):
├── Pre-hospital: mechanism, rescue, initial hospital management
├── ED / Arrival (Hour 0): vital signs, primary survey, initial labs
├── Hour 0–8: resuscitation phase 1 (MAIN FOCUS — finest granularity)
├── Hour 8–24: resuscitation phase 2 (MAIN FOCUS)
├── Day 2–3: early ICU course
├── Day 4–7: continued course
└── Day 7+: later course / outcome
For each time point, record:
- Events: procedures, interventions, clinical changes
- Vitals: BP, HR, RR, Temp, SpO2
- Labs: key values with abnormal flags
- Fluid balance: intake by category, output (UOP), cumulative balance
- Medications: new starts, dose changes
3. Design Slides Based on Clinical Timeline
3.5. Text Formatting Rules (CRITICAL)
Same rules as journal-reading skill — apply to ALL python-pptx text:
Never use p.text = "..."
Always use set_run() or p.add_run(). The p.text = pattern does not guarantee formatting.
Never use \n in text strings
Each line must be a separate paragraph with its own run and explicit formatting.
Every text element must have explicit formatting
Every run must set: font.size, font.color.rgb, font.name. Never rely on defaults.
Every paragraph must have explicit alignment (CRITICAL)
Always set p.alignment = PP_ALIGN.LEFT (or CENTER/RIGHT) on every paragraph. Never rely on PowerPoint defaults — they are inconsistent across text boxes, tables, and shapes. Without explicit alignment, text may render LEFT in some boxes and CENTER in others.
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.LEFT
set_run(p, "text", font_size, color)
p = tf.paragraphs[0]
set_run(p, "text", font_size, color)
Alignment conventions:
- Bullets, captions, section numbers, highlight/key-point box text:
PP_ALIGN.LEFT
- Vital signs cards, table headers, table data (non-first-column):
PP_ALIGN.CENTER
- Slide numbers:
PP_ALIGN.RIGHT
- Title/ending slide (Thank You):
PP_ALIGN.CENTER
- Content slide titles:
PP_ALIGN.LEFT
Prevent text overlap between elements (CRITICAL)
When a slide has multiple vertically stacked elements (bullets + key_point box, timeline + bullets, etc.), calculate the available vertical space before adding content. If content exceeds the space, either:
- Split into two slides — preferred for dense content
- Reduce font size — minimum Pt(12) for readability
- Move the emphasis box lower — but never below
top=Inches(6.2) (slide numbers at 7.05)
Rule of thumb for vertical spacing:
- Mini-timeline occupies
y=0.92 to y=1.75 (~0.83 inches)
- Content area after timeline:
top=Inches(1.85) to top=Inches(5.5) max
- Key_point/highlight box: calculate
top = bullets_top + (n_lines × line_height)
- Never stack more than 12–14 bullet lines + 1 emphasis box on a single slide
4. Slide Structure
Do NOT force a fixed slide count. Use as many slides as needed. Prefer more slides with less content each over fewer dense slides.
Layout density principles:
- Max 4–5 bullet points per slide
- Max 1 table + 1–2 figures per slide
- Font sizes for projection: body text ≥ Pt(18), titles ≥ Pt(28), table cells ≥ Pt(14), captions ≥ Pt(12)
- Leave breathing room — generous padding, whitespace between elements
Required slides (always present):
- Title slide — Case type label (M&M / Case Report / Morning Conference), chief complaint as title, patient demographics summary, presenter info
- Outline slide — Numbered TOC matching subsequent sections. Use uniform 0.5"×0.5" rounded-square badges (not circles) so 2-digit numbers fit. Badge font: 16pt for 1-digit, 13pt for 2-digit, bold white, vertically + horizontally centered,
word_wrap=False, zero margins. Row step 0.6", label font 18pt vertically aligned with badge center. (Implemented in add_outline_slide() in generate_aesthetic_pptx.py.)
- Patient Profile — Demographics, comorbidities, baseline functional status, social history
- Mechanism / Presentation — How the injury/illness occurred, pre-hospital care, include outside hospital fluids/medications with execution times
- Initial Assessment — Arrival vitals (Pattern K cards), primary/secondary survey
- Injury/Disease Assessment — e.g., TBSA by region (Pattern J) for burns, staging for cancer
- Wound / Injury Photos — Clinical photos from ER and procedures (Pattern I). Source from existing PPTX (
add_picture extraction) or image folder. Always include if available.
- Initial Labs — Key lab results in table (Pattern H) with abnormal highlighting
- Initial Imaging — CXR/CT with interpretation. Label by actual source (e.g., "ER Arrival" if taken at receiving hospital, not "Outside Hospital")
- Treatment Focus slides — Detailed slides on the main focus area (e.g., fluid resuscitation for burns). Use PBD (Post-Burn Day) or post-event timeline, not calendar dates, for time reference
- Procedure slides — Operative details, clinical photos
- Daily Course slides (PBD-based) — Each slide MUST include: Weight (with Δ), Labs, IO balance, Rx (daily management), Abx (antibiotics), Vitals from nursing records. Add a mini-timeline indicator (Pattern L) on each slide
- Lab Trends — Serial lab tables (Pattern H) grouped by system (Renal, Hematology, Inflammatory)
- Fluid/UOP Trend — PBD-based summary table: In / UOP / mL·kg⁻¹·hr⁻¹ / Balance / Cr / Weight
- Serial Imaging — Side-by-side comparison (Pattern I)
Case-specific slide templates:
For burns / fluid resuscitation:
- Weight: Use pre-burn weight from op note (not admission weight which includes pre-hospital fluids). Flag the discrepancy explicitly.
- TBSA: Report both ED assessment and post-op reassessment if different.
- Parkland formula: Calculate from burn time (not hospital admission). Account for late presentation — if first 8h window passed, note explicitly. Show
mL/kg/%TBSA actual vs expected (4 mL).
- PBD-based fluid slides: Break down by Phase (outside hospital → ER → BU shifts). Show fluid type detail (LR, NS, NaHCO₃, Albumin, blood products) with execution times from 急診用藥紀錄/住院後用藥簽用記錄.
- UOP tracking: Calculate
mL/kg/hr using pre-burn weight per PBD phase. Red-highlight when below target.
- Outside hospital fluids: Include in PBD1 total. Note Foley bladder drainage vs sustained UOP.
- Wound/escharotomy photos: Extract from existing PPTX if available (e.g., trauma team PPTX). Use
slide.shapes → shape.image.blob to export images.
- Weight trend: Daily weights with Δ from baseline and % change.
For surgical complications:
- Pre-operative assessment slide
- Intra-operative events timeline
- Post-operative complication timeline
For infection / sepsis:
- Antibiotic timeline per PBD — show ER empiric → BU definitive → changes
- Culture results with sensitivity data
- Inflammatory marker trends (CRP, PCT, WBC)
Slide Layout Patterns (16:9, coordinates in Inches)
Reuse patterns A–E from journal-reading skill, plus these new patterns:
| Pattern | Layout | Coordinates | When to use |
|---|
| A: Figure + Analysis | Image left, bullets right | Image: (0.6, 1.4, w=6.0), Bullets: (7.0, 1.4, w=5.7) | Single figure with interpretation |
| B: Figure + Analysis (rev) | Bullets left, image right | Bullets: (0.6, 1.4, w=5.7), Image: (6.8, 1.4, w=6.0) | Alternating visual flow |
| C: Table + Key Takeaway | Table top, highlight box bottom | Table: (0.6, 1.4, w=12.0, h=3.5), Box: (0.6, 5.2) | Results table with summary |
| D: Side-by-Side | Two images side by side | Img1: (0.6, 1.4, w=5.8), Img2: (6.8, 1.4, w=5.8) | Before/after, comparison |
| E: Pure Content | Full-width bullets | Bullets: (0.8, 1.4, w=11.7, h=5.5) | Text-only slides |
| F: Timeline | Horizontal bar + event cards | Bar: (0.8–12.5, y=1.8), Cards below | Key events overview |
| G: Fluid Balance | I/O table + totals highlight | Table: (0.6, 1.4, w=12.0), Box: (0.6, 5.5) | Resuscitation monitoring |
| H: Lab Trend | Serial values table | Table: (0.6, 1.4, w=12.0) | Lab progression |
| I: Image Comparison | 2–4 dated images side by side | Dynamic widths, date labels below | Serial CXR, wound photos |
| J: Body Region | Assessment table by region | Table: (0.6, 1.4, w=12.0) | TBSA, staging |
| K: Vital Signs | Card boxes with key vitals | Cards: 4–6 across, (0.6, 1.6) | Admission vitals |
| L: Mini-Timeline | Horizontal dots at top of slide, inside a container box | Container: L=0.5", W=12.33", H=0.7" (must contain edge labels); track: x=1.1–11.65; ovals 0.2"; labels 0.9" wide, 10pt centered | Daily course slides — use add_pbd_timeline_header(slide, days, current_idx); current day highlighted, past blue, future gray. Container width is mandatory so first/last day labels never overflow. |
Emphasis Box Policy
Same as journal-reading:
add_key_point() — deep blue box, white text — for KEY FINDING, most important takeaway
add_highlight_box() — warm yellow box — for supporting context, targets, criteria
- Max 1 emphasis box per slide
- Default font: 14pt, left-aligned (both helpers). Override
font_size= only when a slide truly needs larger emphasis. Never use centered alignment for multi-line summary text.
5. Generate the PPTX
Write a self-contained Python script to /tmp/create_case_report.py that inlines all helper functions from both:
scripts/generate_aesthetic_pptx.py (base helpers)
scripts/generate_case_report_pptx.py (case-report-specific helpers)
Do NOT import from the helper file paths — copy all function definitions directly.
Script structure:
- Inline all helpers at the top (base + case-report-specific)
- Build slides using layout patterns by name in comments
- Call
add_slide_numbers(prs) as the final step before prs.save()
- Save to
{output_dir}/presentation.pptx
Execute the script:
python3 /tmp/create_case_report.py
6. Generate HTML Website
After the PPTX is generated, create an interactive HTML presentation website following the presentation-website skill patterns:
- Use the same content and slide structure as the PPTX
- Follow the HTML template conventions from
presentation-website/templates/presentation_template.html
- Include all mandatory features:
- Dot navigation (right sidebar)
- Progress bar (top)
- Keyboard navigation (arrows, space, page up/down, presentation clickers)
scroll-snap-type: y mandatory
- Card-based layout with left accent borders
- Inline editing mode
- Double-click source text popup — every content card must have hidden
<div class="source-text"> with original record excerpt
- Presentation mode toggle (P or F5)
- PDF download via html2canvas + jsPDF (screenshot approach)
- PPTX download via html2canvas + PptxGenJS
- Slide counters on every slide ("X / N")
- Fade-in animations
Generate two versions:
presentation.html — external images referenced from figures/
presentation_portable.html — self-contained with base64-encoded images
7. Deliver
Notify the user:
- Output folder path
- Number of PPTX slides and section breakdown
- Number of figures/images embedded
- That both PPTX and HTML are available
- HTML features summary (editing, download, navigation)
Content Guidelines
- Default language: English — use standard medical terminology
- If the user requests Chinese or bilingual, switch accordingly
- De-identify patient data in the presentation — use initials or generic identifiers, not full names
- Preserve exact lab values, vital signs, and clinical data — accuracy is critical
- Use red/bold for abnormal or critical values
- Use green for values returning to normal
- Significant findings should use
add_key_point() boxes
- Target values (e.g., UOP target) should use
add_highlight_box() boxes
When to Use
This skill applies when a user:
- Provides clinical case data (medical records, IO sheets, lab data, imaging)
- Requests a "case report" / "M&M" / "case presentation" / "mortality and morbidity"
- Mentions "case discussion" / "morning conference case" / "晨會 case"
- Wants a timeline-based presentation of a clinical course
- Provides a folder with
醫師記錄/, IO/, LABS/, CXR/ subdirectories