attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment

Make a handwritten notes on the given source ..in a very easy and understandable format covering each and every points

analyse_media
analyse_media
analyse_media
analyse_media
analyse_media
Running Command

mkdir -p /tmp/workspace/cholinergic-notes && ls /tmp/workspace/

Writing File

~/cholinergic-notes/make_notes.py

from PIL import Image, ImageDraw, ImageFont
import textwrap
import os

# Page size: A4 at 150 DPI
W, H = 1240, 1754
MARGIN = 70
LINE_H = 38
pages = []

# Colors
BG = (255, 252, 230)           # cream/yellowed paper
LINE_COLOR = (180, 200, 220)   # faint blue lines
TITLE_COLOR = (30, 80, 160)    # deep blue for headings
TEXT_COLOR = (20, 20, 60)      # dark navy for body
ACCENT = (190, 50, 50)         # red for important/box
HIGHLIGHT = (255, 180, 0)      # yellow highlight color
BOX_BG = (220, 235, 255)       # light blue box bg
ARROW_COLOR = (80, 120, 60)    # green for arrows

# Try to load a handwriting-like font, fallback to default
def get_font(size, bold=False):
    font_paths = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
        "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
        "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf",
    ]
    bold_paths = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
        "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
        "/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf",
    ]
    paths = bold_paths if bold else font_paths
    for p in paths:
        if os.path.exists(p):
            try:
                return ImageFont.truetype(p, size)
            except:
                pass
    return ImageFont.load_default()

def new_page():
    img = Image.new("RGB", (W, H), BG)
    draw = ImageDraw.Draw(img)
    # Draw ruled lines
    for y in range(120, H - 40, LINE_H):
        draw.line([(MARGIN - 10, y), (W - MARGIN + 10, y)], fill=LINE_COLOR, width=1)
    # Red margin line
    draw.line([(MARGIN - 30, 0), (MARGIN - 30, H)], fill=(220, 100, 100), width=2)
    return img, draw

def draw_title_box(draw, text, y, font_size=28):
    font = get_font(font_size, bold=True)
    bbox = draw.textbbox((0, 0), text, font=font)
    tw = bbox[2] - bbox[0]
    x = MARGIN
    draw.rectangle([x - 8, y - 6, x + tw + 14, y + font_size + 8], fill=(30, 80, 160), outline=(10, 40, 100), width=2)
    draw.text((x, y), text, fill="white", font=font)
    return y + font_size + 20

def draw_section(draw, text, y, font_size=22):
    font = get_font(font_size, bold=True)
    bbox = draw.textbbox((0, 0), text, font=font)
    tw = bbox[2] - bbox[0]
    draw.rectangle([MARGIN - 6, y - 4, MARGIN + tw + 10, y + font_size + 4], fill=(255, 230, 100), outline=(200, 160, 0), width=1)
    draw.text((MARGIN, y), text, fill=ACCENT, font=font)
    return y + font_size + 14

def draw_text(draw, text, y, font_size=17, color=TEXT_COLOR, indent=0, bold=False):
    font = get_font(font_size, bold=bold)
    x = MARGIN + indent
    max_w = W - x - MARGIN
    lines = textwrap.wrap(text, width=int(max_w / (font_size * 0.55)))
    for line in lines:
        if y > H - 80:
            return y  # overflow guard
        draw.text((x, y), line, fill=color, font=font)
        y += font_size + 8
    return y

def draw_bullet(draw, text, y, font_size=16, color=TEXT_COLOR, indent=0, symbol="•"):
    font = get_font(font_size)
    sym_font = get_font(font_size, bold=True)
    x = MARGIN + 20 + indent
    bullet_x = MARGIN + indent
    draw.text((bullet_x, y), symbol, fill=ACCENT, font=sym_font)
    max_w = W - x - MARGIN
    lines = textwrap.wrap(text, width=int(max_w / (font_size * 0.55)))
    for i, line in enumerate(lines):
        if y > H - 80:
            return y
        draw.text((x if i == 0 else x + 10, y), line, fill=color, font=font)
        y += font_size + 7
    return y

def draw_box(draw, lines, y, bg=BOX_BG, border=ACCENT, font_size=15):
    font = get_font(font_size)
    pad = 10
    all_text = "\n".join(lines)
    heights = []
    wrapped = []
    for l in lines:
        wl = textwrap.wrap(l, width=int((W - 2*MARGIN - 2*pad) / (font_size * 0.55)))
        if not wl:
            wl = [""]
        wrapped.append(wl)
        heights.append(len(wl) * (font_size + 7))
    total_h = sum(heights) + 2 * pad
    draw.rectangle([MARGIN, y, W - MARGIN, y + total_h], fill=bg, outline=border, width=2)
    cy = y + pad
    for wl in wrapped:
        for wline in wl:
            draw.text((MARGIN + pad + 10, cy), wline, fill=TEXT_COLOR, font=font)
            cy += font_size + 7
    return y + total_h + 14

def draw_arrow_flow(draw, items, y, font_size=15):
    font = get_font(font_size)
    arrow_font = get_font(20, bold=True)
    x = MARGIN
    for i, item in enumerate(items):
        bbox = draw.textbbox((0,0), item, font=font)
        tw = bbox[2] - bbox[0]
        th = bbox[3] - bbox[1]
        draw.rectangle([x - 4, y - 3, x + tw + 8, y + th + 5], fill=(220, 255, 220), outline=ARROW_COLOR, width=1)
        draw.text((x, y), item, fill=TEXT_COLOR, font=font)
        x += tw + 14
        if i < len(items) - 1:
            draw.text((x, y - 2), "→", fill=ARROW_COLOR, font=arrow_font)
            x += 22
        if x > W - MARGIN - 80:
            x = MARGIN + 40
            y += font_size + 22
    return y + font_size + 24

def draw_table(draw, headers, rows, y, col_widths=None, font_size=14):
    if col_widths is None:
        n = len(headers)
        col_widths = [(W - 2*MARGIN) // n] * n
    font_h = get_font(font_size, bold=True)
    font_b = get_font(font_size)
    pad = 6
    row_h = font_size + pad * 2 + 6

    # Header row
    x = MARGIN
    draw.rectangle([MARGIN, y, W - MARGIN, y + row_h], fill=(30, 80, 160))
    for i, h in enumerate(headers):
        wlines = textwrap.wrap(h, width=int(col_widths[i]/(font_size*0.6)))
        draw.text((x + pad, y + pad), wlines[0] if wlines else h, fill="white", font=font_h)
        x += col_widths[i]
    y += row_h

    for ri, row in enumerate(rows):
        # Compute row height (multiline)
        max_lines = 1
        wrapped_cells = []
        for ci, cell in enumerate(row):
            wl = textwrap.wrap(cell, width=max(1, int(col_widths[ci]/(font_size*0.58))))
            if not wl:
                wl = [""]
            wrapped_cells.append(wl)
            max_lines = max(max_lines, len(wl))
        rh = max_lines * (font_size + 5) + pad * 2
        bg_color = (240, 245, 255) if ri % 2 == 0 else (255, 255, 255)
        draw.rectangle([MARGIN, y, W - MARGIN, y + rh], fill=bg_color, outline=LINE_COLOR, width=1)
        x = MARGIN
        for ci, wl in enumerate(wrapped_cells):
            cy2 = y + pad
            for wline in wl:
                draw.text((x + pad, cy2), wline, fill=TEXT_COLOR, font=font_b)
                cy2 += font_size + 5
            x += col_widths[ci]
        # vertical lines
        x2 = MARGIN
        for w2 in col_widths:
            draw.line([(x2, y), (x2, y + rh)], fill=LINE_COLOR, width=1)
            x2 += w2
        draw.line([(W - MARGIN, y), (W - MARGIN, y + rh)], fill=LINE_COLOR, width=1)
        y += rh
    return y + 16

# ─────────────────────────────────────────────────────────────────
# PAGE 1: Cholinergic System Overview + ANS vs SNS
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  CHOLINERGIC SYSTEM  —  Pharmacology Notes  ", y, 30)
y += 4

# Subheading
y = draw_section(draw, "1.  What is Cholinergic Transmission?", y, 20)
y = draw_text(draw, "ACh (Acetylcholine) = neurotransmitter of the cholinergic system.", y, 16, TEXT_COLOR)
y = draw_text(draw, "Neurons that synthesize, store & release ACh → called CHOLINERGIC NEURONS.", y, 16, ACCENT)
y += 6

y = draw_section(draw, "2.  ANS vs Somatic Nervous System", y, 20)
headers = ["Feature", "ANS (Autonomic)", "Somatic NS"]
rows = [
    ["Control", "INVOLUNTARY — maintains homeostasis", "VOLUNTARY — under conscious control"],
    ["Neuron chain", "2 neurons in series (pre + post ganglionic)", "Single motor neuron (CNS → skeletal muscle)"],
    ["Junction", "Neuroeffector junction (smooth muscle/gland)", "NMJ — Neuromuscular junction"],
    ["Innervates", "Heart, smooth muscles, exocrine glands", "Skeletal muscles only"],
    ["Controls", "Circulation, digestion, excretion", "Skeletal muscle tone"],
]
col_w = [200, 440, 400]
y = draw_table(draw, headers, rows, y, col_w, 13)

y = draw_section(draw, "3.  Sites of ACh & NA Release (Fig. 2.1)", y, 20)
items_para = [
    "Preganglionic fibres (both sympathetic & parasympathetic)",
    "Release: ACh",
]
y = draw_bullet(draw, "Postganglionic — PARASYMPATHETIC → releases ACh at effector cell", y, 15)
y = draw_bullet(draw, "Postganglionic — SYMPATHETIC (most) → releases NA (noradrenaline) at blood vessel", y, 15)
y = draw_bullet(draw, "Sympathetic → SWEAT GLANDS → releases ACh (exception!)", y, 15)
y = draw_bullet(draw, "Nerve to adrenal medulla (preganglionic) → ACh → releases adrenaline + NA", y, 15)
y = draw_bullet(draw, "Somatic motor nerve → ACh → skeletal muscle (NMJ)", y, 15)
y += 6

y = draw_section(draw, "4.  Effects of ANS on Organs (Fig. 2.2)", y, 20)
headers2 = ["Organ", "Sympathetic (Fight/Flight)", "Parasympathetic (Rest/Digest)"]
rows2 = [
    ["Heart (HR & FOC)", "↑ HR, ↑ FOC", "↓ HR, ↓ FOC"],
    ["Pupil", "Mydriasis (dilates)", "Miosis (constricts)"],
    ["Bronchi", "Bronchodilatation", "Bronchospasm"],
    ["GIT (gut)", "↓ motility, ↑ sphincter tone", "↑ motility, sphincters relax"],
]
col_w2 = [200, 470, 370]
y = draw_table(draw, headers2, rows2, y, col_w2, 13)

draw.text((MARGIN, H - 50), "Page 1", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 2: Synthesis, Cholinesterases, Receptors
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  ACh SYNTHESIS, CHOLINESTERASES & RECEPTORS  ", y, 28)
y += 4

y = draw_section(draw, "5.  Synthesis of ACh (Fig. 2.3)", y, 20)
steps = ["Choline (enters neuron)", "Reacts with Acetyl-CoA", "ChAT enzyme", "ACh formed", "Stored in vesicles", "Action potential", "Released into synapse", "Activates receptors", "Hydrolysed by AChE"]
y = draw_arrow_flow(draw, steps, y, 14)
y = draw_bullet(draw, "ChAT = Choline AcetylTransferase (enzyme that MAKES ACh)", y, 15, ACCENT)
y = draw_bullet(draw, "AChE = AcetylCholinEsterase (enzyme that BREAKS ACh)", y, 15, ACCENT)
y += 6

y = draw_section(draw, "6.  Types of Cholinesterases", y, 20)
headers3 = ["Type", "Location", "Action", "Hydrolyses"]
rows3 = [
    ["True ChE (AChE)", "Neurons, ganglia, RBCs, NMJ", "Rapidly hydrolyses ACh", "ACh & Methacholine"],
    ["Pseudocholinesterase\n(Butyrylcholinesterase)", "Plasma, liver, glial cells", "Slow hydrolysis", "Wide variety of esters (NOT methacholine)"],
]
col_w3 = [230, 280, 280, 250]
y = draw_table(draw, headers3, rows3, y, col_w3, 13)

y = draw_section(draw, "7.  Cholinergic Receptors", y, 20)
y = draw_text(draw, "Two main types: MUSCARINIC (M) and NICOTINIC (N)", y, 16, TITLE_COLOR, bold=True)
y += 4

y = draw_text(draw, "MUSCARINIC RECEPTORS — G-protein coupled (regulate 2nd messengers)", y, 15, ACCENT, bold=True)
headers4 = ["Subtype", "Location", "Intracellular Effect", "Response"]
rows4 = [
    ["M1", "Gastric glands, Autonomic ganglia, CNS", "↑ IP3 & DAG", "↑ Learning/memory, gland secretion, SM contraction"],
    ["M2", "HEART", "↓ cAMP, opens K+ channels", "Hyperpolarization → ↓ SA node, ↓ AV node, ↓ contraction"],
    ["M3", "Smooth muscle, Exocrine glands, Endothelium", "↑ IP3 & DAG", "Glandular secretion, SM contraction"],
    ["M4 & M5", "CNS only", "G-protein mediated", "CNS functions"],
]
col_w4 = [90, 260, 250, 440]
y = draw_table(draw, headers4, rows4, y, col_w4, 12)
y += 2

y = draw_text(draw, "NICOTINIC RECEPTORS — Directly opens Na+/K+ ion channels → DEPOLARIZATION", y, 15, ACCENT, bold=True)
headers5 = ["Subtype", "Location", "Effect"]
rows5 = [
    ["NN (Nn)", "Autonomic ganglia, Adrenal medulla, CNS", "Depolarization → release of Adrenaline + NA from adrenal medulla"],
    ["NM (Nm)", "NMJ — Neuromuscular Junction", "Depolarization → Skeletal muscle CONTRACTION"],
]
col_w5 = [110, 380, 550]
y = draw_table(draw, headers5, rows5, y, col_w5, 13)

y = draw_box(draw, [
    "🧠  MEMORY TIP:",
    "M1 = gastric/ganglia (1 = stomach acid)  |  M2 = Heart (2 chambers pump)  |  M3 = Smooth muscle/glands (3 = secretion)",
    "NN = Ganglia & adrenal  |  NM = NMJ (M = Muscle)",
], y, bg=(255, 245, 200), border=(180, 140, 0), font_size=13)

draw.text((MARGIN, H - 50), "Page 2", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 3: Classification of Cholinergic Agonists + Choline Esters
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  CHOLINERGIC AGONISTS — Classification & Choline Esters  ", y, 26)
y += 4

y = draw_section(draw, "8.  Classification of Cholinergic Agonists", y, 20)

y = draw_box(draw, [
    "CHOLINERGIC AGONISTS (Cholinomimetics / Parasympathomimetics)",
    "",
    "A) DIRECTLY ACTING:",
    "   i) Choline Esters:  Acetylcholine (ACh) | Bethanechol | Carbachol",
    "   ii) Alkaloids:  Pilocarpine | Muscarine | Arecoline",
    "",
    "B) INDIRECTLY ACTING (Anticholinesterases):",
    "   i) REVERSIBLE:",
    "      • Carbamates: Physostigmine, Neostigmine, Pyridostigmine, Rivastigmine",
    "      • Alcohol: Edrophonium",
    "      • Others: Donepezil, Galantamine, Tacrine",
    "   ii) IRREVERSIBLE:",
    "      • Organophosphates (OP): Parathion, Malathion, Sarin, Soman, Tabun, Dyflos, Echothiophate",
    "      • Carbamates: Propoxur, Carbaryl",
], y, bg=(240, 250, 255), border=TITLE_COLOR, font_size=13)

y = draw_section(draw, "9.  Comparison of Choline Esters", y, 20)
headers6 = ["Property", "Acetylcholine", "Carbachol", "Bethanechol"]
rows6 = [
    ["Metabolized by", "True + Pseudocholinesterase", "Resistant to BOTH", "Resistant to BOTH"],
    ["Muscarinic actions", "+ (Yes)", "+ (Yes)", "+ (Yes)"],
    ["Nicotinic actions", "+ (Yes)", "+ (Yes)", "- (No)"],
    ["Effect of Atropine", "Completely blocks muscarinic", "NOT completely blocked", "Completely blocks muscarinic"],
    ["Therapeutic use", "No clinical use (too short action)", "Glaucoma", "Post-op urinary retention & paralytic ileus"],
]
col_w6 = [210, 280, 280, 270]
y = draw_table(draw, headers6, rows6, y, col_w6, 12)

y = draw_section(draw, "10.  Actions of ACh on Various Organs", y, 20)
y = draw_text(draw, "HEART (via M2 receptor):", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "↓↓ HR (negative chronotropic) — opens K+ channels → hyperpolarization → slows SA node", y, 14)
y = draw_bullet(draw, "↓↓ FOC (negative inotropic) — less force of contraction", y, 14)
y = draw_bullet(draw, "↓↓ A-V conduction (negative dromotropic)", y, 14)
y += 4
y = draw_text(draw, "BLOOD VESSELS (via M3 on endothelium):", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "ACh → M3 → releases NO (EDRF) → vasodilatation → ↓↓ BP", y, 14)
y += 4
y = draw_text(draw, "GIT (via M3):", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "↑ Tone of gut + ↑ Peristalsis + ↑ GI secretions + Relaxes sphincters (may cause defecation)", y, 14)
y += 4
y = draw_text(draw, "URINARY BLADDER (via M3):", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Contracts detrusor muscle → Relaxes trigone & sphincter → URINATION", y, 14)
y += 4
y = draw_text(draw, "BRONCHI (via M3):", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Bronchospasm + ↑ tracheobronchial secretion → CONTRAINDICATED IN ASTHMA!", y, 14, ACCENT)
y += 4
y = draw_text(draw, "EXOCRINE GLANDS:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "↑ Salivary, lacrimal, sweat, bronchial, gastric & GI secretions", y, 14)

draw.text((MARGIN, H - 50), "Page 3", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 4: Eye effects, Nicotinic actions, Alkaloids
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  ACh ON EYE | NICOTINIC ACTIONS | ALKALOIDS  ", y, 28)
y += 4

y = draw_section(draw, "11.  Actions on Eye (M3 receptors)", y, 20)
y = draw_text(draw, "ACh (i.v.), Pilocarpine, Physostigmine act on M3 receptors of eye:", y, 15)
y = draw_box(draw, [
    "M3 receptors in eye activated",
    "         ↓                              ↓",
    "Contract sphincter pupillae     Contract ciliary muscle",
    "→ MIOSIS (pupil constricts)     → Spasm of accommodation",
    "         ↓",
    "Opens trabecular meshwork around canal of Schlemm",
    "         ↓",
    "Facilitates aqueous humour drainage → ↓ IOP (used in GLAUCOMA!)",
    "         ↓",
    "Ciliary muscle contracts → suspensory ligament relaxes → lens bulges",
    "         ↓",
    "Vision fixed for NEAR distance (Accommodation for near)",
], y, bg=(230, 255, 230), border=ARROW_COLOR, font_size=13)

y = draw_text(draw, "Note: Topical ACh has NO effect on eye because it CANNOT penetrate tissue.", y, 14, ACCENT)
y += 6

y = draw_section(draw, "12.  Nicotinic Actions of ACh (higher doses needed)", y, 20)
y = draw_bullet(draw, "Autonomic ganglia: stimulates both sympathetic & parasympathetic ganglia → tachycardia & ↑ BP (atropine must be given first to block dangerous muscarinic effects)", y, 14)
y = draw_bullet(draw, "Skeletal muscles (NMJ): twitching → fasciculations → prolonged depolarization → PARALYSIS", y, 14)
y = draw_bullet(draw, "CNS: NO central effects (ACh does not cross BBB)", y, 14)
y += 6

y = draw_section(draw, "13.  Bethanechol", y, 20)
y = draw_bullet(draw, "Selective muscarinic actions on GIT and urinary bladder", y, 14)
y = draw_bullet(draw, "Preferred in: Post-operative urinary retention & Paralytic ileus", y, 14, ACCENT)
y += 6

y = draw_section(draw, "14.  Pilocarpine (Cholinomimetic Alkaloid)", y, 20)
y = draw_text(draw, "Source: Pilocarpus plant | Tertiary amine | Direct-acting | Muscarinic + Nicotinic effects", y, 14)
y = draw_text(draw, "USES:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Open-angle glaucoma & Acute congestive glaucoma (0.5-4% topical solution)", y, 14)
y = draw_bullet(draw, "Break adhesions between iris & lens (used with mydriatics)", y, 14)
y = draw_bullet(draw, "Reverse pupillary dilatation after refraction testing", y, 14)
y = draw_bullet(draw, "Sialogogue (to stimulate salivation)", y, 14)
y = draw_text(draw, "Adverse effects: Salivation, sweating, bradycardia, diarrhoea, bronchospasm, pulmonary oedema", y, 14, ACCENT)
y += 6

y = draw_section(draw, "15.  Muscarine & Mushroom Poisoning", y, 20)
headers7 = ["Type", "Mushroom", "Toxin", "Features", "Treatment"]
rows7 = [
    ["Rapid onset", "Inocybe spp.", "Muscarine", "Excessive muscarinic effects: vomiting, diarrhoea, bradycardia, salivation, sweating, bronchospasm, hypotension", "IV Atropine"],
    ["Hallucinogen type", "Amanita muscaria, Psilocybe", "Muscimol", "Mainly CENTRAL effects (hallucinations). No specific antidote. Atropine CONTRAINDICATED", "Supportive care"],
    ["Delayed onset", "Amanita phalloides", "Amatoxin", "Delayed gastroenteritis, hepatic & renal damage. Does NOT respond to atropine", "Thioctic acid + supportive"],
]
col_w7 = [130, 180, 120, 420, 190]
y = draw_table(draw, headers7, rows7, y, col_w7, 11)

draw.text((MARGIN, H - 50), "Page 4", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 5: Anticholinesterases (Reversible) + Individual drugs
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  ANTICHOLINESTERASES — Reversible Drugs  ", y, 28)
y += 4

y = draw_section(draw, "16.  How Anticholinesterases Work", y, 20)
y = draw_text(draw, "They INHIBIT cholinesterase enzyme → ACh NOT broken down → ACCUMULATES at muscarinic & nicotinic sites → Cholinergic effects", y, 15)
y = draw_box(draw, [
    "Normal: ACh → binds anionic + esteratic site of ChE → acetylated enzyme → rapid hydrolysis → free enzyme",
    "",
    "Carbamates (e.g. Neostigmine): bind both sites → carbamoylated enzyme → SLOW hydrolysis (reversible)",
    "",
    "Organophosphates: bind COVALENTLY to esteratic site → IRREVERSIBLE inhibition (phosphorylated enzyme doesn't hydrolyse)",
    "",
    "Edrophonium: binds only anionic site → weak H-bond → diffuses away in 8-10 min (very short action)",
], y, bg=(255, 240, 220), border=(200, 100, 0), font_size=13)

y = draw_section(draw, "17.  Physostigmine vs Neostigmine", y, 20)
headers8 = ["Feature", "Physostigmine (Eserine)", "Neostigmine"]
rows8 = [
    ["Source", "Natural alkaloid (Physostigma venenosum)", "Synthetic"],
    ["Chemistry", "Tertiary amine → CROSSES BBB", "Quaternary ammonium → does NOT cross BBB"],
    ["Penetration", "Good tissue penetration → topically effective", "Poor penetration → topically NOT effective"],
    ["CNS effects", "YES — both central & peripheral effects", "NO central effects"],
    ["Uses", "Atropine poisoning, Glaucoma", "Post-op urinary retention, Paralytic ileus, Myasthenia gravis, Curare poisoning"],
]
col_w8 = [180, 430, 430]
y = draw_table(draw, headers8, rows8, y, col_w8, 12)

y = draw_section(draw, "18.  Individual Drugs", y, 20)
y = draw_text(draw, "PHYSOSTIGMINE:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Glaucoma: reduces IOP by producing miosis (BUT causes cataract on chronic use → rarely used now)", y, 14)
y = draw_bullet(draw, "Atropine poisoning: IV physostigmine — reverses BOTH central & peripheral effects (preferred over neostigmine)", y, 14)
y += 4

y = draw_text(draw, "NEOSTIGMINE:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Indirect action: inhibits ChE → ↑ ACh at NMJ", y, 14)
y = draw_bullet(draw, "Direct action: also directly stimulates NM receptors (structural similarity to ACh)", y, 14)
y = draw_bullet(draw, "Preferred over physostigmine in myasthenia gravis (no CNS side effects)", y, 14, ACCENT)
y = draw_bullet(draw, "Available: oral, SC, IV, IM", y, 14)
y += 4

y = draw_text(draw, "PYRIDOSTIGMINE:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Same as neostigmine BUT longer duration of action (twice daily sustained release)", y, 14)
y = draw_bullet(draw, "Less potent but BETTER TOLERATED → PREFERRED in myasthenia gravis", y, 14, ACCENT)
y += 4

y = draw_text(draw, "EDROPHONIUM:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Quaternary ammonium | IV → rapid onset, SHORT action (8-10 min)", y, 14)
y = draw_bullet(draw, "USES: (1) Diagnosis of myasthenia gravis (2) Differentiate myasthenic vs cholinergic crisis (3) Curare poisoning (preferred for rapid onset)", y, 14, ACCENT)
y += 4

y = draw_text(draw, "GALANTAMINE, RIVASTIGMINE, DONEPEZIL:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Cerebroselective anticholinesterases → increase cerebral ACh levels", y, 14)
y = draw_bullet(draw, "Used in ALZHEIMER'S DISEASE", y, 14, ACCENT)
y += 4

y = draw_section(draw, "19.  Adverse Effects of Anticholinesterases", y, 20)
y = draw_box(draw, [
    "Due to overstimulation of BOTH muscarinic & nicotinic receptors:",
    "↑ Sweating | ↑ Salivation | Nausea | Vomiting | Abdominal cramps | Bradycardia | Diarrhoea | Tremors | Hypotension",
], y, bg=(255, 220, 220), border=ACCENT, font_size=13)

draw.text((MARGIN, H - 50), "Page 5", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 6: Therapeutic Uses of Anticholinesterases + OP Poisoning + Glaucoma
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  THERAPEUTIC USES | OP POISONING | GLAUCOMA  ", y, 26)
y += 4

y = draw_section(draw, "20.  Therapeutic Uses of Reversible Anticholinesterases", y, 20)
uses = [
    ("Eye", ["Glaucoma", "Reverse pupillary dilatation after refraction testing", "Break adhesions between iris & lens (with mydriatics)"]),
    ("Myasthenia gravis", ["Neostigmine (IV/IM), Pyridostigmine (oral, preferred)"]),
    ("Postoperative", ["Urinary retention & Paralytic ileus → Neostigmine"]),
    ("Poisoning reversal", ["Curare (non-depolarizing NMJ block) → Neostigmine/Edrophonium", "Belladonna poisoning → Physostigmine"]),
    ("Alzheimer's disease", ["Donepezil, Galantamine, Rivastigmine"]),
]
for label, bullets in uses:
    y = draw_text(draw, f"• {label}:", y, 15, TITLE_COLOR, bold=True)
    for b in bullets:
        y = draw_bullet(draw, b, y, 14, indent=20)
    y += 2
y += 4

y = draw_section(draw, "21.  Irreversible Anticholinesterases — OP Poisoning", y, 20)
y = draw_text(draw, "All OP compounds (except echothiophate) have ONLY toxicological importance.", y, 15, ACCENT)
y = draw_text(draw, "Common OPs: Parathion, Malathion, Dyflos, Sarin, Soman, Tabun (nerve gases)", y, 14)
y += 4
y = draw_text(draw, "SIGNS & SYMPTOMS:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Muscarinic effects: Profuse sweating, salivation, lacrimation, ↑ tracheobronchial secretions, bronchospasm, vomiting, diarrhoea, abdominal cramps, miosis, bradycardia, hypotension, involuntary urination/defecation (SLUDGE + DUMBELS)", y, 14)
y = draw_bullet(draw, "Nicotinic effects: Twitchings, fasciculations, muscle weakness, PARALYSIS (due to prolonged depolarization)", y, 14)
y = draw_bullet(draw, "Central effects: Headache, restlessness, confusion, convulsions, coma, DEATH (respiratory failure)", y, 14)
y += 4

y = draw_text(draw, "DIAGNOSIS of OP poisoning:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "History of exposure", y, 14)
y = draw_bullet(draw, "Characteristic signs & symptoms", y, 14)
y = draw_bullet(draw, "Decreased cholinesterase activity in blood", y, 14)
y += 4

y = draw_section(draw, "22.  Glaucoma — Overview & Drugs", y, 20)
y = draw_text(draw, "Glaucoma = optic nerve damage with ↑ IOP (normal IOP: 10-20 mmHg)", y, 15)
y = draw_text(draw, "Aqueous humour formed by ciliary body → drains via trabecular meshwork (canal of Schlemm) & uveoscleral outflow", y, 14)
y += 4

headers9 = ["Drug Class", "Acute Congestive (Narrow-angle)", "Chronic Simple (Wide-angle)"]
rows9 = [
    ["Osmotic agents", "Mannitol 20% IV, Glycerol 50% oral", "Not used"],
    ["Carbonic anhydrase inhibitors", "Acetazolamide IV/oral", "Dorzolamide 2% topical, Brinzolamide, Acetazolamide oral"],
    ["β-Blockers (topical)", "Timolol 0.5%", "Timolol 0.25%, Betaxolol 0.25%, Carteolol 1%"],
    ["Prostaglandins (topical)", "Latanoprost 0.005%", "Latanoprost 0.005%, Travoprost, Bimatoprost (DRUG OF CHOICE in open-angle)"],
    ["Miotics (topical)", "Pilocarpine 2%", "Pilocarpine 0.5%"],
    ["α-Adrenergic agonists", "Not used", "Apraclonidine, Dipivefrin 0.1%"],
]
col_w9 = [260, 370, 410]
y = draw_table(draw, headers9, rows9, y, col_w9, 12)

y = draw_box(draw, [
    "NOTES on Glaucoma drugs:",
    "• Propranolol NOT used (membrane-stabilizing effect anesthetizes cornea)",
    "• Betaxolol = selective β1-blocker (protective to retinal neurons)",
    "• Levobunolol = long acting β-blocker (use cautiously in asthma/heart failure)",
    "• Timolol: no local anesthetic, no miosis, no accommodation changes, long duration",
    "• Apraclonidine: α2-agonist → ↓ aqueous formation → ↓ IOP (does NOT cross BBB → no hypotension like clonidine)",
    "• Dipivefrin = prodrug of adrenaline → penetrates cornea → converted to adrenaline by esterases",
], y, bg=(240, 245, 255), border=TITLE_COLOR, font_size=12)

draw.text((MARGIN, H - 50), "Page 6", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# PAGE 7: Myasthenia Gravis + Cholinergic Crisis
# ─────────────────────────────────────────────────────────────────
img, draw = new_page()
y = 30
y = draw_title_box(draw, "  MYASTHENIA GRAVIS & CHOLINERGIC CRISIS  ", y, 28)
y += 4

y = draw_section(draw, "23.  Myasthenia Gravis — Key Points", y, 20)
y = draw_text(draw, "Autoimmune disorder: antibodies against NM (Nicotinic-Muscle) receptors at NMJ → ↓ number of NM receptors", y, 15)
y = draw_bullet(draw, "Increased incidence with THYMOMA (thymus is removed → thymectomy can induce remission)", y, 14)
y = draw_bullet(draw, "Features: Marked muscular weakness, varying degree at different times, easy fatigability", y, 14)
y += 4

y = draw_text(draw, "DIAGNOSIS:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Tensilon test (Edrophonium test): 2-10 mg IV slow → dramatic improvement in MG (but NOT in other dystrophies)", y, 14, ACCENT)
y = draw_bullet(draw, "Also used to differentiate myasthenic crisis from cholinergic crisis", y, 14)
y = draw_bullet(draw, "Circulating antibodies to NM receptors (serology)", y, 14)
y += 4

y = draw_text(draw, "TREATMENT:", y, 15, TITLE_COLOR, bold=True)
y = draw_bullet(draw, "Anticholinesterases (symptomatic): Neostigmine, Pyridostigmine (preferred), Ambenonium", y, 14)
y = draw_bullet(draw, "Corticosteroids + Immunosuppressants (azathioprine / cyclophosphamide) — for induction and maintenance of remission", y, 14)
y = draw_bullet(draw, "Plasmapheresis & immune therapy — resistant cases", y, 14)
y += 4

y = draw_box(draw, [
    "DRUGS CONTRAINDICATED in Myasthenia Gravis (they WORSEN it):",
    "Aminoglycoside antibiotics | d-Tubocurarine (d-TC) | β-blockers | Ether | Phenytoin | etc.",
], y, bg=(255, 220, 220), border=ACCENT, font_size=13)
y += 4

y = draw_section(draw, "24.  Myasthenic Crisis vs Cholinergic Crisis", y, 20)
headers10 = ["Feature", "Myasthenic Crisis", "Cholinergic Crisis"]
rows10 = [
    ["Cause", "Under-treatment / exacerbation of MG (↓ ACh at NMJ)", "Overdose of anticholinesterases (↑ ACh → prolonged depolarization)"],
    ["Weakness", "Severe weakness (↓ NMJ activity)", "Severe weakness + NMJ paralysis"],
    ["Other signs", "No cholinergic signs", "SLUDGE signs: salivation, lacrimation, diarrhoea, GI cramps, bradycardia"],
    ["Edrophonium test", "Improvement (crisis is myasthenic)", "Worsening / no improvement (crisis is cholinergic)"],
    ["Treatment", "Give more anticholinesterase", "STOP anticholinesterase, give ATROPINE"],
]
col_w10 = [200, 400, 440]
y = draw_table(draw, headers10, rows10, y, col_w10, 12)

y = draw_box(draw, [
    "⚠️  IMPORTANT: Keep ATROPINE ready before injecting Edrophonium in MG diagnosis",
    "   — if muscular weakness deteriorates (cholinergic crisis), edrophonium will aggravate it!",
    "   Ventilator should be kept ready.",
], y, bg=(255, 240, 200), border=(180,130,0), font_size=13)
y += 6

y = draw_section(draw, "25.  Summary — Quick Recall Table", y, 20)
headers11 = ["Drug", "Type", "Key Use", "Crosses BBB?"]
rows11 = [
    ["Physostigmine", "Reversible anticholinesterase", "Atropine poisoning, Glaucoma", "YES"],
    ["Neostigmine", "Reversible anticholinesterase", "MG, Post-op urinary retention, Curare reversal", "NO"],
    ["Pyridostigmine", "Reversible anticholinesterase", "MG (preferred — better tolerated, longer duration)", "NO"],
    ["Edrophonium", "Reversible anticholinesterase", "Diagnosis of MG, Curare poisoning", "NO"],
    ["Donepezil/Galantamine/Rivastigmine", "Cerebroselective AChE inhibitor", "Alzheimer's disease", "YES"],
    ["Pilocarpine", "Direct muscarinic agonist (alkaloid)", "Glaucoma, Sialogogue", "—"],
    ["Bethanechol", "Direct muscarinic agonist (choline ester)", "Post-op urinary retention, Paralytic ileus", "—"],
    ["Carbachol", "Direct muscarinic agonist (choline ester)", "Glaucoma", "—"],
]
col_w11 = [280, 230, 380, 150]
y = draw_table(draw, headers11, rows11, y, col_w11, 11)

draw.text((MARGIN, H - 50), "Page 7", fill=(150,150,150), font=get_font(14))
pages.append(img)

# ─────────────────────────────────────────────────────────────────
# SAVE as multi-page PDF
# ─────────────────────────────────────────────────────────────────
output_path = "/tmp/workspace/cholinergic-notes/Cholinergic_System_Notes.pdf"
pages[0].save(output_path, save_all=True, append_images=pages[1:], format="PDF")
print(f"Saved: {output_path}")
print(f"Pages: {len(pages)}")
Running Command

cd /tmp/workspace/cholinergic-notes && python make_notes.py 2>&1

Your handwritten-style notes are ready! Here's the download link:

Cholinergic System Notes

PDF Document · PDF


Here's what's covered across all 7 pages of the notes:

Page 1 - Cholinergic System Overview & ANS vs SNS
  • What is ACh and cholinergic transmission
  • Full comparison table: ANS vs Somatic Nervous System
  • Sites of ACh & NA release (Fig 2.1 explained)
  • Effects of sympathetic vs parasympathetic on Heart, Pupil, Bronchi, GIT
Page 2 - ACh Synthesis, Cholinesterases & Receptors
  • Step-by-step synthesis: Choline → ChAT → ACh → vesicles → release → AChE
  • True ChE vs Pseudocholinesterase (locations + what they hydrolyse)
  • Muscarinic receptor subtypes (M1-M5) with location + intracellular effects + response
  • Nicotinic receptor subtypes (NN vs NM) with locations + effects
Page 3 - Classification of Cholinergic Agonists & Choline Esters
  • Full classification tree: Direct (choline esters, alkaloids) vs Indirect (reversible & irreversible)
  • Comparison table: ACh vs Carbachol vs Bethanechol
  • ACh actions on Heart, Blood vessels, GIT, Urinary bladder, Bronchi, Exocrine glands
Page 4 - Eye Effects, Nicotinic Actions, Pilocarpine, Muscarine
  • Complete eye flowchart: M3 → miosis → trabecular meshwork → ↓ IOP → accommodation
  • Nicotinic actions of ACh (ganglia, skeletal muscle, CNS)
  • Bethanechol uses
  • Pilocarpine: mechanism, uses, adverse effects
  • Mushroom poisoning: 3 types with toxins and treatment
Page 5 - Reversible Anticholinesterases
  • Mechanism: how carbamates, OPs, and edrophonium work differently
  • Physostigmine vs Neostigmine comparison table
  • Individual drug profiles: Physostigmine, Neostigmine, Pyridostigmine, Edrophonium
  • Donepezil/Galantamine/Rivastigmine for Alzheimer's
  • Adverse effects of anticholinesterases
Page 6 - Therapeutic Uses, OP Poisoning & Glaucoma Drugs
  • All therapeutic uses organized by condition
  • OP poisoning: signs (muscarinic, nicotinic, central), diagnosis, SLUDGE mnemonic
  • Glaucoma drug table: Acute narrow-angle vs Chronic wide-angle
  • Notes on Timolol, Betaxolol, Dipivefrin, Apraclonidine, Latanoprost
Page 7 - Myasthenia Gravis & Cholinergic Crisis
  • MG pathophysiology, diagnosis (Tensilon test), treatment
  • Drugs contraindicated in MG
  • Myasthenic crisis vs Cholinergic crisis comparison table
  • Final quick-recall summary table of all drugs

Make a beautiful notes and a detailed version notes covering all the heading in detail with proper explanation and diagrams

Running Command

ls /tmp/workspace/cholinergic-notes/

Writing File

~/cholinergic-notes/beautiful_notes.py

from PIL import Image, ImageDraw, ImageFont
import textwrap, os, math

# ── Canvas ──────────────────────────────────────────────────────
W, H = 1400, 1980          # A4-ish at ~167 DPI
MARGIN_L, MARGIN_R = 70, 70
CONTENT_W = W - MARGIN_L - MARGIN_R

# ── Palette ─────────────────────────────────────────────────────
BG_CREAM      = (255, 253, 240)
RULE_BLUE     = (190, 210, 235)
MARGIN_RED    = (220, 80, 80)

C_NAVY        = (15,  40, 100)
C_TEAL        = (0,  130, 140)
C_RUST        = (185,  55,  30)
C_GREEN       = (30,  120,  60)
C_PURPLE      = (120,  40, 160)
C_GOLD        = (180, 130,   0)
C_DARK        = (25,  25,  50)
C_GRAY        = (100, 100, 120)

BAND_NAVY     = (15,  40, 100)
BAND_TEAL     = (0,  115, 125)
BAND_RUST     = (175,  50,  25)
BAND_GREEN    = (25, 110,  55)
BAND_PURPLE   = (110,  35, 150)
BAND_GOLD     = (165, 120,   0)

BOX_YELLOW    = (255, 250, 200)
BOX_BLUE      = (230, 242, 255)
BOX_GREEN     = (225, 248, 230)
BOX_RED       = (255, 232, 230)
BOX_PURPLE    = (242, 230, 255)
BOX_TEAL      = (220, 248, 248)

# ── Font helpers ────────────────────────────────────────────────
def gf(size, bold=False, italic=False):
    candidates = {
        (False, False): [
            "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
            "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
        ],
        (True,  False): [
            "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
            "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
        ],
        (False, True): [
            "/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf",
            "/usr/share/fonts/truetype/liberation/LiberationSans-Italic.ttf",
        ],
        (True,  True): [
            "/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf",
            "/usr/share/fonts/truetype/liberation/LiberationSans-BoldItalic.ttf",
        ],
    }
    for p in candidates.get((bold, italic), candidates[(False,False)]):
        if os.path.exists(p):
            try:
                return ImageFont.truetype(p, size)
            except:
                pass
    return ImageFont.load_default()

def tw(draw, text, font):
    bb = draw.textbbox((0,0), text, font=font)
    return bb[2]-bb[0], bb[3]-bb[1]

# ── Page factory ────────────────────────────────────────────────
def new_page():
    img = Image.new("RGB", (W, H), BG_CREAM)
    d   = ImageDraw.Draw(img)
    for yy in range(130, H-30, 36):
        d.line([(MARGIN_L-15, yy), (W-MARGIN_R+15, yy)], fill=RULE_BLUE, width=1)
    d.line([(MARGIN_L-28, 0), (MARGIN_L-28, H)], fill=MARGIN_RED, width=2)
    return img, d

# ════════════════════════════════════════════════════════════════
#  DRAWING PRIMITIVES
# ════════════════════════════════════════════════════════════════

def page_header(d, title, subtitle, y=18):
    """Full-width gradient banner."""
    font1 = gf(34, bold=True)
    font2 = gf(17, italic=True)
    d.rectangle([0, y, W, y+70], fill=BAND_NAVY)
    d.text((MARGIN_L, y+8),  title,    fill="white",           font=font1)
    d.text((MARGIN_L, y+48), subtitle, fill=(200,220,255),     font=font2)
    return y + 82

def section_banner(d, text, y, color=BAND_TEAL, num=""):
    """Coloured section strip with optional number badge."""
    font = gf(22, bold=True)
    d.rectangle([MARGIN_L-10, y, W-MARGIN_R+10, y+40], fill=color)
    label = f"  {num}  {text}" if num else f"  {text}"
    d.text((MARGIN_L, y+8), label, fill="white", font=font)
    return y + 52

def sub_heading(d, text, y, color=C_NAVY):
    font = gf(18, bold=True)
    w2, _ = tw(d, text, font)
    d.line([(MARGIN_L, y+22), (MARGIN_L+w2+8, y+22)], fill=color, width=2)
    d.text((MARGIN_L, y+2), text, fill=color, font=font)
    return y + 32

def body(d, text, y, size=16, color=C_DARK, indent=0, bold=False, italic=False, max_w=None):
    font = gf(size, bold=bold, italic=italic)
    mw   = (max_w or CONTENT_W) - indent
    chars_per_line = max(10, int(mw / (size * 0.56)))
    lines = textwrap.wrap(text, width=chars_per_line)
    x = MARGIN_L + indent
    for ln in lines:
        if y > H - 60:
            return y
        d.text((x, y), ln, fill=color, font=font)
        y += size + 9
    return y

def bullet(d, text, y, size=15, color=C_DARK, indent=0, dot_color=None, symbol="●"):
    dot_color = dot_color or C_TEAL
    fx = MARGIN_L + indent
    bx = fx + 22
    mw = CONTENT_W - indent - 26
    font = gf(size)
    sym_f= gf(size, bold=True)
    d.text((fx, y+1), symbol, fill=dot_color, font=sym_f)
    chars = max(10, int(mw/(size*0.56)))
    lines = textwrap.wrap(text, width=chars)
    for i, ln in enumerate(lines):
        if y > H - 60: return y
        d.text((bx if i==0 else bx+10, y), ln, fill=color, font=font)
        y += size + 7
    return y

def sub_bullet(d, text, y, size=14, color=C_GRAY):
    return bullet(d, text, y, size=size, color=color, indent=30, dot_color=C_GOLD, symbol="–")

# ── Coloured info box ────────────────────────────────────────────
def info_box(d, lines, y, bg=BOX_BLUE, border=C_NAVY, title=None, font_size=14):
    pad = 12
    font  = gf(font_size)
    font_t= gf(font_size, bold=True)
    wrapped_all = []
    for ln in lines:
        wl = textwrap.wrap(ln, width=max(10, int((CONTENT_W-2*pad)/(font_size*0.56))))
        wrapped_all.append(wl if wl else [""])
    total_h  = sum(len(wl)*(font_size+7) for wl in wrapped_all) + 2*pad
    if title:
        total_h += font_size + 10
    d.rectangle([MARGIN_L, y, W-MARGIN_R, y+total_h], fill=bg, outline=border, width=2)
    cy = y + pad
    if title:
        d.text((MARGIN_L+pad, cy), title, fill=border, font=font_t)
        cy += font_size + 10
    for wl in wrapped_all:
        for piece in wl:
            d.text((MARGIN_L+pad+6, cy), piece, fill=C_DARK, font=font)
            cy += font_size + 7
    return y + total_h + 14

# ── Table ────────────────────────────────────────────────────────
def table(d, headers, rows, y, col_w=None, fs=13, header_color=BAND_NAVY):
    if col_w is None:
        n = len(headers)
        col_w = [CONTENT_W//n]*n
    fh = gf(fs, bold=True)
    fb = gf(fs)
    pad= 6

    # Header
    x = MARGIN_L
    rh = fs + pad*2 + 4
    d.rectangle([MARGIN_L, y, W-MARGIN_R, y+rh], fill=header_color)
    for i,h in enumerate(headers):
        d.text((x+pad, y+pad), h, fill="white", font=fh)
        x += col_w[i]
    y += rh

    for ri, row in enumerate(rows):
        wc = []
        mlines = 1
        for ci, cell in enumerate(row):
            wl = textwrap.wrap(str(cell), width=max(5, int((col_w[ci]-2*pad)/(fs*0.58))))
            if not wl: wl = [""]
            wc.append(wl)
            mlines = max(mlines, len(wl))
        rh2 = mlines*(fs+6)+pad*2
        bg2 = (240,248,255) if ri%2==0 else (252,252,255)
        d.rectangle([MARGIN_L, y, W-MARGIN_R, y+rh2], fill=bg2, outline=RULE_BLUE, width=1)
        x = MARGIN_L
        for ci, wl in enumerate(wc):
            cy2 = y+pad
            for piece in wl:
                d.text((x+pad, cy2), piece, fill=C_DARK, font=fb)
                cy2 += fs+6
            d.line([(x, y),(x, y+rh2)], fill=RULE_BLUE, width=1)
            x += col_w[ci]
        d.line([(W-MARGIN_R, y),(W-MARGIN_R, y+rh2)], fill=RULE_BLUE, width=1)
        y += rh2
    return y + 12

# ── Flow diagram (horizontal boxes + arrows) ─────────────────────
def flow_h(d, items, y, box_color=BOX_TEAL, border=C_TEAL, fs=13):
    font = gf(fs)
    arrow_font = gf(18, bold=True)
    pad = 8
    # compute box sizes
    boxes = []
    for item in items:
        wlines = textwrap.wrap(item, width=14)
        w2 = max(tw(d, ln, font)[0] for ln in wlines) + 2*pad
        h2 = len(wlines)*(fs+5) + 2*pad
        boxes.append((wlines, w2, h2))
    max_h = max(b[2] for b in boxes)
    total_w = sum(b[1] for b in boxes) + 20*(len(boxes)-1)
    x = MARGIN_L + max(0, (CONTENT_W - total_w)//2)
    by = y
    for i,(wlines, bw, bh) in enumerate(boxes):
        bx = x
        d.rectangle([bx, by, bx+bw, by+max_h], fill=box_color, outline=border, width=2)
        cy2 = by + (max_h - bh)//2 + pad
        for ln in wlines:
            d.text((bx+pad, cy2), ln, fill=C_DARK, font=font)
            cy2 += fs+5
        x += bw
        if i < len(boxes)-1:
            d.text((x+2, by+(max_h-18)//2), "→", fill=border, font=arrow_font)
            x += 20
    return y + max_h + 14

# ── Vertical flow diagram ────────────────────────────────────────
def flow_v(d, items, y, box_color=BOX_GREEN, border=C_GREEN, fs=13, x_offset=0):
    font  = gf(fs)
    arrow_font = gf(20, bold=True)
    pad = 8
    bw  = CONTENT_W - 2*x_offset - 80
    cx  = MARGIN_L + x_offset + 40
    for i, item in enumerate(items):
        wlines = textwrap.wrap(item, width=max(10, int(bw/(fs*0.56))))
        bh = len(wlines)*(fs+6) + 2*pad
        d.rectangle([cx, y, cx+bw, y+bh], fill=box_color, outline=border, width=2)
        cy2 = y+pad
        for ln in wlines:
            lw, _ = tw(d, ln, font)
            d.text((cx+(bw-lw)//2, cy2), ln, fill=C_DARK, font=font)
            cy2 += fs+6
        y += bh
        if i < len(items)-1:
            mx = cx + bw//2
            d.line([(mx, y),(mx, y+16)], fill=border, width=2)
            # arrow head
            d.polygon([(mx-6, y+10),(mx+6, y+10),(mx, y+18)], fill=border)
            y += 18
    return y + 10

# ── Two-column flow (splits left / right) ────────────────────────
def flow_split(d, root_text, left_items, right_items, y,
               root_color=BOX_YELLOW, left_color=BOX_GREEN, right_color=BOX_BLUE,
               root_border=C_GOLD, left_border=C_GREEN, right_border=C_TEAL, fs=13):
    font  = gf(fs)
    fontB = gf(fs, bold=True)
    pad   = 8
    col_w = (CONTENT_W - 40) // 2
    root_font = gf(fs+2, bold=True)
    rw, rh = tw(d, root_text, root_font)
    rbox_w = rw + 2*pad + 20
    rx = MARGIN_L + (CONTENT_W - rbox_w)//2
    d.rectangle([rx, y, rx+rbox_w, y+rh+2*pad], fill=root_color, outline=root_border, width=2)
    d.text((rx+pad+10, y+pad), root_text, fill=root_border, font=root_font)
    root_bottom = y + rh + 2*pad
    y2 = root_bottom + 22
    # branch lines
    mid_x = rx + rbox_w//2
    left_mid  = MARGIN_L + col_w//2
    right_mid = MARGIN_L + col_w + 40 + col_w//2
    d.line([(mid_x, root_bottom),(mid_x, root_bottom+12)], fill=C_GOLD, width=2)
    d.line([(left_mid, root_bottom+12),(right_mid, root_bottom+12)], fill=C_GOLD, width=2)
    d.line([(left_mid, root_bottom+12),(left_mid, y2)], fill=left_border, width=2)
    d.line([(right_mid, root_bottom+12),(right_mid, y2)], fill=right_border, width=2)
    # Left column
    lx = MARGIN_L
    ly = y2
    for item in left_items:
        wl = textwrap.wrap(item, width=max(5, int((col_w-2*pad)/(fs*0.57))))
        bh = len(wl)*(fs+6)+2*pad
        d.rectangle([lx, ly, lx+col_w, ly+bh], fill=left_color, outline=left_border, width=1)
        cy2 = ly+pad
        for piece in wl:
            d.text((lx+pad, cy2), piece, fill=C_DARK, font=font)
            cy2 += fs+6
        ly += bh+6
    # Right column
    rx2 = MARGIN_L + col_w + 40
    ry2 = y2
    for item in right_items:
        wl = textwrap.wrap(item, width=max(5, int((col_w-2*pad)/(fs*0.57))))
        bh = len(wl)*(fs+6)+2*pad
        d.rectangle([rx2, ry2, rx2+col_w, ry2+bh], fill=right_color, outline=right_border, width=1)
        cy2 = ry2+pad
        for piece in wl:
            d.text((rx2+pad, cy2), piece, fill=C_DARK, font=font)
            cy2 += fs+6
        ry2 += bh+6
    return max(ly, ry2) + 14

# ── Organ effects diagram (icon + effects) ───────────────────────
def organ_diagram(d, organ, symp_effects, para_effects, y, icon="♥"):
    font_icon = gf(28, bold=True)
    font_h    = gf(14, bold=True)
    font_b    = gf(13)
    col = (CONTENT_W - 100) // 2
    # Header row
    d.rectangle([MARGIN_L, y, MARGIN_L+col, y+28], fill=BAND_RUST)
    d.text((MARGIN_L+8, y+4), "SYMPATHETIC (Fight/Flight)", fill="white", font=font_h)
    cx = MARGIN_L + col + 10
    d.text((cx+4, y+2), f"{icon} {organ}", fill=C_NAVY, font=font_h)
    d.rectangle([MARGIN_L+col+90, y, W-MARGIN_R, y+28], fill=BAND_TEAL)
    d.text((MARGIN_L+col+96, y+4), "PARASYMPATHETIC (Rest/Digest)", fill="white", font=font_h)
    y += 34
    # Effects
    max_rows = max(len(symp_effects), len(para_effects))
    for i in range(max_rows):
        se = symp_effects[i] if i < len(symp_effects) else ""
        pe = para_effects[i] if i < len(para_effects) else ""
        d.text((MARGIN_L+8, y+2), f"→ {se}", fill=C_RUST, font=font_b)
        d.text((MARGIN_L+col+96, y+2), f"→ {pe}", fill=C_TEAL, font=font_b)
        y += 20
    return y + 10

# ── Receptor card ────────────────────────────────────────────────
def receptor_card(d, subtype, location, mechanism, response, y,
                  bg=BOX_TEAL, border=C_TEAL):
    font_h = gf(15, bold=True)
    font_b = gf(13)
    pad = 10
    tag_w = 60
    # Tag
    d.rectangle([MARGIN_L, y, MARGIN_L+tag_w, y+80], fill=border)
    tw2, _ = tw(d, subtype, font_h)
    d.text((MARGIN_L+(tag_w-tw2)//2, y+28), subtype, fill="white", font=font_h)
    # Content box
    d.rectangle([MARGIN_L+tag_w, y, W-MARGIN_R, y+80], fill=bg, outline=border, width=1)
    d.text((MARGIN_L+tag_w+pad, y+5),  f"📍 {location}",  fill=C_NAVY,  font=font_b)
    d.text((MARGIN_L+tag_w+pad, y+24), f"⚙  {mechanism}", fill=C_PURPLE, font=font_b)
    d.text((MARGIN_L+tag_w+pad, y+43), f"➜ {response}",  fill=C_GREEN,  font=font_b)
    return y + 88

def spacer(y, n=10): return y + n

pages = []

# ════════════════════════════════════════════════════════════════
#  PAGE 1 — TITLE + INTRO + ANS vs SNS
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "CHOLINERGIC SYSTEM", "Shanbhag Pharmacology  |  Chapter 2 — Autonomic Pharmacology", y)

# Intro box
y = info_box(d, [
    "Acetylcholine (ACh) is the neurotransmitter of the cholinergic system.",
    "Neurons that SYNTHESIZE, STORE & RELEASE ACh are called CHOLINERGIC NEURONS.",
    "ACh acts at: (1) Parasympathetic post-ganglionic endings  (2) All autonomic ganglia",
    "             (3) Sympathetic fibres to sweat glands  (4) NMJ (neuromuscular junction)",
    "             (5) Some CNS synapses",
], y, bg=BOX_BLUE, border=C_NAVY, title="What is the Cholinergic System?", font_size=15)

y = section_banner(d, "ANS vs SOMATIC NERVOUS SYSTEM", y, BAND_NAVY, "1")
y = table(d,
    ["Feature", "Autonomic NS (ANS)", "Somatic NS"],
    [
      ["Control",       "INVOLUNTARY — maintains homeostasis",     "VOLUNTARY — under conscious control"],
      ["Fibre chain",   "2 neurons: Pre-ganglionic + Post-ganglionic (in series)", "Single motor neuron: CNS → skeletal muscle directly"],
      ["Synapse",       "Neuroeffector junction (smooth muscle / gland / heart)", "NMJ — Neuromuscular Junction (skeletal muscle)"],
      ["Innervates",    "Heart, smooth muscles, exocrine glands",  "Skeletal muscles ONLY"],
      ["Controls",      "Circulation, digestion, excretion (visceral)", "Skeletal muscle tone (movement)"],
      ["Transmitter",   "ACh (pre-ganglionic) + ACh/NA (post-ganglionic)", "ACh at NMJ"],
    ],
    y, col_w=[200, 510, 550], fs=13, header_color=BAND_NAVY)

y = section_banner(d, "SITES OF ACh & NA RELEASE (Fig 2.1)", y, BAND_TEAL, "2")

# Annotated site diagram
items_site = [
    "Pre-ganglionic fibre\n(BOTH Symp + Para)\nReleases: ACh",
    "Para Post-ganglionic\nReleases: ACh\n→ Effector cell",
    "Symp Post-ganglionic\n(most)\nReleases: NA\n→ Blood vessel",
    "Symp → Sweat gland\n(exception!)\nReleases: ACh",
    "Pre-ganglionic\n→ Adrenal medulla\nReleases: ACh\n→ Adrenaline + NA",
    "Somatic motor\n→ NMJ\nReleases: ACh\n→ Skeletal muscle",
]
font_site = gf(12)
pad_s = 8
bw_s = (CONTENT_W - 5*12) // 6
x_s = MARGIN_L
max_bh = 0
for item in items_site:
    wl = item.split("\n")
    bh = len(wl)*(12+5)+2*pad_s
    max_bh = max(max_bh, bh)
boxes_data = []
x_s2 = MARGIN_L
colors_site = [BOX_YELLOW, BOX_GREEN, BOX_TEAL, BOX_BLUE, BOX_RED, BOX_PURPLE]
borders_site = [C_GOLD, C_GREEN, C_TEAL, C_NAVY, C_RUST, C_PURPLE]
for i, item in enumerate(items_site):
    wl = item.split("\n")
    bh = len(wl)*(12+5)+2*pad_s
    d.rectangle([x_s2, y, x_s2+bw_s, y+max_bh], fill=colors_site[i], outline=borders_site[i], width=2)
    cy2 = y+pad_s
    for piece in wl:
        lw, _ = tw(d, piece, font_site)
        d.text((x_s2+(bw_s-lw)//2, cy2), piece, fill=C_DARK, font=font_site)
        cy2 += 12+5
    boxes_data.append((x_s2, bw_s))
    x_s2 += bw_s + 12
    if i < len(items_site)-1:
        aff = gf(14, bold=True)
        d.text((x_s2-10, y+max_bh//2-8), "↔", fill=C_GRAY, font=aff)
y = y + max_bh + 14

y = section_banner(d, "SYMPATHETIC vs PARASYMPATHETIC — Organ Effects (Fig 2.2)", y, BAND_RUST, "3")
y = table(d,
    ["Organ", "Sympathetic Effect (Adrenergic)", "Parasympathetic Effect (Cholinergic)"],
    [
      ["Heart (Rate)", "↑ HR (positive chronotropic)", "↓ HR (negative chronotropic)"],
      ["Heart (Force)", "↑ FOC (positive inotropic)", "↓ FOC (negative inotropic)"],
      ["Pupil", "Mydriasis — dilator pupillae contracts (α1)", "Miosis — sphincter pupillae contracts (M3)"],
      ["Bronchi", "Broncho-DILATATION (β2)", "Broncho-SPASM + ↑ secretions (M3)"],
      ["GIT motility", "↓ Motility, ↑ sphincter tone (α1)", "↑ Motility, sphincters relax (M3)"],
      ["Urinary bladder", "Detrusor relaxes, sphincter contracts (retention)", "Detrusor contracts, sphincter relaxes (urination)"],
      ["Blood vessels", "Vasoconstriction (α1) / Vasodilatation (β2)", "Vasodilatation via NO release (M3 on endothelium)"],
      ["Salivary glands", "Thick viscid secretion (α1)", "Profuse watery secretion (M3)"],
      ["Sweat glands", "↑ Sweating (cholinergic! — ACh, not NA)", "—"],
    ],
    y, col_w=[210, 480, 570], fs=12, header_color=BAND_RUST)

d.text((MARGIN_L, H-44), "Page  1  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "1", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 2 — ACh SYNTHESIS + CHOLINESTERASES
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "ACh SYNTHESIS, STORAGE & BREAKDOWN", "Cholinergic Neurotransmission — Detailed Mechanism", y)

y = section_banner(d, "SYNTHESIS OF ACETYLCHOLINE (Fig 2.3)", y, BAND_TEAL, "4")

# Synthesis flow
y = flow_v(d, [
    "STEP 1 — Choline enters the cholinergic neuron via CARRIER-MEDIATED TRANSPORT",
    "STEP 2 — Choline + Acetyl-CoA (from mitochondria)  ── ChAT enzyme ──►  ACh formed",
    "STEP 3 — ACh stored in STORAGE VESICLES near nerve terminal",
    "STEP 4 — ACTION POTENTIAL arrives → Ca²⁺ influx → vesicles fuse → ACh released into synaptic cleft",
    "STEP 5 — ACh interacts with CHOLINERGIC RECEPTORS on effector cell → response",
    "STEP 6 — ACh rapidly hydrolysed by AChE enzyme  →  Choline + Acetic acid  (choline recycled!)",
], y, box_color=BOX_TEAL, border=C_TEAL, fs=14)

y = info_box(d, [
    "ChAT  =  Choline AcetylTransferase  →  enzyme that MAKES ACh",
    "AChE  =  AcetylCholinEsterase       →  enzyme that BREAKS ACh (in the synapse)",
    "Choline is recycled back into the nerve terminal after hydrolysis (high-affinity choline uptake)",
    "Hemicholinium blocks choline uptake — depletes ACh stores",
    "Vesamicol blocks ACh transport into vesicles",
    "Botulinum toxin blocks ACh release from nerve terminals",
], y, bg=BOX_YELLOW, border=C_GOLD, title="Key Points — ACh Synthesis", font_size=14)

y = section_banner(d, "CHOLINESTERASES — Types & Properties", y, BAND_PURPLE, "5")

y = table(d,
    ["Type", "Also Called", "Location", "Hydrolyses", "Key Feature"],
    [
      ["True ChE",  "AChE — Acetylcholinesterase", "Cholinergic neurons, Ganglia, RBCs, NMJ", "ACh + Methacholine (rapidly)", "HIGH specificity; the MAIN enzyme for ACh breakdown"],
      ["Pseudo-ChE","Butyrylcholinesterase (BuChE)", "Plasma, Liver, Glial cells", "ACh + wide variety of esters (slowly); NOT methacholine", "LOW specificity; destroyed a lot of IV ACh before it reaches target"],
    ],
    y, col_w=[120, 230, 280, 340, 290], fs=12, header_color=BAND_PURPLE)

y = info_box(d, [
    "Clinical importance of Pseudocholinesterase:",
    "→ Suxamethonium (succinylcholine) is hydrolysed by pseudocholinesterase",
    "→ Pseudocholinesterase deficiency (genetic) → prolonged apnoea after suxamethonium administration",
    "→ OP poisoning inhibits BOTH true and pseudocholinesterase",
    "→ ACh has NO therapeutic use because pseudocholinesterase in blood destroys it before reaching organs",
], y, bg=BOX_RED, border=C_RUST, title="Clinical Note — Why ACh has no therapeutic use", font_size=13)

y = section_banner(d, "FATE OF ACh IN THE SYNAPSE", y, BAND_GREEN, "6")
y = flow_h(d,
    ["ACh released", "Binds receptor\n(muscarinic/\nnicotinic)", "Receptor\nactivation\n→ Response", "AChE cleaves\nACh quickly", "Choline\nrecycled\nback", "Acetic acid\ndiffuses away"],
    y, box_color=BOX_GREEN, border=C_GREEN, fs=13)

y = info_box(d, [
    "The synapse is cleared of ACh within MILLISECONDS — ensuring precision of nerve signalling",
    "Anticholinesterases slow this breakdown → ACh accumulates → prolonged/enhanced cholinergic effect",
    "This is the basis of: Neostigmine (MG), Physostigmine (atropine poisoning), OP insecticides (toxicity)",
], y, bg=BOX_BLUE, border=C_NAVY, font_size=14)

d.text((MARGIN_L, H-44), "Page  2  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "2", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 3 — CHOLINERGIC RECEPTORS (Detailed)
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "CHOLINERGIC RECEPTORS", "Muscarinic & Nicotinic — Subtypes, Locations & Mechanisms", y)

y = section_banner(d, "OVERVIEW — Two Main Receptor Types", y, BAND_NAVY, "7")
y = table(d,
    ["Property", "MUSCARINIC Receptors", "NICOTINIC Receptors"],
    [
      ["Coupling",     "G-protein coupled (GPCR) → 2nd messenger",         "Ligand-gated ION CHANNELS → direct depolarization"],
      ["Speed",        "Slow (seconds) — via 2nd messengers",               "Fast (milliseconds) — direct ion flow"],
      ["Subtypes",     "M1, M2, M3, M4, M5",                                "NN (neuronal), NM (muscular)"],
      ["Blocker",      "Atropine, Hyoscine, Ipratropium",                    "Tubocurarine (NM), Hexamethonium (NN)"],
      ["Agonist",      "ACh, Muscarine, Pilocarpine, Bethanechol",           "ACh, Nicotine, Suxamethonium"],
      ["Location",     "Heart, smooth muscle, glands, CNS, endothelium",    "Autonomic ganglia, NMJ, adrenal medulla"],
    ],
    y, col_w=[200, 530, 530], fs=13, header_color=BAND_NAVY)

y = section_banner(d, "MUSCARINIC RECEPTOR SUBTYPES — Detailed Cards", y, BAND_TEAL, "8")
y = body(d, "All muscarinic receptors are G-protein coupled and regulate intracellular second messengers:", y, 15)

y = receptor_card(d, "M1",
    "Gastric glands  |  Autonomic ganglia  |  CNS",
    "Gq → ↑ IP3 + ↑ DAG → ↑ intracellular Ca²⁺",
    "↑ Learning & memory | ↑ Gastric acid secretion | ↑ Smooth muscle contraction",
    y, bg=BOX_YELLOW, border=C_GOLD)

y = receptor_card(d, "M2",
    "HEART (SA node, AV node, atria, ventricles)",
    "Gi → ↓ cAMP + opens K⁺ channels → HYPERPOLARIZATION",
    "↓ HR (negative chronotropic) | ↓ A-V conduction (dromotropic) | ↓ Atrial contraction (inotropic)",
    y, bg=BOX_RED, border=C_RUST)

y = receptor_card(d, "M3",
    "Smooth muscles | Exocrine glands | Vascular endothelial cells",
    "Gq → ↑ IP3 + ↑ DAG → ↑ Ca²⁺ → smooth muscle contraction",
    "Glandular secretion | Smooth muscle contraction | Endothelium releases NO → vasodilatation",
    y, bg=BOX_GREEN, border=C_GREEN)

y = receptor_card(d, "M4 & M5",
    "CNS only (striatum, hippocampus, brainstem)",
    "G-protein mediated — CNS modulation",
    "M4: modulates dopamine release | M5: cerebrovascular effects | Both involved in CNS diseases",
    y, bg=BOX_PURPLE, border=C_PURPLE)

y = section_banner(d, "NICOTINIC RECEPTOR SUBTYPES — Detailed Cards", y, BAND_GREEN, "9")
y = body(d, "Nicotinic receptors are LIGAND-GATED ION CHANNELS — opening Na⁺/K⁺ channels → rapid depolarization:", y, 15)

y = receptor_card(d, "NN",
    "Autonomic ganglia (all) | Adrenal medulla | Some CNS",
    "Direct opening of Na⁺/K⁺ ion channels → MEMBRANE DEPOLARIZATION",
    "Ganglionic transmission (sympathetic + parasympathetic) | Adrenaline + NA release from adrenal medulla",
    y, bg=BOX_TEAL, border=C_TEAL)

y = receptor_card(d, "NM",
    "Neuromuscular Junction (NMJ) — skeletal muscle",
    "Direct opening of Na⁺/K⁺ ion channels → END-PLATE POTENTIAL → muscle action potential",
    "SKELETAL MUSCLE CONTRACTION | Target of suxamethonium (depolarising block) & tubocurarine (competitive block)",
    y, bg=BOX_BLUE, border=C_NAVY)

y = info_box(d, [
    "MEMORY TRICK for receptor locations:",
    "M1 = Gastric (1 = 1st letter G like Gastric) + Ganglia + CNS",
    "M2 = Heart ONLY (2 chambers pump blood — remember the 2)",
    "M3 = 3 smooth organs: Smooth muscle + Secretory glands + endothelial cells",
    "NN = Neuronal nicotinic (Ganglia + CNS + adrenal) — everywhere EXCEPT muscle",
    "NM = Muscle nicotinic (NMJ only) — the one that contracts SKELETAL muscle",
], y, bg=BOX_YELLOW, border=C_GOLD, title="Memory Tips", font_size=14)

d.text((MARGIN_L, H-44), "Page  3  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "3", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 4 — CLASSIFICATION + ACh ACTIONS
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "CHOLINERGIC AGONISTS — Classification", "Cholinomimetics / Parasympathomimetics  |  Direct & Indirect Acting", y)

y = section_banner(d, "CLASSIFICATION TREE", y, BAND_NAVY, "10")

# Big classification box
y = info_box(d, [
    "CHOLINERGIC AGONISTS",
    "",
    "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
    "A)  DIRECTLY ACTING  (mimic ACh by binding receptors directly)",
    "",
    "    1. Choline Esters — have ester bond:",
    "       • Acetylcholine (ACh) — natural, no clinical use (destroyed rapidly)",
    "       • Carbachol — resistant to hydrolysis; muscarinic + nicotinic; used in glaucoma",
    "       • Bethanechol — selective muscarinic; used in post-op urinary retention & paralytic ileus",
    "",
    "    2. Alkaloids — plant-derived, tertiary amines:",
    "       • Pilocarpine — from Pilocarpus plant; used in glaucoma, sialogogue",
    "       • Muscarine — from Amanita muscaria mushroom; only M receptors",
    "       • Arecoline — from areca nut; both M + N actions",
    "",
    "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
    "B)  INDIRECTLY ACTING — ANTICHOLINESTERASES  (inhibit AChE → ↑ ACh accumulation)",
    "",
    "    i.  REVERSIBLE:",
    "        Carbamates: Physostigmine | Neostigmine | Pyridostigmine | Rivastigmine",
    "        Alcohol:    Edrophonium (very short acting: 8–10 min)",
    "        Others:     Donepezil | Galantamine | Tacrine",
    "",
    "    ii. IRREVERSIBLE (covalent bond — phosphorylation of esteratic site):",
    "        Organophosphates (OPs): Parathion | Malathion | Echothiophate | Dyflos",
    "                                Nerve gases: Sarin, Soman, Tabun, Novichok",
    "        Carbamates (irreversible): Propoxur | Carbaryl (insecticides)",
], y, bg=BOX_BLUE, border=C_NAVY, font_size=13)

y = section_banner(d, "ACTIONS OF ACh — Muscarinic Effects", y, BAND_TEAL, "11")
y = body(d, "ACh produces muscarinic effects at M1/M2/M3 receptors on target organs. Recall: ACh itself has no therapeutic use due to rapid hydrolysis by both true + pseudocholinesterases. Actions studied by IV injection.", y, 14)

y = table(d,
    ["Organ", "Receptor", "Mechanism", "Effect"],
    [
      ["Heart — SA node / AV node", "M2", "↑ K⁺ conductance → hyperpolarization", "↓ HR, ↓ AV conduction, ↓ FOC (vagal mimicry)"],
      ["Blood vessels (endothelium)", "M3", "→ releases NO (EDRF) → SMC relaxation", "VASODILATION → ↓ Blood Pressure"],
      ["GIT (smooth muscle)", "M3", "↑ IP3/DAG → ↑ Ca²⁺ → contraction", "↑ Tone, ↑ Peristalsis, ↑ secretions, relax sphincters"],
      ["Urinary bladder", "M3", "Contracts DETRUSOR muscle", "Contracts detrusor + relaxes trigone/sphincter → URINATION"],
      ["Bronchi", "M3", "Bronchial smooth muscle contracts", "BRONCHOSPASM + ↑ tracheobronchial secretions (CI in asthma!)"],
      ["Exocrine glands", "M3", "↑ glandular secretion", "↑ Saliva, tears, sweat, gastric acid, bronchial mucus"],
      ["Eye (iris)", "M3", "Sphincter pupillae contracts", "MIOSIS (pupil constriction)"],
      ["Eye (ciliary muscle)", "M3", "Ciliary muscle contracts", "Accommodation for near vision; ↓ IOP (opens trabecular meshwork)"],
    ],
    y, col_w=[230, 90, 340, 600], fs=12, header_color=BAND_TEAL)

y = info_box(d,[
    "Why ACh is contraindicated in ASTHMA:",
    "→ ACh activates M3 receptors in bronchi → bronchospasm + ↑ mucus secretion → can be fatal",
    "→ Therefore ALL cholinergic/parasympathomimetic drugs are contraindicated in asthma patients",
], y, bg=BOX_RED, border=C_RUST, font_size=13)

d.text((MARGIN_L, H-44), "Page  4  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "4", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 5 — EYE + NICOTINIC ACTIONS + CHOLINE ESTER COMPARISON
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "ACh ON EYE | NICOTINIC ACTIONS | CHOLINE ESTERS", "Muscarinic Eye Effects • Nicotinic Actions • Drug Comparison Table", y)

y = section_banner(d, "EFFECT OF ACh ON THE EYE (Fig 2.9) — Muscarinic Actions", y, BAND_TEAL, "12")

# Eye anatomy description
y = body(d, "The eye has TWO muscular systems controlled by the autonomic nervous system:", y, 15)
y = bullet(d, "IRIS — contains sphincter pupillae (parasympathetic, M3 → MIOSIS) and dilator pupillae (sympathetic, α1 → MYDRIASIS)", y)
y = bullet(d, "CILIARY MUSCLE — contracts under parasympathetic stimulation (M3) → relaxes suspensory ligaments → lens becomes MORE CONVEX (bulges) → near vision", y)
y = bullet(d, "Canal of SCHLEMM — aqueous humour drains through trabecular meshwork into this canal (key in glaucoma)", y)
y = spacer(y, 8)

# Full eye flow diagram
y = section_banner(d, "Muscarinic Agonist Action on Eye — Step by Step", y, BAND_GREEN, "")
y = flow_v(d, [
    "ACh (IV) / Pilocarpine / Physostigmine activate M3 receptors in the eye",
    "TWO parallel effects occur simultaneously ↓",
    "LEFT: Contract SPHINCTER PUPILLAE → MIOSIS (pupil constricts)",
    "RIGHT: Contract CILIARY MUSCLE → Spasm of accommodation (lens bulges for near vision)",
    "Miosis opens TRABECULAR MESHWORK around the canal of Schlemm",
    "Facilitates DRAINAGE of aqueous humour",
    "↓ Intraocular Pressure (IOP) → USEFUL IN GLAUCOMA",
    "Note: Topical ACh has NO effect on eye (cannot penetrate corneal epithelium)",
], y, box_color=BOX_TEAL, border=C_TEAL, fs=14)

y = section_banner(d, "NICOTINIC ACTIONS OF ACh (larger doses required)", y, BAND_RUST, "13")
y = body(d, "To study nicotinic effects, ATROPINE must be given first to block muscarinic effects.", y, 14, C_RUST, bold=True)

y = table(d,
    ["Site", "Receptor", "Effect at Low Dose", "Effect at High Dose"],
    [
      ["Autonomic ganglia (all)", "NN", "Stimulates both sympathetic + para ganglia → tachycardia, ↑ BP", "Ganglionic BLOCK (depolarization block) → paradoxical effects"],
      ["Skeletal muscle (NMJ)", "NM", "Twitchings, fasciculations", "Prolonged depolarization → PARALYSIS of all skeletal muscles"],
      ["Adrenal medulla", "NN", "Adrenaline + NA release", "Excessive catecholamine release → hypertension"],
      ["CNS", "NN (central)", "NONE — ACh does NOT cross BBB (IV administration)", "No central effects observed from peripheral ACh"],
    ],
    y, col_w=[210, 90, 450, 510], fs=12, header_color=BAND_RUST)

y = section_banner(d, "CHOLINE ESTERS — Comparison Table", y, BAND_PURPLE, "14")
y = table(d,
    ["Property", "Acetylcholine (ACh)", "Carbachol", "Bethanechol"],
    [
      ["Chemical", "Choline ester (quaternary)", "Carbamylcholine (quaternary)", "Carbamyl-β-methyl choline (quaternary)"],
      ["Metabolized by", "True + Pseudo ChE (rapidly hydrolysed)", "RESISTANT to both cholinesterases", "RESISTANT to both cholinesterases"],
      ["Muscarinic actions", "++ (YES — strong)", "+ (YES)", "+ (YES)"],
      ["Nicotinic actions", "+ (YES)", "+ (YES)", "— (NO — purely muscarinic)"],
      ["Effect of Atropine", "Completely blocks muscarinic actions", "NOT completely blocked by atropine", "Completely blocks muscarinic actions"],
      ["Selectivity", "Non-selective (M + N)", "Mixed (M + N)", "Selective for M3 on bladder + GIT"],
      ["Therapeutic use", "NONE (too short acting — destroyed in blood)", "Glaucoma (ophthalmic drops)", "Post-op urinary retention, Paralytic ileus"],
      ["Route of admin", "IV only (to study pharmacology)", "Topical (eye)", "Oral / SC (not IV — severe hypotension risk)"],
    ],
    y, col_w=[210, 320, 310, 420], fs=12, header_color=BAND_PURPLE)

d.text((MARGIN_L, H-44), "Page  5  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "5", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 6 — PILOCARPINE + MUSCARINE + GLAUCOMA
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "PILOCARPINE  |  MUSCARINE  |  GLAUCOMA", "Cholinomimetic Alkaloids & Glaucoma Pharmacology in Detail", y)

y = section_banner(d, "PILOCARPINE — Cholinomimetic Alkaloid", y, BAND_TEAL, "15")

y = table(d,
    ["Property", "Details"],
    [
      ["Source", "Obtained from PILOCARPUS plant (P. jaborandi)"],
      ["Chemistry", "TERTIARY AMINE → good tissue penetration; crosses BBB; effective topically"],
      ["Mechanism", "Directly acts on muscarinic (M3 predominant) AND nicotinic receptors"],
      ["Predominant effect", "Muscarinic — especially on SECRETORY activity (most potent sialogogue)"],
    ],
    y, col_w=[200, 1060], fs=13, header_color=BAND_TEAL)

y = sub_heading(d, "USES of Pilocarpine:", y)
y = bullet(d, "GLAUCOMA (0.5%–4% topical drops): Increases ciliary muscle tone → miosis → opens trabecular meshwork → ↓ IOP. Both open-angle and acute congestive (narrow-angle) glaucoma. Also available as Pilocarpine Ocusert (sustained release over 7 days)", y, 14)
y = bullet(d, "BREAK ADHESIONS between iris and lens (posterior synechiae) — used alternately with mydriatics", y, 14)
y = bullet(d, "REVERSE PUPILLARY DILATATION after refraction testing", y, 14)
y = bullet(d, "SIALOGOGUE — stimulates salivation; used in xerostomia (dry mouth), Sjögren's syndrome", y, 14)
y = bullet(d, "Pilocarpine is the drug of choice for ACUTE CONGESTIVE GLAUCOMA (emergency)", y, 14, color=C_RUST)

y = info_box(d, [
    "Adverse Effects of Pilocarpine: Salivation | Sweating | Bradycardia | Diarrhoea | Bronchospasm",
    "Pulmonary oedema can occur following systemic therapy",
    "Contraindicated in: Asthma, COPD, heart block",
], y, bg=BOX_RED, border=C_RUST, font_size=13)

y = section_banner(d, "MUSCARINE & MUSHROOM POISONING", y, BAND_RUST, "16")
y = body(d, "Muscarine is the active toxin in Inocybe and Amanita muscaria mushrooms. Three distinct types of mushroom poisoning exist:", y, 14)

y = table(d,
    ["Type", "Mushroom Species", "Toxin", "Onset", "Clinical Features", "Treatment"],
    [
      ["Rapid onset\n(Muscarine type)", "Inocybe spp.", "MUSCARINE", "< 30 min", "SLUDGE signs: Salivation, Lacrimation, Urination, Defecation, GI cramps, Emesis. Also: bradycardia, bronchospasm, sweating, hypotension", "IV ATROPINE (reverses muscarinic)"],
      ["Hallucinogen type", "A. muscaria, Psilocybe spp.", "MUSCIMOL (ibotenic acid)", "30 min – 2 h", "Mainly CENTRAL effects: hallucinations, disorientation, euphoria, tachycardia. Muscarinic features minimal", "Supportive ONLY. Atropine CONTRAINDICATED"],
      ["Delayed onset\n(Deadly type)", "Amanita phalloides (Death Cap)", "AMATOXIN (amatoxin)", "6–24 h", "Delayed gastroenteritis (6–24h), then hepatic + renal failure (day 3–5). Does NOT respond to atropine", "Thioctic acid (alpha-lipoic acid) + Supportive. No antidote"],
    ],
    y, col_w=[150, 180, 160, 100, 480, 190], fs=11, header_color=BAND_RUST)

y = section_banner(d, "GLAUCOMA — Pathophysiology & Drug Overview", y, BAND_NAVY, "17")
y = body(d, "Glaucoma = Optic nerve damage with loss of visual function associated with raised IOP (>21 mmHg). Aqueous humour is continuously produced by the ciliary body and drained via trabecular meshwork (Canal of Schlemm) + uveoscleral outflow.", y, 14)

y = table(d,
    ["Drug Class", "Acute Congestive (Narrow-angle)", "Chronic Simple (Wide-angle / Open-angle)"],
    [
      ["Osmotic agents", "Mannitol 20% IV (1.5g/kg), Glycerol 50% oral — draw fluid from eye osmotically", "NOT used"],
      ["Carbonic Anhydrase Inhibitors", "Acetazolamide IV/oral — reduces aqueous formation by inhibiting CA enzyme in ciliary epithelium", "Dorzolamide 2% topical, Brinzolamide topical, Acetazolamide oral"],
      ["β-Blockers (topical)", "Timolol 0.5% topical — blocks β2 on ciliary epithelium → ↓ aqueous formation", "Timolol 0.25%, Betaxolol 0.25% (β1-selective, safe in asthma), Carteolol 1%, Levobunolol (long-acting)"],
      ["Prostaglandins (topical)", "Latanoprost 0.005%", "DRUG OF CHOICE in open-angle: Latanoprost, Travoprost, Bimatoprost (PGF2α analogues, once daily, ↑ uveoscleral outflow)"],
      ["Miotics (Cholinergic)", "Pilocarpine 2% topical", "Pilocarpine 0.5% topical"],
      ["α-Adrenergic agonists", "NOT first-line", "Apraclonidine (α2-agonist, ↓ aqueous), Dipivefrin (prodrug of adrenaline — penetrates cornea via esterases)"],
    ],
    y, col_w=[250, 430, 580], fs=11, header_color=BAND_NAVY)

y = info_box(d, [
    "Key facts on glaucoma drugs:",
    "• Propranolol NOT used in glaucoma — membrane-stabilizing effect anesthetizes cornea",
    "• Betaxolol is β1-selective → SAFE in patients with asthma/COPD (does not cause bronchospasm)",
    "• Prostaglandins (latanoprost): once daily dosing, high efficacy, ↓ systemic toxicity → DRUG OF CHOICE open-angle glaucoma",
    "• Apraclonidine: α2-agonist on ciliary epithelium → ↓ aqueous formation; does NOT cross BBB (no hypotension)",
    "• Dipivefrin = prodrug of adrenaline → penetrates cornea → converted by esterases inside the eye",
], y, bg=BOX_YELLOW, border=C_GOLD, font_size=13)

d.text((MARGIN_L, H-44), "Page  6  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "6", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 7 — ANTICHOLINESTERASES MECHANISM + REVERSIBLE DRUGS
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "ANTICHOLINESTERASES — Mechanism & Reversible Drugs", "Physostigmine | Neostigmine | Pyridostigmine | Edrophonium | Alzheimer's drugs", y)

y = section_banner(d, "MECHANISM OF ANTICHOLINESTERASES (Fig 2.11)", y, BAND_NAVY, "18")
y = body(d, "Anticholinesterases inhibit the enzyme AChE → ACh NOT broken down → ACCUMULATES at muscarinic AND nicotinic sites → Prolonged/enhanced cholinergic effects. They are called INDIRECTLY ACTING cholinergic drugs.", y, 14)

y = table(d,
    ["Drug Type", "Binding Site", "Bond Type", "Duration", "Hydrolysis of enzyme", "Example"],
    [
      ["ACh (normal)", "Anionic + Esteratic", "Non-covalent (transient)", "Milliseconds", "Rapid — acetylated enzyme hydrolyses quickly", "Normal physiological process"],
      ["Edrophonium", "Anionic site ONLY", "Weak hydrogen bond", "8–10 minutes", "Diffuses away spontaneously", "Diagnosis of MG"],
      ["Carbamates\n(Neostigmine etc.)", "Anionic + Esteratic", "Carbamoylation (covalent but hydrolysable)", "30 min – 6 hours", "SLOW hydrolysis → reversible", "Neostigmine, Physostigmine"],
      ["Organophosphates (OPs)", "Esteratic site ONLY", "COVALENT PHOSPHORYLATION (irreversible)", "Days–weeks ('aging')", "NO spontaneous hydrolysis → permanent unless treated with PAM", "Sarin, Malathion, Echothiophate"],
    ],
    y, col_w=[180, 170, 250, 170, 370, 120], fs=11, header_color=BAND_NAVY)

y = info_box(d, [
    "'AGING' of organophosphate-AChE complex:",
    "After OP binds esteratic site → if not treated promptly → the bond STRENGTHENS (dealkylation)",
    "→ Enzyme becomes PERMANENTLY inactivated even by oximes (PAM)",
    "→ Therefore, treatment must be given EARLY in OP poisoning",
    "Echothiophate: binds BOTH anionic and esteratic sites — even stronger irreversible inhibition",
], y, bg=BOX_RED, border=C_RUST, font_size=13)

y = section_banner(d, "REVERSIBLE ANTICHOLINESTERASES — Individual Drugs", y, BAND_TEAL, "19")

y = table(d,
    ["Drug", "Chemistry", "Crosses BBB?", "Key Actions", "Uses", "Notes"],
    [
      ["Physostigmine\n(Eserine)", "Natural alkaloid\n(Physostigma venenosum)\nTertiary amine", "YES — central + peripheral effects", "Inhibits true + pseudo ChE reversibly. Good tissue penetration → effective topically", "1. Atropine & antimuscarinic poisoning (IV)\n2. Glaucoma (now rarely used)", "Causes cataract on chronic use in glaucoma. Give SLOWLY IV (causes bradycardia)"],
      ["Neostigmine", "Synthetic\nQuaternary ammonium\n(structural similarity to ACh)", "NO — peripheral effects only", "Indirect: inhibits ChE → ↑ ACh at NMJ\nDirect: directly stimulates NM receptors", "1. Myasthenia gravis\n2. Post-op urinary retention\n3. Paralytic ileus\n4. Reverse non-depolarizing block\n5. Curare poisoning", "Give atropine simultaneously (block muscarinic side-effects)"],
      ["Pyridostigmine", "Synthetic\nQuaternary ammonium", "NO — peripheral only", "Same as neostigmine. Longer duration", "PREFERRED in myasthenia gravis (better tolerated, can give twice daily sustained release)", "Less potent than neostigmine but BETTER TOLERATED; preferred in MG"],
      ["Edrophonium", "Synthetic\nQuaternary ammonium", "NO", "Binds anionic site only → weak reversible inhibition", "1. DIAGNOSIS of myasthenia gravis (Tensilon test)\n2. Differentiate myasthenic vs cholinergic crisis\n3. Curare poisoning", "Very rapid onset, VERY SHORT duration (8–10 min). Keep atropine ready!"],
      ["Galantamine\nRivastigmine\nDonepezil", "Synthetic (cerebroselective)", "YES — cross BBB selectively", "Preferentially inhibit brain AChE → ↑ cerebral ACh", "ALZHEIMER'S DISEASE — improves cognition in mild-moderate disease", "Do not cross BBB as much as physostigmine — fewer peripheral side effects"],
    ],
    y, col_w=[155, 175, 120, 295, 340, 175], fs=11, header_color=BAND_TEAL)

y = info_box(d, [
    "KEY COMPARISON — Physostigmine vs Neostigmine at a glance:",
    "Physostigmine = TERTIARY amine = crosses BBB → used when CENTRAL effects needed (atropine poisoning)",
    "Neostigmine  = QUATERNARY ammonium = NO CNS = peripheral only → used in MG (no CNS side effects)",
    "",
    "Pyridostigmine is PREFERRED over neostigmine in MYASTHENIA GRAVIS because:",
    "→ Longer duration of action (can be given twice daily in SR form)",
    "→ Better tolerated (fewer side effects) even though it is less potent",
], y, bg=BOX_YELLOW, border=C_GOLD, title="Must-Know Comparison", font_size=13)

d.text((MARGIN_L, H-44), "Page  7  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "7", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 8 — MYASTHENIA GRAVIS
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "MYASTHENIA GRAVIS", "Pathophysiology | Diagnosis | Treatment | Crisis Management", y)

y = section_banner(d, "WHAT IS MYASTHENIA GRAVIS?", y, BAND_NAVY, "20")
y = body(d, "Myasthenia Gravis (MG) is an AUTOIMMUNE NEUROMUSCULAR DISEASE in which the immune system produces antibodies against NM (nicotinic-muscle) receptors at the NMJ → decreased number of functional NM receptors → impaired neuromuscular transmission → muscle weakness.", y, 14)

y = info_box(d, [
    "Pathophysiology in steps:",
    "1. Thymus produces abnormal T-cells → stimulate B-cells",
    "2. B-cells produce IgG antibodies against NM receptors at NMJ",
    "3. Antibodies bind NM receptors → complement-mediated destruction",
    "4. ↓ Functional NM receptors at NMJ → reduced end-plate potentials",
    "5. Muscle WEAKNESS — worse with activity, better with rest",
    "6. Thymoma (thymic tumour) present in ~15% of MG patients — thymectomy can induce remission",
], y, bg=BOX_BLUE, border=C_NAVY, font_size=13)

y = sub_heading(d, "Clinical Features:", y)
y = bullet(d, "Marked MUSCULAR WEAKNESS varying in degree at different times of day (worse in evening)", y, 14)
y = bullet(d, "EASY FATIGABILITY — weakness increases with repetitive activity", y, 14)
y = bullet(d, "Typically involves: ocular muscles (ptosis, diplopia), facial muscles, bulbar muscles (dysphagia, dysarthria), limb muscles, respiratory muscles", y, 14)

y = section_banner(d, "DIAGNOSIS OF MYASTHENIA GRAVIS", y, BAND_GREEN, "21")

y = table(d,
    ["Diagnostic Test", "Method", "Result in MG", "Interpretation"],
    [
      ["Tensilon Test\n(Edrophonium test)", "IV Edrophonium 2–10 mg (given slowly)", "DRAMATIC improvement in muscle weakness within 30–60 seconds", "Positive = MG. Improvement is transient (8–10 min). Keep ATROPINE ready (may cause bradycardia)"],
      ["Anti-NM receptor antibodies", "Blood test for circulating antibodies against NM receptors", "POSITIVE in ~85% of MG patients", "Confirmatory test. Negative does not exclude MG (seronegative MG)"],
      ["EMG (Repetitive nerve stimulation)", "Electrical stimulation of nerve at 3 Hz", "DECREMENTAL response in compound muscle action potential (CMAP)", "Indicates progressive failure of NMJ transmission"],
      ["Chest CT/MRI", "Imaging of anterior mediastinum", "Thymoma or thymic hyperplasia in 75% of MG patients", "Indicates need for thymectomy"],
    ],
    y, col_w=[200, 270, 350, 440], fs=12, header_color=BAND_GREEN)

y = section_banner(d, "TREATMENT OF MYASTHENIA GRAVIS", y, BAND_TEAL, "22")

y = table(d,
    ["Treatment", "Drug/Method", "Mechanism", "Notes"],
    [
      ["Symptomatic\n(anticholinesterases)", "Pyridostigmine (PREFERRED)\nNeostigmine\nAmbenonium", "Inhibit AChE → ↑ ACh at NMJ → better NMJ transmission", "Do NOT cure MG — only symptomatic relief. Atropine given alongside for muscarinic SE"],
      ["Immunosuppression\n(disease modifying)", "Corticosteroids (Prednisolone)\nAzathioprine\nCyclophosphamide\nMycophenolate", "Suppress abnormal immune response → ↓ antibody production", "Corticosteroids: initial worsening then sustained improvement. Azathioprine: for maintenance"],
      ["Thymectomy", "Surgical removal of thymus", "Removes source of abnormal T-cell stimulation", "Recommended in all MG patients < 60 years, especially if thymoma present"],
      ["Plasmapheresis", "Plasma exchange (removes antibodies)", "Removes circulating anti-NM antibodies", "Short-term benefit (days–weeks). Used in myasthenic crisis or pre-surgery"],
      ["IV Immunoglobulin (IVIG)", "High-dose IV IgG", "Modulates immune response; Fc receptor blockade", "Alternative to plasmapheresis in crisis. Effect lasts 3–6 weeks"],
    ],
    y, col_w=[200, 280, 330, 450], fs=11, header_color=BAND_TEAL)

y = info_box(d, [
    "DRUGS CONTRAINDICATED in Myasthenia Gravis (they WORSEN neuromuscular block):",
    "• Aminoglycoside antibiotics (Gentamicin, Streptomycin) — inhibit Ca²⁺ at NMJ",
    "• d-Tubocurarine (d-TC) and other non-depolarizing NMJ blockers",
    "• β-Blockers (reduce end-plate sensitivity)",
    "• Ether (anaesthetic)",
    "• Phenytoin (membrane stabilizer)",
    "• Magnesium (inhibits ACh release)",
], y, bg=BOX_RED, border=C_RUST, title="DANGER — Contraindicated Drugs in MG", font_size=13)

d.text((MARGIN_L, H-44), "Page  8  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "8", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 9 — MYASTHENIC CRISIS + OP POISONING
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "MYASTHENIC CRISIS  |  OP POISONING  |  THERAPEUTIC USES", "Crisis Management | Organophosphate Toxicology | Clinical Applications", y)

y = section_banner(d, "MYASTHENIC CRISIS vs CHOLINERGIC CRISIS", y, BAND_RUST, "23")

y = table(d,
    ["Feature", "Myasthenic Crisis", "Cholinergic Crisis"],
    [
      ["Definition", "Sudden severe exacerbation of MG weakness (under-treatment or stress)", "Overdose of anticholinesterase drugs → ↑ ACh → prolonged depolarization block"],
      ["Cause", "Too LITTLE ACh effect at NMJ (under-treatment, infection, surgery, stress)", "Too MUCH ACh effect (anticholinesterase overdose)"],
      ["Muscle weakness", "Severe — due to failure of NMJ transmission", "Severe — due to depolarization block (excess ACh paralyses)"],
      ["Cholinergic signs\n(SLUDGE)", "ABSENT (no excess ACh)", "PRESENT: Salivation, Lacrimation, Urination, Defecation, GI cramps, Emesis + Bradycardia, Bronchospasm, Sweating"],
      ["Pupils", "Normal or slightly dilated", "MIOSIS (constricted)"],
      ["Edrophonium test", "IMPROVEMENT → confirms myasthenic crisis", "WORSENING or no improvement → confirms cholinergic crisis"],
      ["Treatment", "Give MORE anticholinesterase (Neostigmine/Pyridostigmine) + mechanical ventilation if needed", "STOP anticholinesterase immediately + Give ATROPINE + Ventilator support"],
    ],
    y, col_w=[190, 470, 600], fs=12, header_color=BAND_RUST)

y = info_box(d, [
    "IMPORTANT PROTOCOL: Before giving Edrophonium for Tensilon test:",
    "→ Keep ATROPINE ready (0.6 mg IV) — if cholinergic crisis worsens, atropine reverses muscarinic effects",
    "→ Keep VENTILATOR on standby (respiratory muscle paralysis can occur)",
    "→ Give Edrophonium SLOWLY IV (2 mg test dose first, then 8 mg if no adverse reaction)",
], y, bg=BOX_YELLOW, border=C_GOLD, font_size=13)

y = section_banner(d, "ORGANOPHOSPHATE (OP) POISONING — Irreversible Anticholinesterases", y, BAND_PURPLE, "24")
y = body(d, "OP compounds irreversibly phosphorylate the esteratic site of AChE → ACh accumulates at ALL cholinergic sites. Most common poisoning worldwide. Common agents: Parathion, Malathion, Dyflos. Nerve agents: Sarin, Soman, Tabun.", y, 14)

y = sub_heading(d, "SIGNS & SYMPTOMS — The SLUDGE + DUMBELS Mnemonic:", y)
y = table(d,
    ["Type", "Features", "Mnemonic"],
    [
      ["MUSCARINIC effects\n(M receptors)", "Salivation, Lacrimation, Urination, Defecation (involuntary)\nGI cramps, Emesis, Bradycardia, Hypotension\nMiosis, Bronchospasm, ↑ Bronchial secretions, Sweating", "SLUDGE:\nSalivation Lacrimation Urination\nDefecation GI-cramps Emesis\n\nDUMBELS:\nDiarrhoea Urination Miosis Bradycardia\nEmesis Lacrimation Salivation"],
      ["NICOTINIC effects\n(N receptors)", "Twitchings, Fasciculations\nMuscle weakness → PARALYSIS\n(Prolonged depolarization of NMJ)", "The 'Killer' — respiratory muscle paralysis causes DEATH"],
      ["CENTRAL effects\n(CNS)", "Headache, Restlessness, Anxiety\nConfusion, Convulsions\nComa → DEATH (respiratory failure)", "CNS signs = SEVERE poisoning"],
    ],
    y, col_w=[200, 580, 480], fs=12, header_color=BAND_PURPLE)

y = sub_heading(d, "DIAGNOSIS of OP poisoning:", y)
y = bullet(d, "History of exposure (agricultural, industrial, intentional)", y, 14)
y = bullet(d, "Characteristic clinical signs (miosis + bradycardia + bronchospasm = classic triad)", y, 14)
y = bullet(d, "Decreased plasma/RBC cholinesterase activity (blood test — specific biomarker)", y, 14)
y = spacer(y, 6)

y = sub_heading(d, "TREATMENT of OP poisoning:", y)
y = bullet(d, "ATROPINE — HIGH DOSE IV (2–4 mg every 5–10 min until secretions dry up): Blocks MUSCARINIC effects only. Does NOT reverse paralysis (nicotinic). Give until 'atropinisation' achieved (dry mouth, ↑ HR, ↑ BP)", y, 14, color=C_RUST)
y = bullet(d, "PRALIDOXIME (PAM / 2-PAM) — IV infusion: Reactivates phosphorylated AChE IF given EARLY (before aging). Reverses BOTH muscarinic + nicotinic effects. Must be given within 24–48 hours (before aging)", y, 14, color=C_RUST)
y = bullet(d, "DIAZEPAM — IV: Prevents/treats convulsions (seizures from CNS ACh excess)", y, 14)
y = bullet(d, "Remove contaminated clothing, wash skin thoroughly", y, 14)
y = bullet(d, "Mechanical ventilation if respiratory muscle paralysis", y, 14)

y = info_box(d, [
    "Why ATROPINE works but cannot fully save in OP poisoning:",
    "→ Atropine blocks M receptors only → dries secretions, reverses bradycardia + bronchospasm",
    "→ Atropine has NO effect on NICOTINIC sites → cannot reverse muscle paralysis",
    "→ PRALIDOXIME (PAM) reactivates AChE → reduces ACh at BOTH M and N sites",
    "→ BUT PAM must be given EARLY before 'aging' of phosphorylated AChE complex (usually < 24–48h)",
], y, bg=BOX_RED, border=C_RUST, title="Critical Point — OP Poisoning Treatment", font_size=13)

d.text((MARGIN_L, H-44), "Page  9  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "9", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  PAGE 10 — THERAPEUTIC USES + MASTER SUMMARY
# ════════════════════════════════════════════════════════════════
img, d = new_page()
y = 10
y = page_header(d, "THERAPEUTIC USES & MASTER SUMMARY", "All Clinical Applications  |  Quick Revision Table  |  High-Yield Points", y)

y = section_banner(d, "THERAPEUTIC USES OF REVERSIBLE ANTICHOLINESTERASES", y, BAND_GREEN, "25")

y = table(d,
    ["Indication", "Drug of Choice", "Why / Mechanism"],
    [
      ["Myasthenia Gravis\n(symptomatic)", "Pyridostigmine (1st choice)\nNeostigmine (alt)", "Inhibit AChE → ↑ ACh at NMJ → improves neuromuscular transmission"],
      ["Diagnosis of MG\n(Tensilon test)", "Edrophonium IV", "Rapid onset (30 sec); dramatic improvement in MG; differentiates myasthenic vs cholinergic crisis"],
      ["Glaucoma", "Physostigmine (now rarely)\nPilocarpine (miotics)", "↓ IOP by miosis → opens trabecular meshwork → ↑ aqueous drainage"],
      ["Post-operative urinary\nretention & paralytic ileus", "Neostigmine\nBethanechol (alt)", "↑ detrusor tone + ↑ GIT motility; bethanechol more selective for bladder + GIT"],
      ["Reverse non-depolarizing\nNMJ block (curare reversal)", "Neostigmine + Atropine\nEdrophonium (if rapid)", "↑ ACh competes with curare at NM receptors; atropine prevents bradycardia"],
      ["Belladonna / Atropine\npoisoning", "Physostigmine IV\n(not neostigmine)", "ONLY physostigmine crosses BBB → reverses BOTH central + peripheral atropine effects"],
      ["Alzheimer's disease", "Donepezil (1st line)\nRivastigmine\nGalantamine", "Cerebroselective AChE inhibition → ↑ cerebral ACh → improved cognition in mild-moderate AD"],
      ["Sialogogue\n(dry mouth / xerostomia)", "Pilocarpine (oral)", "Direct M3 agonist → stimulates salivary glands"],
      ["Break iris-lens adhesions\n(posterior synechiae)", "Pilocarpine (alternated\nwith mydriatics)", "Repeated contraction/relaxation of iris breaks adhesions"],
    ],
    y, col_w=[250, 250, 760], fs=12, header_color=BAND_GREEN)

y = section_banner(d, "MASTER DRUG SUMMARY TABLE", y, BAND_NAVY, "26")

y = table(d,
    ["Drug", "Class", "BBB?", "Key Clinical Use", "Major Adverse Effect"],
    [
      ["Acetylcholine", "Choline ester (direct M+N)", "No", "Research only (no clinical use)", "No clinical use"],
      ["Bethanechol", "Choline ester (direct M)", "No", "Post-op urinary retention, Paralytic ileus", "Bronchospasm (CI in asthma)"],
      ["Carbachol", "Choline ester (direct M+N)", "No", "Glaucoma (topical)", "Miosis, bronchospasm"],
      ["Pilocarpine", "Alkaloid (direct M>N)", "Yes (tertiary)", "Glaucoma, Sialogogue, Break iris adhesions", "Salivation, sweating, bradycardia"],
      ["Physostigmine", "Reversible AChE inhibitor", "YES", "Atropine poisoning, Glaucoma (rarely)", "Bradycardia, bronchospasm, cataract (chronic)"],
      ["Neostigmine", "Reversible AChE inhibitor", "NO", "MG, Post-op urinary retention, Curare reversal", "SLUDGE signs (give atropine)"],
      ["Pyridostigmine", "Reversible AChE inhibitor", "NO", "MG (preferred — better tolerated, longer acting)", "SLUDGE signs (milder than neostigmine)"],
      ["Edrophonium", "Reversible AChE inhibitor", "NO", "Diagnosis of MG, Crisis differentiation", "Bradycardia, bronchospasm — KEEP ATROPINE READY"],
      ["Donepezil", "Cerebroselective AChE inhib", "YES", "Alzheimer's disease (1st line)", "GI upset (nausea, diarrhoea)"],
      ["Galantamine", "Cerebroselective AChE inhib", "YES", "Alzheimer's disease", "GI upset, dizziness"],
      ["Rivastigmine", "Cerebroselective AChE inhib", "YES", "Alzheimer's + Parkinson's dementia", "GI upset (patch formulation reduces this)"],
      ["Parathion/Malathion", "Irreversible OP (toxic)", "YES", "Insecticides (NO therapeutic use)", "Severe OP toxidrome → death"],
      ["Echothiophate", "Irreversible OP", "Minimal", "Glaucoma (rarely — resistant cases)", "Prolonged miosis, cataract"],
      ["Sarin/Soman/Tabun", "Irreversible OP (nerve agents)", "YES", "None — only toxicological (bioweapons)", "Rapid death if untreated"],
    ],
    y, col_w=[195, 220, 70, 420, 355], fs=11, header_color=BAND_NAVY)

y = section_banner(d, "HIGH-YIELD EXAM POINTS", y, BAND_RUST, "27")
points = [
    "Bethanechol = selective M3 agonist, NO nicotinic effects, NOT blocked fully by atropine in carbachol (carbachol is not completely blocked) ",
    "Pilocarpine = TERTIARY amine → penetrates cornea → effective TOPICALLY for glaucoma",
    "Neostigmine/Pyridostigmine = QUATERNARY → cannot cross BBB → safe in MG (no CNS effects)",
    "Physostigmine = crosses BBB → used for ATROPINE POISONING (reverses central effects neostigmine cannot)",
    "Edrophonium = 8–10 min duration → DIAGNOSIS only (Tensilon test) — not treatment",
    "PAM (Pralidoxime) = MUST be given EARLY in OP poisoning (before aging of enzyme at 24–48h)",
    "Atropine in OP poisoning = reverses MUSCARINIC effects only; PAM reverses BOTH M + N",
    "Prostaglandins (Latanoprost) = DRUG OF CHOICE in open-angle glaucoma (once daily, ↑ uveoscleral outflow)",
    "Propranolol is NOT used in glaucoma (membrane stabilising effect anesthetises cornea)",
    "Betaxolol = β1-selective blocker for glaucoma → SAFE in asthma (unlike timolol which is non-selective)",
    "ACh has NO therapeutic use — destroyed by pseudocholinesterase in blood even if given IV",
    "All cholinergic drugs CONTRAINDICATED in ASTHMA (bronchospasm risk)",
    "Pyridostigmine > Neostigmine in MG: longer duration, better tolerated, twice daily SR dosing",
]
for pt in points:
    y = bullet(d, pt, y, 13, C_DARK, symbol="★", dot_color=C_GOLD)

d.text((MARGIN_L, H-44), "Page  10  of  10  |  Cholinergic System — Detailed Notes", fill=C_GRAY, font=gf(13, italic=True))
d.text((W-MARGIN_R-60, H-44), "10", fill=C_NAVY, font=gf(16, bold=True))
pages.append(img)

# ════════════════════════════════════════════════════════════════
#  SAVE
# ════════════════════════════════════════════════════════════════
output = "/tmp/workspace/cholinergic-notes/Cholinergic_Detailed_Beautiful_Notes.pdf"
pages[0].save(output, save_all=True, append_images=pages[1:], format="PDF")
print(f"Saved: {output}")
print(f"Total pages: {len(pages)}")
Running Command

cd /tmp/workspace/cholinergic-notes && python beautiful_notes.py 2>&1

Your beautiful detailed notes are ready! Download here:

Cholinergic Detailed Beautiful Notes

PDF Document · PDF


What's inside — 10 detailed pages:

PageTopicWhat's Covered
1Overview + ANS vs SNSCholinergic system intro, ANS vs Somatic NS comparison table, Sites of ACh/NA release, Sympathetic vs Parasympathetic organ effects
2ACh Synthesis & CholinesterasesStep-by-step synthesis flow diagram, ChAT/AChE explained, True vs Pseudocholinesterase table, fate of ACh in synapse, clinical importance
3Cholinergic ReceptorsMuscarinic vs Nicotinic comparison, receptor cards for M1/M2/M3/M4-5/NN/NM — each with location, mechanism & response, memory tips
4Classification + ACh Muscarinic ActionsFull classification tree (all drugs), detailed table of ACh effects on every organ with receptor + mechanism
5Eye Effects + Nicotinic + Choline EstersComplete eye flowchart with steps, nicotinic actions at ganglia/NMJ/CNS, full ACh/Carbachol/Bethanechol comparison table
6Pilocarpine + Muscarine + GlaucomaPilocarpine uses in detail, mushroom poisoning 3-type table, glaucoma pathophysiology, drugs table for acute vs chronic glaucoma
7Anticholinesterase Mechanism + DrugsMechanism table (ACh vs Edrophonium vs Carbamates vs OPs), full drug cards for Physostigmine/Neostigmine/Pyridostigmine/Edrophonium/Alzheimer's drugs
8Myasthenia GravisPathophysiology, diagnosis tests table, full treatment table (symptomatic + immunosuppression + thymectomy + IVIG), contraindicated drugs
9Crises + OP PoisoningMyasthenic vs Cholinergic crisis comparison, OP poisoning SLUDGE/DUMBELS signs, diagnosis, treatment with Atropine + PAM explained
10Therapeutic Uses + Master SummaryAll indications with drug of choice table, 14-drug master summary table, 13 high-yield exam points starred
This is a shared conversation. Sign in to Orris to start your own chat.