guideline to treat mi
"myocardial infarction"[MeSH Terms] AND "practice guideline"[pt]
ACC AHA 2024 STEMI NSTEMI guidelines treatment
PMID: 40014670
https://reference.medscape.com/cc1/p10/acc-2025-acc-aha-guid…
| Intervention | Detail |
|---|---|
| Oxygen | Only if SpO₂ < 90% - routine O₂ not recommended |
| Aspirin | 162-325 mg loading dose immediately (chewed), then 81 mg/day indefinitely |
| Nitrates | Sublingual NTG for pain; IV NTG if persistent pain, hypertension, pulmonary edema - avoid if hypotension or RV infarction |
| Morphine | For severe pain unresponsive to nitrates - use cautiously as it may mask ongoing ischemia and has been associated with worse outcomes |
| Beta-blockers | Oral, within 24 hours; reduces ventricular arrhythmias and reinfarction - avoid in cardiogenic shock, acute HF, significant bradycardia/hypotension |

| Timing | Indication |
|---|---|
| Immediate (<2 h) | Refractory angina, hemodynamic instability/shock, sustained VT/VF, acute HF/MR |
| Early invasive (<24 h) | High TIMI score (≥3) or GRACE >140, rapid rise in biomarkers, new ST depression |
| Delayed invasive (24-72 h) | Diabetes, renal insufficiency (GFR <60), EF <40%, prior CABG, TIMI ≥2 or GRACE 109-140 |
| Ischemia-driven (conservative) | Low-risk (TIMI ≤1, GRACE <109), biomarker-negative, patient preference |
| Drug | Indication/Timing |
|---|---|
| Beta-blockers | Within 24 h orally; titrate to HR 50-60 bpm |
| ACE inhibitors | Start within 24 h if EF <40%, anterior STEMI, HF, hypertension, or diabetes; ARB if ACE intolerant |
| High-intensity statin | Start immediately: atorvastatin 40-80 mg or rosuvastatin 20-40 mg |
| Aldosterone antagonist | If EF ≤40% + HF or diabetes, without significant renal impairment |
| Complication | Management |
|---|---|
| Cardiogenic shock | Primary PCI (culprit-only), inotropes (dobutamine), consider IABP or mechanical support |
| Acute HF/pulmonary edema | IV diuretics, nitrates, CPAP, intubation if severe |
| Ventricular fibrillation/VT | Defibrillation; amiodarone for refractory VT; beta-blockers |
| Complete heart block (inferior MI) | Temporary pacing; often resolves |
| Pericarditis (Dressler's) | Aspirin, colchicine; avoid NSAIDs/steroids in early post-MI period |
| Mechanical complications | (Free wall rupture, VSD, papillary muscle rupture) - urgent surgical repair |
| Goal | Target |
|---|---|
| ECG acquisition/interpretation | ≤10 minutes of arrival |
| Door-to-balloon (primary PCI) | ≤90 minutes |
| First-medical-contact to device (transferred) | ≤120 minutes |
| Door-to-needle (fibrinolysis) | ≤30 minutes |
| Angiography post-fibrinolysis | 2-24 hours |
Create a quick-reference PDF on STEMI reperfusion algorithms
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"
mkdir -p /home/daytona/workspace/stemi-pdf && echo "done"
~/stemi-pdf/generate_stemi_pdf.py
"""
STEMI Reperfusion Algorithm - Quick Reference PDF
Uses ReportLab to build a clinical, colour-coded reference card.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Arrow
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
import os
OUTPUT = "/home/daytona/workspace/stemi-pdf/STEMI_Reperfusion_QuickRef.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
RED = colors.HexColor("#C0392B")
DARK_RED = colors.HexColor("#922B21")
ORANGE = colors.HexColor("#E67E22")
GREEN = colors.HexColor("#1A7A4A")
DARK_GREEN= colors.HexColor("#145A32")
BLUE = colors.HexColor("#1A5276")
LIGHT_BLUE= colors.HexColor("#D6EAF8")
LIGHT_RED = colors.HexColor("#FADBD8")
LIGHT_GREEN=colors.HexColor("#D5F5E3")
LIGHT_ORANGE=colors.HexColor("#FDEBD0")
YELLOW = colors.HexColor("#F9E79F")
LIGHT_YELLOW=colors.HexColor("#FEF9E7")
GRAY = colors.HexColor("#566573")
LIGHT_GRAY= colors.HexColor("#F2F3F4")
MID_GRAY = colors.HexColor("#D5D8DC")
WHITE = colors.white
BLACK = colors.black
HEADER_BG = colors.HexColor("#1B2631")
SUBHDR_BG = colors.HexColor("#2E4057")
W, H = A4 # 210 x 297 mm
# ── Custom Flowables ─────────────────────────────────────────────────────────
class ColorBar(Flowable):
"""A solid coloured bar with optional text."""
def __init__(self, width, height, fill_color, text="", text_color=WHITE,
font_size=11, bold=True, radius=3):
super().__init__()
self.width = width
self.height = height
self.fill_color = fill_color
self.text = text
self.text_color = text_color
self.font_size = font_size
self.bold = bold
self.radius = radius
def draw(self):
c = self.canv
c.setFillColor(self.fill_color)
c.roundRect(0, 0, self.width, self.height, self.radius, fill=1, stroke=0)
if self.text:
c.setFillColor(self.text_color)
font = "Helvetica-Bold" if self.bold else "Helvetica"
c.setFont(font, self.font_size)
c.drawCentredString(self.width / 2, self.height / 2 - self.font_size * 0.35,
self.text)
class TimingBox(Flowable):
"""A prominent time-target box."""
def __init__(self, label, value, unit, color, width=None):
super().__init__()
self.label = label
self.value = value
self.unit = unit
self.color = color
self.width = width or 50 * mm
self.height = 22 * mm
def draw(self):
c = self.canv
w, h = self.width, self.height
# Outer box
c.setFillColor(self.color)
c.roundRect(0, 0, w, h, 4, fill=1, stroke=0)
# Inner white zone for value
c.setFillColor(WHITE)
c.roundRect(2*mm, 2*mm, w - 4*mm, h - 9*mm, 2, fill=1, stroke=0)
# Value
c.setFillColor(self.color)
c.setFont("Helvetica-Bold", 16)
c.drawCentredString(w / 2, h - 13*mm, self.value)
# Unit
c.setFont("Helvetica", 7)
c.setFillColor(self.color)
c.drawCentredString(w / 2, h - 16*mm, self.unit)
# Label at bottom
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 7)
c.drawCentredString(w / 2, 1.5*mm, self.label)
# ── Document styles ──────────────────────────────────────────────────────────
def make_styles():
s = {}
s["title"] = ParagraphStyle("title",
fontName="Helvetica-Bold", fontSize=18, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=2, leading=22)
s["subtitle"] = ParagraphStyle("subtitle",
fontName="Helvetica", fontSize=10, textColor=colors.HexColor("#AEB6BF"),
alignment=TA_CENTER, spaceAfter=2, leading=13)
s["section"] = ParagraphStyle("section",
fontName="Helvetica-Bold", fontSize=10, textColor=WHITE,
alignment=TA_LEFT, leading=13, leftIndent=3)
s["body"] = ParagraphStyle("body",
fontName="Helvetica", fontSize=8.5, textColor=BLACK,
leading=12, spaceAfter=2, leftIndent=4)
s["body_bold"] = ParagraphStyle("body_bold",
fontName="Helvetica-Bold", fontSize=8.5, textColor=BLACK,
leading=12, spaceAfter=2, leftIndent=4)
s["bullet"] = ParagraphStyle("bullet",
fontName="Helvetica", fontSize=8, textColor=BLACK,
leading=11, leftIndent=10, bulletIndent=3, spaceAfter=1)
s["bullet_bold"] = ParagraphStyle("bullet_bold",
fontName="Helvetica-Bold", fontSize=8, textColor=BLACK,
leading=11, leftIndent=10, bulletIndent=3, spaceAfter=1)
s["small"] = ParagraphStyle("small",
fontName="Helvetica", fontSize=7, textColor=GRAY,
leading=9, alignment=TA_CENTER)
s["small_left"] = ParagraphStyle("small_left",
fontName="Helvetica", fontSize=7, textColor=GRAY,
leading=9, alignment=TA_LEFT, leftIndent=4)
s["warning"] = ParagraphStyle("warning",
fontName="Helvetica-Bold", fontSize=8, textColor=DARK_RED,
leading=11, leftIndent=4)
s["green_bold"] = ParagraphStyle("green_bold",
fontName="Helvetica-Bold", fontSize=8.5, textColor=DARK_GREEN,
leading=11, leftIndent=4)
s["table_header"] = ParagraphStyle("table_header",
fontName="Helvetica-Bold", fontSize=8, textColor=WHITE,
alignment=TA_CENTER, leading=10)
s["table_cell"] = ParagraphStyle("table_cell",
fontName="Helvetica", fontSize=7.5, textColor=BLACK,
leading=10, leftIndent=2)
s["table_cell_bold"] = ParagraphStyle("table_cell_bold",
fontName="Helvetica-Bold", fontSize=7.5, textColor=BLACK,
leading=10, leftIndent=2)
return s
# ── Helper builders ──────────────────────────────────────────────────────────
def section_header(text, color, styles, width=None):
w = width or (W - 30*mm)
return [
ColorBar(w, 7*mm, color, text=text, font_size=9.5),
Spacer(1, 2*mm),
]
def two_col_table(left_content, right_content, col_widths=None, style_extra=None):
"""Wrap two lists of flowables in a side-by-side table."""
col_widths = col_widths or [88*mm, 88*mm]
data = [[left_content, right_content]]
ts = TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
])
if style_extra:
ts.add(*style_extra)
return Table(data, colWidths=col_widths, style=ts)
def info_table(headers, rows, col_widths, header_color=BLUE):
"""Build a styled clinical table."""
data = [[Paragraph(h, ParagraphStyle("th", fontName="Helvetica-Bold",
fontSize=7.5, textColor=WHITE, alignment=TA_CENTER, leading=10))
for h in headers]]
for row in rows:
data.append([Paragraph(str(cell),
ParagraphStyle("td", fontName="Helvetica", fontSize=7.5,
textColor=BLACK, leading=10, leftIndent=2))
for cell in row])
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), header_color),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
("GRID", (0,0), (-1,-1), 0.4, MID_GRAY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROUNDEDCORNERS", [3]),
])
return Table(data, colWidths=col_widths, style=ts)
def alert_box(text, bg_color, text_color=BLACK, styles=None, width=None):
w = width or (W - 30*mm)
p = Paragraph(text, ParagraphStyle("alert",
fontName="Helvetica-Bold", fontSize=8, textColor=text_color,
leading=11, leftIndent=6, rightIndent=6))
t = Table([[p]], colWidths=[w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [3]),
]))
return t
# ── Main build ───────────────────────────────────────────────────────────────
def build_pdf():
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=12*mm, bottomMargin=10*mm,
title="STEMI Reperfusion Algorithm - Quick Reference",
author="Orris Medical Reference",
subject="STEMI Management Guidelines 2025"
)
styles = make_styles()
story = []
full_w = W - 30*mm # 180 mm usable
# ═══════════════════════════════════════════════════════════════════
# HEADER BLOCK
# ═══════════════════════════════════════════════════════════════════
header_data = [[
Paragraph("STEMI REPERFUSION ALGORITHM", styles["title"]),
Paragraph("Quick Reference Card | Based on 2025 ACC/AHA/ACEP/NAEMSP/SCAI Guideline", styles["subtitle"]),
Paragraph("For Emergency & Cardiology Use | Orris Medical Reference | July 2026", styles["subtitle"]),
]]
header_table = Table(header_data, colWidths=[full_w])
header_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), HEADER_BG),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [5]),
]))
story.append(header_table)
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# KEY TIME TARGETS
# ═══════════════════════════════════════════════════════════════════
story += section_header("KEY TIME TARGETS", RED, styles, full_w)
box_w = 42*mm
gap = (full_w - 4 * box_w) / 5
time_data = [[
TimingBox("ECG Acquisition", "≤10", "min from arrival", RED, box_w),
TimingBox("Door-to-Balloon\n(Primary PCI)", "≤90", "min", DARK_RED, box_w),
TimingBox("1st Contact to Device\n(Transfer PCI)", "≤120", "min", ORANGE, box_w),
TimingBox("Door-to-Needle\n(Fibrinolysis)", "≤30", "min", GREEN, box_w),
]]
time_table = Table(time_data,
colWidths=[box_w + gap, box_w + gap, box_w + gap, box_w + gap])
time_table.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), gap/2),
("RIGHTPADDING", (0,0), (-1,-1), gap/2),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("ALIGN", (0,0), (-1,-1), "CENTER"),
]))
story.append(time_table)
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# DIAGNOSIS CRITERIA
# ═══════════════════════════════════════════════════════════════════
story += section_header("STEMI DIAGNOSIS CRITERIA", BLUE, styles, full_w)
diag_left = [
Paragraph("<b>ST Elevation (New J-point elevation):</b>", styles["body_bold"]),
Paragraph("• Men <40 yrs: ≥2.5 mm in V2-V3; ≥1 mm in other leads", styles["bullet"]),
Paragraph("• Men ≥40 yrs: ≥2.0 mm in V2-V3; ≥1 mm in other leads", styles["bullet"]),
Paragraph("• Women: ≥1.5 mm in V2-V3; ≥1 mm in other leads", styles["bullet"]),
Paragraph("• Posterior MI: ST depression ≥0.5 mm in V1-V3 + tall R waves", styles["bullet"]),
Paragraph("• New LBBB with ischaemic symptoms = treat as STEMI", styles["bullet"]),
]
diag_right = [
Paragraph("<b>Immediate Actions:</b>", styles["body_bold"]),
Paragraph("• 12-lead ECG within <b>10 min</b> of presentation", styles["bullet"]),
Paragraph("• Serial ECGs if initial non-diagnostic", styles["bullet"]),
Paragraph("• hs-Troponin: baseline + 1-2 h repeat", styles["bullet"]),
Paragraph("• IV access, O<sub>2</sub> only if SpO<sub>2</sub> <90%", styles["bullet"]),
Paragraph("• Aspirin 162-325 mg (chewed) immediately", styles["bullet"]),
Paragraph("• Activate cath lab / transfer pathway NOW", styles["bullet"]),
]
story.append(two_col_table(diag_left, diag_right, [90*mm, 90*mm]))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# REPERFUSION DECISION
# ═══════════════════════════════════════════════════════════════════
story += section_header("REPERFUSION STRATEGY DECISION", SUBHDR_BG, styles, full_w)
# PCI column
pci_items = [
ColorBar(88*mm, 6*mm, DARK_RED, "PRIMARY PCI (Preferred Strategy)", font_size=8.5),
Spacer(1, 2*mm),
Paragraph("<b>Indications / Favours PCI:</b>", styles["body_bold"]),
Paragraph("• PCI available within <b>90 min</b> of 1st medical contact", styles["bullet"]),
Paragraph("• Transfer possible with device time <b>≤120 min</b>", styles["bullet"]),
Paragraph("• Cardiogenic shock / Killip III-IV", styles["bullet"]),
Paragraph("• Contraindication to fibrinolysis", styles["bullet"]),
Paragraph("• Symptoms >3 h (clot less lysable)", styles["bullet"]),
Paragraph("• Diagnosis uncertain", styles["bullet"]),
Paragraph("• Prior CABG or PCI", styles["bullet"]),
Paragraph("• High bleeding risk with lytics", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>Technical Points:</b>", styles["body_bold"]),
Paragraph("• Stenting superior to balloon angioplasty alone", styles["bullet"]),
Paragraph("• <b>Transradial access preferred</b> (↓ bleeding, possible mortality benefit)", styles["bullet"]),
Paragraph("• Complete revascularisation of non-culprit arteries (index or within 45 days)", styles["bullet"]),
Paragraph("• <b>Cardiogenic shock:</b> culprit-only PCI (CULPRIT-SHOCK trial)", styles["bullet"]),
Paragraph("• No facilitated PCI (lytics + GPIIb/IIIa pre-PCI — increases bleeding)", styles["bullet"]),
]
# Fibrinolysis column
fib_items = [
ColorBar(88*mm, 6*mm, DARK_GREEN, "FIBRINOLYSIS (When PCI Unavailable)", font_size=8.5),
Spacer(1, 2*mm),
Paragraph("<b>Indications / Favours Fibrinolysis:</b>", styles["body_bold"]),
Paragraph("• PCI delay >120 min (1st contact to device)", styles["bullet"]),
Paragraph("• Very early presentation (<2-3 h) at non-PCI hospital", styles["bullet"]),
Paragraph("• Low bleeding risk", styles["bullet"]),
Spacer(1, 1*mm),
Paragraph("<b>Agents (IV):</b>", styles["body_bold"]),
Paragraph("• Tenecteplase (TNK) — weight-based bolus <b>[preferred]</b>", styles["bullet"]),
Paragraph("• Alteplase (tPA) — 15 mg IV bolus → 0.75 mg/kg over 30 min → 0.5 mg/kg over 60 min", styles["bullet"]),
Paragraph("• Reteplase (rPA) — 10 U IV x 2 (30 min apart)", styles["bullet"]),
Paragraph("• Streptokinase — 1.5 MU over 60 min (no fibrin specificity)", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>Post-Fibrinolysis:</b>", styles["body_bold"]),
Paragraph("• Transfer ALL patients to PCI-capable centre", styles["bullet"]),
Paragraph("• Angiography at <b>2-24 h</b> if successful reperfusion", styles["bullet"]),
Paragraph("• <b>Rescue PCI immediately</b> if reperfusion fails:", styles["bullet"]),
Paragraph(" - No ≥50% ST resolution at 60-90 min", styles["small_left"]),
Paragraph(" - Persistent pain / haemodynamic instability", styles["small_left"]),
]
story.append(two_col_table(pci_items, fib_items, [90*mm, 90*mm]))
story.append(Spacer(1, 2*mm))
# Fibrinolysis contraindications
abs_ci = [
"Prior intracranial haemorrhage (any time)",
"Known intracranial neoplasm / AVM",
"Ischaemic stroke within 3 months",
"Suspected aortic dissection",
"Active internal bleeding (not menses)",
"Significant closed-head trauma/facial fracture <3 months",
]
rel_ci = [
"Uncontrolled HTN (SBP >180 or DBP >110 mmHg)",
"Ischaemic stroke >3 months ago",
"Traumatic or prolonged CPR (>10 min)",
"Major surgery within 3 weeks",
"Internal bleeding within 2-4 weeks",
"Pregnancy",
"Active peptic ulcer",
"Current anticoagulant use (INR >2-3)",
]
ci_left = [
ColorBar(88*mm, 5.5*mm, RED, "ABSOLUTE CONTRAINDICATIONS to Fibrinolysis", font_size=8),
Spacer(1, 1.5*mm),
] + [Paragraph(f"<b>✖</b> {x}", styles["bullet"]) for x in abs_ci]
ci_right = [
ColorBar(88*mm, 5.5*mm, ORANGE, "RELATIVE CONTRAINDICATIONS to Fibrinolysis", font_size=8),
Spacer(1, 1.5*mm),
] + [Paragraph(f"△ {x}", styles["bullet"]) for x in rel_ci]
story.append(two_col_table(ci_left, ci_right, [90*mm, 90*mm]))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# ANTITHROMBOTIC THERAPY
# ═══════════════════════════════════════════════════════════════════
story += section_header("ANTITHROMBOTIC THERAPY", BLUE, styles, full_w)
antip_headers = ["Agent", "Loading Dose", "Maintenance", "Notes"]
antip_rows = [
["Aspirin", "162-325 mg PO (chewed)", "81 mg/day indefinitely", "Give immediately; first line always"],
["Ticagrelor", "180 mg PO", "90 mg BID x 12 months", "Preferred P2Y12 for PCI/ACS; reversible"],
["Prasugrel", "60 mg PO", "10 mg/day x 12 months", "Preferred with PCI; avoid if prior TIA/stroke, age >75, wt <60 kg"],
["Clopidogrel", "300-600 mg PO", "75 mg/day x 12 months", "Use with fibrinolysis or if ticagrelor/prasugrel contraindicated"],
]
story.append(info_table(antip_headers, antip_rows,
[28*mm, 42*mm, 48*mm, 62*mm], BLUE))
story.append(Spacer(1, 2*mm))
anticoag_headers = ["Anticoagulant", "Dose / Route", "Indication", "Notes"]
anticoag_rows = [
["UFH", "60 U/kg IV bolus (max 4000 U) + 12 U/kg/h infusion", "Primary PCI or fibrinolysis", "Adjust to aPTT 50-70 s; stop after PCI unless indicated"],
["Enoxaparin (LMWH)", "1 mg/kg SC q12h (or 0.75 mg/kg if age >75)", "Fibrinolysis / NSTEMI", "Continue up to 8 days or until revascularisation; preferred over UFH with lytics"],
["Bivalirudin", "0.75 mg/kg IV bolus + 1.75 mg/kg/h during PCI", "Primary PCI", "Alternative to UFH; fewer bleeding complications"],
["Fondaparinux", "2.5 mg SC daily", "NSTEMI conservative strategy", "Do NOT use alone for primary PCI (risk catheter thrombus)"],
]
story.append(info_table(anticoag_headers, anticoag_rows,
[26*mm, 50*mm, 44*mm, 60*mm], BLUE))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# ADDITIONAL THERAPIES & COMPLICATION MANAGEMENT
# ═══════════════════════════════════════════════════════════════════
story += section_header("ADDITIONAL ACUTE THERAPIES", GRAY, styles, full_w)
med_left = [
Paragraph("<b>Beta-Blockers</b>", styles["body_bold"]),
Paragraph("• Oral, within 24 h; target HR 50-60 bpm", styles["bullet"]),
Paragraph("• Metoprolol 25-50 mg PO q6-12 h (titrate up)", styles["bullet"]),
Paragraph("• <b>Avoid if:</b> cardiogenic shock, acute HF, significant bradycardia, PR >240 ms, 2nd/3rd degree AVB", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>ACE Inhibitors / ARBs</b>", styles["body_bold"]),
Paragraph("• Start within 24 h if: EF <40%, anterior STEMI, HF, hypertension, or diabetes", styles["bullet"]),
Paragraph("• Ramipril 2.5 mg → titrate to 10 mg/day; Lisinopril 5 mg/day", styles["bullet"]),
Paragraph("• ARB (e.g. valsartan) if ACE inhibitor intolerant", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>Statins (High-Intensity)</b>", styles["body_bold"]),
Paragraph("• Start immediately: Atorvastatin 40-80 mg OR Rosuvastatin 20-40 mg", styles["bullet"]),
Paragraph("• Target LDL <55 mg/dL (ESC) / <70 mg/dL (ACC/AHA)", styles["bullet"]),
]
med_right = [
Paragraph("<b>Nitrates</b>", styles["body_bold"]),
Paragraph("• Sublingual GTN for chest pain relief", styles["bullet"]),
Paragraph("• IV nitroglycerine if persistent pain, HTN, pulmonary oedema", styles["bullet"]),
Paragraph("• <b>Avoid if:</b> SBP <90 mmHg, HR <50 or >100, RV infarction, phosphodiesterase inhibitor use", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>Aldosterone Antagonist</b>", styles["body_bold"]),
Paragraph("• Eplerenone 25 mg/day → 50 mg/day (preferred); or spironolactone", styles["bullet"]),
Paragraph("• Indication: EF ≤40% + HF symptoms OR diabetes", styles["bullet"]),
Paragraph("• Avoid if: K >5.0 mEq/L, creatinine >2.5 (men) / >2.0 (women) mg/dL", styles["bullet"]),
Spacer(1, 2*mm),
Paragraph("<b>Oxygen</b>", styles["body_bold"]),
Paragraph("• Only if SpO<sub>2</sub> <90% — routine O<sub>2</sub> is <b>NOT</b> recommended", styles["bullet"]),
Spacer(1, 1*mm),
Paragraph("<b>Avoid:</b>", styles["warning"]),
Paragraph("• NSAIDs / corticosteroids (except aspirin): impair healing, increase rupture risk", styles["bullet"]),
Paragraph("• Morphine: use cautiously — may mask ischaemia, associated with worse outcomes", styles["bullet"]),
]
story.append(two_col_table(med_left, med_right, [90*mm, 90*mm]))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# COMPLICATIONS
# ═══════════════════════════════════════════════════════════════════
story += section_header("COMPLICATION MANAGEMENT", DARK_RED, styles, full_w)
comp_headers = ["Complication", "Clinical Features", "Management"]
comp_rows = [
["Cardiogenic Shock\n(Killip IV)", "SBP <90, cool peripheries,\nconfusion, oliguria",
"Culprit-only primary PCI; dobutamine/dopamine; consider IABP or Impella; avoid routine non-culprit PCI"],
["Acute Pulm. Oedema\n(Killip III)", "Dyspnoea, crackles, SpO2 ↓,\nfoamy sputum",
"Upright positioning, IV furosemide, IV nitrates (if SBP >100), CPAP/NIV; intubate if severe"],
["VF / Pulseless VT", "Cardiac arrest", "Immediate defibrillation; CPR; amiodarone 300 mg IV after 3rd shock"],
["Sustained VT\n(haemodynamically unstable)", "Hypotension, syncope", "Synchronised DC cardioversion; amiodarone 150 mg IV over 10 min"],
["Complete Heart Block\n(inferior MI)", "HR <40, haemodynamic compromise", "Atropine 0.5-1 mg IV; transcutaneous/transvenous pacing; usually reversible"],
["Acute MR\n(papillary muscle rupture)", "Sudden pulm. oedema, new murmur", "Urgent surgical repair; bridge with IABP, vasodilators if haemodynamically stable"],
["VSD\n(septal rupture)", "New harsh pansystolic murmur,\nRHF + LHF", "Urgent surgery; IABP as bridge; high mortality if surgery delayed"],
["Free Wall Rupture", "Sudden haemodynamic collapse,\ntamponade", "Emergency pericardiocentesis; immediate cardiac surgery"],
["Pericarditis\n(early / Dressler)", "Pleuritic chest pain, friction rub,\nST changes (saddle-shaped)", "Aspirin (high dose) + colchicine; avoid NSAIDs/steroids early post-MI"],
]
story.append(info_table(comp_headers, comp_rows,
[30*mm, 44*mm, 106*mm], DARK_RED))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# SECONDARY PREVENTION
# ═══════════════════════════════════════════════════════════════════
story += section_header("SECONDARY PREVENTION (DISCHARGE)", DARK_GREEN, styles, full_w)
sec_left = [
Paragraph("<b>Medications at Discharge:</b>", styles["body_bold"]),
Paragraph("✓ Aspirin 81 mg/day — <b>indefinitely</b>", styles["bullet"]),
Paragraph("✓ P2Y12 inhibitor (ticagrelor or clopidogrel) — <b>12 months</b>", styles["bullet"]),
Paragraph("✓ Beta-blocker — <b>minimum 1-3 years post-MI</b> (lifelong if EF <40%)", styles["bullet"]),
Paragraph("✓ High-intensity statin — <b>indefinitely</b>", styles["bullet"]),
Paragraph("✓ ACE inhibitor/ARB — indefinitely if EF <40%, HF, DM, or HTN", styles["bullet"]),
Paragraph("✓ Aldosterone antagonist — if EF ≤40% + HF or DM", styles["bullet"]),
]
sec_right = [
Paragraph("<b>Lifestyle & Targets:</b>", styles["body_bold"]),
Paragraph("• <b>Smoking cessation</b> — most impactful secondary prevention", styles["bullet"]),
Paragraph("• Cardiac rehabilitation — strongly recommended", styles["bullet"]),
Paragraph("• BP target: <130/80 mmHg", styles["bullet"]),
Paragraph("• LDL target: <55 mg/dL (ESC) / <70 mg/dL (ACC/AHA)", styles["bullet"]),
Paragraph("• HbA1c: <7% in diabetics", styles["bullet"]),
Paragraph("• BMI: target 18.5-24.9 kg/m<sup>2</sup>; Mediterranean diet", styles["bullet"]),
Paragraph("• Physical activity: 150 min moderate aerobic/week after clearance", styles["bullet"]),
]
story.append(two_col_table(sec_left, sec_right, [90*mm, 90*mm]))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# NSTEMI TIMING SUMMARY
# ═══════════════════════════════════════════════════════════════════
story += section_header("NSTEMI / UNSTABLE ANGINA: INVASIVE STRATEGY TIMING", BLUE, styles, full_w)
nstemi_headers = ["Timing", "Criteria", "Examples"]
nstemi_rows = [
["Immediate\n(<2 h)", "Any HIGH-RISK feature", "Refractory ischaemia, haemodynamic instability, cardiogenic shock, sustained VT/VF, acute HF/MR"],
["Early Invasive\n(<24 h)", "High-risk without immediate criteria", "TIMI ≥3 or GRACE >140; rapid biomarker rise; new ST depression; prior PCI <6 months"],
["Delayed Invasive\n(24-72 h)", "Intermediate risk", "Diabetes; renal insufficiency (GFR <60); EF <40%; early post-infarct angina; GRACE 109-140; prior CABG"],
["Ischemia-Driven\n(Conservative)", "Low risk", "TIMI ≤1 or GRACE <109; biomarker-negative; low-risk female patients; patient/clinician preference without high-risk features"],
]
story.append(info_table(nstemi_headers, nstemi_rows,
[30*mm, 38*mm, 112*mm], BLUE))
story.append(Spacer(1, 3*mm))
# ═══════════════════════════════════════════════════════════════════
# FOOTER
# ═══════════════════════════════════════════════════════════════════
story.append(HRFlowable(width=full_w, thickness=0.5, color=MID_GRAY, spaceAfter=2*mm))
footer_data = [[
Paragraph(
"<b>Source:</b> 2025 ACC/AHA/ACEP/NAEMSP/SCAI Guideline for Management of Patients With Acute Coronary Syndromes "
"(Rao SV et al., Circulation 2025; DOI: 10.1161/CIR.0000000000001309 | PMID: 40014670). "
"Also: Harrison's Principles of Internal Medicine 22e; Goldman-Cecil Medicine; Washington Manual of Medical Therapeutics; "
"Fuster and Hurst's The Heart 15e.",
styles["small"]
),
Paragraph(
"<b>Disclaimer:</b> For educational use only. Always apply clinical judgement and consult local protocols.",
styles["small"]
),
]]
footer_table = Table(footer_data, colWidths=[full_w])
footer_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_GRAY),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [3]),
]))
story.append(footer_table)
# ── Build ──
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
if __name__ == "__main__":
build_pdf()
cd /home/daytona/workspace/stemi-pdf && python generate_stemi_pdf.py 2>&1
~/stemi-pdf/generate_stemi_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stemi-pdf/generate_stemi_pdf.py'
cd /home/daytona/workspace/stemi-pdf && python generate_stemi_pdf.py 2>&1
ls -lh /home/daytona/workspace/stemi-pdf/STEMI_Reperfusion_QuickRef.pdf
cd /home/daytona/workspace/stemi-pdf && python -c " from pypdf import PdfReader …
cd /home/daytona/workspace/stemi-pdf && python -c " from pypdf import PdfReader …
STEMI Reperfusion QuickRef
PDF Document · PDF
| Section | Content |
|---|---|
| Key Time Targets | Colour-coded boxes: ECG ≤10 min, door-to-balloon ≤90 min, transfer ≤120 min, lytic door-to-needle ≤30 min |
| STEMI Diagnosis Criteria | ST elevation thresholds by sex/age; posterior MI; new LBBB |
| Reperfusion Decision | Primary PCI indications vs. fibrinolysis indications side-by-side; absolute and relative contraindications to fibrinolysis |
| Antithrombotic Therapy | Antiplatelet table (aspirin, ticagrelor, prasugrel, clopidogrel with doses); anticoagulant table (UFH, enoxaparin, bivalirudin, fondaparinux) |
| Additional Therapies | Beta-blockers, ACE inhibitors, statins, nitrates, aldosterone antagonists; avoid list (NSAIDs, routine O2, morphine caution) |
| Complications | 9-row table covering cardiogenic shock, pulmonary oedema, VF/VT, CHB, acute MR, VSD, free wall rupture, pericarditis |
| Secondary Prevention | Discharge medications checklist + lifestyle targets |
| NSTEMI Timing | Immediate/early/delayed/conservative invasive strategy criteria |