Mbbs medicine book
Give me pdf
Create a PDF study guide on a topic you're learning
mkdir -p /home/daytona/workspace/mi-study-guide && ls /home/daytona/workspace/mi…
~/mi-study-guide/generate_mi_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.platypus.flowables import Flowable
OUTPUT = "/home/daytona/workspace/mi-study-guide/MI_Study_Guide_MBBS.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
RED = colors.HexColor("#C0392B")
DARK_RED = colors.HexColor("#922B21")
LIGHT_RED= colors.HexColor("#FADBD8")
BLUE = colors.HexColor("#1A5276")
LIGHT_BLUE=colors.HexColor("#D6EAF8")
YELLOW = colors.HexColor("#FEF9E7")
ORANGE = colors.HexColor("#F39C12")
GREEN = colors.HexColor("#1E8449")
LIGHT_GREEN=colors.HexColor("#D5F5E3")
GREY_DARK= colors.HexColor("#2C3E50")
GREY_MID = colors.HexColor("#566573")
GREY_LIGHT=colors.HexColor("#F2F3F4")
WHITE = colors.white
# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("Title",
fontSize=28, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER, spaceAfter=4)
subtitle_style = S("Subtitle",
fontSize=13, fontName="Helvetica",
textColor=colors.HexColor("#F9EBEA"), alignment=TA_CENTER, spaceAfter=2)
meta_style = S("Meta",
fontSize=9, fontName="Helvetica",
textColor=colors.HexColor("#D5D8DC"), alignment=TA_CENTER)
h1 = S("H1",
fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, spaceAfter=6, spaceBefore=4)
h2 = S("H2",
fontSize=12, fontName="Helvetica-Bold",
textColor=BLUE, spaceAfter=4, spaceBefore=8)
h3 = S("H3",
fontSize=10, fontName="Helvetica-Bold",
textColor=DARK_RED, spaceAfter=3, spaceBefore=5)
body = S("Body",
fontSize=9.5, fontName="Helvetica",
textColor=GREY_DARK, leading=15, spaceAfter=4,
alignment=TA_JUSTIFY)
bullet = S("Bullet",
fontSize=9.5, fontName="Helvetica",
textColor=GREY_DARK, leading=14, spaceAfter=2,
leftIndent=14, firstLineIndent=-10)
bold_bullet = S("BoldBullet",
fontSize=9.5, fontName="Helvetica-Bold",
textColor=GREY_DARK, leading=14, spaceAfter=2,
leftIndent=14, firstLineIndent=-10)
small = S("Small",
fontSize=8, fontName="Helvetica",
textColor=GREY_MID, leading=12)
citation = S("Citation",
fontSize=7.5, fontName="Helvetica-Oblique",
textColor=GREY_MID, leading=11, spaceAfter=2)
# ── Header / Footer canvas ────────────────────────────────────────────────────
def add_page_decorations(canvas_obj, doc):
canvas_obj.saveState()
w, h = A4
# Top thin bar
canvas_obj.setFillColor(RED)
canvas_obj.rect(0, h - 6*mm, w, 6*mm, fill=1, stroke=0)
# Bottom bar
canvas_obj.setFillColor(GREY_DARK)
canvas_obj.rect(0, 0, w, 10*mm, fill=1, stroke=0)
# Footer text
canvas_obj.setFillColor(WHITE)
canvas_obj.setFont("Helvetica", 7.5)
canvas_obj.drawString(15*mm, 3.5*mm, "MBBS Medicine Study Guide • Myocardial Infarction")
canvas_obj.drawRightString(w - 15*mm, 3.5*mm, f"Page {doc.page}")
canvas_obj.restoreState()
# ── Helper flowables ──────────────────────────────────────────────────────────
def section_header(text, color=BLUE):
data = [[Paragraph(text, h1)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("ROUNDEDCORNERS", [4,4,4,4]),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 12),
]))
return t
def info_box(title, items, bg=LIGHT_BLUE, title_color=BLUE):
rows = [[Paragraph(f"<b>{title}</b>", ParagraphStyle("bh",
fontSize=10, fontName="Helvetica-Bold", textColor=title_color))]]
for item in items:
rows.append([Paragraph(f"• {item}", bullet)])
t = Table(rows, colWidths=[16.5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), bg),
("BACKGROUND", (0,1), (-1,-1), WHITE),
("BOX", (0,0), (-1,-1), 0.8, title_color),
("LINEBELOW", (0,0), (0,0), 0.5, title_color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return t
def warning_box(title, items):
return info_box(title, items, bg=LIGHT_RED, title_color=DARK_RED)
def green_box(title, items):
return info_box(title, items, bg=LIGHT_GREEN, title_color=GREEN)
def yellow_box(title, text_lines):
rows = [[Paragraph(f"<b>{title}</b>", ParagraphStyle("yh",
fontSize=10, fontName="Helvetica-Bold", textColor=GREY_DARK))]]
for line in text_lines:
rows.append([Paragraph(line, body)])
t = Table(rows, colWidths=[16.5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), YELLOW),
("BOX", (0,0), (-1,-1), 0.8, ORANGE),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return t
def two_col_table(left_items, right_items, left_title, right_title,
left_bg=LIGHT_BLUE, right_bg=LIGHT_RED):
header = [
Paragraph(f"<b>{left_title}</b>",
ParagraphStyle("lh", fontSize=9.5, fontName="Helvetica-Bold",
textColor=BLUE)),
Paragraph(f"<b>{right_title}</b>",
ParagraphStyle("rh", fontSize=9.5, fontName="Helvetica-Bold",
textColor=DARK_RED)),
]
max_len = max(len(left_items), len(right_items))
left_items += [""] * (max_len - len(left_items))
right_items += [""] * (max_len - len(right_items))
rows = [header]
for l, r in zip(left_items, right_items):
rows.append([
Paragraph(f"• {l}" if l else "", bullet),
Paragraph(f"• {r}" if r else "", bullet),
])
t = Table(rows, colWidths=[8.2*cm, 8.2*cm], hAlign="LEFT")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), left_bg),
("BACKGROUND", (1,0), (1,0), right_bg),
("BACKGROUND", (0,1), (0,-1), WHITE),
("BACKGROUND", (1,1), (1,-1), WHITE),
("BOX", (0,0), (0,-1), 0.6, BLUE),
("BOX", (1,0), (1,-1), 0.6, DARK_RED),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
def spacer(h=8):
return Spacer(1, h)
def hr(color=colors.HexColor("#AEB6BF"), thickness=0.5):
return HRFlowable(width="100%", thickness=thickness, color=color,
spaceAfter=4, spaceBefore=4)
# ── Document ──────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm,
title="Myocardial Infarction - MBBS Study Guide",
author="Orris Medical Library",
)
story = []
# ══════════════════════════════════════════════════════════════════════════════
# COVER PAGE
# ══════════════════════════════════════════════════════════════════════════════
cover_data = [[
Paragraph("MYOCARDIAL INFARCTION", title_style),
Paragraph("MBBS Medicine Study Guide", subtitle_style),
Paragraph("Internal Medicine • Cardiology • Pathology • Physiology", meta_style),
]]
cover_table = Table(cover_data, colWidths=[17*cm])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), RED),
("ROUNDEDCORNERS",[6,6,6,6]),
("TOPPADDING", (0,0), (-1,-1), 20),
("BOTTOMPADDING", (0,0), (-1,-1), 20),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
story.append(spacer(10))
story.append(cover_table)
story.append(spacer(18))
# Quick-reference card on cover
qr_items = [
["<b>Definition</b>", "Irreversible ischaemic necrosis of myocardium due to prolonged coronary artery occlusion"],
["<b>Classic Triad</b>", "Chest pain + ECG changes + Cardiac biomarker rise"],
["<b>Commonest cause</b>", "Rupture of an atherosclerotic plaque → thrombosis"],
["<b>Most common site</b>", "LAD territory (anterior wall, septum)"],
["<b>Earliest ECG change</b>", "Peaked (hyperacute) T waves → ST elevation"],
["<b>Gold standard Dx</b>", "Troponin I/T (high-sensitivity assay)"],
["<b>1st-line reperfusion</b>", "Primary PCI within 90 minutes (door-to-balloon)"],
]
qr_table = Table(qr_items, colWidths=[4.5*cm, 12*cm])
qr_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), GREY_DARK),
("BACKGROUND", (1,0), (1,-1), GREY_LIGHT),
("TEXTCOLOR", (0,0), (0,-1), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 9),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,0),(-1,-1), [GREY_DARK, GREY_DARK]), # handled per col
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#BDC3C7")),
("BOX", (0,0), (-1,-1), 1, GREY_DARK),
]))
# Alternate rows in right column
for i in range(len(qr_items)):
bg = colors.HexColor("#E8EAED") if i % 2 == 0 else WHITE
qr_table.setStyle(TableStyle([("BACKGROUND",(1,i),(1,i), bg)]))
story.append(Paragraph("<b>QUICK REFERENCE CARD</b>",
ParagraphStyle("qrt", fontSize=11, fontName="Helvetica-Bold",
textColor=GREY_DARK, spaceAfter=5)))
story.append(qr_table)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 1. DEFINITION & CLASSIFICATION
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("1. DEFINITION & CLASSIFICATION", RED))
story.append(spacer(6))
story.append(Paragraph(
"Myocardial infarction (MI) is defined as <b>myocardial cell death</b> due to prolonged "
"ischaemia, evidenced by a rise and/or fall of cardiac troponin (cTn) with at least one "
"value above the 99th percentile upper reference limit, together with clinical evidence "
"of myocardial ischaemia.", body))
story.append(spacer(4))
# Types table
types_data = [
[Paragraph("<b>Type</b>", bold_bullet),
Paragraph("<b>Cause</b>", bold_bullet),
Paragraph("<b>Example</b>", bold_bullet)],
[Paragraph("Type 1", bullet), Paragraph("Atherosclerotic plaque rupture/erosion → thrombus", bullet), Paragraph("Spontaneous MI", bullet)],
[Paragraph("Type 2", bullet), Paragraph("Supply-demand mismatch (non-thrombotic)", bullet), Paragraph("Vasospasm, severe anaemia, tachyarrhythmia", bullet)],
[Paragraph("Type 3", bullet), Paragraph("Sudden cardiac death before biomarkers drawn", bullet), Paragraph("Presumed MI at autopsy", bullet)],
[Paragraph("Type 4a", bullet), Paragraph("PCI-related (>5× 99th percentile cTn)", bullet), Paragraph("Post-PCI MI", bullet)],
[Paragraph("Type 4b", bullet), Paragraph("In-stent thrombosis", bullet), Paragraph("Confirmed angiographically", bullet)],
[Paragraph("Type 5", bullet), Paragraph("CABG-related (>10× 99th percentile cTn)", bullet), Paragraph("Perioperative MI", bullet)],
]
types_table = Table(types_data, colWidths=[2.5*cm, 8*cm, 6*cm])
types_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_BLUE, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, BLUE),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#BDC3C7")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(Paragraph("<b>Universal Classification of MI (ESC/ACC/AHA 4th Universal Definition)</b>", h2))
story.append(types_table)
story.append(spacer(6))
# STEMI vs NSTEMI
story.append(Paragraph("<b>STEMI vs NSTEMI vs UA</b>", h2))
story.append(two_col_table(
left_title="STEMI (ST-Elevation MI)",
right_title="NSTEMI / Unstable Angina",
left_items=[
"Full-thickness (transmural) ischaemia",
"ST elevation on ECG (≥1 mm in 2 contiguous leads)",
"New LBBB may be equivalent",
"Troponin POSITIVE",
"Urgent reperfusion mandatory (PCI/thrombolysis)",
"Q-waves may develop (old infarct marker)",
],
right_items=[
"Partial-thickness (subendocardial) ischaemia",
"ST depression / T-wave inversion / normal ECG",
"NSTEMI: Troponin POSITIVE",
"UA: Troponin NEGATIVE",
"Risk-stratified management (GRACE score)",
"No Q-waves typically",
],
left_bg=LIGHT_RED, right_bg=LIGHT_BLUE
))
story.append(spacer(8))
story.append(citation("Sources: Goldman-Cecil Medicine; Braunwald's Heart Disease; Harrison's Principles of Internal Medicine 22e"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 2. AETIOLOGY & RISK FACTORS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2. AETIOLOGY & RISK FACTORS", DARK_RED))
story.append(spacer(6))
story.append(Paragraph(
"Over <b>90% of MIs</b> result from coronary atherosclerosis complicated by "
"acute plaque rupture or erosion, triggering thrombus formation that partially "
"or completely occludes the vessel lumen.", body))
story.append(spacer(5))
story.append(two_col_table(
left_title="Non-modifiable Risk Factors",
right_title="Modifiable Risk Factors",
left_items=[
"Age (men >45 yrs, women >55 yrs)",
"Male sex (oestrogen protective pre-menopause)",
"Family history of premature CAD (<55 M, <65 F)",
"Genetic predisposition (APOE, LPA loci)",
],
right_items=[
"Hypertension (strongest modifiable RF)",
"Dyslipidaemia (↑LDL, ↓HDL)",
"Diabetes mellitus / insulin resistance",
"Cigarette smoking",
"Obesity (BMI >30) / metabolic syndrome",
"Physical inactivity",
"Psychosocial stress",
"Cocaine / amphetamine use",
],
left_bg=LIGHT_BLUE, right_bg=LIGHT_RED
))
story.append(spacer(6))
story.append(warning_box("INTERHEART Study (Lancet 2004) — 9 Risk Factors account for >90% of MI risk globally",
["Dyslipidaemia (ApoB/ApoA1 ratio)",
"Smoking",
"Hypertension",
"Diabetes",
"Abdominal obesity",
"Psychosocial factors",
"Lack of daily fruit/vegetable consumption",
"Absence of regular physical activity",
"No regular alcohol consumption"]))
story.append(spacer(8))
# Pathophysiology
story.append(section_header("3. PATHOPHYSIOLOGY", BLUE))
story.append(spacer(6))
story.append(Paragraph("<b>Step-by-step sequence of events in Type 1 MI:</b>", h2))
steps = [
("1. Atherosclerotic plaque formation",
"Lipid accumulation → foam cells → fibrous cap over lipid-rich necrotic core. "
"Vulnerable plaques have thin caps, large lipid cores, and abundant macrophages."),
("2. Plaque rupture / erosion",
"Mechanical stress, inflammation (MMP activation), or erosion of endothelium "
"exposes sub-endothelial collagen and tissue factor."),
("3. Platelet activation & aggregation",
"Von Willebrand factor and collagen bind GP Ib and GP IIb/IIIa receptors → "
"platelet plug. Thromboxane A₂ and ADP amplify aggregation."),
("4. Coagulation cascade activation",
"Tissue factor → extrinsic pathway → thrombin → fibrinogen → fibrin. "
"Stabilised thrombus occludes the lumen."),
("5. Ischaemia onset",
"Cessation of blood flow → O₂ deprivation → anaerobic metabolism → "
"lactic acidosis, ATP depletion, intracellular Ca²⁺ rise within minutes."),
("6. Irreversible cell death",
"If ischaemia persists >20-40 minutes → coagulative necrosis begins. "
"Wavefront of necrosis progresses from subendocardium outward over 3-6 hours."),
("7. Reperfusion injury",
"Restoration of flow generates ROS (reactive oxygen species), calcium overload, "
"and neutrophil infiltration → additional cell death (reperfusion injury paradox)."),
("8. Remodelling",
"Inflammatory phase (neutrophils → macrophages) → granulation tissue → "
"fibrotic scar. Infarct expansion and ventricular remodelling over weeks-months."),
]
for title, text in steps:
step_data = [[
Paragraph(title, ParagraphStyle("st", fontSize=9.5, fontName="Helvetica-Bold",
textColor=WHITE)),
Paragraph(text, ParagraphStyle("sb", fontSize=9, fontName="Helvetica",
textColor=GREY_DARK, leading=13))
]]
step_table = Table(step_data, colWidths=[4.5*cm, 12*cm])
step_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), BLUE),
("BACKGROUND", (1,0), (1,0), GREY_LIGHT),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("LINEBELOW", (0,0), (-1,0), 0.3, colors.HexColor("#BDC3C7")),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(step_table)
story.append(spacer(6))
story.append(citation("Source: Robbins & Cotran Pathologic Basis of Disease; Guyton & Hall Textbook of Medical Physiology"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 4. CLINICAL FEATURES
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4. CLINICAL FEATURES", RED))
story.append(spacer(6))
story.append(Paragraph("<b>Classic Presentation</b>", h2))
story.append(info_box("Chest Pain (Present in ~75% of MI)",
["Heavy, crushing, vice-like, or pressure sensation",
"Retrosternal with radiation to left arm, jaw, neck, or epigastrium",
"Duration >20 minutes (distinguishes from stable angina)",
"Not relieved by nitrates (or only partial relief)",
"Associated with sweating (diaphoresis), nausea, vomiting"],
bg=LIGHT_RED, title_color=DARK_RED))
story.append(spacer(5))
story.append(Paragraph("<b>Associated Symptoms</b>", h2))
story.append(two_col_table(
left_title="Symptoms",
right_title="Signs on Examination",
left_items=[
"Breathlessness / dyspnoea (LVF)",
"Palpitations (arrhythmia)",
"Syncope or pre-syncope",
"Anxiety / sense of impending doom",
"Epigastric pain / heartburn (inferior MI)",
],
right_items=[
"Pale, cold, clammy skin (sympathetic activation)",
"Tachycardia (sinus or VT)",
"Bradycardia (inferior MI → vagal tone)",
"Hypotension (cardiogenic shock) or hypertension",
"S3 gallop (LV dysfunction), S4 (reduced compliance)",
"Crackles at lung bases (pulmonary oedema)",
"Raised JVP (RV infarct or LVF)",
"Mitral regurgitation murmur (papillary muscle rupture)",
],
left_bg=LIGHT_BLUE, right_bg=LIGHT_RED
))
story.append(spacer(5))
story.append(warning_box("SILENT MI — High Yield",
["20-30% of MIs are silent (no chest pain)",
"More common in diabetics (autonomic neuropathy), elderly, and women",
"May present as sudden-onset heart failure, syncope, or incidental ECG finding",
"Inferior MI often mimics GI pathology — always check ECG for epigastric pain"]))
story.append(spacer(6))
# Killip Classification
story.append(Paragraph("<b>Killip Classification (Haemodynamic Status in Acute MI)</b>", h2))
killip_data = [
[Paragraph("<b>Class</b>", bold_bullet),
Paragraph("<b>Clinical Features</b>", bold_bullet),
Paragraph("<b>In-hospital Mortality</b>", bold_bullet)],
[Paragraph("I", bullet), Paragraph("No heart failure signs", bullet), Paragraph("~6%", bullet)],
[Paragraph("II", bullet), Paragraph("Mild HF: crackles <50% lung fields, S3, raised JVP", bullet), Paragraph("~17%", bullet)],
[Paragraph("III", bullet), Paragraph("Acute pulmonary oedema", bullet), Paragraph("~38%", bullet)],
[Paragraph("IV", bullet), Paragraph("Cardiogenic shock: SBP <90 mmHg + hypoperfusion", bullet), Paragraph("~67-80%", bullet)],
]
killip_table = Table(killip_data, colWidths=[2.5*cm, 10*cm, 4*cm])
killip_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_RED),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_RED, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, DARK_RED),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#F5B7B1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
("ALIGN", (2,0), (2,-1), "CENTER"),
]))
story.append(killip_table)
story.append(spacer(4))
story.append(citation("Source: Braunwald's Heart Disease 12e"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 5. INVESTIGATIONS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5. INVESTIGATIONS", BLUE))
story.append(spacer(6))
# ECG Changes
story.append(Paragraph("<b>A. Electrocardiogram (ECG) — Must do within 10 minutes of presentation</b>", h2))
ecg_data = [
[Paragraph("<b>Phase</b>", bold_bullet),
Paragraph("<b>ECG Finding</b>", bold_bullet),
Paragraph("<b>Timing</b>", bold_bullet)],
[Paragraph("Hyperacute", bullet), Paragraph("Tall, peaked (hyperacute) T waves — earliest change", bullet), Paragraph("Minutes", bullet)],
[Paragraph("Acute", bullet), Paragraph("ST elevation (STEMI) — 'tombstone' pattern in severe cases", bullet), Paragraph("Hours", bullet)],
[Paragraph("Evolving", bullet), Paragraph("T-wave inversion, ST returning to baseline", bullet), Paragraph("Hours–days", bullet)],
[Paragraph("Old/healed", bullet), Paragraph("Pathological Q waves (>40 ms wide, >1/4 R height)", bullet), Paragraph("Days–permanent", bullet)],
]
ecg_table = Table(ecg_data, colWidths=[3.5*cm, 10*cm, 3*cm])
ecg_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_BLUE, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, BLUE),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
]))
story.append(ecg_table)
story.append(spacer(5))
# Territory localisation
story.append(Paragraph("<b>ECG Localisation of MI Territory</b>", h3))
loc_data = [
[Paragraph("<b>Leads with Changes</b>", bold_bullet),
Paragraph("<b>Territory</b>", bold_bullet),
Paragraph("<b>Artery</b>", bold_bullet)],
[Paragraph("V1–V4", bullet), Paragraph("Anterior", bullet), Paragraph("LAD (proximal)", bullet)],
[Paragraph("V1–V2", bullet), Paragraph("Septal", bullet), Paragraph("LAD (septal branches)", bullet)],
[Paragraph("V3–V4", bullet), Paragraph("Anterior", bullet), Paragraph("LAD (diagonal)", bullet)],
[Paragraph("I, aVL, V5–V6", bullet), Paragraph("Lateral", bullet), Paragraph("LCx or LAD diagonal", bullet)],
[Paragraph("II, III, aVF", bullet), Paragraph("Inferior", bullet), Paragraph("RCA (80%) or LCx (20%)", bullet)],
[Paragraph("V1–V2 (tall R, ST depression)", bullet), Paragraph("Posterior", bullet), Paragraph("RCA or LCx", bullet)],
[Paragraph("V3R–V4R (ST elevation)", bullet), Paragraph("Right Ventricle", bullet), Paragraph("RCA (proximal)", bullet)],
]
loc_table = Table(loc_data, colWidths=[5*cm, 5*cm, 6.5*cm])
loc_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), GREY_DARK),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, GREY_DARK),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#BDC3C7")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 7),
]))
story.append(loc_table)
story.append(spacer(6))
# Cardiac Biomarkers
story.append(Paragraph("<b>B. Cardiac Biomarkers</b>", h2))
bio_data = [
[Paragraph("<b>Marker</b>", bold_bullet),
Paragraph("<b>Rises</b>", bold_bullet),
Paragraph("<b>Peaks</b>", bold_bullet),
Paragraph("<b>Normalises</b>", bold_bullet),
Paragraph("<b>Key Point</b>", bold_bullet)],
[Paragraph("hs-Troponin I/T", bullet), Paragraph("1-3 hrs", bullet), Paragraph("12-24 hrs", bullet), Paragraph("5-14 days", bullet), Paragraph("Gold standard; serial measurements", bullet)],
[Paragraph("CK-MB", bullet), Paragraph("3-6 hrs", bullet), Paragraph("12-24 hrs", bullet), Paragraph("48-72 hrs", bullet), Paragraph("Useful for reinfarction detection", bullet)],
[Paragraph("Myoglobin", bullet), Paragraph("1-2 hrs", bullet), Paragraph("6-8 hrs", bullet), Paragraph("24-36 hrs", bullet), Paragraph("Earliest; non-specific (skeletal muscle)", bullet)],
[Paragraph("LDH (LDH1)", bullet), Paragraph("24-48 hrs", bullet), Paragraph("3-6 days", bullet), Paragraph("8-14 days", bullet), Paragraph("Useful for late presentation (>24 hrs)", bullet)],
]
bio_table = Table(bio_data, colWidths=[3.5*cm, 2.5*cm, 2.5*cm, 3*cm, 5*cm])
bio_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_BLUE, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, BLUE),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(bio_table)
story.append(spacer(4))
story.append(yellow_box("HIGH-YIELD: hs-Troponin rule-in/rule-out protocol",
["• 0h/1h algorithm: draw hs-cTn at 0h and 1h. Rise ≥5 ng/L within 1h = rule in.",
"• 0h/3h algorithm: draw at 0h and 3h if 1h not available.",
"• 'Delta' troponin rise is more specific than a single elevated value alone.",
"• Always interpret in clinical context — troponin rises in PE, myocarditis, ARDS, renal failure."]))
story.append(spacer(6))
# Other investigations
story.append(Paragraph("<b>C. Other Essential Investigations</b>", h2))
story.append(info_box("Routine Investigations in Acute MI",
["ECG — repeat at 30 min, 6h, and if symptoms change",
"Full blood count — anaemia (worsens ischaemia), leukocytosis (stress response)",
"Urea & electrolytes — baseline for ACE-I, check K⁺ (arrhythmia risk if low)",
"Lipid profile (fasting) — LDL target <1.4 mmol/L post-MI",
"Random glucose + HbA1c — diabetes screen",
"Coagulation (PT/APTT) — if thrombolysis planned",
"CXR — cardiomegaly, pulmonary oedema, widened mediastinum (rule out dissection)",
"Echocardiogram — LV function, wall motion abnormalities, complications",
"Coronary angiography — defines anatomy, guides revascularisation"]))
story.append(spacer(4))
story.append(citation("Sources: Harrison's Principles of Internal Medicine 22e; Braunwald's Heart Disease"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 6. MANAGEMENT
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("6. MANAGEMENT", GREEN))
story.append(spacer(6))
# Immediate
story.append(Paragraph("<b>A. Immediate Management — 'TIME IS MUSCLE'</b>", h2))
story.append(green_box("MONABCH Acronym (Acute MI initial treatment)",
["M — Morphine (2.5-5 mg IV for pain; use with caution — may mask worsening)",
"O — Oxygen (ONLY if SpO₂ <94%; routine O₂ is harmful in normoxic patients)",
"N — Nitrates (sublingual GTN for pain relief; avoid if SBP <90 mmHg or RV infarct)",
"A — Aspirin 300 mg stat (then 75 mg/day lifelong) — antiplatelet",
"B — Beta-blocker (metoprolol/atenolol IV or oral) — reduce infarct size",
"C — Clopidogrel (or ticagrelor 180 mg / prasugrel 60 mg) — dual antiplatelet",
"H — Heparin (LMWH or UFH) — anticoagulation"]))
story.append(spacer(6))
# STEMI management
story.append(Paragraph("<b>B. STEMI Reperfusion Strategy</b>", h2))
stemi_data = [
[Paragraph("<b>Strategy</b>", bold_bullet),
Paragraph("<b>Indication</b>", bold_bullet),
Paragraph("<b>Time target</b>", bold_bullet)],
[Paragraph("Primary PCI\n(1st choice)", bullet),
Paragraph("Available within 120 min of first medical contact", bullet),
Paragraph("Door-to-balloon\n≤90 minutes", bullet)],
[Paragraph("Thrombolysis\n(if PCI unavailable)", bullet),
Paragraph("Presentation ≤12 hrs, PCI not available in time", bullet),
Paragraph("Door-to-needle\n≤30 minutes", bullet)],
[Paragraph("Pharmaco-invasive\nstrategy", bullet),
Paragraph("Thrombolysis given → transfer for angiography within 3-24 hrs", bullet),
Paragraph("Angiography\n3-24 hrs post-lysis", bullet)],
[Paragraph("CABG", bullet),
Paragraph("Unsuitable for PCI (left main disease, multi-vessel complex disease)", bullet),
Paragraph("Elective or\nsemi-urgent", bullet)],
]
stemi_table = Table(stemi_data, colWidths=[3.5*cm, 9*cm, 4*cm])
stemi_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), GREEN),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_GREEN, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, GREEN),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#A9DFBF")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(stemi_table)
story.append(spacer(6))
# Thrombolytic agents
story.append(Paragraph("<b>Thrombolytic Agents</b>", h3))
thrombo_data = [
[Paragraph("<b>Agent</b>", bold_bullet),
Paragraph("<b>Type</b>", bold_bullet),
Paragraph("<b>Dose</b>", bold_bullet),
Paragraph("<b>Notes</b>", bold_bullet)],
[Paragraph("Streptokinase", bullet), Paragraph("Non-fibrin specific", bullet),
Paragraph("1.5 MU over 60 min", bullet), Paragraph("Cheapest; antigenic (no repeat dose)", bullet)],
[Paragraph("Alteplase (tPA)", bullet), Paragraph("Fibrin specific", bullet),
Paragraph("Accelerated 90-min protocol", bullet), Paragraph("Preferred in anterior STEMI", bullet)],
[Paragraph("Tenecteplase (TNK)", bullet), Paragraph("Fibrin specific", bullet),
Paragraph("Weight-based single IV bolus", bullet), Paragraph("Most convenient; preferred in pre-hospital", bullet)],
[Paragraph("Reteplase (rPA)", bullet), Paragraph("Fibrin specific", bullet),
Paragraph("Two 10U IV boluses 30 min apart", bullet), Paragraph("Simple dosing", bullet)],
]
thrombo_table = Table(thrombo_data, colWidths=[3.5*cm, 3*cm, 5*cm, 5*cm])
thrombo_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), GREY_DARK),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, GREY_DARK),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#BDC3C7")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(thrombo_table)
story.append(spacer(5))
story.append(warning_box("Absolute Contraindications to Thrombolysis",
["Previous haemorrhagic stroke (any time)",
"Ischaemic stroke in past 3 months",
"CNS neoplasm / arteriovenous malformation",
"Active internal bleeding (not menstruation)",
"Suspected aortic dissection",
"Significant closed-head or facial trauma within 3 months",
"Intracranial/intraspinal surgery within 2 months"]))
story.append(spacer(6))
# Long-term medications
story.append(Paragraph("<b>C. Secondary Prevention — Long-term Medications ('ABCDE')</b>", h2))
abcde_data = [
[Paragraph("A", ParagraphStyle("abc", fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER)),
Paragraph("<b>Aspirin + Antiplatelet (DAPT)</b><br/>"
"Aspirin 75mg lifelong + P2Y12 inhibitor for 12 months (ticagrelor preferred over clopidogrel)<br/>"
"Anticoagulation if AF, thrombus, or mechanical valve",
ParagraphStyle("abcb", fontSize=9, fontName="Helvetica", textColor=GREY_DARK, leading=13))],
[Paragraph("B", ParagraphStyle("abc2", fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER)),
Paragraph("<b>Beta-blocker + Blood pressure control</b><br/>"
"Metoprolol/carvedilol — reduce mortality post-MI, prevent arrhythmias<br/>"
"BP target <130/80 mmHg",
ParagraphStyle("abcb2", fontSize=9, fontName="Helvetica", textColor=GREY_DARK, leading=13))],
[Paragraph("C", ParagraphStyle("abc3", fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER)),
Paragraph("<b>Cholesterol reduction (Statin) + Cigarette cessation</b><br/>"
"High-intensity statin: atorvastatin 40-80 mg or rosuvastatin 20-40 mg<br/>"
"LDL target <1.4 mmol/L (or ≥50% reduction); PCSK9 inhibitor if target not met",
ParagraphStyle("abcb3", fontSize=9, fontName="Helvetica", textColor=GREY_DARK, leading=13))],
[Paragraph("D", ParagraphStyle("abc4", fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER)),
Paragraph("<b>Diet + Diabetes management + DAPT</b><br/>"
"Mediterranean diet; HbA1c <7% (SGLT2 inhibitors have additional cardioprotective benefit)<br/>"
"Cardiac rehabilitation",
ParagraphStyle("abcb4", fontSize=9, fontName="Helvetica", textColor=GREY_DARK, leading=13))],
[Paragraph("E", ParagraphStyle("abc5", fontSize=16, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER)),
Paragraph("<b>Exercise + ACE inhibitor/ARB</b><br/>"
"ACE inhibitor (ramipril/lisinopril) — all post-MI patients especially if EF <40%<br/>"
"Add MRA (eplerenone) if EF <35% and HF or diabetes",
ParagraphStyle("abcb5", fontSize=9, fontName="Helvetica", textColor=GREY_DARK, leading=13))],
]
abcde_table = Table(abcde_data, colWidths=[1.5*cm, 15*cm])
abcde_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), RED),
("BACKGROUND", (0,1), (0,1), colors.HexColor("#E74C3C")),
("BACKGROUND", (0,2), (0,2), DARK_RED),
("BACKGROUND", (0,3), (0,3), colors.HexColor("#C0392B")),
("BACKGROUND", (0,4), (0,4), colors.HexColor("#A93226")),
("BACKGROUND", (1,0), (1,-1), WHITE),
("BOX", (0,0), (-1,-1), 0.8, RED),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#F5B7B1")),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(abcde_table)
story.append(spacer(4))
story.append(citation("Sources: ESC Guidelines 2023; ACC/AHA Guidelines; Harrison's 22e; Goldman-Cecil Medicine"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 7. COMPLICATIONS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("7. COMPLICATIONS OF MI", DARK_RED))
story.append(spacer(6))
story.append(Paragraph("<b>Complications by Timing</b>", h2))
comp_data = [
[Paragraph("<b>Timing</b>", bold_bullet),
Paragraph("<b>Complication</b>", bold_bullet),
Paragraph("<b>Notes</b>", bold_bullet)],
[Paragraph("Immediate\n(0-24h)", bullet),
Paragraph("Ventricular fibrillation (VF) — most common cause of early death\nVentricular tachycardia (VT)\nHeart block (inferior MI → Mobitz II/complete block)\nCardiogenic shock", bullet),
Paragraph("Defibrillate immediately for VF\nTemporary pacing for complete block in inferior MI", bullet)],
[Paragraph("Early\n(1-7 days)", bullet),
Paragraph("Free wall rupture → haemopericardium → cardiac tamponade\nVSD (ventricular septal defect)\nAcute mitral regurgitation (papillary muscle rupture)\nAcute LV failure/pulmonary oedema\nPericarditis (1-3 days)", bullet),
Paragraph("Free wall rupture: surgical emergency (mortality >90%)\nVSD: loud pansystolic murmur, surgical repair\nMR: soft murmur, IABP + surgery", bullet)],
[Paragraph("Late\n(weeks–months)", bullet),
Paragraph("Dressler's syndrome (autoimmune pericarditis, 2-10 weeks post-MI)\nLV aneurysm (persistent ST elevation, risk of mural thrombus)\nMural thrombus → systemic embolism\nChronic heart failure\nRecurrent ischaemia / reinfarction", bullet),
Paragraph("Dressler's: NSAIDs / colchicine\nAneurysm: anticoagulate if thrombus present\nHF: ACEI + BB + MRA + SGLT2i", bullet)],
]
comp_table = Table(comp_data, colWidths=[2.5*cm, 8.5*cm, 5.5*cm])
comp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_RED),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_RED, colors.HexColor("#FDEDEC"), WHITE]),
("BOX", (0,0), (-1,-1), 0.8, DARK_RED),
("LINEBELOW", (0,0), (-1,-2), 0.4, colors.HexColor("#F5B7B1")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(comp_table)
story.append(spacer(8))
# ══════════════════════════════════════════════════════════════════════════════
# 8. PROGNOSIS & EXAM TIPS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("8. PROGNOSIS & HIGH-YIELD EXAM POINTS", BLUE))
story.append(spacer(6))
story.append(Paragraph("<b>Prognostic Indicators</b>", h2))
story.append(two_col_table(
left_title="Poor Prognosis",
right_title="Better Prognosis",
left_items=[
"Low ejection fraction (EF <35%)",
"Anterior MI (larger territory)",
"Cardiogenic shock (Killip IV)",
"Delayed reperfusion (>12 hours)",
"Advanced age, female sex, diabetes",
"Multi-vessel coronary disease",
"Raised BNP / NT-proBNP",
"Ventricular arrhythmias post-MI",
],
right_items=[
"High EF (>50%)",
"Inferior MI (smaller territory)",
"Killip Class I",
"Early reperfusion (<3 hours)",
"Young age, good collateral flow",
"Single-vessel disease",
"Complete revascularisation",
"Cardiac rehab compliance",
],
left_bg=LIGHT_RED, right_bg=LIGHT_GREEN
))
story.append(spacer(6))
story.append(yellow_box("TOP 10 HIGH-YIELD EXAM POINTS",
["1. VF is the most common cause of death in the FIRST HOUR of MI (before hospital).",
"2. Troponin is detectable at 1-3h, peaks at 12-24h, stays elevated for 5-14 days.",
"3. The LAD is the most commonly occluded artery in MI (anterior STEMI).",
"4. Inferior MI → check right-sided leads (V3R/V4R) to exclude RV infarct.",
"5. In RV infarct: raised JVP + hypotension + clear lungs = classic triad; give IV fluids, AVOID nitrates.",
"6. New LBBB + chest pain = treat as STEMI equivalent (call PCI lab).",
"7. Primary PCI is superior to thrombolysis if door-to-balloon time ≤120 min.",
"8. Aspirin + high-intensity statin are the two most evidence-based secondary prevention drugs.",
"9. Papillary muscle rupture causes ACUTE MR — soft murmur (low pressure gradient), pulmonary oedema.",
"10. Free wall rupture = cardiac tamponade = Beck's triad (hypotension + muffled heart sounds + raised JVP)."]))
story.append(spacer(6))
# GRACE score
story.append(Paragraph("<b>Risk Stratification Scores</b>", h2))
story.append(info_box("GRACE Score (Global Registry of Acute Coronary Events) — for NSTEMI/UA",
["Variables: age, heart rate, SBP, creatinine, Killip class, cardiac arrest, ST deviation, troponin",
"Low risk (<109): in-hospital mortality <1% → conservative strategy acceptable",
"Intermediate risk (109-140): invasive strategy within 24-72h",
"High risk (>140): early invasive strategy within 24h",
"Available as online calculator: gracescore.org"]))
story.append(spacer(4))
story.append(info_box("TIMI Score (Thrombolysis in Myocardial Infarction) — simpler bedside score",
["7 variables each scoring 1 point (age ≥65, ≥3 CAD risk factors, prior coronary stenosis ≥50%, ST deviation, ≥2 anginal events in 24h, aspirin use in past 7 days, elevated cardiac markers)",
"Score 0-1 = 4.7% risk of MACE at 14 days",
"Score 6-7 = 40.9% risk of MACE at 14 days"]))
story.append(spacer(4))
story.append(citation("Sources: Braunwald's Heart Disease; Harrison's Principles of Internal Medicine 22e; Goldman-Cecil Medicine; Robbins & Cotran Pathologic Basis of Disease; Guyton & Hall Medical Physiology"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# 9. MNEMONICS & REVISION SUMMARY
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("9. MNEMONICS & QUICK REVISION", RED))
story.append(spacer(6))
mnem_data = [
[Paragraph("<b>Mnemonic</b>", bold_bullet), Paragraph("<b>Stands for</b>", bold_bullet)],
[Paragraph("MONABCH", bullet), Paragraph("Morphine, Oxygen, Nitrates, Aspirin, Beta-blocker, Clopidogrel, Heparin — acute treatment", bullet)],
[Paragraph("ABCDE", bullet), Paragraph("Aspirin/Antiplatelet, Beta-blocker/BP, Cholesterol/Cigarettes, Diet/Diabetes, Exercise/ACE-I — secondary prevention", bullet)],
[Paragraph("GRACE", bullet), Paragraph("Global Registry of Acute Coronary Events — NSTEMI risk score", bullet)],
[Paragraph("TIMI", bullet), Paragraph("Thrombolysis In Myocardial Infarction — risk stratification score", bullet)],
[Paragraph("SAD (RV infarct)", bullet), Paragraph("ST elevation in aVR + ST depression in I/aVL — reciprocal changes in inferior MI", bullet)],
[Paragraph("STEM(I) = STEM(cell)", bullet), Paragraph("ST Elevation MI = needs urgent reperfusion within the 'golden hour'", bullet)],
]
mnem_table = Table(mnem_data, colWidths=[4*cm, 12.5*cm])
mnem_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), RED),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LIGHT_RED, WHITE]),
("BOX", (0,0), (-1,-1), 0.8, RED),
("LINEBELOW", (0,0), (-1,-2), 0.3, colors.HexColor("#F5B7B1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mnem_table)
story.append(spacer(10))
# Final summary
story.append(Paragraph("<b>One-Page Revision Summary</b>", h2))
summary_items = [
"<b>Definition:</b> Ischaemic necrosis of myocardium. Type 1 (plaque rupture) is most common.",
"<b>Pathology:</b> Plaque rupture → thrombus → occlusion → necrosis from subendocardium outward.",
"<b>Symptoms:</b> Crushing chest pain, radiation to arm/jaw, diaphoresis, nausea, dyspnoea.",
"<b>ECG:</b> Hyperacute T → ST elevation → T inversion → Q waves.",
"<b>Biomarkers:</b> hs-Troponin (best), CK-MB, Myoglobin (earliest), LDH (latest).",
"<b>STEMI Rx:</b> Aspirin + P2Y12 + heparin + primary PCI ≤90 min (or thrombolysis).",
"<b>NSTEMI Rx:</b> DAPT + anticoagulation + risk stratify with GRACE score → early angiography.",
"<b>Secondary prevention:</b> ABCDE — Aspirin, Beta-blocker, statin, ACE-I, cardiac rehab.",
"<b>Key complications:</b> VF (early), free wall rupture/VSD/MR (1 week), Dressler's/aneurysm (late).",
"<b>RV infarct:</b> Right-sided leads, IV fluids, AVOID nitrates and diuretics.",
]
for item in summary_items:
story.append(Paragraph(item,
ParagraphStyle("sum", fontSize=9.5, fontName="Helvetica", textColor=GREY_DARK,
leading=14, spaceAfter=3, leftIndent=10, firstLineIndent=-10,
bulletText="✓")))
story.append(spacer(10))
story.append(Paragraph(
"Compiled from: Harrison's Principles of Internal Medicine 22e • Goldman-Cecil Medicine • "
"Braunwald's Heart Disease • Robbins & Cotran Pathologic Basis of Disease • "
"Guyton & Hall Medical Physiology • Ganong's Review of Medical Physiology",
citation))
# ── Build ────────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=add_page_decorations, onLaterPages=add_page_decorations)
print(f"PDF created: {OUTPUT}")
cd /home/daytona/workspace/mi-study-guide && python generate_mi_guide.py
~/mi-study-guide/generate_mi_guide.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mi-study-guide/generate_mi_guide.py'
cd /home/daytona/workspace/mi-study-guide && sed -i 's/citation("/Paragraph("/g;…
python3 -c " content = open('/home/daytona/workspace/mi-study-guide/generate_mi_…
cd /home/daytona/workspace/mi-study-guide && python generate_mi_guide.py 2>&1
grep -n "citation" /home/daytona/workspace/mi-study-guide/generate_mi_guide.py
~/mi-study-guide/generate_mi_guide.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mi-study-guide/generate_mi_guide.py'
cd /home/daytona/workspace/mi-study-guide && python generate_mi_guide.py 2>&1
MI Study Guide MBBS
PDF Document · PDF
| Section | Contents |
|---|---|
| Cover + Quick Ref Card | At-a-glance summary of definition, ECG changes, diagnosis, treatment |
| 1. Definition & Classification | 4th Universal Definition, STEMI vs NSTEMI vs UA comparison table, all 5 MI types |
| 2. Aetiology & Risk Factors | Modifiable vs non-modifiable, INTERHEART study box |
| 3. Pathophysiology | 8-step sequence from plaque rupture to remodelling |
| 4. Clinical Features | Symptoms, signs, Killip classification table, silent MI warning box |
| 5. Investigations | ECG phases + territory localisation table, biomarker timing table (hs-Troponin, CK-MB, Myoglobin, LDH), delta troponin rules |
| 6. Management | MONABCH acute Rx, STEMI reperfusion strategy, thrombolytic agents, contraindications, ABCDE secondary prevention |
| 7. Complications | Immediate / early / late complications with management notes |
| 8. Prognosis & Exam Points | Top 10 high-yield MCQ facts, GRACE + TIMI score summaries |
| 9. Mnemonics + Revision | Key mnemonics, one-page revision checklist |