Prepare a ppt topic cardioembolic stroke with subheading etiology symptoms and signs relevant findings treatment

Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Finding Sources
Running Command

mkdir -p /tmp/workspace/cardioembolic-stroke && ls /tmp/workspace/

Writing File

~/cardioembolic-stroke/build_ppt.py

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import copy

# ── Colour palette ────────────────────────────────────────────────────────────
DARK_NAVY   = RGBColor(0x0D, 0x1B, 0x3E)   # slide background / title bar
MID_BLUE    = RGBColor(0x1A, 0x53, 0x8A)   # accent bars
ACCENT_TEAL = RGBColor(0x00, 0x8C, 0x9A)   # bullet icons / highlight
LIGHT_GREY  = RGBColor(0xF4, 0xF6, 0xF8)   # content area bg
WHITE       = RGBColor(0xFF, 0xFF, 0xFF)
TEXT_DARK   = RGBColor(0x1E, 0x1E, 0x2E)
YELLOW_HL   = RGBColor(0xFF, 0xD7, 0x00)   # key stat highlight

prs = Presentation()
prs.slide_width  = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]   # fully blank


# ── Helper utilities ──────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_rgb, alpha=None):
    from pptx.util import Inches
    shape = slide.shapes.add_shape(1, x, y, w, h)   # MSO_SHAPE_TYPE.RECTANGLE = 1
    shape.line.fill.background()                      # no border
    shape.fill.solid()
    shape.fill.fore_color.rgb = fill_rgb
    return shape

def add_textbox(slide, x, y, w, h, text, font_size=18, bold=False,
                color=WHITE, align=PP_ALIGN.LEFT, wrap=True,
                italic=False, v_anchor=MSO_ANCHOR.TOP):
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.word_wrap = wrap
    tf.vertical_anchor = v_anchor
    tf.margin_left = 0; tf.margin_right = 0
    tf.margin_top = 0;  tf.margin_bottom = 0
    p = tf.paragraphs[0]
    p.alignment = align
    r = p.add_run()
    r.text = text
    r.font.size = Pt(font_size)
    r.font.bold = bold
    r.font.italic = italic
    r.font.color.rgb = color
    r.font.name = "Calibri"
    return tb, tf

def add_slide_chrome(slide, title_text, subtitle_text=""):
    """Add the common top bar + title."""
    # Full background
    add_rect(slide, 0, 0, prs.slide_width, prs.slide_height, LIGHT_GREY)
    # Top banner
    add_rect(slide, 0, 0, prs.slide_width, Inches(1.15), DARK_NAVY)
    # Left accent stripe
    add_rect(slide, 0, Inches(1.15), Inches(0.07), prs.slide_height - Inches(1.15), ACCENT_TEAL)
    # Title text
    add_textbox(slide, Inches(0.2), Inches(0.12), Inches(12.5), Inches(0.75),
                title_text, font_size=30, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
    if subtitle_text:
        add_textbox(slide, Inches(0.2), Inches(0.72), Inches(12.5), Inches(0.36),
                    subtitle_text, font_size=14, bold=False, color=ACCENT_TEAL,
                    align=PP_ALIGN.LEFT)
    # Bottom accent bar
    add_rect(slide, 0, Inches(7.2), prs.slide_width, Inches(0.3), MID_BLUE)
    add_textbox(slide, Inches(0.2), Inches(7.22), Inches(10), Inches(0.26),
                "Sources: Harrison's Principles of Internal Medicine 22E | Fuster & Hurst's The Heart 15E | Frameworks for Internal Medicine",
                font_size=8, color=WHITE, align=PP_ALIGN.LEFT)

def add_bullets(slide, x, y, w, h, items, font_size=16, color=TEXT_DARK,
                bullet_color=ACCENT_TEAL, indent=0):
    """Add a bulleted list as stacked textboxes for easy formatting."""
    from pptx.oxml.ns import qn
    import lxml.etree as etree
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left = Inches(0.08)
    tf.margin_top  = Inches(0.05)
    first = True
    for item in items:
        if first:
            p = tf.paragraphs[0]
            first = False
        else:
            p = tf.add_paragraph()
        p.space_before = Pt(4)
        p.space_after  = Pt(2)
        # bullet dot
        run_dot = p.add_run()
        run_dot.text = "● "
        run_dot.font.size = Pt(font_size - 2)
        run_dot.font.color.rgb = bullet_color
        run_dot.font.name = "Calibri"
        # text
        run_txt = p.add_run()
        run_txt.text = item
        run_txt.font.size = Pt(font_size)
        run_txt.font.color.rgb = color
        run_txt.font.name = "Calibri"
    return tb

def stat_box(slide, x, y, w, h, label, value, val_color=YELLOW_HL):
    """A highlighted stat card."""
    add_rect(slide, x, y, w, h, MID_BLUE)
    add_textbox(slide, x + Inches(0.1), y + Inches(0.05), w - Inches(0.2), Inches(0.45),
                value, font_size=28, bold=True, color=val_color,
                align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
    add_textbox(slide, x + Inches(0.1), y + Inches(0.52), w - Inches(0.2), Inches(0.38),
                label, font_size=12, bold=False, color=WHITE,
                align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — Title Slide
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, prs.slide_width, prs.slide_height, DARK_NAVY)
# Decorative teal band
add_rect(s, 0, Inches(3.2), prs.slide_width, Inches(0.08), ACCENT_TEAL)
add_rect(s, 0, Inches(5.4), prs.slide_width, Inches(0.05), MID_BLUE)

add_textbox(s, Inches(1), Inches(1.3), Inches(11), Inches(1.2),
            "CARDIOEMBOLIC STROKE",
            font_size=48, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

add_textbox(s, Inches(1), Inches(2.6), Inches(11), Inches(0.5),
            "Etiology  |  Symptoms & Signs  |  Relevant Findings  |  Treatment",
            font_size=20, bold=False, color=ACCENT_TEAL, align=PP_ALIGN.CENTER)

add_textbox(s, Inches(2), Inches(3.5), Inches(9), Inches(0.4),
            "Cardioembolic stroke accounts for ~20–25% of all ischemic strokes",
            font_size=16, italic=True, color=LIGHT_GREY, align=PP_ALIGN.CENTER)

# Stat boxes on title slide
stat_box(s, Inches(1.5),  Inches(4.4), Inches(2.2), Inches(1.0), "of all ischemic strokes", "~20%")
stat_box(s, Inches(4.1),  Inches(4.4), Inches(2.2), Inches(1.0), "annual stroke risk in AF", "~5%")
stat_box(s, Inches(6.7),  Inches(4.4), Inches(2.2), Inches(1.0), "risk reduction with OAC", "~67%")
stat_box(s, Inches(9.3),  Inches(4.4), Inches(2.2), Inches(1.0), "PFO in general population", "~15%")

add_rect(s, 0, Inches(7.2), prs.slide_width, Inches(0.3), MID_BLUE)
add_textbox(s, Inches(0.2), Inches(7.22), Inches(10), Inches(0.26),
            "Sources: Harrison's 22E | Fuster & Hurst's The Heart 15E | Frameworks for Internal Medicine",
            font_size=8, color=WHITE, align=PP_ALIGN.LEFT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — Overview & Pathophysiology
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Overview & Pathophysiology", "Mechanism of cardioembolic stroke")

# Left column
add_rect(s, Inches(0.15), Inches(1.25), Inches(6.2), Inches(5.75), WHITE)
add_textbox(s, Inches(0.25), Inches(1.35), Inches(6.0), Inches(0.4),
            "Definition & Mechanism", font_size=16, bold=True, color=MID_BLUE)

bullets_l = [
    "Cardioembolism: ~20% of all ischemic strokes",
    "Thrombus forms on atrial/ventricular wall or left heart valves → detaches → embolises into arterial circulation",
    "Thrombus may fragment/lyse quickly → TIA; prolonged occlusion → stroke",
    "Embolic strokes: sudden onset with MAXIMUM neurologic deficit at onset",
    "Petechial haemorrhages may follow reperfusion (distinguish from frank haemorrhagic transformation)",
    "Most common lodgement sites: ICA, MCA, PCA, and their branches",
    "Large embolus (3–4 mm) occludes MCA stem → large infarct (deep grey + white matter + cortex)",
    "Multiple-territory infarction is a hallmark (unlike thrombotic strokes)"
]
add_bullets(s, Inches(0.2), Inches(1.8), Inches(6.1), Inches(5.0), bullets_l, font_size=14)

# Right column
add_rect(s, Inches(6.55), Inches(1.25), Inches(6.6), Inches(5.75), WHITE)
add_textbox(s, Inches(6.65), Inches(1.35), Inches(6.4), Inches(0.4),
            "Embolism Mechanisms", font_size=16, bold=True, color=MID_BLUE)

mechanisms = [
    ("Cardioembolism", "Large cardiac output → brain; thrombus originates in heart chambers"),
    ("Artery-to-Artery", "Atherosclerotic plaque fragments travel downstream"),
    ("Paradoxical Embolism", "Venous thrombus crosses to arterial circulation via PFO or ASD"),
    ("Fat / Tumour Emboli", "Rare; fat (fractures), atrial myxoma, bacterial vegetations"),
]
ypos = Inches(1.85)
for title, desc in mechanisms:
    add_rect(s, Inches(6.6), ypos, Inches(6.4), Inches(0.28), ACCENT_TEAL)
    add_textbox(s, Inches(6.7), ypos, Inches(6.2), Inches(0.28),
                title, font_size=13, bold=True, color=WHITE)
    add_textbox(s, Inches(6.7), ypos + Inches(0.3), Inches(6.2), Inches(0.42),
                desc, font_size=12, color=TEXT_DARK)
    ypos += Inches(0.82)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — Etiology
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Etiology", "Major cardiac sources of cerebral embolism")

# Two-column layout
# Col 1 — High risk
add_rect(s, Inches(0.15), Inches(1.25), Inches(6.0), Inches(5.75), WHITE)
add_rect(s, Inches(0.15), Inches(1.25), Inches(6.0), Inches(0.42), MID_BLUE)
add_textbox(s, Inches(0.25), Inches(1.27), Inches(5.8), Inches(0.38),
            "HIGH RISK — Anticoagulation Standard of Care", font_size=13, bold=True, color=WHITE)

high_risk = [
    "Non-rheumatic (non-valvular) atrial fibrillation — MOST COMMON cause overall",
    "Atrial flutter",
    "Left atrial / left atrial appendage thrombus",
    "Left ventricular thrombus",
    "Recent anterior MI (<4 weeks) with LV thrombus",
    "Left ventricular assist device (LVAD)",
    "Rheumatic mitral stenosis with AF / recurrent embolic events",
    "Mechanical prosthetic valves (aortic or mitral)",
    "Ischaemic cardiomyopathy with very low EF (<15%)",
]
add_bullets(s, Inches(0.2), Inches(1.75), Inches(5.9), Inches(5.0), high_risk, font_size=13)

# Col 2 — Moderate / other
add_rect(s, Inches(6.45), Inches(1.25), Inches(6.75), Inches(5.75), WHITE)
add_rect(s, Inches(6.45), Inches(1.25), Inches(6.75), Inches(0.42), ACCENT_TEAL)
add_textbox(s, Inches(6.55), Inches(1.27), Inches(6.55), Inches(0.38),
            "MODERATE / SPECIAL RISK", font_size=13, bold=True, color=WHITE)

mod_risk = [
    "Infective endocarditis (antibiotics; anticoagulation CONTRAINDICATED)",
    "Non-bacterial thrombotic endocarditis (marantic) — especially with hypercoagulability",
    "Papillary fibroelastoma (anticoag if surgery contraindicated)",
    "Atrial myxoma (surgical resection — anticoag contraindicated)",
    "Mitral valve prolapse (anticoag only if AF present; aspirin if cryptogenic TIA)",
    "Bioprosthetic aortic/mitral valve — antiplatelet standard of care",
    "Patent foramen ovale (PFO) — cryptogenic stroke, closure if causative",
    "Aortic arch mobile atheroma — aspirin or OAC",
    "Mitral annular calcification — aspirin unless AF (then OAC)",
    "Paradoxical embolism via ASD / pulmonary AVM",
]
add_bullets(s, Inches(6.5), Inches(1.75), Inches(6.65), Inches(5.0), mod_risk, font_size=13)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — Symptoms & Signs
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Symptoms & Signs", "Clinical presentation of cardioembolic stroke")

# Top banner note
add_rect(s, Inches(0.15), Inches(1.28), Inches(13.0), Inches(0.42), MID_BLUE)
add_textbox(s, Inches(0.3), Inches(1.3), Inches(12.7), Inches(0.38),
            "KEY FEATURE: Sudden onset with maximum deficit at onset; may involve multiple vascular territories simultaneously",
            font_size=13, bold=True, color=YELLOW_HL, align=PP_ALIGN.LEFT)

# Three columns: MCA, ICA/ACA, PCA/Posterior
col_w = Inches(4.15)
cols = [
    {
        "title": "MCA Territory",
        "items": [
            "Contralateral hemiplegia (face + arm > leg)",
            "Contralateral hemisensory loss",
            "Homonymous hemianopia",
            "Aphasia (dominant hemisphere — Broca, Wernicke or global)",
            "Neglect / anosognosia (non-dominant)",
            "Gaze deviation towards infarct side",
            "Dysarthria",
            "Large MCA: impaired consciousness, cerebral oedema (malignant MCA syndrome)",
        ]
    },
    {
        "title": "ICA / ACA Territory",
        "items": [
            "ICA occlusion: combined MCA + ACA territory deficits",
            "Monocular blindness (amaurosis fugax) — ophthalmic artery",
            "ACA: contralateral leg > arm weakness",
            "ACA: abulia, personality change, urinary incontinence",
            "Carotid terminus occlusion: large hemispheric infarct ± herniation",
        ]
    },
    {
        "title": "Posterior / Vertebrobasilar",
        "items": [
            "PCA: contralateral hemianopia, visual agnosia, alexia",
            "Basilar apex emboli: bilateral signs (hallmark), sudden coma",
            "Weber syndrome (CN III palsy + contralateral hemiplegia)",
            "Cerebellar infarct: ataxia, vertigo, nausea, vomiting",
            "Lateral medullary (Wallenberg) syndrome",
            "Diplopia, nystagmus, dysphagia, dysarthria",
            "Top-of-basilar: hypersomnolence, pupillary abnormalities",
        ]
    }
]
x = Inches(0.15)
for col in cols:
    add_rect(s, x, Inches(1.78), col_w, Inches(5.3), WHITE)
    add_rect(s, x, Inches(1.78), col_w, Inches(0.38), ACCENT_TEAL)
    add_textbox(s, x + Inches(0.1), Inches(1.80), col_w - Inches(0.2), Inches(0.34),
                col["title"], font_size=13, bold=True, color=WHITE)
    add_bullets(s, x + Inches(0.05), Inches(2.2), col_w - Inches(0.1), Inches(4.8),
                col["items"], font_size=12)
    x += col_w + Inches(0.22)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — Relevant Findings (Investigations)
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Relevant Findings & Investigations", "Diagnostic workup for cardioembolic stroke")

invest = [
    {
        "cat": "Neuroimaging",
        "items": [
            "CT brain (non-contrast): first-line — exclude haemorrhage; early ischaemia in <60% within 6 h",
            "MRI DWI: most sensitive for acute infarct; shows restricted diffusion within minutes",
            "Multiple cortical / subcortical infarcts in DIFFERENT vascular territories → strongly suggests embolism",
            "Cortical 'wedge' infarcts or 'rosette' haemorrhagic transformation — embolic pattern",
            "MRI FLAIR / GRE: identifies haemorrhagic transformation",
            "CT/MR Angiography: identifies vessel occlusion (MCA, ICA, basilar)",
        ]
    },
    {
        "cat": "Cardiac Investigations",
        "items": [
            "12-lead ECG: AF, flutter, recent MI (Q waves), LV hypertrophy",
            "Prolonged cardiac monitoring (Holter 24–72 h or implantable loop recorder): detect paroxysmal AF",
            "Transthoracic echocardiogram (TTE): LV thrombus, wall motion abnormality, valve disease, EF",
            "Transesophageal echocardiogram (TEE): superior for LAA thrombus, PFO, aortic arch atheroma, vegetations",
            "Bubble-contrast echo (agitated saline): detects right-to-left shunt (PFO/ASD)",
            "Transcranial Doppler + bubble study: detect right-to-left shunt (microemboli)",
            "Troponin / BNP: myocardial injury, heart failure",
        ]
    },
    {
        "cat": "Laboratory & Other",
        "items": [
            "CBC, PT/INR, aPTT, glucose: baseline coagulation, exclude metabolic causes",
            "Hypercoagulability screen (protein C/S, antiphospholipid antibodies) in young/cryptogenic stroke",
            "CHA₂DS₂-VASc score: quantify stroke risk in AF to guide anticoagulation",
            "Carotid duplex / CTA: exclude large-vessel atherosclerosis as alternative source",
            "Blood cultures: if infective endocarditis suspected",
            "ESR / CRP / ANA: vasculitis / inflammatory causes in young patients",
        ]
    }
]

# Three rows
ypos = Inches(1.28)
for idx, inv in enumerate(invest):
    add_rect(s, Inches(0.15), ypos, Inches(13.0), Inches(0.35), MID_BLUE if idx % 2 == 0 else ACCENT_TEAL)
    add_textbox(s, Inches(0.3), ypos + Inches(0.03), Inches(12.7), Inches(0.30),
                inv["cat"], font_size=14, bold=True, color=WHITE)
    add_rect(s, Inches(0.15), ypos + Inches(0.35), Inches(13.0), Inches(1.5), WHITE)
    add_bullets(s, Inches(0.25), ypos + Inches(0.38), Inches(12.7), Inches(1.4),
                inv["items"], font_size=12)
    ypos += Inches(1.95)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — CHA₂DS₂-VASc Score
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "CHA₂DS₂-VASc Score", "Stroke risk stratification in non-valvular atrial fibrillation")

# Table
headers = ["Risk Factor", "Points", "Recommendation"]
rows = [
    ("C — Congestive Heart Failure / LV dysfunction", "1", ""),
    ("H — Hypertension", "1", ""),
    ("A₂ — Age ≥ 75 years", "2", ""),
    ("D — Diabetes Mellitus", "1", ""),
    ("S₂ — Prior Stroke / TIA / thromboembolism", "2", ""),
    ("V — Vascular disease (MI, PAD, aortic plaque)", "1", ""),
    ("A — Age 65–74 years", "1", ""),
    ("Sc — Sex category (Female)", "1", ""),
]
recs = [
    ("Score 0", "No antithrombotic OR aspirin"),
    ("Score 1", "Aspirin OR oral anticoagulant (OAC)"),
    ("Score ≥ 2", "OAC (preferred DOAC over warfarin)"),
]

# Left: table
add_rect(s, Inches(0.15), Inches(1.28), Inches(7.5), Inches(5.72), WHITE)
add_rect(s, Inches(0.15), Inches(1.28), Inches(7.5), Inches(0.38), DARK_NAVY)
hx = Inches(0.2)
for h, hw in zip(headers, [Inches(4.5), Inches(0.9), Inches(1.8)]):
    add_textbox(s, hx, Inches(1.3), hw, Inches(0.34), h, font_size=13, bold=True, color=WHITE)
    hx += hw

yrow = Inches(1.7)
for i, (rf, pts, _) in enumerate(rows):
    bg = LIGHT_GREY if i % 2 == 0 else WHITE
    add_rect(s, Inches(0.15), yrow, Inches(7.5), Inches(0.52), bg)
    add_textbox(s, Inches(0.25), yrow + Inches(0.05), Inches(4.4), Inches(0.44),
                rf, font_size=12, color=TEXT_DARK)
    add_textbox(s, Inches(4.75), yrow + Inches(0.05), Inches(0.85), Inches(0.44),
                pts, font_size=14, bold=True, color=MID_BLUE, align=PP_ALIGN.CENTER)
    yrow += Inches(0.53)

# Right: recommendations
add_rect(s, Inches(7.85), Inches(1.28), Inches(5.35), Inches(5.72), WHITE)
add_rect(s, Inches(7.85), Inches(1.28), Inches(5.35), Inches(0.38), ACCENT_TEAL)
add_textbox(s, Inches(7.95), Inches(1.30), Inches(5.15), Inches(0.34),
            "Treatment Recommendations", font_size=14, bold=True, color=WHITE)
ypos2 = Inches(1.75)
for score, rec in recs:
    add_rect(s, Inches(7.9), ypos2, Inches(5.2), Inches(0.85), MID_BLUE)
    add_textbox(s, Inches(8.0), ypos2 + Inches(0.06), Inches(5.0), Inches(0.35),
                score, font_size=14, bold=True, color=YELLOW_HL)
    add_textbox(s, Inches(8.0), ypos2 + Inches(0.42), Inches(5.0), Inches(0.38),
                rec, font_size=12, color=WHITE)
    ypos2 += Inches(1.0)

# Max score note
add_textbox(s, Inches(7.9), ypos2 + Inches(0.3), Inches(5.15), Inches(0.4),
            "Maximum score: 9\nFemale sex alone (score=1) does NOT mandate anticoagulation",
            font_size=11, italic=True, color=MID_BLUE)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — Treatment: Acute Management
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Treatment: Acute Management", "Immediate intervention in cardioembolic stroke")

boxes = [
    {
        "title": "1. IV Thrombolysis (tPA)",
        "color": MID_BLUE,
        "items": [
            "Alteplase 0.9 mg/kg IV (max 90 mg) — 10% bolus, remainder over 60 min",
            "Window: ≤4.5 hours from symptom onset (selected patients up to 9 h with imaging mismatch)",
            "DO NOT delay for cardiac workup if within window",
            "Haemorrhagic transformation risk is higher in cardioembolic stroke",
            "Tenecteplase: emerging as equivalent alternative (single bolus)",
        ]
    },
    {
        "title": "2. Mechanical Thrombectomy (EVT)",
        "color": ACCENT_TEAL,
        "items": [
            "Indicated for LVO (large vessel occlusion: ICA, M1/M2 MCA, basilar)",
            "Window: up to 24 h with perfusion imaging selection (DAWN / DEFUSE-3 criteria)",
            "Stent-retriever or aspiration technique",
            "Can be combined with IV tPA (drip-and-ship)",
            "Cardioembolic clots: often red/fibrin-rich — may respond well to retrieval",
        ]
    },
    {
        "title": "3. General Supportive Care",
        "color": MID_BLUE,
        "items": [
            "Permissive hypertension: allow BP up to 220/120 mmHg (unless tPA given: <180/105)",
            "Normoglycaemia: treat hypo/hyperglycaemia (glucose 140–180 mg/dL)",
            "Supplemental O₂ only if SpO₂ <94%; avoid routine O₂",
            "Fever management: paracetamol ± cooling (target normothermia)",
            "DVT prophylaxis: pneumatic compression stockings acutely",
            "Swallow assessment before oral intake",
            "Stroke unit admission: reduces mortality and disability",
        ]
    }
]

x = Inches(0.15)
bw = Inches(4.28)
for box in boxes:
    add_rect(s, x, Inches(1.28), bw, Inches(5.72), WHITE)
    add_rect(s, x, Inches(1.28), bw, Inches(0.4), box["color"])
    add_textbox(s, x + Inches(0.1), Inches(1.30), bw - Inches(0.2), Inches(0.36),
                box["title"], font_size=13, bold=True, color=WHITE)
    add_bullets(s, x + Inches(0.05), Inches(1.73), bw - Inches(0.1), Inches(5.15),
                box["items"], font_size=12)
    x += bw + Inches(0.18)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — Treatment: Secondary Prevention & Antithrombotic Therapy
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_slide_chrome(s, "Treatment: Secondary Prevention", "Antithrombotic therapy & anticoagulation")

# Key messages banner
add_rect(s, Inches(0.15), Inches(1.28), Inches(13.0), Inches(0.4), DARK_NAVY)
add_textbox(s, Inches(0.3), Inches(1.30), Inches(12.7), Inches(0.36),
            "OAC reduces recurrent stroke by ~67% in NVAF | DOACs preferred over VKA (warfarin) in most cases",
            font_size=13, bold=True, color=YELLOW_HL, align=PP_ALIGN.LEFT)

# Two columns
add_rect(s, Inches(0.15), Inches(1.72), Inches(6.4), Inches(5.28), WHITE)
add_rect(s, Inches(0.15), Inches(1.72), Inches(6.4), Inches(0.38), MID_BLUE)
add_textbox(s, Inches(0.25), Inches(1.74), Inches(6.2), Inches(0.34),
            "Direct Oral Anticoagulants (DOACs)", font_size=14, bold=True, color=WHITE)

doacs = [
    "Dabigatran (thrombin inhibitor): 110 mg or 150 mg BD — non-inferior to warfarin; 150 mg BD superior; no INR monitoring",
    "Apixaban 5 mg BD (factor Xa inhibitor): superior to warfarin (1.27% vs 1.6% endpoint); less major bleeding",
    "Rivaroxaban 20 mg OD (factor Xa inhibitor): non-inferior to warfarin; less intracranial haemorrhage",
    "Edoxaban 60 mg OD (factor Xa inhibitor): non-inferior to warfarin",
    "Reversal agents: Idarucizumab (dabigatran); Andexanet alfa (apixaban, rivaroxaban)",
    "DOACs require no routine INR monitoring; minimal dietary interaction",
    "AVOID DOACs in: mechanical heart valves, moderate-severe rheumatic mitral stenosis",
]
add_bullets(s, Inches(0.2), Inches(2.14), Inches(6.3), Inches(4.75), doacs, font_size=12)

add_rect(s, Inches(6.75), Inches(1.72), Inches(6.4), Inches(5.28), WHITE)
add_rect(s, Inches(6.75), Inches(1.72), Inches(6.4), Inches(0.38), ACCENT_TEAL)
add_textbox(s, Inches(6.85), Inches(1.74), Inches(6.2), Inches(0.34),
            "Vitamin K Antagonists & Special Situations", font_size=14, bold=True, color=WHITE)

vka = [
    "Warfarin (VKA): INR 2–3 for NVAF; still gold standard for mechanical valves",
    "Mechanical aortic valve (bileaflet): VKA INR 2.5–3.5",
    "Mechanical mitral valve: VKA INR 3.0 (range 2.5–3.5)",
    "Mechanical valve + AF / low EF: Aspirin + VKA INR 3.0",
    "If OAC not tolerated (bleeding risk): Clopidogrel + Aspirin (ACTIVE-A — more effective than aspirin alone but ↑ bleeding)",
    "LAA occlusion device (Watchman): non-inferior to DOACs in high bleeding-risk patients",
    "Infective endocarditis: antibiotics; anticoagulation CONTRAINDICATED",
    "Timing to restart OAC after stroke: typically 2–4 weeks (varies by infarct size & haemorrhagic transformation risk)",
]
add_bullets(s, Inches(6.8), Inches(2.14), Inches(6.3), Inches(4.75), vka, font_size=12)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — Summary
# ═══════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, prs.slide_width, prs.slide_height, DARK_NAVY)
add_rect(s, 0, Inches(1.1), prs.slide_width, Inches(0.06), ACCENT_TEAL)
add_rect(s, 0, Inches(6.5), prs.slide_width, Inches(0.06), MID_BLUE)

add_textbox(s, Inches(1), Inches(0.2), Inches(11), Inches(0.8),
            "SUMMARY: CARDIOEMBOLIC STROKE",
            font_size=34, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

summary_items = [
    ("Incidence", "~20–25% of all ischaemic strokes; MOST COMMON embolic stroke type"),
    ("Onset", "Sudden, MAXIMAL deficit at onset; multiple territory involvement is hallmark"),
    ("Top Aetiology", "Non-valvular atrial fibrillation (AF) — annual stroke risk ~5%"),
    ("Other Sources", "LV thrombus, MI, prosthetic valves, endocarditis, PFO, cardiomyopathy"),
    ("Key Investigations", "MRI DWI + MRA, ECG (prolonged monitoring), TTE/TEE, bubble echo, CHA₂DS₂-VASc"),
    ("Acute Treatment", "IV tPA (≤4.5 h) and/or mechanical thrombectomy for LVO (up to 24 h)"),
    ("Secondary Prevention", "OAC (DOACs preferred) for AF: reduces recurrence by ~67%"),
    ("Special Cases", "Mechanical valves → warfarin; Infective endocarditis → antibiotics only"),
]

x_positions = [Inches(0.2), Inches(6.7)]
y_start = Inches(1.25)
for i, (key, val) in enumerate(summary_items):
    col = i % 2
    row = i // 2
    xp = x_positions[col]
    yp = y_start + row * Inches(1.22)
    add_rect(s, xp, yp, Inches(6.2), Inches(1.1), MID_BLUE)
    add_rect(s, xp, yp, Inches(1.8), Inches(1.1), ACCENT_TEAL)
    add_textbox(s, xp + Inches(0.1), yp + Inches(0.2), Inches(1.6), Inches(0.65),
                key, font_size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER,
                v_anchor=MSO_ANCHOR.MIDDLE)
    add_textbox(s, xp + Inches(1.9), yp + Inches(0.08), Inches(4.2), Inches(0.94),
                val, font_size=12, color=WHITE, v_anchor=MSO_ANCHOR.MIDDLE)

add_rect(s, 0, Inches(7.2), prs.slide_width, Inches(0.3), MID_BLUE)
add_textbox(s, Inches(0.2), Inches(7.22), Inches(10), Inches(0.26),
            "Sources: Harrison's Principles of Internal Medicine 22E | Fuster & Hurst's The Heart 15E | Frameworks for Internal Medicine",
            font_size=8, color=WHITE, align=PP_ALIGN.LEFT)


# ── Save ──────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/cardioembolic-stroke/Cardioembolic_Stroke.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
Running Command

cd /tmp/workspace/cardioembolic-stroke && python build_ppt.py 2>&1

Running Command

python3 -c " from pptx import Presentation prs = Presentation('/tmp/workspace/cardioembolic-stroke/Cardioembolic_Stroke.pptx') print(f'Slides: {len(prs.slides)}') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text.strip()[:60] for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f' Slide {i}: {texts[0] if texts else \"(empty)\"}') "

Your presentation is ready:

Cardioembolic Stroke

Presentation · PPTX


What's inside — 9 slides, 16:9 widescreen

#SlideContent
1Title slideKey stats: 20% of strokes, 5% annual AF risk, 67% OAC risk reduction, 15% PFO prevalence
2Overview & PathophysiologyMechanism of clot formation, embolisation, infarct patterns, all 4 embolism types
3EtiologyTwo-column layout — High risk (AF, LV thrombus, MI, prosthetic valves) vs Moderate/Special risk (endocarditis, PFO, myxoma, MVP)
4Symptoms & SignsThree-column: MCA territory, ICA/ACA territory, Posterior/Vertebrobasilar — with "sudden maximal onset" highlighted
5Relevant FindingsNeuroimaging (CT/MRI DWI), Cardiac investigations (ECG, Holter, TTE/TEE, bubble echo), Lab & other
6CHA₂DS₂-VASc ScoreFull scoring table + treatment thresholds for AF anticoagulation
7Acute TreatmentIV tPA, Mechanical Thrombectomy, General supportive care (3 columns)
8Secondary PreventionDOACs (dabigatran, apixaban, rivaroxaban, edoxaban) vs VKA, reversal agents, special situations
9Summary8-box grid recap of all key points
Sources used: Harrison's Principles of Internal Medicine 22E (2025), Fuster & Hurst's The Heart 15E, Frameworks for Internal Medicine.
This is a shared conversation. Sign in to Orris to start your own chat.