Show me the 10 most common heart disease with ecg pattern

Reading File
Finding Sources
Finding Sources
Searching Images

ECG patterns common heart diseases electrocardiogram

Finding Sources
Searching Images

ST elevation myocardial infarction STEMI ECG leads

Searching Images

atrial fibrillation ECG irregular rhythm no P waves

Reading File
Searching Images

heart block complete AV block third degree ECG bradycardia

Searching Images

left ventricular hypertrophy ECG voltage criteria Sokolow

Searching Images

ventricular tachycardia wide QRS tachycardia ECG

Searching Images

pericarditis saddle-shaped ST elevation diffuse ECG

Searching Images

hypertrophic cardiomyopathy ECG deep Q waves LVH

Searching Images

pulmonary embolism ECG S1Q3T3 right heart strain sinus tachycardia

Searching Images

Wolff-Parkinson-White WPW delta wave short PR ECG pre-excitation

I now have excellent ECG images for all 10 conditions. Here is a comprehensive guide:

10 Common Heart Diseases & Their ECG Patterns


1. πŸ«€ ST-Elevation Myocardial Infarction (STEMI)

ECG Pattern:
  • ST elevation β‰₯1 mm in β‰₯2 contiguous limb leads, or β‰₯2 mm in β‰₯2 contiguous precordial leads
  • Hyperacute T waves (tall, peaked) in early phase
  • Pathological Q waves (>40 ms wide, >25% of R-wave height) in evolved MI
  • Reciprocal ST depression in opposing leads
  • "Tombstone" morphology in severe proximal LAD occlusion
TerritoryLeads with ST ElevationArtery
AnteriorV1–V4LAD
InferiorII, III, aVFRCA
LateralI, aVL, V5–V6LCx
PosteriorST depression V1–V2 + tall RRCA/LCx
Anterior STEMI with tombstone morphology

2. πŸ«€ Atrial Fibrillation (AF)

ECG Pattern:
  • Irregularly irregular R-R intervals β€” the hallmark
  • Absent P waves replaced by fine/coarse fibrillatory (f) waves (best seen in V1)
  • Narrow QRS complexes (unless aberrant conduction or bundle branch block)
  • Rapid ventricular response if uncontrolled (>100 bpm)
Atrial fibrillation β€” irregularly irregular rhythm, absent P waves

3. πŸ«€ Complete (3rd-Degree) AV Heart Block

ECG Pattern:
  • AV dissociation β€” P waves and QRS complexes fire completely independently
  • Atrial rate faster than ventricular rate
  • Regular, slow ventricular escape rhythm (~20–40 bpm)
  • Narrow QRS = nodal escape; Wide QRS = ventricular/infranodal escape
  • No fixed PR interval
Complete 3rd-degree AV block β€” P waves and QRS dissociated

4. πŸ«€ Left Ventricular Hypertrophy (LVH) β€” Hypertensive Heart Disease

ECG Pattern:
  • Sokolow-Lyon criteria: S in V1 + R in V5 or V6 β‰₯35 mm
  • Cornell criteria: R in aVL + S in V3 >28 mm (men), >20 mm (women)
  • LV strain pattern: ST depression + T-wave inversion in I, aVL, V5–V6
  • Left axis deviation
  • Broadened QRS (not always frank LBBB)
LVH with strain pattern β€” deep T inversions in lateral leads

5. πŸ«€ Ventricular Tachycardia (VT)

ECG Pattern:
  • Wide QRS tachycardia (QRS >120 ms) at rate β‰₯100 bpm
  • Regular or slightly irregular rhythm
  • AV dissociation (P waves independent of QRS)
  • Fusion beats and capture beats (pathognomonic)
  • Concordance in precordial leads (all positive or all negative)
  • Northwest/superior axis deviation
FeaturePoints toward VT
QRS >160 msβœ“
Positive concordance V1–V6βœ“
AV dissociationβœ“ (pathognomonic)
Brugada/Wellens criteriaβœ“
Monomorphic VT β€” wide complex tachycardia with positive concordance

6. πŸ«€ Acute Pericarditis

ECG Pattern (4 evolutionary stages):
  • Stage 1: Diffuse saddle-shaped (concave) ST elevation in almost all leads; PR depression; ST elevation in aVR absent or with PR elevation
  • Stage 2: ST normalizes, T waves flatten
  • Stage 3: Diffuse T-wave inversions
  • Stage 4: Normalization
  • Key differentiator from STEMI: Diffuse (not localised), no reciprocal changes except aVR, PR segment depression
Acute pericarditis β€” diffuse saddle-shaped ST elevation + PR depression

7. πŸ«€ Pulmonary Embolism (PE)

ECG Pattern:
  • Most common: Sinus tachycardia (non-specific)
  • Classic S₁Q₃T₃ pattern: Deep S in I, Q wave in III, inverted T in III
  • Right bundle branch block (complete or incomplete)
  • T-wave inversions in V1–V4 (right ventricular strain)
  • Right axis deviation
  • P pulmonale (peaked P waves in II β‰₯2.5 mm)
  • New AF in massive PE
Pulmonary embolism β€” S1Q3T3 pattern + RV strain

8. πŸ«€ Hypertrophic Cardiomyopathy (HCM)

ECG Pattern:
  • LVH voltage criteria (tall R in lateral leads, deep S in right leads)
  • Deep narrow Q waves in lateral (I, aVL, V5–V6) and inferior leads β€” due to septal hypertrophy
  • Apical HCM (Yamaguchi): Giant deep symmetric T-wave inversions in V3–V5 (β‰₯10 mm depth)
  • ST depression in lateral leads
  • Left axis deviation
  • AF occurs in 20–25% of patients
Apical HCM β€” giant symmetric T-wave inversions in precordial leads

9. πŸ«€ Wolff-Parkinson-White (WPW) Syndrome

ECG Pattern (Classic Triad):
  1. Short PR interval (<120 ms)
  2. Delta wave β€” slurred initial upstroke of QRS
  3. Widened QRS (>120 ms) due to pre-excitation
  • Secondary ST-T changes discordant with delta wave direction
  • Risk: can precipitate AF β†’ rapid conduction via accessory pathway β†’ VF
Pathway LocationDelta Polarity
Left lateralNegative in V1, positive in I
PosteroseptalNegative in II, III, aVF
AnteroseptalPositive in V1
WPW β€” short PR, delta wave, widened QRS

10. πŸ«€ Dilated Cardiomyopathy (DCM)

ECG Pattern:
  • Left bundle branch block (LBBB) β€” most characteristic
    • QRS β‰₯120 ms, broad notched R in I/aVL/V5–V6, deep S/QS in V1–V3
  • Diffuse ST-T changes (secondary to LBBB or ischaemia)
  • Left axis deviation
  • AF is common (30–40%)
  • Low voltage QRS (if severe fibrosis or pericardial effusion co-exists)
  • P mitrale (broad bifid P waves in II) β€” left atrial enlargement
  • Pseudo-infarction Q waves mimicking prior MI
LBBB pattern β€” broad notched R waves laterally, deep QS in V1–V3

Quick Reference Summary

#ConditionKey ECG Finding
1STEMIST elevation, Q waves, reciprocal depression
2Atrial FibrillationIrregularly irregular, no P waves
3Complete Heart BlockAV dissociation, slow escape rhythm
4LVH / HTN Heart DiseaseHigh voltage + strain pattern
5Ventricular TachycardiaWide QRS β‰₯120 ms, AV dissociation
6Acute PericarditisDiffuse saddle ST elevation, PR depression
7Pulmonary EmbolismSinus tachycardia, S₁Q₃T₃, RV strain
8Hypertrophic CardiomyopathyGiant T inversions, deep Q waves
9WPW SyndromeShort PR, delta wave, widened QRS
10Dilated CardiomyopathyLBBB, AF, low voltage
Sources: Braunwald's Heart Disease (Elsevier), ROSEN's Emergency Medicine; ECG images from peer-reviewed clinical literature via PMC.

Convert this information into pdf

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not foun…

Running Command

mkdir -p /home/daytona/workspace/ecg-guide && python3 -c "from reportlab.lib.pag…

Writing File

~/ecg-guide/generate_pdf.py

import requests
import os
from io import BytesIO
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.graphics.shapes import Drawing, Rect
from reportlab.pdfgen import canvas

OUTPUT_PATH = "/home/daytona/workspace/ecg-guide/Heart_Diseases_ECG_Guide.pdf"

# ─── Colour palette ────────────────────────────────────────────────────────────
DARK_RED   = colors.HexColor("#8B0000")
MED_RED    = colors.HexColor("#C0392B")
LIGHT_RED  = colors.HexColor("#FADBD8")
DARK_GREY  = colors.HexColor("#2C3E50")
MID_GREY   = colors.HexColor("#5D6D7E")
LIGHT_GREY = colors.HexColor("#EAF0FB")
TABLE_HDR  = colors.HexColor("#1A3A5C")
TABLE_ALT  = colors.HexColor("#EBF5FB")
WHITE      = colors.white
BLACK      = colors.black

# ─── ECG Data ──────────────────────────────────────────────────────────────────
DISEASES = [
    {
        "num": 1,
        "name": "ST-Elevation Myocardial Infarction (STEMI)",
        "icon": "❀",
        "key_findings": [
            "ST elevation β‰₯1 mm in β‰₯2 contiguous limb leads; β‰₯2 mm in precordial leads",
            "Hyperacute T waves (tall, peaked) in early phase",
            "Pathological Q waves (>40 ms, >25% R height) in evolved MI",
            "Reciprocal ST depression in opposing leads",
            '"Tombstone" morphology in proximal LAD occlusion',
        ],
        "table": {
            "headers": ["Territory", "Leads", "Artery"],
            "rows": [
                ["Anterior", "V1–V4", "LAD"],
                ["Inferior", "II, III, aVF", "RCA"],
                ["Lateral", "I, aVL, V5–V6", "LCx"],
                ["Posterior", "ST↓ V1–V2 + tall R", "RCA/LCx"],
            ]
        },
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_0f5964997b5f333f6a7b13ecdc70a73ef6e81127eaee03ef38d9c724b26bbf31.jpg",
        "img_caption": "Anterior STEMI β€” tombstone ST elevation V2–V5 with reciprocal inferior depression",
    },
    {
        "num": 2,
        "name": "Atrial Fibrillation (AF)",
        "icon": "❀",
        "key_findings": [
            "Irregularly irregular R-R intervals β€” the hallmark",
            "Absent P waves replaced by fine/coarse fibrillatory (f) waves (best in V1)",
            "Narrow QRS complexes unless aberrant conduction or BBB",
            "Rapid ventricular response if uncontrolled (>100 bpm)",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_a8e7a35a18d282cc6de8c169a0213a6712f9fe9e4a7253f7828e22c867033097.jpg",
        "img_caption": "AF β€” irregularly irregular rhythm, absent P waves, fine fibrillatory baseline",
    },
    {
        "num": 3,
        "name": "Complete (3rd-Degree) AV Heart Block",
        "icon": "❀",
        "key_findings": [
            "AV dissociation β€” P waves and QRS complexes fire independently",
            "Atrial rate faster than ventricular rate",
            "Regular, slow ventricular escape rhythm (~20–40 bpm)",
            "Narrow QRS = nodal escape; Wide QRS = ventricular/infranodal escape",
            "No fixed PR interval",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_c76f7d8cf3869000720e9ce457857cf031f9b360704aa4236ad85275ba26169e.jpg",
        "img_caption": "3rd-degree AV block β€” P waves march through independently of slow wide QRS escape",
    },
    {
        "num": 4,
        "name": "Left Ventricular Hypertrophy (LVH) β€” Hypertensive Heart Disease",
        "icon": "❀",
        "key_findings": [
            "Sokolow-Lyon: S in V1 + R in V5/V6 β‰₯35 mm",
            "Cornell: R in aVL + S in V3 >28 mm (men), >20 mm (women)",
            "LV strain pattern: ST depression + T-wave inversion in I, aVL, V5–V6",
            "Left axis deviation",
            "Broadened QRS (not always frank LBBB)",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_03152b722b1cb86ef1d57f4d755aa687989488df7da9defa36d7d35f9ab80e28.jpg",
        "img_caption": "LVH with strain pattern β€” high voltage laterally with ST depression and T-wave inversions",
    },
    {
        "num": 5,
        "name": "Ventricular Tachycardia (VT)",
        "icon": "❀",
        "key_findings": [
            "Wide QRS tachycardia (QRS >120 ms) at rate β‰₯100 bpm",
            "Regular or slightly irregular rhythm",
            "AV dissociation (P waves independent of QRS)",
            "Fusion beats and capture beats (pathognomonic)",
            "Concordance in precordial leads (all positive or all negative)",
            "Northwest/superior axis deviation",
        ],
        "table": {
            "headers": ["Feature", "Points toward VT"],
            "rows": [
                ["QRS >160 ms", "βœ“"],
                ["Positive concordance V1–V6", "βœ“"],
                ["AV dissociation", "βœ“ (pathognomonic)"],
                ["Brugada/Wellens criteria", "βœ“"],
            ]
        },
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_d15a92de4e89b46f273b22d254d1e30fcd6a190c6d581b193e6dd338338c6bb6.jpg",
        "img_caption": "Monomorphic VT β€” wide complex tachycardia with positive concordance, no P waves",
    },
    {
        "num": 6,
        "name": "Acute Pericarditis",
        "icon": "❀",
        "key_findings": [
            "Stage 1: Diffuse saddle-shaped (concave) ST elevation + PR depression",
            "Stage 2: ST normalises, T waves flatten",
            "Stage 3: Diffuse T-wave inversions",
            "Stage 4: Full normalisation",
            "Key differentiator from STEMI: diffuse, no territory, PR depression present",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_0be5b02bdb0710f3bd3fcdbdc88b2944c0c2c3f7e84ae335cad7b36d24ffb97c.jpg",
        "img_caption": "Acute pericarditis β€” diffuse saddle-shaped ST elevation + PR depression across multiple leads",
    },
    {
        "num": 7,
        "name": "Pulmonary Embolism (PE)",
        "icon": "❀",
        "key_findings": [
            "Most common: Sinus tachycardia (non-specific but sensitive)",
            "Classic S₁Q₃T₃ pattern: deep S in I, Q wave in III, inverted T in III",
            "Right bundle branch block (complete or incomplete)",
            "T-wave inversions in V1–V4 (right ventricular strain)",
            "Right axis deviation; P pulmonale (peaked P β‰₯2.5 mm in II)",
            "New AF in massive PE",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_7cfb4819f88c84d02f863ca2f948165b6f4f6fafd405ca0b0a7df41e2d8d8e2a.jpg",
        "img_caption": "Pulmonary embolism β€” sinus tachycardia, S1Q3T3 pattern, RV strain T inversions V1–V3",
    },
    {
        "num": 8,
        "name": "Hypertrophic Cardiomyopathy (HCM)",
        "icon": "❀",
        "key_findings": [
            "LVH voltage criteria (tall R laterally, deep S right leads)",
            "Deep narrow Q waves in lateral (I, aVL, V5–V6) and inferior leads",
            "Apical HCM (Yamaguchi): giant deep symmetric T inversions in V3–V5 (β‰₯10 mm)",
            "ST depression in lateral leads",
            "Left axis deviation; AF in 20–25% of patients",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_3d2687643839a530919d460d4461031928da6585c23315b742b24d71296327a0.jpg",
        "img_caption": "Apical HCM (Yamaguchi) β€” giant symmetric T-wave inversions reaching 15 mm depth in V2–V4",
    },
    {
        "num": 9,
        "name": "Wolff-Parkinson-White (WPW) Syndrome",
        "icon": "❀",
        "key_findings": [
            "Short PR interval (<120 ms)",
            "Delta wave β€” slurred initial upstroke of the QRS",
            "Widened QRS (>120 ms) due to ventricular pre-excitation",
            "Secondary ST-T changes discordant with delta wave direction",
            "Risk: AF β†’ rapid accessory pathway conduction β†’ VF",
        ],
        "table": {
            "headers": ["Pathway Location", "Delta Polarity"],
            "rows": [
                ["Left lateral", "Negative in V1, positive in I"],
                ["Posteroseptal", "Negative in II, III, aVF"],
                ["Anteroseptal", "Positive in V1"],
            ]
        },
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_fd0d58cc1913acd56cbc62cbf42657e4a465f052a9bb2ea0d3893584ef6f70e6.jpg",
        "img_caption": "WPW syndrome β€” short PR interval, prominent delta waves, widened QRS complexes",
    },
    {
        "num": 10,
        "name": "Dilated Cardiomyopathy (DCM)",
        "icon": "❀",
        "key_findings": [
            "Left bundle branch block (LBBB) β€” most characteristic (QRS β‰₯120 ms)",
            "Broad notched R in I/aVL/V5–V6; deep QS in V1–V3",
            "Diffuse ST-T changes secondary to LBBB",
            "Left axis deviation; AF common (30–40%)",
            "Low voltage QRS (if fibrosis or pericardial effusion)",
            "Pseudo-infarction Q waves mimicking prior MI",
        ],
        "table": None,
        "img_url": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_3adea767053955d22dff275d5b4935c292277e5153fb88fae914ccff7abedb82.jpg",
        "img_caption": "DCM/LBBB pattern β€” low voltage QRS, broad notched morphology, secondary ST-T changes",
    },
]

SUMMARY_ROWS = [
    ["1", "STEMI", "ST elevation, Q waves, reciprocal depression"],
    ["2", "Atrial Fibrillation", "Irregularly irregular, no P waves"],
    ["3", "Complete Heart Block", "AV dissociation, slow escape rhythm"],
    ["4", "LVH / HTN Heart Disease", "High voltage + lateral strain pattern"],
    ["5", "Ventricular Tachycardia", "Wide QRS β‰₯120 ms, AV dissociation"],
    ["6", "Acute Pericarditis", "Diffuse saddle ST elevation, PR depression"],
    ["7", "Pulmonary Embolism", "Sinus tachycardia, S₁Q₃T₃, RV strain"],
    ["8", "Hypertrophic Cardiomyopathy", "Giant T inversions, deep Q waves"],
    ["9", "WPW Syndrome", "Short PR, delta wave, widened QRS"],
    ["10", "Dilated Cardiomyopathy", "LBBB, AF, low voltage"],
]


# ─── Helper: download image ─────────────────────────────────────────────────
def fetch_image_bytes(url, timeout=15):
    try:
        r = requests.get(url, timeout=timeout)
        r.raise_for_status()
        return BytesIO(r.content)
    except Exception as e:
        print(f"  [WARN] Could not fetch {url}: {e}")
        return None


# ─── Page template with header/footer ──────────────────────────────────────
def make_canvas_callback(title_text):
    def on_page(canv, doc):
        canv.saveState()
        w, h = A4
        # Header bar
        canv.setFillColor(DARK_RED)
        canv.rect(0, h - 22*mm, w, 22*mm, fill=1, stroke=0)
        canv.setFont("Helvetica-Bold", 11)
        canv.setFillColor(WHITE)
        canv.drawString(15*mm, h - 14*mm, title_text)
        canv.setFont("Helvetica", 9)
        canv.drawRightString(w - 15*mm, h - 14*mm, "Clinical ECG Reference Guide")
        # Footer bar
        canv.setFillColor(DARK_GREY)
        canv.rect(0, 0, w, 12*mm, fill=1, stroke=0)
        canv.setFont("Helvetica", 8)
        canv.setFillColor(WHITE)
        canv.drawString(15*mm, 4*mm, "Source: Braunwald's Heart Disease | ROSEN's Emergency Medicine")
        canv.drawRightString(w - 15*mm, 4*mm, f"Page {doc.page}")
        canv.restoreState()
    return on_page


# ─── Styles ─────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

title_style = ParagraphStyle(
    "MainTitle", fontSize=28, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_CENTER, spaceAfter=6
)
subtitle_style = ParagraphStyle(
    "Subtitle", fontSize=14, fontName="Helvetica",
    textColor=colors.HexColor("#FADBD8"), alignment=TA_CENTER, spaceAfter=4
)
disease_title_style = ParagraphStyle(
    "DiseaseTitle", fontSize=15, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_LEFT, spaceAfter=0, leading=18
)
section_num_style = ParagraphStyle(
    "SectionNum", fontSize=30, fontName="Helvetica-Bold",
    textColor=colors.HexColor("#FADBD8"), alignment=TA_LEFT
)
bullet_style = ParagraphStyle(
    "Bullet", fontSize=9.5, fontName="Helvetica",
    textColor=DARK_GREY, leftIndent=12, bulletIndent=0,
    spaceAfter=3, leading=13
)
caption_style = ParagraphStyle(
    "Caption", fontSize=8, fontName="Helvetica-Oblique",
    textColor=MID_GREY, alignment=TA_CENTER, spaceAfter=4
)
body_style = ParagraphStyle(
    "Body", fontSize=9.5, fontName="Helvetica",
    textColor=DARK_GREY, spaceAfter=4, leading=13
)
table_hdr_style = ParagraphStyle(
    "TblHdr", fontSize=9, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_CENTER
)
table_cell_style = ParagraphStyle(
    "TblCell", fontSize=9, fontName="Helvetica",
    textColor=DARK_GREY, alignment=TA_LEFT
)
summary_hdr_style = ParagraphStyle(
    "SumHdr", fontSize=10, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_CENTER
)
summary_cell_style = ParagraphStyle(
    "SumCell", fontSize=9, fontName="Helvetica",
    textColor=DARK_GREY
)


# ─── Build ───────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT_PATH,
    pagesize=A4,
    leftMargin=18*mm, rightMargin=18*mm,
    topMargin=30*mm, bottomMargin=20*mm,
    title="10 Common Heart Diseases & ECG Patterns",
    author="Orris Medical Reference",
)

story = []
PAGE_W = A4[0] - 36*mm   # usable width


# ════════════════════ COVER PAGE ════════════════════════════════════════════
# Big coloured cover block drawn via a custom flowable trick β€”
# we use a table with coloured background instead.

cover_title_style = ParagraphStyle(
    "CoverTitle", fontSize=32, fontName="Helvetica-Bold",
    textColor=WHITE, alignment=TA_CENTER, leading=38, spaceAfter=8
)
cover_sub_style = ParagraphStyle(
    "CoverSub", fontSize=14, fontName="Helvetica",
    textColor=colors.HexColor("#FADBD8"), alignment=TA_CENTER, spaceAfter=6
)
cover_body_style = ParagraphStyle(
    "CoverBody", fontSize=11, fontName="Helvetica",
    textColor=colors.HexColor("#D5E8F5"), alignment=TA_CENTER, spaceAfter=4
)

cover_content = [
    [Paragraph("10 Common Heart Diseases", cover_title_style)],
    [Paragraph("& Their ECG Patterns", cover_title_style)],
    [Spacer(1, 8*mm)],
    [Paragraph("A Clinical Reference Guide", cover_sub_style)],
    [Spacer(1, 6*mm)],
    [Paragraph(
        "STEMI  β€’  Atrial Fibrillation  β€’  Heart Block  β€’  LVH  β€’  VT<br/>"
        "Pericarditis  β€’  Pulmonary Embolism  β€’  HCM  β€’  WPW  β€’  DCM",
        cover_body_style)],
    [Spacer(1, 10*mm)],
    [Paragraph("Source: Braunwald's Heart Disease | ROSEN's Emergency Medicine", ParagraphStyle(
        "src", fontSize=9, textColor=colors.HexColor("#A9CCE3"), alignment=TA_CENTER
    ))],
]

cover_table = Table(cover_content, colWidths=[PAGE_W])
cover_table.setStyle(TableStyle([
    ("BACKGROUND", (0, 0), (-1, -1), DARK_RED),
    ("TOPPADDING",    (0, 0), (-1, -1), 8),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 8),
    ("LEFTPADDING",   (0, 0), (-1, -1), 20),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 20),
    ("VALIGN",        (0, 0), (-1, -1), "MIDDLE"),
    ("ROWBACKGROUNDS",(0, 0), (-1, -1), [DARK_RED]),
]))

# Outer wrapper to add a red box that fills most of the page
story.append(Spacer(1, 25*mm))
story.append(cover_table)
story.append(Spacer(1, 12*mm))

intro_style = ParagraphStyle(
    "Intro", fontSize=10, fontName="Helvetica",
    textColor=DARK_GREY, alignment=TA_JUSTIFY, leading=15
)
story.append(Paragraph(
    "Electrocardiography remains the fastest, most accessible, and most widely used tool in cardiovascular "
    "diagnosis. This guide presents the 10 most clinically encountered heart diseases alongside their "
    "characteristic ECG patterns, diagnostic criteria, and representative tracings sourced from peer-reviewed "
    "clinical literature. Each section includes key findings, localisation tables where applicable, and an "
    "annotated 12-lead ECG image.",
    intro_style
))
story.append(PageBreak())


# ════════════════════ DISEASE SECTIONS ══════════════════════════════════════
for d in DISEASES:
    print(f"Building section {d['num']}: {d['name']} ...")

    # ── Section header bar ──────────────────────────────────────────────────
    num_para  = Paragraph(f"{d['num']:02d}", ParagraphStyle(
        "Num", fontSize=36, fontName="Helvetica-Bold",
        textColor=colors.HexColor("#FADBD8"), alignment=TA_LEFT
    ))
    name_para = Paragraph(d["name"], disease_title_style)

    header_data = [[num_para, name_para]]
    header_table = Table(header_data, colWidths=[22*mm, PAGE_W - 22*mm])
    header_table.setStyle(TableStyle([
        ("BACKGROUND",    (0, 0), (-1, -1), DARK_RED),
        ("VALIGN",        (0, 0), (-1, -1), "MIDDLE"),
        ("LEFTPADDING",   (0, 0), (0, 0),   6),
        ("LEFTPADDING",   (1, 0), (1, 0),   4),
        ("RIGHTPADDING",  (0, 0), (-1, -1), 8),
        ("TOPPADDING",    (0, 0), (-1, -1), 6),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("ROUNDEDCORNERS",(0, 0), (-1, -1), [4, 4, 4, 4]),
    ]))

    # ── Key findings ────────────────────────────────────────────────────────
    findings_paras = [Paragraph("<b>Key ECG Findings</b>", ParagraphStyle(
        "FH", fontSize=10, fontName="Helvetica-Bold",
        textColor=DARK_RED, spaceAfter=4
    ))]
    for f in d["key_findings"]:
        findings_paras.append(Paragraph(f"β€’ {f}", bullet_style))

    # ── Optional table ──────────────────────────────────────────────────────
    tbl_element = None
    if d["table"]:
        td = d["table"]
        t_data = [[Paragraph(h, table_hdr_style) for h in td["headers"]]]
        for i, row in enumerate(td["rows"]):
            bg = TABLE_ALT if i % 2 == 0 else WHITE
            t_data.append([Paragraph(cell, table_cell_style) for cell in row])

        col_count = len(td["headers"])
        col_w = PAGE_W / col_count
        tbl = Table(t_data, colWidths=[col_w] * col_count)
        tbl.setStyle(TableStyle([
            ("BACKGROUND",    (0, 0), (-1, 0),  TABLE_HDR),
            ("ROWBACKGROUNDS",(0, 1), (-1, -1), [TABLE_ALT, WHITE]),
            ("GRID",          (0, 0), (-1, -1), 0.5, colors.HexColor("#BFC9CA")),
            ("TOPPADDING",    (0, 0), (-1, -1), 4),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
            ("LEFTPADDING",   (0, 0), (-1, -1), 6),
            ("RIGHTPADDING",  (0, 0), (-1, -1), 6),
            ("VALIGN",        (0, 0), (-1, -1), "MIDDLE"),
        ]))
        tbl_element = tbl

    # ── ECG Image ────────────────────────────────────────────────────────────
    img_bytes = fetch_image_bytes(d["img_url"])
    img_element = None
    if img_bytes:
        img_max_w = PAGE_W
        img_max_h = 55*mm
        img_element = Image(img_bytes, width=img_max_w, height=img_max_h)
        img_element.hAlign = "CENTER"

    # ── Assemble section ────────────────────────────────────────────────────
    section_parts = [
        header_table,
        Spacer(1, 4*mm),
    ]
    section_parts.extend(findings_paras)
    if tbl_element:
        section_parts.append(Spacer(1, 3*mm))
        section_parts.append(tbl_element)
    if img_element:
        section_parts.append(Spacer(1, 5*mm))
        section_parts.append(img_element)
        section_parts.append(Paragraph(d["img_caption"], caption_style))
    section_parts.append(HRFlowable(width=PAGE_W, thickness=0.5, color=colors.HexColor("#BFC9CA")))
    section_parts.append(Spacer(1, 6*mm))

    story.extend(section_parts)

    # Page break after every 2 diseases to keep layout clean
    if d["num"] % 2 == 0 and d["num"] < 10:
        story.append(PageBreak())


# ════════════════════ SUMMARY TABLE PAGE ════════════════════════════════════
story.append(PageBreak())

story.append(Paragraph("Quick Reference Summary", ParagraphStyle(
    "SumTitle", fontSize=18, fontName="Helvetica-Bold",
    textColor=DARK_RED, spaceAfter=8, alignment=TA_CENTER
)))
story.append(HRFlowable(width=PAGE_W, thickness=2, color=DARK_RED))
story.append(Spacer(1, 4*mm))

sum_data = [[
    Paragraph("#", summary_hdr_style),
    Paragraph("Condition", summary_hdr_style),
    Paragraph("Hallmark ECG Finding", summary_hdr_style),
]]
for row in SUMMARY_ROWS:
    sum_data.append([
        Paragraph(row[0], ParagraphStyle("SC", fontSize=10, fontName="Helvetica-Bold",
                                         textColor=DARK_RED, alignment=TA_CENTER)),
        Paragraph(row[1], summary_cell_style),
        Paragraph(row[2], summary_cell_style),
    ])

sum_table = Table(sum_data, colWidths=[12*mm, 65*mm, PAGE_W - 77*mm])
sum_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0),  TABLE_HDR),
    ("ROWBACKGROUNDS",(0, 1), (-1, -1), [TABLE_ALT, WHITE]),
    ("GRID",          (0, 0), (-1, -1), 0.5, colors.HexColor("#BFC9CA")),
    ("TOPPADDING",    (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
    ("LEFTPADDING",   (0, 0), (-1, -1), 8),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 8),
    ("VALIGN",        (0, 0), (-1, -1), "MIDDLE"),
    ("FONTSIZE",      (0, 1), (-1, -1), 9.5),
]))
story.append(sum_table)

story.append(Spacer(1, 10*mm))
story.append(Paragraph(
    "<b>Sources:</b> Braunwald's Heart Disease: A Textbook of Cardiovascular Medicine (Elsevier, 10th ed.) | "
    "ROSEN's Emergency Medicine: Concepts and Clinical Practice (Elsevier) | "
    "ECG images sourced from peer-reviewed PMC clinical literature.",
    ParagraphStyle("Sources", fontSize=8, textColor=MID_GREY, leading=12, alignment=TA_JUSTIFY)
))


# ─── Build PDF ───────────────────────────────────────────────────────────────
doc.build(
    story,
    onFirstPage=make_canvas_callback("10 Common Heart Diseases & ECG Patterns"),
    onLaterPages=make_canvas_callback("10 Common Heart Diseases & ECG Patterns"),
)
print(f"\nβœ“ PDF saved to: {OUTPUT_PATH}")
Running Command

cd /home/daytona/workspace/ecg-guide && python3 generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/ecg-guide/Heart_Diseases_ECG_Guide.pdf

Your PDF is ready β€” 832 KB, all 10 conditions with real ECG images included.

Heart Diseases ECG Guide

PDF Document Β· PDF

What's inside the PDF:
  • Cover page with title and condition list on a deep red background
  • 10 individual sections, each with:
    • Numbered header bar (red)
    • Bullet-point key ECG findings
    • Localisation/criteria table (where applicable β€” STEMI, VT, WPW)
    • Full-width real 12-lead ECG image from peer-reviewed clinical literature
    • Annotated caption describing the ECG
  • Quick Reference Summary table at the end listing all 10 conditions and their hallmark ECG finding
  • Running header and page footer with source attribution on every page
This is a shared conversation. Sign in to Orris to start your own chat.