# Case Report

> 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.

- Skill: `yizhao6211999/case-report` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add yizhao6211999/case-report`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yizhao6211999/case-report/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: yizhao6211999 (https://skillmd.com/u/yizhao6211999)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yizhao6211999/case-report

---


# 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

```bash
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:

```python
import os, glob

user_input = "..."  # folder path provided by user

# Expected structure
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, "護理紀錄")

# Find all files
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:

1. **Visually inspect** each IO image using the Read tool to understand the format
2. **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), 總輸入/總排出/差值
3. **Structure into tables** for the fluid resuscitation slides (Pattern G)
4. 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.

```python
# CORRECT — explicit alignment on every paragraph
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.LEFT  # ← MUST SET
set_run(p, "text", font_size, color)

# WRONG — missing alignment → inconsistent rendering
p = tf.paragraphs[0]
set_run(p, "text", font_size, color)  # ← alignment undefined
```

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:
1. **Split into two slides** — preferred for dense content
2. **Reduce font size** — minimum Pt(12) for readability
3. **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):

1. **Title slide** — Case type label (M&M / Case Report / Morning Conference), chief complaint as title, patient demographics summary, presenter info
2. **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`.)
3. **Patient Profile** — Demographics, comorbidities, baseline functional status, social history
4. **Mechanism / Presentation** — How the injury/illness occurred, pre-hospital care, **include outside hospital fluids/medications with execution times**
5. **Initial Assessment** — Arrival vitals (Pattern K cards), primary/secondary survey
6. **Injury/Disease Assessment** — e.g., TBSA by region (Pattern J) for burns, staging for cancer
7. **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.**
8. **Initial Labs** — Key lab results in table (Pattern H) with abnormal highlighting
9. **Initial Imaging** — CXR/CT with interpretation. **Label by actual source** (e.g., "ER Arrival" if taken at receiving hospital, not "Outside Hospital")
10. **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
11. **Procedure slides** — Operative details, clinical photos
12. **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
13. **Lab Trends** — Serial lab tables (Pattern H) grouped by system (Renal, Hematology, Inflammatory)
14. **Fluid/UOP Trend** — PBD-based summary table: In / UOP / mL·kg⁻¹·hr⁻¹ / Balance / Cr / Weight
15. **Serial Imaging** — Side-by-side comparison (Pattern I)
16. **Complications** — Summary of complications encountered
17. **Outcome** — Final status, contributing factors
18. **Learning Points / Discussion / Summary** — Based on presentation type selected in step 0a
19. **Ending slide** — "Thank You — Questions?" with presenter info
20. **Supplementary slides (after Thank You)** — Individual CXR with radiology reports, IO screenshots, SMAC/CBC/CRP screenshots, blood sugar. Marked with "SUPPLEMENTARY" tag and gray accent bar

#### 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:
1. **Inline all helpers** at the top (base + case-report-specific)
2. **Build slides** using layout patterns by name in comments
3. **Call `add_slide_numbers(prs)`** as the final step before `prs.save()`
4. Save to `{output_dir}/presentation.pptx`

Execute the script:
```bash
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

