RCMY notes
Restrictive cardiomyopathy
"restrictive cardiomyopathy"[MeSH Terms]

| Category | Examples |
|---|---|
| Infiltrative (material between myocytes) | Amyloidosis (most common cause - AL, ATTRv, ATTRwt), Cardiac sarcoidosis |
| Storage (material within myocytes) | Hemochromatosis (iron), Fabry disease, Glycogen storage disease (II, III) |
| Fibrotic | Radiation, Scleroderma, Drugs (doxorubicin, serotonin, ergotamine) |
| Endomyocardial | Tropical endomyocardial fibrosis, Hypereosinophilic syndrome (Löffler endocarditis), Carcinoid syndrome |
| Cancer-related | Chemotherapy (high-dose anthracyclines), Radiotherapy |
Most RCM is due to acquired causes. Wild-type ATTR (ATTRwt) amyloidosis is the most prevalent form and increases in frequency in older patients. - Goldman-Cecil Medicine, Harrison's 22e
| Feature | RCM | Constrictive Pericarditis |
|---|---|---|
| Kussmaul sign | Present | Present |
| Pericardial knock | Absent | Present (S3-like, early) |
| Pericardium on CT/MRI | Normal | Thickened (≥4mm), calcified |
| LVEDP vs RVEDP | LVEDP > RVEDP by ≥5 mmHg | Equalized (within 5 mmHg) |
| Ventricular interdependence | Absent (pressures change in parallel) | Present (discordant LV/RV pressures with respiration) |
| E/e′ (tissue Doppler) | ↑ (reduced myocardial relaxation) | Normal/↑ annular velocities |
| Mitral inflow variability | <10% respiratory variation | >25% respiratory variation |
| Hepatic vein Doppler | Increased inspiratory forward flow | Expiratory diastolic reversal |
| Response to fluid | Worsening pressures | Equalization maintained |

Create a pdf
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && ls -la /tmp/workspace/
mkdir -p /tmp/workspace/rcm-notes && cat > /tmp/workspace/rcm-notes/build_pdf.py << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import cm from reportlab.lib import colors from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, KeepTogether ) from reportlab.lib.enums import TA_LEFT, TA_CENTER from reportlab.platypus import PageBreak import urllib.request import os # ── Download images ────────────────────────────────────────────────────────── IMG_DIR = "/tmp/workspace/rcm-notes/imgs" os.makedirs(IMG_DIR, exist_ok=True) img_urls = { "classification": "https://cdn.orris.care/cdss_images/2a6a2bbfd9bae4921760f6a49e2fc8afa73e11a0de8e3f3a3c5f3091c8cbcaf5.png", "hemodynamics": "https://cdn.orris.care/cdss_images/dea3236dc868eee21631363519709ef491faa365306fea13b811972ac55b4f61.png", } for name, url in img_urls.items(): dest = f"{IMG_DIR}/{name}.png" if not os.path.exists(dest): urllib.request.urlretrieve(url, dest) print(f"Downloaded {name}") # ── Styles ─────────────────────────────────────────────────────────────────── PAGE_W, PAGE_H = A4 MARGIN = 2*cm doc = SimpleDocTemplate( "/tmp/workspace/rcm-notes/Restrictive_Cardiomyopathy_Notes.pdf", pagesize=A4, leftMargin=MARGIN, rightMargin=MARGIN, topMargin=MARGIN, bottomMargin=MARGIN, title="Restrictive Cardiomyopathy – Study Notes", author="Orris Medical Library" ) styles = getSampleStyleSheet() NAVY = colors.HexColor("#1a3a5c") TEAL = colors.HexColor("#0d7e8a") AMBER = colors.HexColor("#e07b00") LTBLUE = colors.HexColor("#e8f4f8") LTAMB = colors.HexColor("#fff8e6") GREY = colors.HexColor("#f5f5f5") RED = colors.HexColor("#c0392b") title_style = ParagraphStyle("Title2", parent=styles["Title"], fontSize=22, textColor=NAVY, spaceAfter=6, alignment=TA_CENTER, fontName="Helvetica-Bold") subtitle_style = ParagraphStyle("Sub", parent=styles["Normal"], fontSize=10, textColor=TEAL, spaceAfter=12, alignment=TA_CENTER, fontName="Helvetica-Oblique") h1 = ParagraphStyle("H1", parent=styles["Heading1"], fontSize=13, textColor=colors.white, backColor=NAVY, spaceBefore=14, spaceAfter=4, leftIndent=-4, rightIndent=-4, fontName="Helvetica-Bold", borderPad=4) h2 = ParagraphStyle("H2", parent=styles["Heading2"], fontSize=11, textColor=NAVY, spaceBefore=10, spaceAfter=3, fontName="Helvetica-Bold", borderPad=2, borderColor=TEAL, borderWidth=0, leftIndent=0) h3 = ParagraphStyle("H3", parent=styles["Heading3"], fontSize=10, textColor=TEAL, spaceBefore=6, spaceAfter=2, fontName="Helvetica-Bold") body = ParagraphStyle("Body", parent=styles["Normal"], fontSize=9.5, leading=14, spaceAfter=4, fontName="Helvetica") bullet = ParagraphStyle("Bullet", parent=styles["Normal"], fontSize=9.5, leading=14, leftIndent=14, firstLineIndent=-10, spaceAfter=2, fontName="Helvetica", bulletText="•") subbullet = ParagraphStyle("SubBullet", parent=styles["Normal"], fontSize=9, leading=13, leftIndent=28, firstLineIndent=-10, spaceAfter=1, fontName="Helvetica", bulletText="–") note_box = ParagraphStyle("Note", parent=styles["Normal"], fontSize=9, leading=13, leftIndent=8, rightIndent=8, backColor=LTAMB, borderColor=AMBER, borderWidth=1, borderPad=5, spaceAfter=6, fontName="Helvetica-Oblique") caption = ParagraphStyle("Cap", parent=styles["Normal"], fontSize=8, leading=11, textColor=colors.grey, alignment=TA_CENTER, spaceAfter=8, fontName="Helvetica-Oblique") def sec(txt): return Paragraph(f" {txt}", h1) def head(txt): return Paragraph(txt, h2) def sub(txt): return Paragraph(txt, h3) def p(txt): return Paragraph(txt, body) def b(txt): return Paragraph(txt, bullet) def sb(txt): return Paragraph(txt, subbullet) def note(txt): return Paragraph(txt, note_box) def sp(n=4): return Spacer(1, n) def hr(): return HRFlowable(width="100%", thickness=0.5, color=TEAL, spaceAfter=4) # ── Table helper ───────────────────────────────────────────────────────────── def make_table(data, col_widths=None, header=True): t = Table(data, colWidths=col_widths, repeatRows=1 if header else 0) cmds = [ ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,0), 9), ("BACKGROUND",(0,0), (-1,0), NAVY), ("TEXTCOLOR", (0,0), (-1,0), colors.white), ("FONTNAME", (0,1), (-1,-1), "Helvetica"), ("FONTSIZE", (0,1), (-1,-1), 8.5), ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, GREY]), ("GRID", (0,0), (-1,-1), 0.4, colors.lightgrey), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("TOPPADDING",(0,0), (-1,-1), 4), ("BOTTOMPADDING",(0,0), (-1,-1), 4), ("LEFTPADDING",(0,0), (-1,-1), 5), ("RIGHTPADDING",(0,0), (-1,-1), 5), ] t.setStyle(TableStyle(cmds)) return t # ── Image helper ───────────────────────────────────────────────────────────── from reportlab.platypus import Image as RLImage def img(name, width, cap_text): path = f"{IMG_DIR}/{name}.png" im = RLImage(path, width=width, height=None) # height auto return [im, Paragraph(cap_text, caption)] # ── Content ────────────────────────────────────────────────────────────────── story = [] # Title page block story += [ sp(12), Paragraph("Restrictive Cardiomyopathy", title_style), Paragraph("Comprehensive Study Notes", subtitle_style), HRFlowable(width="60%", thickness=2, color=TEAL, spaceAfter=4), Paragraph("Sources: Harrison's 22e · Goldman-Cecil Medicine · Robbins Pathologic Basis of Disease", caption), sp(16), ] # ── SECTION 1: DEFINITION ──────────────────────────────────────────────────── story += [ sec("1 Definition & Overview"), sp(4), p("Restrictive cardiomyopathy (RCM) is characterized by a <b>primary decrease in ventricular compliance</b>, " "resulting in impaired ventricular <b>diastolic filling</b> despite normal (or near-normal) systolic " "function and wall thickness. The fundamental defect is a <b>stiff, noncompliant ventricle</b> that " "resists filling."), sp(4), p("Key pathophysiologic features:"), b("Ejection fraction often mildly decreased (30–50%) but may be near-normal"), b("Both atria markedly dilated — sometimes dwarfing the ventricles"), b("Resting cardiac output maintained until late stage"), b("Exertional intolerance is usually the first symptom"), b("Right-sided symptoms (edema, ascites, abdominal discomfort) often predominate"), sp(4), note("Most RCM is due to acquired causes. Wild-type ATTR amyloidosis is the most prevalent form " "and increases in frequency in older patients."), sp(4), ] # ── SECTION 2: CLASSIFICATION ───────────────────────────────────────────────── story += [ sec("2 Classification & Causes"), sp(4), ] story += img("classification", 16*cm, "Fig 1. Classification of restrictive cardiomyopathies. " "(Goldman-Cecil Medicine, adapted from Ditaranto et al. Front Pediatr. 2022)") story += [sp(4)] # Causes table causes_data = [ ["Category", "Sub-type", "Examples"], ["Genetic\n(Familial)", "Sarcomeric / Cytoskeletal", "TNNI3, MYH7 mutations; DES (desmin) → RCM + skeletal myopathy + conduction disease"], ["", "Storage (within myocytes)", "Fabry disease, Danon disease, PRKAG2 syndrome"], ["", "Other connective tissue", "Pseudoxanthoma elasticum"], ["Acquired\n(Infiltrative)", "Amyloidosis (most common)", "AL amyloid (plasma cells), ATTRv (hereditary), ATTRwt (wild-type, senile)"], ["", "Sarcoidosis", "Non-caseating granulomas, lateral LV wall most common site"], ["Acquired\n(Storage)", "Iron overload", "Hereditary hemochromatosis, Beta-thalassemia, Sickle cell anemia"], ["Acquired\n(Fibrotic)", "Radiation / Drugs", "Chest radiotherapy; doxorubicin, serotonin, ergotamine; scleroderma"], ["Endomyocardial", "Tropical EMF", "Most common RCM worldwide; children/young adults; Africa & tropics"], ["", "Löffler endocarditis", "Hypereosinophilic syndrome; no geographic predilection"], ["", "Carcinoid / Drugs", "Carcinoid syndrome; serotonin; ergotamine"], ["Cancer-related", "", "High-dose anthracyclines, chest radiotherapy"], ] # Convert to Paragraph cells def tc(txt, bold=False): fn = "Helvetica-Bold" if bold else "Helvetica" return Paragraph(f'<font name="{fn}" size="8">{txt}</font>', styles["Normal"]) causes_para = [[tc(c, bold=(r==0)) for c in row] for r, row in enumerate(causes_data)] cw = [3.2*cm, 3.8*cm, 9.5*cm] story.append(make_table(causes_para, col_widths=cw)) story.append(sp(6)) # ── SECTION 3: PATHOPHYSIOLOGY & MORPHOLOGY ────────────────────────────────── story += [ sec("3 Pathophysiology & Morphology"), sp(4), head("Pathophysiology"), b("Abnormal myocardial stiffness → ↑ diastolic pressures → impaired filling → ↓ stroke volume"), b("Systolic function preserved until late in disease"), b("End-diastolic pressures elevated in <b>both</b> ventricles"), b("LV more affected than RV → LVEDP typically ≥5 mmHg > RVEDP (key distinction from constrictive pericarditis)"), sp(4), head("Gross Morphology"), b("Ventricles: approximately <b>normal size</b>; cavities <b>not dilated</b>; myocardium firm"), b("<b>Biatrial dilation</b> — hallmark finding"), b("Thrombus in atrial appendages; patchy endocardial fibrosis"), sp(4), head("Microscopy"), b("Patchy or diffuse <b>interstitial fibrosis</b> (minimal to extensive)"), b("Myocyte disarray in idiopathic RCM"), b("Endomyocardial biopsy can identify specific etiology (amyloid, granulomas, iron deposits)"), sp(4), ] # ── SECTION 4: CLINICAL FEATURES ───────────────────────────────────────────── story += [ sec("4 Clinical Features"), sp(4), head("Symptoms"), b("<b>Exertional dyspnea</b> — usually first symptom (often unrecognized early)"), b("Fatigue, weakness, recurrent respiratory infections"), b("Progressive to: orthopnea, PND, dyspnea at rest"), b("<b>Right-sided</b> symptoms often predominate: peripheral edema, ascites, abdominal discomfort (hepatic engorgement)"), b("Chest pain, palpitations"), b("Rarely: <b>sudden death</b> as initial presentation"), sp(6), head("Physical Signs"), b("<b>Elevated JVP</b> with <b>prominent Y descent</b>"), b("<b>Kussmaul sign</b>: JVP fails to fall (or rises) with inspiration"), b("S4 more common than S3 in sinus rhythm; <b>atrial fibrillation</b> is common"), b("Loud P2 if pulmonary hypertension present"), b("Hepatomegaly, ascites, peripheral edema"), b("Cardiac impulse: less displaced than DCM; less dynamic than HCM"), sp(6), ] # ── SECTION 5: INVESTIGATIONS ──────────────────────────────────────────────── story += [ sec("5 Investigations"), sp(4), head("ECG"), b("No pathognomonic finding"), b("P mitrale, P pulmonale"), b("Nonspecific ST-T changes; ST depression & T-wave inversion (inferolateral)"), b("<b>Low-voltage QRS</b> — characteristic of amyloidosis (thick walls + low voltage = red flag)"), b("Heart block, bundle branch block"), sp(4), head("Echocardiography"), b("Markedly dilated atria with <b>normal-sized ventricles</b>"), b("Pulsed-wave Doppler (mitral inflow): ↑E, ↓A, ↑E/A, shortened deceleration time, shortened IVRT → <b>restrictive filling pattern</b>"), b("Pulmonary/hepatic vein Doppler: higher diastolic than systolic velocities"), b("Tissue Doppler: ↓ e′ (diastolic annular velocities), ↑ E/e′ (elevated LVEDP)"), b("Myocardial granular sparkling texture → suggests amyloidosis"), sp(4), head("Cardiac Catheterization"), b("<b>\"Dip-and-plateau\" / \"Square root sign\"</b>: rapid early diastolic pressure decline → rapid rise to plateau"), b("<b>LVEDP > RVEDP by ≥5 mmHg</b> (key distinguishing feature vs. constrictive pericarditis)"), b("Volume loading and exercise accentuate the LV-RV pressure difference"), sp(4), head("Cardiac MRI"), b("Gold standard for tissue characterization"), b("Late gadolinium enhancement (LGE) patterns help identify specific etiologies"), b("Amyloidosis: diffuse subendocardial LGE; sarcoidosis: patchy mid-myocardial LGE"), sp(4), head("Etiology-Specific Workup"), ] workup_data = [ ["Disease", "Key Investigation(s)"], ["Amyloidosis", "Congo red stain (apple-green birefringence), SPEP/UPEP, technetium pyrophosphate scan (ATTR), TTR genotyping, serum free light chains"], ["Sarcoidosis", "FDG-PET, endomyocardial biopsy (non-caseating granulomas), ACE level, chest CT"], ["Hemochromatosis", "Serum ferritin, transferrin saturation, HFE gene mutation, hepatic iron index"], ["Fabry disease", "α-galactosidase A levels (↓), GLA gene sequencing"], ["Eosinophilic", "Eosinophil count, bone marrow biopsy, PDGFR gene rearrangement"], ] workup_para = [[tc(c, bold=(r==0)) for c in row] for r, row in enumerate(workup_data)] story.append(make_table(workup_para, col_widths=[5*cm, 11.5*cm])) story.append(sp(8)) # ── SECTION 6: RCM vs CP ────────────────────────────────────────────────────── story += [ sec("6 Key Differential: RCM vs. Constrictive Pericarditis"), sp(4), ] diff_data = [ ["Feature", "RCM", "Constrictive Pericarditis"], ["Kussmaul sign", "Present", "Present"], ["Pericardial knock", "Absent", "Present (early S3-like)"], ["Pericardium (CT/MRI)", "Normal", "Thickened (≥4 mm), calcified"], ["LVEDP vs. RVEDP", "LVEDP > RVEDP by ≥5 mmHg", "Equalized (within 5 mmHg)"], ["Ventricular interdependence", "ABSENT — pressures change in parallel", "PRESENT — discordant LV/RV with respiration"], ["E/e′ (Tissue Doppler)", "↑ (reduced myocardial relaxation)", "Normal or ↑ annular velocities"], ["Mitral inflow variation (resp.)", "<10%", ">25%"], ["Hepatic vein Doppler", "Increased inspiratory forward flow", "Expiratory diastolic reversal"], ["Response to fluid", "Worsening pressures", "Equalization maintained"], ["ECG voltage", "Often low (amyloid)", "Normal"], ] diff_para = [[tc(c, bold=(r==0)) for c in row] for r, row in enumerate(diff_data)] story.append(make_table(diff_para, col_widths=[5.2*cm, 5.7*cm, 5.7*cm])) story.append(sp(6)) story += img("hemodynamics", 14*cm, "Fig 2. Simultaneous RV and LV pressure tracings. Top: Constrictive pericarditis — " "enhanced ventricular interdependence (discordant LV/RV pressure areas). " "Bottom: Restrictive cardiomyopathy — parallel LV/RV pressure changes, no ventricular interdependence. " "(Goldman-Cecil Medicine, adapted from Geske et al. JACC 2016)") story.append(sp(8)) # ── SECTION 7: SPECIAL ENTITIES ─────────────────────────────────────────────── story += [ sec("7 Special Entities"), sp(4), head("Endomyocardial Fibrosis (EMF)"), b("<b>Most common RCM worldwide</b>"), b("Predominantly children & young adults in <b>tropical Africa</b> and other tropical regions"), b("Fibrosis of ventricular endocardium from <b>apex upward</b>, often involving tricuspid/mitral valves"), b("Linked to nutritional deficiencies and parasitic infections (hypereosinophilia)"), b("Ventricular mural thrombi common (organized thrombus = much of the fibrosis)"), sp(6), head("Löffler Endocarditis (Hypereosinophilic Syndrome)"), b("Morphologically similar to EMF but <b>no geographic predilection</b>"), b("Peripheral <b>hypereosinophilia</b> + eosinophilic infiltrates in multiple organs"), b("Mechanism: eosinophil <b>major basic protein</b> → endomyocardial necrosis → scarring → thrombus → organization"), b("Stages: Necrotic → Thrombotic → Fibrotic"), b("Some cases: myeloid neoplasm with tyrosine kinase gene rearrangement → responds to <b>imatinib</b>"), sp(6), head("Cardiac Amyloidosis (Most Important Secondary Cause)"), b("Two main types: <b>AL amyloid</b> (light chains from plasma cell dyscrasia) and <b>ATTR</b> (transthyretin)"), sb("ATTRv (hereditary variant): Val122Ile mutation in <b>4% of African Americans</b> → 4× ↑ risk"), sb("ATTRwt (wild-type / 'senile'): normal TTR depositing in elderly"), b("Staining: <b>Congo red → apple-green birefringence</b> under polarized light"), b("EM: non-branching fibrils ~10 nm diameter"), b("ECG: <b>low voltage despite thick walls</b> (classic dissociation — pseudo-LVH)"), b("Endomyocardial biopsy almost always diagnostic"), b("<b>Treatment is type-specific</b> — incorrect typing leads to inappropriate therapy"), sb("AL: plasma cell-directed therapy (daratumumab-based regimens)"), sb("ATTR: tafamidis (stabilizes TTR tetramer), patisiran/vutrisiran (RNAi) for ATTRv"), note("⚠️ Determining the precise amyloid precursor protein is critical before initiating treatment. " "Incorrect typing will lead to inappropriate therapy."), sp(6), head("Endocardial Fibroelastosis"), b("Uncommon; fibroelastic thickening typically involving left-sided chambers"), b("Often presents in infants and young children"), sp(6), ] # ── SECTION 8: MANAGEMENT ──────────────────────────────────────────────────── story += [ sec("8 Management"), sp(4), head("General Principles"), b("Maintain <b>optimal volume status</b>: balance adequate ventricular filling with systemic decongestion"), b("<b>Diuretics</b> are the mainstay for fluid overload"), b("<b>Beta-blockers</b>: use cautiously — reducing HR reduces cardiac output in RCM (stroke volume is relatively fixed)"), b("<b>Vasodilators</b>: generally not well tolerated (preload-dependent state)"), b("HFrEF therapies (ACEi, ARB, ARNI, SGLT2i beyond volume): <b>not recommended</b> for routine use in RCM"), b("Rate control for atrial fibrillation"), b("Anticoagulation: indicated for AF; also in endomyocardial disease with mural thrombi"), sp(6), head("Disease-Specific Therapies"), ] rx_data = [ ["Disease", "Specific Treatment"], ["ATTR amyloidosis (ATTRwt/ATTRv)", "Tafamidis (TTR stabilizer) — reduces mortality & hospitalization; patisiran/vutrisiran (RNAi, for ATTRv)"], ["AL amyloidosis", "Plasma cell-directed chemotherapy; stem cell transplant if eligible"], ["Cardiac sarcoidosis", "Corticosteroids for active inflammation; ICD for ventricular arrhythmias"], ["Hemochromatosis", "Phlebotomy or chelation therapy — reversible if treated early"], ["Fabry disease", "Enzyme replacement therapy (agalsidase alfa/beta)"], ["Hypereosinophilic RCM", "Imatinib if PDGFR rearrangement; corticosteroids otherwise"], ["End-stage RCM", "Cardiac transplantation"], ] rx_para = [[tc(c, bold=(r==0)) for c in row] for r, row in enumerate(rx_data)] story.append(make_table(rx_para, col_widths=[6*cm, 10.5*cm])) story.append(sp(6)) story += [ head("Prognosis"), b("Idiopathic/most secondary RCM: slow, protracted course — survival often <b>>10 years</b> from diagnosis"), b("<b>AL amyloidosis</b>: much more rapid progression, worse prognosis"), b("Heart failure symptoms generally progressive and respond poorly to treatment"), b("Cardiac transplantation considered for eligible patients with refractory disease"), sp(8), ] # ── SECTION 9: QUICK SUMMARY BOX ───────────────────────────────────────────── story += [ sec("9 Quick Summary"), sp(4), ] summary_data = [ ["Parameter", "Restrictive Cardiomyopathy"], ["Core defect", "↓ ventricular compliance → impaired diastolic filling"], ["Systolic function", "Preserved (EF often 30–50%)"], ["Chambers", "Normal ventricles; BIATRIAL DILATION"], ["JVP", "↑ with prominent Y descent; Kussmaul sign"], ["Heart sounds", "S4 > S3; AF common"], ["ECG", "Low voltage (amyloid), nonspecific ST-T changes"], ["Echo Doppler", "Restrictive filling: ↑E/A, ↓DT, ↑E/e′"], ["Cath hallmark", "Dip-and-plateau (square root sign); LVEDP > RVEDP ≥5 mmHg"], ["Most common cause", "ATTRwt amyloidosis (elderly); AL amyloidosis (any age)"], ["Most common RCM worldwide", "Endomyocardial fibrosis (tropical)"], ["Key treatment", "Diuretics (symptom); tafamidis for ATTR amyloid"], ["Main differential", "Constrictive pericarditis (absent ventricular interdependence = RCM)"], ] sum_para = [[tc(c, bold=(r==0 or c==row[0])) for c in row] for r, row in enumerate(summary_data)] story.append(make_table(sum_para, col_widths=[6*cm, 10.5*cm])) story.append(sp(8)) # ── FOOTER NOTE ────────────────────────────────────────────────────────────── story.append(HRFlowable(width="100%", thickness=0.5, color=colors.lightgrey, spaceAfter=4)) story.append(Paragraph( "Sources: Harrison's Principles of Internal Medicine 22e (2025, McGraw Hill) · " "Goldman-Cecil Medicine International Edition · " "Robbins & Kumar Pathologic Basis of Disease · Robbins Basic Pathology", caption )) # ── BUILD ───────────────────────────────────────────────────────────────────── doc.build(story) print("PDF built successfully.") PYEOF python /tmp/workspace/rcm-notes/build_pdf.py
python3 << 'EOF' from PIL import Image im = Image.open("/tmp/workspace/rcm-notes/imgs/classification.png") print("classification:", im.size) im2 = Image.open("/tmp/workspace/rcm-notes/imgs/hemodynamics.png") print("hemodynamics:", im2.size) EOF
~/rcm-notes/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/rcm-notes/build_pdf.py'
python /tmp/workspace/rcm-notes/build_pdf.py
Restrictive Cardiomyopathy Notes
PDF Document · PDF