Is it necessory to revise neuroanatomy before reading cns in medicibe
Make a quick reference PDF on essential neuroanatomy for CNS disorders
mkdir -p /tmp/workspace/neuroanatomy-pdf && ls /tmp/workspace/
~/neuroanatomy-pdf/build_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, Circle, Line, String, Polygon
from reportlab.graphics import renderPDF
import os
OUTPUT = "/tmp/workspace/neuroanatomy-pdf/Neuroanatomy_Quick_Reference.pdf"
# ── Colour palette ─────────────────────────────────────────────────────────────
C_DARK_BLUE = colors.HexColor("#1a2e4a")
C_MID_BLUE = colors.HexColor("#2563a8")
C_LIGHT_BLUE = colors.HexColor("#dbeafe")
C_TEAL = colors.HexColor("#0f766e")
C_TEAL_LIGHT = colors.HexColor("#ccfbf1")
C_RED = colors.HexColor("#b91c1c")
C_RED_LIGHT = colors.HexColor("#fee2e2")
C_AMBER = colors.HexColor("#b45309")
C_AMBER_LIGHT = colors.HexColor("#fef3c7")
C_PURPLE = colors.HexColor("#7c3aed")
C_PURPLE_LIGHT= colors.HexColor("#ede9fe")
C_GREEN = colors.HexColor("#15803d")
C_GREEN_LIGHT = colors.HexColor("#dcfce7")
C_ORANGE = colors.HexColor("#c2410c")
C_ORANGE_LIGHT= colors.HexColor("#ffedd5")
C_GREY_BG = colors.HexColor("#f8fafc")
C_GREY_LINE = colors.HexColor("#cbd5e1")
C_WHITE = colors.white
C_BLACK = colors.HexColor("#0f172a")
# ── Document ───────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=2.0*cm, bottomMargin=2.0*cm,
title="Essential Neuroanatomy for CNS Disorders",
author="Orris Medical Reference"
)
W = A4[0] - 3.6*cm # usable width
styles = getSampleStyleSheet()
# Custom styles
def S(name, **kw):
return ParagraphStyle(name, **kw)
COVER_TITLE = S("CoverTitle",
fontSize=28, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_CENTER, leading=34, spaceAfter=6)
COVER_SUB = S("CoverSub",
fontSize=13, fontName="Helvetica",
textColor=colors.HexColor("#bfdbfe"), alignment=TA_CENTER, leading=18)
SEC_HEADER = S("SecHeader",
fontSize=14, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_LEFT, leading=18,
leftIndent=6, spaceBefore=2, spaceAfter=2)
SUBSEC = S("Subsec",
fontSize=10.5, fontName="Helvetica-Bold",
textColor=C_DARK_BLUE, spaceBefore=8, spaceAfter=3, leading=14)
BODY = S("Body",
fontSize=9, fontName="Helvetica",
textColor=C_BLACK, leading=13, spaceAfter=3, alignment=TA_JUSTIFY)
BULLET = S("Bullet",
fontSize=9, fontName="Helvetica",
textColor=C_BLACK, leading=13, spaceAfter=2,
leftIndent=12, bulletIndent=0)
SMALL = S("Small",
fontSize=8, fontName="Helvetica",
textColor=colors.HexColor("#475569"), leading=11)
TABLE_HDR = S("TblHdr",
fontSize=8.5, fontName="Helvetica-Bold",
textColor=C_WHITE, alignment=TA_CENTER, leading=11)
TABLE_CELL = S("TblCell",
fontSize=8, fontName="Helvetica",
textColor=C_BLACK, alignment=TA_LEFT, leading=11)
TABLE_CELL_C = S("TblCellC",
fontSize=8, fontName="Helvetica",
textColor=C_BLACK, alignment=TA_CENTER, leading=11)
CAPTION = S("Caption",
fontSize=7.5, fontName="Helvetica-Oblique",
textColor=colors.HexColor("#64748b"), alignment=TA_CENTER, leading=10)
MNEMONIC = S("Mnemonic",
fontSize=9, fontName="Helvetica-Bold",
textColor=C_PURPLE, leading=13, spaceAfter=2, leftIndent=8)
CLINICAL = S("Clinical",
fontSize=8.5, fontName="Helvetica-Oblique",
textColor=C_TEAL, leading=12, spaceAfter=2, leftIndent=8)
# ── Helper Flowables ────────────────────────────────────────────────────────────
class ColorBox(Flowable):
"""A coloured banner for section headers."""
def __init__(self, text, bg=C_DARK_BLUE, fg=C_WHITE, height=22, radius=4):
super().__init__()
self.text = text
self.bg = bg
self.fg = fg
self.height = height
self.radius = radius
self.width = W
def wrap(self, avW, avH):
return self.width, self.height + 4
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 2, self.width, self.height, self.radius, fill=1, stroke=0)
c.setFillColor(self.fg)
c.setFont("Helvetica-Bold", 12)
c.drawString(8, self.height/2 - 4, self.text)
class NoteBox(Flowable):
"""Coloured note/callout box."""
def __init__(self, text, bg=C_AMBER_LIGHT, border=C_AMBER, label="NOTE", width=None):
super().__init__()
self.text = text
self.bg = bg
self.border = border
self.label = label
self.bwidth = width or W
self._lines = []
def wrap(self, avW, avH):
from reportlab.lib.utils import simpleSplit
lines = simpleSplit(self.text, "Helvetica", 8.5, self.bwidth - 30)
self._lines = lines
self._height = max(24, len(lines)*12 + 14)
return self.bwidth, self._height
def draw(self):
c = self.canv
h = self._height
c.setFillColor(self.bg)
c.roundRect(0, 0, self.bwidth, h, 4, fill=1, stroke=0)
c.setFillColor(self.border)
c.roundRect(0, 0, self.bwidth, h, 4, fill=0, stroke=1)
c.setFillColor(self.border)
c.setFont("Helvetica-Bold", 8)
c.drawString(8, h - 12, self.label)
c.setFillColor(C_BLACK)
c.setFont("Helvetica", 8.5)
y = h - 24
for ln in self._lines:
c.drawString(12, y, ln)
y -= 12
def HR(color=C_GREY_LINE, thickness=0.5):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4, spaceBefore=4)
def SP(h=4):
return Spacer(1, h)
def P(text, style=BODY):
return Paragraph(text, style)
def B(text):
return Paragraph(f"• {text}", BULLET)
def tbl_style(header_color=C_DARK_BLUE):
return TableStyle([
("BACKGROUND", (0,0), (-1,0), header_color),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 8.5),
("ALIGN", (0,0), (-1,0), "CENTER"),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,1), (-1,-1), 8),
("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, C_GREY_LINE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("LEFTPADDING",(0,0), (-1,-1), 5),
("RIGHTPADDING",(0,0),(-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
])
# ── Spinal Cord ASCII diagram via ReportLab drawing ────────────────────────────
def spinal_cord_diagram():
"""Draw a schematic spinal cord cross-section."""
d = Drawing(W, 160)
cx, cy = W/2, 80
# Outer white matter (large ellipse outline)
d.add(Circle(cx, cy, 60, fillColor=colors.HexColor("#e0f2fe"),
strokeColor=C_MID_BLUE, strokeWidth=1.5))
# Inner grey matter H-shape (butterfly) - approximate with 3 rects
# Central canal
d.add(Circle(cx, cy, 5, fillColor=colors.HexColor("#fbbf24"),
strokeColor=C_AMBER, strokeWidth=1))
# Dorsal horns
d.add(Polygon([cx-8,cy+5, cx+8,cy+5, cx+5,cy+38, cx,cy+40, cx-5,cy+38],
fillColor=colors.HexColor("#fde68a"),
strokeColor=C_AMBER, strokeWidth=1))
# Ventral horns
d.add(Polygon([cx-10,cy-5, cx+10,cy-5, cx+14,cy-35, cx,cy-42, cx-14,cy-35],
fillColor=colors.HexColor("#fde68a"),
strokeColor=C_AMBER, strokeWidth=1))
# Lateral horns (small bumps)
d.add(Polygon([cx+7,cy+2, cx+7,cy-2, cx+30,cy],
fillColor=colors.HexColor("#fde68a"),
strokeColor=C_AMBER, strokeWidth=0.8))
d.add(Polygon([cx-7,cy+2, cx-7,cy-2, cx-30,cy],
fillColor=colors.HexColor("#fde68a"),
strokeColor=C_AMBER, strokeWidth=0.8))
# Tract labels - right side
def lbl(x, y, txt, col=C_DARK_BLUE, sz=7):
d.add(String(x, y, txt, fontName="Helvetica-Bold", fontSize=sz, fillColor=col))
# Dorsal columns (top)
d.add(Rect(cx-18, cy+42, 36, 14, fillColor=colors.HexColor("#bbf7d0"),
strokeColor=C_GREEN, strokeWidth=0.8))
lbl(cx-16, cy+47, "Dorsal Columns", C_GREEN, 6.5)
# Lateral CST (right)
d.add(Circle(cx+38, cy+20, 10, fillColor=colors.HexColor("#fecaca"),
strokeColor=C_RED, strokeWidth=0.8))
lbl(cx+50, cy+22, "Lat. CST", C_RED, 6.5)
lbl(cx+50, cy+13, "(motor)", C_RED, 6)
# Lateral CST (left)
d.add(Circle(cx-38, cy+20, 10, fillColor=colors.HexColor("#fecaca"),
strokeColor=C_RED, strokeWidth=0.8))
lbl(cx-72, cy+22, "Lat. CST", C_RED, 6.5)
# Spinothalamic (right)
d.add(Circle(cx+40, cy-15, 10, fillColor=colors.HexColor("#ddd6fe"),
strokeColor=C_PURPLE, strokeWidth=0.8))
lbl(cx+52, cy-13, "Spino-", C_PURPLE, 6.5)
lbl(cx+52, cy-22, "thalamic", C_PURPLE, 6.5)
# Spinothalamic (left)
d.add(Circle(cx-40, cy-15, 10, fillColor=colors.HexColor("#ddd6fe"),
strokeColor=C_PURPLE, strokeWidth=0.8))
lbl(cx-80, cy-13, "Spino-", C_PURPLE, 6.5)
lbl(cx-82, cy-22, "thalamic", C_PURPLE, 6.5)
# Title
lbl(cx-55, 148, "Spinal Cord Cross-Section (Schematic)", C_DARK_BLUE, 8)
return d
def visual_pathway_diagram():
"""Simple visual pathway schematic."""
d = Drawing(W, 180)
def lbl(x, y, txt, col=C_DARK_BLUE, sz=7.5, bold=False):
fn = "Helvetica-Bold" if bold else "Helvetica"
d.add(String(x, y, txt, fontName=fn, fontSize=sz, fillColor=col))
def box(x, y, w, h, fc, sc):
d.add(Rect(x, y, w, h, fillColor=fc, strokeColor=sc, strokeWidth=1))
col = W/2
# Eyes
box(col-120, 145, 30, 18, colors.HexColor("#dbeafe"), C_MID_BLUE)
lbl(col-116, 151, "L Eye", C_MID_BLUE, 7.5, True)
box(col+90, 145, 30, 18, colors.HexColor("#dbeafe"), C_MID_BLUE)
lbl(col+94, 151, "R Eye", C_MID_BLUE, 7.5, True)
# Optic nerves
d.add(Line(col-105, 145, col-20, 110, strokeColor=C_DARK_BLUE, strokeWidth=1.2))
d.add(Line(col+105, 145, col+20, 110, strokeColor=C_DARK_BLUE, strokeWidth=1.2))
# Nasal fibres cross at chiasm
d.add(Line(col-10, 110, col+10, 90, strokeColor=C_RED, strokeWidth=1.2))
d.add(Line(col+10, 110, col-10, 90, strokeColor=C_RED, strokeWidth=1.2))
# Chiasm box
box(col-22, 93, 44, 20, colors.HexColor("#fef3c7"), C_AMBER)
lbl(col-18, 100, "Optic Chiasm", C_AMBER, 7, True)
# Optic tracts
d.add(Line(col-10, 93, col-50, 68, strokeColor=C_TEAL, strokeWidth=1.2))
d.add(Line(col+10, 93, col+50, 68, strokeColor=C_TEAL, strokeWidth=1.2))
lbl(col-85, 78, "L Optic Tract", C_TEAL, 7)
lbl(col+52, 78, "R Optic Tract", C_TEAL, 7)
# LGN
box(col-65, 50, 32, 18, colors.HexColor("#ede9fe"), C_PURPLE)
lbl(col-63, 57, "L LGN", C_PURPLE, 7, True)
box(col+33, 50, 32, 18, colors.HexColor("#ede9fe"), C_PURPLE)
lbl(col+35, 57, "R LGN", C_PURPLE, 7, True)
# Optic radiations
d.add(Line(col-49, 50, col-30, 22, strokeColor=C_GREEN, strokeWidth=1.2))
d.add(Line(col+49, 50, col+30, 22, strokeColor=C_GREEN, strokeWidth=1.2))
# Visual cortex
box(col-45, 5, 90, 18, colors.HexColor("#dcfce7"), C_GREEN)
lbl(col-38, 12, "Visual Cortex (V1)", C_GREEN, 7.5, True)
# Legend
lbl(10, 30, "Red = crossing fibres (nasal retina)", C_RED, 7)
lbl(10, 18, "Green = optic radiation", C_GREEN, 7)
lbl(col-60, 168, "Visual Pathway - Schematic", C_DARK_BLUE, 8.5, True)
return d
# ══════════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER PAGE ─────────────────────────────────────────────────────────────────
class CoverPage(Flowable):
def __init__(self, w, h):
super().__init__()
self.w = w
self.h = h
def wrap(self, avW, avH):
return self.w, self.h
def draw(self):
c = self.canv
# Background gradient-ish (two rects)
c.setFillColor(C_DARK_BLUE)
c.rect(0, 0, self.w, self.h, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#1e3a5f"))
c.rect(0, 0, self.w, self.h*0.45, fill=1, stroke=0)
# Top decorative band
c.setFillColor(C_MID_BLUE)
c.rect(0, self.h-8, self.w, 8, fill=1, stroke=0)
# Brain icon (simple circles schematic)
cx, cy = self.w/2, self.h*0.55
c.setFillColor(colors.HexColor("#2563a8"))
c.circle(cx, cy, 70, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#1d4ed8"))
c.circle(cx-10, cy+10, 52, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#3b82f6"))
c.circle(cx+15, cy-5, 45, fill=1, stroke=0)
# Sulci lines
c.setStrokeColor(colors.HexColor("#93c5fd"))
c.setLineWidth(1.5)
for i, (x1,y1,x2,y2) in enumerate([
(cx-30, cy+40, cx+10, cy+60),
(cx-50, cy+10, cx-20, cy+30),
(cx+5, cy+20, cx+45, cy+35),
(cx-40, cy-20, cx-10, cy+10),
(cx+10, cy-10, cx+50, cy+10),
(cx-20, cy-40, cx+20, cy-20),
]):
c.bezier(x1,y1, x1+10,y1+15, x2-10,y2-15, x2,y2)
# Title text
c.setFillColor(C_WHITE)
c.setFont("Helvetica-Bold", 26)
c.drawCentredString(self.w/2, self.h*0.30, "Essential Neuroanatomy")
c.setFont("Helvetica-Bold", 20)
c.setFillColor(colors.HexColor("#93c5fd"))
c.drawCentredString(self.w/2, self.h*0.23, "for CNS Disorders")
# Subtitle
c.setFont("Helvetica", 11)
c.setFillColor(colors.HexColor("#bfdbfe"))
c.drawCentredString(self.w/2, self.h*0.165,
"Tracts · Cranial Nerves · Vascular · Syndromes · Visual Pathway")
# Tagline
c.setFont("Helvetica-Oblique", 9)
c.setFillColor(colors.HexColor("#94a3b8"))
c.drawCentredString(self.w/2, self.h*0.10, "Quick Reference for Medical Students & Clinicians")
c.drawCentredString(self.w/2, self.h*0.06, "Orris Medical Reference | 2026")
# Bottom band
c.setFillColor(C_MID_BLUE)
c.rect(0, 0, self.w, 6, fill=1, stroke=0)
cover_h = A4[1] - 4.0*cm
story.append(CoverPage(W, cover_h))
story.append(PageBreak())
# ── PAGE HEADER helper ─────────────────────────────────────────────────────────
def section(title, color=C_DARK_BLUE):
return [SP(6), ColorBox(title, bg=color), SP(6)]
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 1: MAJOR TRACTS
# ══════════════════════════════════════════════════════════════════════════════
story += section("1. MAJOR SPINAL CORD TRACTS", C_DARK_BLUE)
story.append(P(
"Understanding tracts is the key to <b>lesion localization</b>. "
"Each tract carries specific modalities, crosses at a defined level, "
"and produces characteristic deficits when damaged.", BODY))
story.append(SP(4))
tract_data = [
[P("Tract", TABLE_HDR), P("Location", TABLE_HDR), P("Modality", TABLE_HDR),
P("Crosses", TABLE_HDR), P("1st Neuron", TABLE_HDR), P("Clinical Loss", TABLE_HDR)],
[P("Dorsal Columns\n(Fasciculus gracilis\n& cuneatus)", TABLE_CELL),
P("Posterior white matter", TABLE_CELL),
P("Fine touch, vibration, proprioception, 2-pt discrimination", TABLE_CELL),
P("Medulla\n(at nucleus gracilis/cuneatus)", TABLE_CELL),
P("Ipsilateral: ascends same side", TABLE_CELL),
P("Ipsilateral loss at level of lesion and below", TABLE_CELL)],
[P("Lateral Corticospinal\nTract (CST)", TABLE_CELL),
P("Lateral white matter", TABLE_CELL),
P("Voluntary motor (UMN)", TABLE_CELL),
P("Medulla\n(pyramidal decussation)", TABLE_CELL),
P("Contralateral motor cortex", TABLE_CELL),
P("Ipsilateral UMN weakness below lesion", TABLE_CELL)],
[P("Lateral\nSpinothalamic", TABLE_CELL),
P("Anterolateral white matter", TABLE_CELL),
P("Pain, temperature", TABLE_CELL),
P("Within 1-2 spinal segments of entry", TABLE_CELL),
P("Ipsilateral: enters, crosses quickly", TABLE_CELL),
P("Contralateral pain/temp loss 1-2 levels below lesion", TABLE_CELL)],
[P("Anterior\nSpinothalamic", TABLE_CELL),
P("Anterior white matter", TABLE_CELL),
P("Crude touch, pressure", TABLE_CELL),
P("Within 1-2 spinal segments", TABLE_CELL),
P("Crosses early", TABLE_CELL),
P("Contralateral crude touch loss (often spared in practice)", TABLE_CELL)],
[P("Rubrospinal", TABLE_CELL),
P("Lateral (near CST)", TABLE_CELL),
P("Motor coordination", TABLE_CELL),
P("Midbrain tegmentum", TABLE_CELL),
P("Red nucleus", TABLE_CELL),
P("Minor in humans; arm flexor tone", TABLE_CELL)],
[P("Vestibulospinal", TABLE_CELL),
P("Anterior column", TABLE_CELL),
P("Postural tone, balance", TABLE_CELL),
P("Does NOT cross", TABLE_CELL),
P("Vestibular nucleus", TABLE_CELL),
P("Loss: truncal ataxia, falls to side", TABLE_CELL)],
]
t = Table(tract_data, colWidths=[2.8*cm, 2.5*cm, 3.2*cm, 2.8*cm, 2.5*cm, 3.0*cm])
ts = tbl_style(C_DARK_BLUE)
t.setStyle(ts)
story.append(t)
story.append(SP(8))
story.append(P("SPINAL CORD CROSS-SECTION", SUBSEC))
story.append(spinal_cord_diagram())
story.append(P("Yellow = Grey matter (H-shape) | Green = Dorsal columns | Red = Lateral CST | Purple = Spinothalamic tracts", CAPTION))
story.append(SP(8))
story.append(NoteBox(
"Mnemonic - DCML vs Spinothalamic sides: Dorsal Columns go up the SAME side as the entry, cross in the MEDULLA. "
"Spinothalamic fibres cross within 1-2 segments of entry. "
"So a unilateral cord lesion causes IPSILATERAL loss of vibration/proprioception + CONTRALATERAL loss of pain/temp.",
bg=C_AMBER_LIGHT, border=C_AMBER, label="KEY CONCEPT"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2: SPINAL CORD SYNDROMES
# ══════════════════════════════════════════════════════════════════════════════
story += section("2. SPINAL CORD SYNDROMES", C_TEAL)
synd_data = [
[P("Syndrome", TABLE_HDR), P("Lesion Site", TABLE_HDR), P("Motor", TABLE_HDR),
P("DCML (vib/prop)", TABLE_HDR), P("Pain/Temp", TABLE_HDR), P("Causes", TABLE_HDR)],
[P("Complete\nTransection", TABLE_CELL_C),
P("Complete cord", TABLE_CELL),
P("Bilateral UMN below; LMN at level", TABLE_CELL),
P("Bilateral loss", TABLE_CELL),
P("Bilateral loss", TABLE_CELL),
P("Trauma, MS", TABLE_CELL)],
[P("Brown-Séquard\n(Hemisection)", TABLE_CELL_C),
P("Half the cord (one side)", TABLE_CELL),
P("Ipsilateral UMN weakness below", TABLE_CELL),
P("Ipsilateral loss", TABLE_CELL),
P("CONTRALATERAL loss 1-2 levels below", TABLE_CELL),
P("Trauma, MS, tumour", TABLE_CELL)],
[P("Central Cord\nSyndrome", TABLE_CELL_C),
P("Central grey + crossing fibers", TABLE_CELL),
P("UE > LE weakness (cape pattern)", TABLE_CELL),
P("Preserved (outer columns spared)", TABLE_CELL),
P("Bilateral loss in cape distribution", TABLE_CELL),
P("Syringomyelia, hyperextension injury", TABLE_CELL)],
[P("Anterior Cord\nSyndrome", TABLE_CELL_C),
P("Anterior 2/3 of cord", TABLE_CELL),
P("Bilateral UMN below", TABLE_CELL),
P("PRESERVED (posterior columns intact)", TABLE_CELL),
P("Bilateral loss", TABLE_CELL),
P("Anterior spinal artery occlusion", TABLE_CELL)],
[P("Posterior Cord\nSyndrome", TABLE_CELL_C),
P("Posterior columns", TABLE_CELL),
P("Normal", TABLE_CELL),
P("Bilateral loss - sensory ataxia", TABLE_CELL),
P("Preserved", TABLE_CELL),
P("B12 deficiency (SCD), tabes dorsalis", TABLE_CELL)],
[P("Subacute Combined\nDegeneration (SCD)", TABLE_CELL_C),
P("Lateral + Posterior columns", TABLE_CELL),
P("UMN (lateral CST)", TABLE_CELL),
P("Loss (posterior columns)", TABLE_CELL),
P("Variable", TABLE_CELL),
P("Vitamin B12 deficiency", TABLE_CELL)],
[P("Conus Medullaris\nSyndrome", TABLE_CELL_C),
P("S3-S5 cord (conus)", TABLE_CELL),
P("Saddle anaesthesia, LMN bladder/bowel", TABLE_CELL),
P("Saddle area loss", TABLE_CELL),
P("Saddle area loss", TABLE_CELL),
P("Trauma, disc prolapse", TABLE_CELL)],
[P("Cauda Equina\nSyndrome", TABLE_CELL_C),
P("Spinal nerve roots (below L1)", TABLE_CELL),
P("Asymmetric LMN weakness, absent reflexes", TABLE_CELL),
P("Asymmetric loss", TABLE_CELL),
P("Asymmetric loss, saddle", TABLE_CELL),
P("Disc prolapse, tumour - EMERGENCY", TABLE_CELL)],
]
t2 = Table(synd_data, colWidths=[2.4*cm, 2.6*cm, 3.2*cm, 2.6*cm, 2.6*cm, 2.8*cm])
ts2 = tbl_style(C_TEAL)
t2.setStyle(ts2)
story.append(t2)
story.append(SP(6))
story.append(NoteBox(
"Brown-Séquard tip: Ipsilateral UMN + vibration/proprioception loss + CONTRALATERAL pain/temp loss = classic hemisection. "
"Anterior cord: motor gone, vibration/prop PRESERVED = classic ASA territory. "
"Cauda equina is a surgical EMERGENCY - saddle anaesthesia + bladder/bowel dysfunction needs immediate MRI.",
bg=C_RED_LIGHT, border=C_RED, label="CLINICAL PEARL"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3: UMN vs LMN
# ══════════════════════════════════════════════════════════════════════════════
story += section("3. UMN vs LMN SIGNS", C_MID_BLUE)
umn_lmn = [
[P("Feature", TABLE_HDR), P("UMN Lesion", TABLE_HDR), P("LMN Lesion", TABLE_HDR)],
[P("Tone", TABLE_CELL_C), P("Increased (spasticity, clasp-knife)", TABLE_CELL),
P("Decreased (flaccidity)", TABLE_CELL)],
[P("Power", TABLE_CELL_C), P("Weakness (pyramidal pattern: UE extensors > flexors; LE flexors > extensors)", TABLE_CELL),
P("Weakness in distribution of nerve/root", TABLE_CELL)],
[P("Reflexes", TABLE_CELL_C), P("Hyperreflexia, Babinski positive (extensor plantar)", TABLE_CELL),
P("Hyporeflexia / areflexia", TABLE_CELL)],
[P("Clonus", TABLE_CELL_C), P("Present (sustained)", TABLE_CELL), P("Absent", TABLE_CELL)],
[P("Wasting", TABLE_CELL_C), P("Mild (disuse atrophy only)", TABLE_CELL),
P("Severe muscle wasting", TABLE_CELL)],
[P("Fasciculations", TABLE_CELL_C), P("Absent", TABLE_CELL), P("Present", TABLE_CELL)],
[P("Distribution", TABLE_CELL_C), P("Contralateral to cortical lesion; below cord lesion", TABLE_CELL),
P("Same side as lesion, segmental/nerve territory", TABLE_CELL)],
[P("Location of lesion", TABLE_CELL_C), P("Motor cortex, internal capsule, brainstem, spinal cord", TABLE_CELL),
P("Anterior horn cell, nerve root, peripheral nerve, NMJ", TABLE_CELL)],
]
t3 = Table(umn_lmn, colWidths=[2.8*cm, 6.0*cm, 6.0*cm])
ts3 = tbl_style(C_MID_BLUE)
ts3.add("BACKGROUND", (1,1), (1,-1), colors.HexColor("#eff6ff"))
ts3.add("BACKGROUND", (2,1), (2,-1), colors.HexColor("#fff7ed"))
t3.setStyle(ts3)
story.append(t3)
story.append(SP(6))
story.append(NoteBox(
"Mnemonic: UMN = 'UP' signs (tone UP, reflexes UP, plantar UP/Babinski). "
"LMN = 'DOWN' signs (tone DOWN, reflexes DOWN, wasting). "
"Mixed UMN+LMN = think MND/ALS, B12 deficiency (SCD), syphilis (tabes + meningomyelitis).",
bg=C_LIGHT_BLUE, border=C_MID_BLUE, label="MNEMONIC"))
story.append(SP(8))
story += section("4. INTERNAL CAPSULE", C_PURPLE)
story.append(P(
"The internal capsule carries <b>all ascending and descending fibres</b> between cortex and "
"brainstem/spinal cord, packed tightly. Small lesions (e.g. lacunar infarcts) cause "
"dense contralateral deficits.", BODY))
ic_data = [
[P("Limb/Genu", TABLE_HDR), P("Fibres", TABLE_HDR), P("Clinical Deficit if Damaged", TABLE_HDR)],
[P("Anterior Limb", TABLE_CELL_C),
P("Frontopontine fibres, anterior thalamic radiation", TABLE_CELL),
P("Frontal lobe dysfunction, cognitive changes", TABLE_CELL)],
[P("Genu (knee)", TABLE_CELL_C),
P("Corticobulbar fibres (CN V, VII, IX, X, XI, XII)", TABLE_CELL),
P("Contralateral lower face weakness (UMN VII); dysarthria, dysphagia", TABLE_CELL)],
[P("Posterior Limb\n(anterior portion)", TABLE_CELL_C),
P("Corticospinal (motor) fibres: arm > leg arrangement", TABLE_CELL),
P("Contralateral hemiplegia (arm > leg if anterior, leg > arm if posterior)", TABLE_CELL)],
[P("Posterior Limb\n(posterior portion)", TABLE_CELL_C),
P("Thalamocortical sensory fibres", TABLE_CELL),
P("Contralateral hemisensory loss", TABLE_CELL)],
[P("Retrolenticular", TABLE_CELL_C),
P("Optic radiation (lower fibers = Meyer's loop)", TABLE_CELL),
P("Contralateral homonymous hemianopia or superior quadrantanopia", TABLE_CELL)],
[P("Sublenticular", TABLE_CELL_C),
P("Auditory radiation, temporopontine", TABLE_CELL),
P("Auditory processing deficits (rarely clinically significant alone)", TABLE_CELL)],
]
t4 = Table(ic_data, colWidths=[3.0*cm, 5.5*cm, 6.3*cm])
t4.setStyle(tbl_style(C_PURPLE))
story.append(t4)
story.append(SP(6))
story.append(NoteBox(
"Pure motor hemiplegia (face + arm + leg) + no sensory loss = posterior limb IC lacunar infarct. "
"Pure sensory stroke = VPL thalamus or posterior limb IC. "
"Lacunar infarcts are supplied by lenticulostriate branches of MCA - hypertension is the #1 cause.",
bg=C_PURPLE_LIGHT, border=C_PURPLE, label="CLINICAL PEARL"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5: CRANIAL NERVES
# ══════════════════════════════════════════════════════════════════════════════
story += section("5. CRANIAL NERVES - ORIGINS, COURSE & CLINICAL", C_RED)
story.append(P(
"Cranial nerves arise from nuclei in the brainstem (except CN I and II). "
"Knowing their exit foramina and course is essential for localizing lesions.", BODY))
cn_data = [
[P("CN", TABLE_HDR), P("Name", TABLE_HDR), P("Type", TABLE_HDR),
P("Nucleus/Origin", TABLE_HDR), P("Exit Foramen", TABLE_HDR), P("Key Clinical", TABLE_HDR)],
[P("I", TABLE_CELL_C), P("Olfactory", TABLE_CELL_C), P("Sensory", TABLE_CELL_C),
P("Olfactory bulb", TABLE_CELL), P("Cribriform plate", TABLE_CELL),
P("Anosmia: head trauma, meningioma, zinc deficiency", TABLE_CELL)],
[P("II", TABLE_CELL_C), P("Optic", TABLE_CELL_C), P("Sensory", TABLE_CELL_C),
P("Retinal ganglion cells", TABLE_CELL), P("Optic canal", TABLE_CELL),
P("Optic neuritis (MS), AION, visual field defects", TABLE_CELL)],
[P("III", TABLE_CELL_C), P("Oculomotor", TABLE_CELL_C), P("Motor + PS", TABLE_CELL_C),
P("Midbrain (CN III nucleus + EW nucleus)", TABLE_CELL), P("Superior orbital fissure", TABLE_CELL),
P("Down+out gaze, ptosis, dilated pupil (PCOM aneurysm = surgical III palsy)", TABLE_CELL)],
[P("IV", TABLE_CELL_C), P("Trochlear", TABLE_CELL_C), P("Motor", TABLE_CELL_C),
P("Midbrain (crosses before exit - only CN that does)", TABLE_CELL), P("Superior orbital fissure", TABLE_CELL),
P("Vertical diplopia worse looking down (reading). Head tilt AWAY from lesion.", TABLE_CELL)],
[P("V", TABLE_CELL_C), P("Trigeminal", TABLE_CELL_C), P("Mixed", TABLE_CELL_C),
P("Pons (main sensory + motor); mesencephalic + spinal nucleus", TABLE_CELL),
P("V1: SOF; V2: foramen rotundum; V3: foramen ovale", TABLE_CELL),
P("Trigeminal neuralgia (V2/V3), corneal reflex (afferent V1)", TABLE_CELL)],
[P("VI", TABLE_CELL_C), P("Abducens", TABLE_CELL_C), P("Motor", TABLE_CELL_C),
P("Pons (CN VI nucleus - MLF connects)", TABLE_CELL), P("Superior orbital fissure", TABLE_CELL),
P("Medial deviation at rest; cannot abduct. Longest intracranial course - false localizing sign in raised ICP.", TABLE_CELL)],
[P("VII", TABLE_CELL_C), P("Facial", TABLE_CELL_C), P("Mixed", TABLE_CELL_C),
P("Pons (motor, superior salivatory, NTS)", TABLE_CELL), P("Stylomastoid foramen", TABLE_CELL),
P("LMN (Bell's): entire face. UMN: lower face only (forehead spared). Taste ant 2/3 tongue.", TABLE_CELL)],
[P("VIII", TABLE_CELL_C), P("Vestibulocochlear", TABLE_CELL_C), P("Sensory", TABLE_CELL_C),
P("Pons/medulla", TABLE_CELL), P("Internal auditory meatus", TABLE_CELL),
P("SNHL (acoustic neuroma), vestibular neuritis, Meniere's", TABLE_CELL)],
[P("IX", TABLE_CELL_C), P("Glossopharyngeal", TABLE_CELL_C), P("Mixed", TABLE_CELL_C),
P("Medulla (nucleus ambiguus, inferior salivatory)", TABLE_CELL), P("Jugular foramen", TABLE_CELL),
P("Gag reflex afferent, taste post 1/3, stylopharyngeus. Glossopharyngeal neuralgia.", TABLE_CELL)],
[P("X", TABLE_CELL_C), P("Vagus", TABLE_CELL_C), P("Mixed", TABLE_CELL_C),
P("Medulla (nucleus ambiguus, DMNV)", TABLE_CELL), P("Jugular foramen", TABLE_CELL),
P("Hoarseness (RLN), gag efferent, palatal palsy (nasal voice, uvula deviates away), autonomics", TABLE_CELL)],
[P("XI", TABLE_CELL_C), P("Accessory", TABLE_CELL_C), P("Motor", TABLE_CELL_C),
P("Spinal cord C1-C5 + cranial root from nucleus ambiguus", TABLE_CELL), P("Jugular foramen", TABLE_CELL),
P("SCM (head turn) + trapezius (shoulder shrug) weakness. Wasted SCM + cannot turn to opposite side.", TABLE_CELL)],
[P("XII", TABLE_CELL_C), P("Hypoglossal", TABLE_CELL_C), P("Motor", TABLE_CELL_C),
P("Medulla (hypoglossal nucleus)", TABLE_CELL), P("Hypoglossal canal", TABLE_CELL),
P("Tongue deviates TOWARDS lesion (LMN). Contralateral if UMN. Tongue wasting in MND.", TABLE_CELL)],
]
t5 = Table(cn_data, colWidths=[0.8*cm, 2.4*cm, 1.5*cm, 3.2*cm, 2.4*cm, 5.5*cm])
ts5 = tbl_style(C_RED)
ts5.add("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.HexColor("#fff5f5"), C_WHITE])
t5.setStyle(ts5)
story.append(t5)
story.append(SP(6))
story.append(NoteBox(
"Mnemonic for CN types: Some Say Marry Money But My Brother Says Big Brains Matter = "
"S, S, M, M, B(oth), M, B(oth), S, B(oth), B(oth), M, M (CN I-XII). "
"Jugular foramen syndrome (CN IX, X, XI): hoarseness + dysphagia + SCM/trapezius weakness. "
"CN III surgical palsy (posterior communicating artery aneurysm) = painful, dilated pupil.",
bg=C_RED_LIGHT, border=C_RED, label="KEY POINTS + MNEMONIC"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6: BRAINSTEM SYNDROMES
# ══════════════════════════════════════════════════════════════════════════════
story += section("6. BRAINSTEM VASCULAR SYNDROMES", C_ORANGE)
story.append(P(
"Brainstem strokes produce crossed deficits: ipsilateral CN signs (LMN, at level of lesion) + "
"contralateral long tract signs (UMN, below lesion). "
"Pattern of CN involvement tells you the <b>level</b>.", BODY))
bs_data = [
[P("Syndrome", TABLE_HDR), P("Artery", TABLE_HDR), P("Level", TABLE_HDR),
P("Ipsilateral Signs", TABLE_HDR), P("Contralateral Signs", TABLE_HDR)],
[P("Weber's\n(Ventral midbrain)", TABLE_CELL_C),
P("PCA / paramedian branches", TABLE_CELL),
P("Midbrain (cerebral peduncle)", TABLE_CELL),
P("CN III palsy (ptosis, down+out, dilated pupil)", TABLE_CELL),
P("Hemiplegia (CST)", TABLE_CELL)],
[P("Benedikt's\n(Tegmental midbrain)", TABLE_CELL_C),
P("PCA branches to tegmentum", TABLE_CELL),
P("Midbrain tegmentum", TABLE_CELL),
P("CN III palsy", TABLE_CELL),
P("Hemiataxia + tremor (red nucleus), hemisensory loss", TABLE_CELL)],
[P("Claude's", TABLE_CELL_C),
P("PCA", TABLE_CELL),
P("Midbrain (CN III + red nucleus)", TABLE_CELL),
P("CN III palsy", TABLE_CELL),
P("Hemiataxia (red nucleus); no hemiplegia", TABLE_CELL)],
[P("Millard-Gubler\n(Ventral pons)", TABLE_CELL_C),
P("Basilar artery branches", TABLE_CELL),
P("Pons (CN VI + VII)", TABLE_CELL),
P("CN VI (medial deviation) + CN VII (LMN facial)", TABLE_CELL),
P("Hemiplegia (CST)", TABLE_CELL)],
[P("Foville's\n(Dorsal pons)", TABLE_CELL_C),
P("Basilar branches", TABLE_CELL),
P("Pons (paramedian)", TABLE_CELL),
P("CN VI + VII + ipsilateral gaze palsy (PPRF)", TABLE_CELL),
P("Hemiplegia", TABLE_CELL)],
[P("Lateral Medullary\n(Wallenberg)", TABLE_CELL_C),
P("PICA (or vertebral artery)", TABLE_CELL),
P("Lateral medulla", TABLE_CELL),
P("CN V (facial pain/temp), IX/X (hoarse, dysphagia), XI, Horner's, cerebellar (ataxia, nystagmus)", TABLE_CELL),
P("Pain/temp loss (body) - spinothalamic", TABLE_CELL)],
[P("Medial Medullary\n(Dejerine)", TABLE_CELL_C),
P("Anterior spinal artery / vertebral branches", TABLE_CELL),
P("Medial medulla", TABLE_CELL),
P("CN XII (tongue deviates ipsilateral)", TABLE_CELL),
P("Hemiplegia (CST) + DCML sensory loss (vibration/proprioception)", TABLE_CELL)],
]
t6 = Table(bs_data, colWidths=[2.6*cm, 2.4*cm, 2.4*cm, 4.2*cm, 4.2*cm])
ts6 = tbl_style(C_ORANGE)
ts6.add("ROWBACKGROUNDS", (0,1), (-1,-1), [C_ORANGE_LIGHT, C_WHITE])
t6.setStyle(ts6)
story.append(t6)
story.append(SP(6))
story.append(NoteBox(
"Wallenberg (Lateral Medullary) Syndrome mnemonic: PICA = Pain, Ipsilateral Cerebellar Ataxia. "
"Classic features: sudden onset vertigo + hiccups + ipsilateral Horner's + ipsilateral facial numbness "
"+ contralateral body pain/temp loss + dysphagia/hoarseness. 'Alternating' hemianesthesia = crossed face/body = LATERAL MEDULLA.",
bg=C_ORANGE_LIGHT, border=C_ORANGE, label="WALLENBERG - MUST KNOW"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7: CIRCLE OF WILLIS & VASCULAR TERRITORIES
# ══════════════════════════════════════════════════════════════════════════════
story += section("7. CEREBRAL VASCULAR TERRITORIES", C_GREEN)
story.append(P(
"The cerebral arteries supply distinct cortical and subcortical territories. "
"Recognizing the territory predicts the clinical syndrome.", BODY))
vasc_data = [
[P("Artery", TABLE_HDR), P("Territory", TABLE_HDR), P("Key Structures", TABLE_HDR),
P("Occlusion Syndrome", TABLE_HDR)],
[P("ACA\n(Ant. Cerebral)", TABLE_CELL_C),
P("Medial frontal and parietal lobes", TABLE_CELL),
P("Medial motor/sensory strip (leg area), SMA, cingulate", TABLE_CELL),
P("Contralateral leg > arm weakness/sensory loss; urinary incontinence; abulia", TABLE_CELL)],
[P("MCA\n(Mid. Cerebral)", TABLE_CELL_C),
P("Lateral frontal, parietal, temporal", TABLE_CELL),
P("Motor cortex (arm/face), Broca's (L F3), Wernicke's (L STG), internal capsule (lenticulostriate), basal ganglia", TABLE_CELL),
P("Contralateral hemi plegia (arm/face > leg), hemisensory loss, homonymous hemianopia; aphasia if dominant; neglect if non-dominant", TABLE_CELL)],
[P("PCA\n(Post. Cerebral)", TABLE_CELL_C),
P("Occipital lobe, posteromedial temporal, thalamus", TABLE_CELL),
P("Visual cortex, hippocampus, thalamus, midbrain (via perforators)", TABLE_CELL),
P("Contralateral homonymous hemianopia (macular sparing often); thalamic pain; memory loss; CN III palsy if midbrain perforators", TABLE_CELL)],
[P("Basilar Artery", TABLE_CELL_C),
P("Pons, cerebellum, midbrain (perforators)", TABLE_CELL),
P("ARAS (reticular), CST, sensory tracts, CN nuclei III-VIII", TABLE_CELL),
P("'Locked-in' syndrome (ventral pontine), coma, bilateral CN signs, cerebellar signs, quadriplegia", TABLE_CELL)],
[P("PICA\n(Post. Inf. Cerebellar)", TABLE_CELL_C),
P("Lateral medulla + inferior cerebellum", TABLE_CELL),
P("Lateral medullary structures, inferior cerebellar hemisphere", TABLE_CELL),
P("Wallenberg syndrome (see above) + cerebellar ataxia", TABLE_CELL)],
[P("AICA\n(Ant. Inf. Cerebellar)", TABLE_CELL_C),
P("Lateral pons + anterior-inferior cerebellum", TABLE_CELL),
P("CN VII, VIII nuclei, lateral pons, labyrinthine artery", TABLE_CELL),
P("Ipsilateral facial palsy, deafness, tinnitus, vertigo + cerebellar signs", TABLE_CELL)],
[P("SCA\n(Sup. Cerebellar)", TABLE_CELL_C),
P("Superior cerebellar hemisphere + pons", TABLE_CELL),
P("Superior cerebellum, lateral pons", TABLE_CELL),
P("Ipsilateral cerebellar ataxia, Horner's; contralateral pain/temp loss", TABLE_CELL)],
[P("Lenticulostriate\narteries (MCA branches)", TABLE_CELL_C),
P("Basal ganglia, internal capsule", TABLE_CELL),
P("Putamen, caudate, posterior IC limb", TABLE_CELL),
P("Lacunar infarcts: pure motor, pure sensory, ataxic hemiparesis, dysarthria-clumsy hand", TABLE_CELL)],
]
t7 = Table(vasc_data, colWidths=[2.4*cm, 3.0*cm, 4.6*cm, 5.8*cm])
ts7 = tbl_style(C_GREEN)
ts7.add("ROWBACKGROUNDS", (0,1), (-1,-1), [C_GREEN_LIGHT, C_WHITE])
t7.setStyle(ts7)
story.append(t7)
story.append(SP(6))
story.append(NoteBox(
"ACA = LEG (medial strip). MCA = ARM + FACE (lateral strip). "
"MCA occlusion = most common large vessel stroke. "
"Macular sparing in PCA territory infarct = because macula has dual blood supply (MCA + PCA). "
"Basilar artery thrombosis is life-threatening - 'locked-in' = aware but quadriplegic, communicate by blinking.",
bg=C_GREEN_LIGHT, border=C_GREEN, label="KEY CONCEPTS"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 8: VISUAL PATHWAY
# ══════════════════════════════════════════════════════════════════════════════
story += section("8. VISUAL PATHWAY & FIELD DEFECTS", C_MID_BLUE)
story.append(visual_pathway_diagram())
story.append(P("L LGN = Left Lateral Geniculate Nucleus. Red fibres = crossing nasal retinal fibres at chiasm.", CAPTION))
story.append(SP(6))
vp_data = [
[P("Lesion Site", TABLE_HDR), P("Field Defect", TABLE_HDR), P("Cause", TABLE_HDR)],
[P("Optic nerve (before chiasm)", TABLE_CELL),
P("Monocular blindness / monocular visual loss in that eye only", TABLE_CELL),
P("Optic neuritis (MS), AION, trauma, optic nerve tumour", TABLE_CELL)],
[P("Optic chiasm (centre)", TABLE_CELL),
P("Bitemporal hemianopia (lose outer fields both eyes) - 'tunnel vision'", TABLE_CELL),
P("Pituitary adenoma (most common), craniopharyngioma, meningioma", TABLE_CELL)],
[P("Optic chiasm (lateral)", TABLE_CELL),
P("Binasal hemianopia (rare - lose inner fields)", TABLE_CELL),
P("Bilateral ICA aneurysms compressing from outside", TABLE_CELL)],
[P("Optic tract (post-chiasm)", TABLE_CELL),
P("Contralateral homonymous hemianopia (incongruous)", TABLE_CELL),
P("Temporal lobe lesion, vascular", TABLE_CELL)],
[P("Meyer's loop (temporal lobe - optic radiation)", TABLE_CELL),
P("Contralateral superior quadrantanopia ('pie in the sky')", TABLE_CELL),
P("Temporal lobe lesion (epilepsy surgery, tumour)", TABLE_CELL)],
[P("Parietal optic radiation", TABLE_CELL),
P("Contralateral inferior quadrantanopia ('pie on the floor')", TABLE_CELL),
P("Parietal lobe lesion", TABLE_CELL)],
[P("Visual cortex (occipital lobe)", TABLE_CELL),
P("Contralateral homonymous hemianopia WITH macular sparing", TABLE_CELL),
P("PCA territory infarct (most common)", TABLE_CELL)],
[P("Bilateral occipital lobes", TABLE_CELL),
P("Cortical blindness (Anton's syndrome - patient denies blindness)", TABLE_CELL),
P("Top of basilar syndrome, bilateral PCA infarcts", TABLE_CELL)],
]
t8 = Table(vp_data, colWidths=[4.0*cm, 5.8*cm, 5.0*cm])
ts8 = tbl_style(C_MID_BLUE)
t8.setStyle(ts8)
story.append(t8)
story.append(SP(6))
story.append(NoteBox(
"Memory hook: Lesions ANTERIOR to chiasm = monocular. AT chiasm = bitemporal (pituitary!). "
"POSTERIOR to chiasm = homonymous defects (same side field loss in BOTH eyes). "
"Macular sparing = PCA stroke (dual blood supply to macula from MCA collaterals).",
bg=C_LIGHT_BLUE, border=C_MID_BLUE, label="VISUAL FIELDS - RULE"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 9: BASAL GANGLIA & CEREBELLUM
# ══════════════════════════════════════════════════════════════════════════════
story += section("9. BASAL GANGLIA, THALAMUS & CEREBELLUM", C_TEAL)
story.append(P("<b>Basal Ganglia Circuits</b>", SUBSEC))
story.append(P(
"The basal ganglia modulate movement through direct (facilitatory) and indirect (inhibitory) pathways, "
"both funneling through the thalamus to motor cortex.", BODY))
bg_data = [
[P("Structure", TABLE_HDR), P("Function", TABLE_HDR), P("Disease if Damaged", TABLE_HDR), P("Key Features", TABLE_HDR)],
[P("Striatum\n(Putamen + Caudate)", TABLE_CELL_C),
P("Input station; direct and indirect pathway modulation", TABLE_CELL),
P("Huntington's (caudate atrophy), Hemiballismus (subthalamic nucleus)", TABLE_CELL),
P("Dopamine (D1: direct; D2: indirect). Caudate: cognitive. Putamen: motor.", TABLE_CELL)],
[P("Substantia Nigra\npars compacta (SNc)", TABLE_CELL_C),
P("Dopamine source to striatum (nigrostriatal pathway)", TABLE_CELL),
P("Parkinson's disease (>70% depletion)", TABLE_CELL),
P("Loss -> increased inhibition of thalamus -> reduced movement (hypokinesia)", TABLE_CELL)],
[P("Subthalamic\nNucleus (STN)", TABLE_CELL_C),
P("Indirect pathway - inhibits movement", TABLE_CELL),
P("Hemiballismus (contralateral to lesion)", TABLE_CELL),
P("Unilateral STN lesion -> wild flinging movements of contralateral limb", TABLE_CELL)],
[P("Globus Pallidus\nInterna (GPi)", TABLE_CELL_C),
P("Output of BG - inhibits thalamus", TABLE_CELL),
P("Target for DBS in Parkinson's and dystonia", TABLE_CELL),
P("GABA-ergic; direct pathway reduces GPi -> disinhibits thalamus -> promotes movement", TABLE_CELL)],
[P("Putamen\n(dominant atrophy)", TABLE_CELL_C),
P("Motor aspects of striatum", TABLE_CELL),
P("Multiple system atrophy - parkinsonism type (MSA-P)", TABLE_CELL),
P("'Hot cross bun' sign on MRI pons + putaminal rim sign", TABLE_CELL)],
]
t9 = Table(bg_data, colWidths=[2.8*cm, 3.8*cm, 4.0*cm, 5.2*cm])
t9.setStyle(tbl_style(C_TEAL))
story.append(t9)
story.append(SP(6))
story.append(P("<b>Cerebellum</b>", SUBSEC))
cereb_data = [
[P("Zone", TABLE_HDR), P("Function", TABLE_HDR), P("Lesion Effects", TABLE_HDR), P("Conditions", TABLE_HDR)],
[P("Vermis\n(midline)", TABLE_CELL_C),
P("Truncal balance, gait", TABLE_CELL),
P("Truncal ataxia, wide-based gait, cannot stand with feet together", TABLE_CELL),
P("Alcohol (vermis most sensitive), MS, tumour", TABLE_CELL)],
[P("Lateral\nhemispheres", TABLE_CELL_C),
P("Limb coordination (SAME side)", TABLE_CELL),
P("IPSILATERAL limb ataxia, intention tremor, dysmetria, dysdiadochokinesia", TABLE_CELL),
P("Cerebellar hemisphere infarct, tumour, MS, paraneoplastic", TABLE_CELL)],
[P("Flocculo-nodular\nlobe", TABLE_CELL_C),
P("Vestibular integration, eye movement", TABLE_CELL),
P("Nystagmus (direction away from lesion), vertigo, nausea", TABLE_CELL),
P("Medulloblastoma (children - vermis/flocculonodular)", TABLE_CELL)],
]
t10 = Table(cereb_data, colWidths=[2.4*cm, 3.8*cm, 5.2*cm, 4.4*cm])
t10.setStyle(tbl_style(C_TEAL))
story.append(t10)
story.append(SP(6))
story.append(NoteBox(
"DANISH mnemonic for cerebellar signs: Dysdiadochokinesia, Ataxia (gait), Nystagmus, Intention tremor, "
"Slurred speech (scanning dysarthria), Hypotonia. "
"Cerebellum = IPSILATERAL signs (no crossing). Basal ganglia = CONTRALATERAL (except rare ipsilateral in STN lesion for hemiballismus).",
bg=C_TEAL_LIGHT, border=C_TEAL, label="MNEMONIC + RULE"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 10: THALAMIC NUCLEI
# ══════════════════════════════════════════════════════════════════════════════
story += section("10. THALAMIC NUCLEI & CLINICAL RELEVANCE", C_AMBER)
thal_data = [
[P("Nucleus", TABLE_HDR), P("Afferent from", TABLE_HDR), P("Projects to", TABLE_HDR), P("Function / Lesion", TABLE_HDR)],
[P("VPL\n(Ventral Posterolateral)", TABLE_CELL_C),
P("Medial lemniscus + spinothalamic (body sensation)", TABLE_CELL),
P("Primary somatosensory cortex (S1), post-central gyrus", TABLE_CELL),
P("Body sensation relay. Lesion: contralateral hemisensory loss. Thalamic pain syndrome (Dejerine-Roussy) after thalamic infarct.", TABLE_CELL)],
[P("VPM\n(Ventral Posteromedial)", TABLE_CELL_C),
P("Trigeminal lemniscus (face sensation)", TABLE_CELL),
P("S1 (face area)", TABLE_CELL),
P("Face sensation relay. Lesion: contralateral facial sensory loss.", TABLE_CELL)],
[P("VL\n(Ventral Lateral)", TABLE_CELL_C),
P("Cerebellum (dentate nucleus), GPi", TABLE_CELL),
P("Motor cortex (precentral gyrus)", TABLE_CELL),
P("Motor coordination relay. Target for DBS in tremor (essential tremor, Parkinson's).", TABLE_CELL)],
[P("VA\n(Ventral Anterior)", TABLE_CELL_C),
P("GPi, SNr (basal ganglia output)", TABLE_CELL),
P("Pre-motor and supplementary motor cortex", TABLE_CELL),
P("Modulates motor initiation via BG-thalamo-cortical loop.", TABLE_CELL)],
[P("Pulvinar", TABLE_CELL_C),
P("Superior colliculus, visual cortex", TABLE_CELL),
P("Association cortex, parietal", TABLE_CELL),
P("Visual attention, multisensory integration. Enlarged in some metabolic diseases.", TABLE_CELL)],
[P("MD\n(Mediodorsal)", TABLE_CELL_C),
P("Amygdala, olfactory cortex, prefrontal", TABLE_CELL),
P("Prefrontal cortex", TABLE_CELL),
P("Memory, emotion, planning. Damaged in Wernicke-Korsakoff (bilateral MD infarcts).", TABLE_CELL)],
[P("Anterior nucleus", TABLE_CELL_C),
P("Mammillary bodies (via mammillothalamic tract)", TABLE_CELL),
P("Cingulate cortex", TABLE_CELL),
P("Papez circuit - memory. Damaged in Korsakoff's; mammillothalamic tract damage.", TABLE_CELL)],
[P("LGN\n(Lateral Geniculate)", TABLE_CELL_C),
P("Optic tract", TABLE_CELL),
P("Primary visual cortex (V1)", TABLE_CELL),
P("Visual relay. Lesion: contralateral homonymous hemianopia.", TABLE_CELL)],
[P("MGN\n(Medial Geniculate)", TABLE_CELL_C),
P("Inferior colliculus", TABLE_CELL),
P("Primary auditory cortex (Heschl's gyri)", TABLE_CELL),
P("Auditory relay.", TABLE_CELL)],
]
t11 = Table(thal_data, colWidths=[2.2*cm, 3.8*cm, 3.4*cm, 6.4*cm])
t11.setStyle(tbl_style(C_AMBER))
story.append(t11)
story.append(SP(6))
story.append(NoteBox(
"Thalamic stroke (VPL): Pure sensory stroke or thalamic pain (burning, lancinating contralateral body pain). "
"Korsakoff's syndrome: mamillary body atrophy + anterior/MD thalamic nuclei damage -> anterograde amnesia + confabulation. "
"DBS targets: VL thalamus for tremor; STN or GPi for Parkinson's motor symptoms.",
bg=C_AMBER_LIGHT, border=C_AMBER, label="CLINICAL PEARLS"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 11: LIMBIC SYSTEM & MEMORY
# ══════════════════════════════════════════════════════════════════════════════
story += section("11. LIMBIC SYSTEM, MEMORY & LANGUAGE", C_PURPLE)
story.append(P("<b>Papez Circuit (Memory)</b>", SUBSEC))
story.append(P(
"Hippocampus → Fornix → Mammillary bodies → Mammillothalamic tract → "
"Anterior thalamus → Cingulate cortex → Entorhinal cortex → Hippocampus", BODY))
story.append(SP(4))
story.append(P("Damage at any point disrupts declarative/episodic memory formation:", BODY))
limb_data = [
[P("Structure", TABLE_HDR), P("Lesion", TABLE_HDR), P("Result", TABLE_HDR)],
[P("Hippocampus (bilateral)", TABLE_CELL), P("Herpes encephalitis, hypoxia, Alzheimer's", TABLE_CELL),
P("Anterograde amnesia (cannot form new memories); retrograde amnesia (recent > remote)", TABLE_CELL)],
[P("Mammillary bodies", TABLE_CELL), P("Wernicke-Korsakoff (thiamine def)", TABLE_CELL),
P("Anterograde amnesia + confabulation + personality change", TABLE_CELL)],
[P("Amygdala (bilateral)", TABLE_CELL), P("Kluver-Bucy syndrome (bilateral temporal lobe damage)", TABLE_CELL),
P("Hyperorality, hypersexuality, placidity, visual agnosia, memory impairment", TABLE_CELL)],
[P("Fornix", TABLE_CELL), P("Colloid cyst of 3rd ventricle (obstructs foramen of Monro)", TABLE_CELL),
P("Memory impairment, sudden death if large (hydrocephalus)", TABLE_CELL)],
]
t12 = Table(limb_data, colWidths=[3.2*cm, 4.8*cm, 7.8*cm])
t12.setStyle(tbl_style(C_PURPLE))
story.append(t12)
story.append(SP(8))
story.append(P("<b>Language Areas (Dominant Hemisphere = Left in >95%)</b>", SUBSEC))
lang_data = [
[P("Area", TABLE_HDR), P("Location", TABLE_HDR), P("Function", TABLE_HDR), P("Lesion = Aphasia Type", TABLE_HDR)],
[P("Broca's area\n(44, 45)", TABLE_CELL_C),
P("Inferior frontal gyrus (IFG), dominant", TABLE_CELL),
P("Speech production, motor programming of speech", TABLE_CELL),
P("Broca's (expressive) aphasia: non-fluent, effortful speech; comprehension intact; frustrated patient", TABLE_CELL)],
[P("Wernicke's area\n(22)", TABLE_CELL_C),
P("Posterior superior temporal gyrus (STG), dominant", TABLE_CELL),
P("Language comprehension, word selection", TABLE_CELL),
P("Wernicke's (receptive) aphasia: fluent but paraphasic, poor comprehension, unaware of errors", TABLE_CELL)],
[P("Arcuate\nFasciculus", TABLE_CELL_C),
P("White matter connecting Broca's and Wernicke's", TABLE_CELL),
P("Connects expression + comprehension areas", TABLE_CELL),
P("Conduction aphasia: fluent speech, good comprehension, POOR repetition (the hallmark)", TABLE_CELL)],
[P("Angular Gyrus\n(39)", TABLE_CELL_C),
P("Posterior parietal (junction TPO)", TABLE_CELL),
P("Reading, writing, visual-language integration", TABLE_CELL),
P("Alexia with agraphia; Gerstmann's syndrome (if dominant) - finger agnosia, agraphia, acalculia, L-R confusion", TABLE_CELL)],
]
t13 = Table(lang_data, colWidths=[2.4*cm, 3.4*cm, 3.8*cm, 6.2*cm])
t13.setStyle(tbl_style(C_PURPLE))
story.append(t13)
story.append(SP(6))
story.append(NoteBox(
"Key: Fluency + Comprehension + Repetition. "
"Broca's = non-fluent (frontal lesion, struggles to speak). Wernicke's = fluent jargon (temporal, doesn't understand). "
"Global aphasia = large MCA territory: non-fluent + poor comprehension + poor repetition. "
"Non-dominant hemisphere: neglect, aprosodia, dressing apraxia.",
bg=C_PURPLE_LIGHT, border=C_PURPLE, label="APHASIA QUICK SUMMARY"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 12: AUTONOMIC & HYPOTHALAMUS
# ══════════════════════════════════════════════════════════════════════════════
story += section("12. AUTONOMIC PATHWAYS & HYPOTHALAMUS", C_GREEN)
auto_data = [
[P("Pathway", TABLE_HDR), P("Origin", TABLE_HDR), P("Function", TABLE_HDR), P("Clinical Relevance", TABLE_HDR)],
[P("Sympathetic\n(Thoracolumbar T1-L2)", TABLE_CELL_C),
P("Lateral horn (IML column) T1-L2 -> superior cervical ganglion for head", TABLE_CELL),
P("Fight/flight: dilates pupils, tachycardia, vasoconstriction, inhibits GI", TABLE_CELL),
P("Horner's syndrome (ptosis + miosis + anhidrosis) = interruption of oculosympathetic pathway (T1 root, superior cervical ganglion, or carotid plexus)", TABLE_CELL)],
[P("Parasympathetic\n(Craniosacral)", TABLE_CELL_C),
P("CN III (Edinger-Westphal), VII, IX, X nuclei; S2-S4 sacral cord", TABLE_CELL),
P("Rest/digest: constricts pupils, bradycardia, GI motility, erection", TABLE_CELL),
P("CN III palsy: dilated pupil (PS fibres on outside of nerve - compressed first by aneurysm/herniation)", TABLE_CELL)],
[P("Hypothalamus", TABLE_CELL_C),
P("Integrates autonomic + endocrine + behavioral functions", TABLE_CELL),
P("Temperature, hunger, thirst, circadian rhythm, ADH, oxytocin", TABLE_CELL),
P("Lesions: diabetes insipidus (supraoptic/paraventricular), Frohlich's syndrome, Diencephalic syndrome (children)", TABLE_CELL)],
]
t14 = Table(auto_data, colWidths=[2.6*cm, 3.6*cm, 4.0*cm, 5.6*cm])
t14.setStyle(tbl_style(C_GREEN))
story.append(t14)
story.append(SP(6))
story.append(NoteBox(
"Horner's Syndrome = ptosis (partial) + miosis + anhidrosis + enophthalmos (apparent). "
"Localizing Horner's: Central (hypothalamus to C8-T2) = stroke, MS, syrinx. "
"Preganglionic (T1 root to superior cervical ganglion) = Pancoast tumour, neck dissection. "
"Postganglionic (SCG to eye) = carotid dissection/aneurysm, cluster headache. "
"Cocaine test: no dilation = confirms Horner's. Hydroxyamphetamine: no dilation = postganglionic.",
bg=C_GREEN_LIGHT, border=C_GREEN, label="HORNER'S SYNDROME"))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 13: CLINICAL LOCALIZATION SUMMARY
# ══════════════════════════════════════════════════════════════════════════════
story += section("13. RAPID LESION LOCALIZATION GUIDE", C_DARK_BLUE)
story.append(P(
"Use this table as a fast reference to identify the lesion site from the clinical picture.", BODY))
loc_data = [
[P("Finding", TABLE_HDR), P("Likely Localization", TABLE_HDR), P("Key Distinguishing Feature", TABLE_HDR)],
[P("Contralateral hemiplegia + ipsilateral CN III palsy", TABLE_CELL),
P("Midbrain (Weber's syndrome)", TABLE_CELL),
P("CN III at midbrain level; pyramids still intact (no decussation yet)", TABLE_CELL)],
[P("Contralateral hemiplegia + ipsilateral CN VI + VII palsy", TABLE_CELL),
P("Pons (Millard-Gubler)", TABLE_CELL),
P("CN VI (abducens) + CN VII at pontine level", TABLE_CELL)],
[P("Ipsilateral facial pain/temp + contralateral body pain/temp + Horner's + vertigo + dysphagia", TABLE_CELL),
P("Lateral medulla (Wallenberg - PICA)", TABLE_CELL),
P("'Crossed' face-body dissociation hallmark", TABLE_CELL)],
[P("Ipsilateral CN XII + contralateral hemiplegia + vibration loss", TABLE_CELL),
P("Medial medulla (Dejerine)", TABLE_CELL),
P("ASA territory; pyramid + medial lemniscus + CN XII", TABLE_CELL)],
[P("Bitemporal hemianopia", TABLE_CELL),
P("Optic chiasm (pituitary fossa)", TABLE_CELL),
P("First think pituitary adenoma", TABLE_CELL)],
[P("Macular-sparing homonymous hemianopia", TABLE_CELL),
P("Occipital cortex (PCA infarct)", TABLE_CELL),
P("Macular sparing = dual blood supply", TABLE_CELL)],
[P("Leg weakness + bladder/bowel incontinence + no arm weakness", TABLE_CELL),
P("ACA territory or parasagittal meningioma", TABLE_CELL),
P("Medial motor strip (leg area)", TABLE_CELL)],
[P("Ipsilateral limb ataxia + intention tremor (no weakness)", TABLE_CELL),
P("Ipsilateral cerebellar hemisphere", TABLE_CELL),
P("Cerebellum: IPSILATERAL signs", TABLE_CELL)],
[P("Saddle anaesthesia + urinary retention + preserved leg power", TABLE_CELL),
P("Conus medullaris or cauda equina", TABLE_CELL),
P("Conus = UMN + LMN; Cauda = pure LMN", TABLE_CELL)],
[P("Ipsilateral vibration/prop loss + contralateral pain/temp loss + ipsilateral UMN", TABLE_CELL),
P("Ipsilateral spinal cord hemisection (Brown-Séquard)", TABLE_CELL),
P("Classic triad of hemisection", TABLE_CELL)],
[P("Bilateral vibration loss + UMN signs + absent ankle jerks", TABLE_CELL),
P("Posterior + lateral cord (SCD)", TABLE_CELL),
P("Think B12 deficiency", TABLE_CELL)],
[P("Non-fluent aphasia + right arm > leg weakness + right facial droop", TABLE_CELL),
P("Left MCA territory (dominant hemisphere)", TABLE_CELL),
P("Broca's area + motor cortex arm area together", TABLE_CELL)],
[P("Pure sensory stroke (contralateral hemisensory)", TABLE_CELL),
P("VPL thalamus or posterior internal capsule", TABLE_CELL),
P("Small vessel lacunar infarct", TABLE_CELL)],
[P("Miosis + ptosis + anhidrosis (partial ptosis)", TABLE_CELL),
P("Horner's syndrome - ipsilateral sympathetic chain", TABLE_CELL),
P("Localize first-order (central), second-order (preganglionic), third-order (postganglionic)", TABLE_CELL)],
]
t15 = Table(loc_data, colWidths=[5.5*cm, 4.2*cm, 6.1*cm])
ts15 = tbl_style(C_DARK_BLUE)
ts15.add("ROWBACKGROUNDS", (0,1), (-1,-1), [C_LIGHT_BLUE, C_WHITE])
t15.setStyle(ts15)
story.append(t15)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 14: QUICK MNEMONICS
# ══════════════════════════════════════════════════════════════════════════════
story += section("14. ESSENTIAL MNEMONICS & MEMORY HOOKS", C_PURPLE)
mnemonics = [
("CN Types (I-XII)", "Some Say Marry Money But My Brother Says Big Brains Matter\n(S=Sensory, M=Motor, B=Both) → S,S,M,M,B,M,B,S,B,B,M,M"),
("CN Exit Foramina (trigeminal)", "Standing Room Only (V1=Superior orbital fissure, V2=Foramen Rotundum, V3=foramen Ovale)"),
("Cerebellar signs", "DANISH: Dysdiadochokinesia, Ataxia, Nystagmus, Intention tremor, Slurred speech, Hypotonia"),
("Papez circuit", "HMMAC: Hippocampus → Mammillary bodies → Mammillothalamic tract → Anterior thalamus → Cingulate"),
("UMN vs LMN", "UMN = UP (tone UP, reflexes UP, plantar UP/Babinski). LMN = DOWN (tone ↓, reflexes ↓, wasting)"),
("Brown-Séquard", "IPSILATERAL: motor (UMN) + DCML. CONTRALATERAL: pain + temp"),
("Wallenberg's PICA", "PICA = Pain/temp crossed, Ipsilateral Cerebellar Ataxia, Horner's; plus vertigo, dysphagia"),
("Visual fields", "Pre-chiasm = monocular. At chiasm = bitemporal. Post-chiasm = homonymous. Occipital = macular sparing"),
("Aphasia quick", "Broca's = Broken/non-fluent speech (frontal). Wernicke's = Wordy/fluent nonsense (temporal). Conduction = Can't repeat"),
("Gerstmann's (angular gyrus)", "ALDA: Agraphia, alexia, Left-right confusion, Dyscalculia (acalculia), finger Agnosia"),
("Thalamic nuclei relay", "VPL = body sensation. VPM = face. VL = motor (cerebellum). VA = basal ganglia. LGN = vision. MGN = hearing"),
("Horner's signs", "PAM: Ptosis (partial, Muller's), Anhidrosis, Miosis"),
("Jugular foramen CN", "Glosso-Vagal-Accessory (IX, X, XI) - 'Going Very Quietly through jugular'"),
("Lacunar syndromes", "Pure Motor (posterior IC/pons), Pure Sensory (thalamus VPL), Ataxic Hemiparesis (pons/IC), Dysarthria-Clumsy Hand (pons)"),
]
for title, text in mnemonics:
row = Table(
[[P(f"<b>{title}</b>", S("mn_t", fontSize=8.5, fontName="Helvetica-Bold", textColor=C_PURPLE, leading=12)),
P(text, S("mn_b", fontSize=8.5, fontName="Helvetica", textColor=C_BLACK, leading=12, alignment=TA_LEFT))]],
colWidths=[4.0*cm, 11.8*cm]
)
row.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), C_PURPLE_LIGHT),
("BACKGROUND", (1,0), (1,0), C_WHITE),
("BOX", (0,0), (-1,-1), 0.5, C_PURPLE),
("LINEAFTER", (0,0), (0,0), 0.5, C_PURPLE),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(row)
story.append(SP(3))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# FINAL PAGE: REFERENCE CARD
# ══════════════════════════════════════════════════════════════════════════════
story += section("QUICK REFERENCE CARD - IMPORTANT NUMBERS & LANDMARKS", C_DARK_BLUE)
ref_data = [
[P("Fact", TABLE_HDR), P("Detail", TABLE_HDR)],
[P("Corticospinal fibres cross", TABLE_CELL), P("Pyramidal decussation at caudal medulla (only 85-90% cross; 10-15% stay ipsilateral as anterior CST)", TABLE_CELL)],
[P("Spinothalamic fibres cross", TABLE_CELL), P("Within 1-2 spinal cord segments of entry (via anterior white commissure)", TABLE_CELL)],
[P("DCML fibres cross", TABLE_CELL), P("In the medulla at nucleus gracilis (lower limb) and cuneatus (upper limb)", TABLE_CELL)],
[P("Blood-brain barrier", TABLE_CELL), P("Tight junctions of endothelial cells + astrocyte endfeet. Absent in circumventricular organs (area postrema, OVLT, SFO)", TABLE_CELL)],
[P("Watershed zones", TABLE_CELL), P("ACA-MCA junction (parasagittal), MCA-PCA junction (posterior parieto-occipital). Vulnerable in hypotension/cardiac arrest", TABLE_CELL)],
[P("CSF production", TABLE_CELL), P("Choroid plexus in lateral, 3rd and 4th ventricles. 500mL/day produced; 150mL in circulation at any time", TABLE_CELL)],
[P("CSF drainage", TABLE_CELL), P("Arachnoid granulations (Pacchionian bodies) into superior sagittal sinus. Also spinal roots, lymphatics", TABLE_CELL)],
[P("Lumbar puncture level", TABLE_CELL), P("L3-L4 or L4-L5 (below conus medullaris at L1-L2 in adults). Iliac crest = L4 landmark", TABLE_CELL)],
[P("Foramen of Monro", TABLE_CELL), P("Connects lateral to 3rd ventricle. Colloid cyst here = obstructive hydrocephalus + memory loss", TABLE_CELL)],
[P("Aqueduct of Sylvius", TABLE_CELL), P("Connects 3rd to 4th ventricle. Stenosis = non-communicating hydrocephalus (most common cause in adults)", TABLE_CELL)],
[P("CN IV unique features", TABLE_CELL), P("Only CN that: exits posteriorly, decussates before exit, has longest intracranial course", TABLE_CELL)],
[P("CN VI false localizing sign", TABLE_CELL), P("Raised ICP stretches CN VI as it runs along clivus → abducens palsy even if no pontine lesion", TABLE_CELL)],
[P("Dominant hemisphere", TABLE_CELL), P("Left in >95% right-handers and ~70% left-handers. Language (Broca 44/45, Wernicke 22), praxis, calculation", TABLE_CELL)],
[P("Non-dominant hemisphere", TABLE_CELL), P("Right in most. Visuospatial, prosody (emotional tone of speech), dressing apraxia, spatial neglect (right parietal)", TABLE_CELL)],
[P("Uncal herniation signs", TABLE_CELL), P("Progressive: ipsilateral CN III palsy (PS fibers outside → dilated pupil first) → contralateral hemiplegia → coma. Kernohan's notch = ipsilateral hemiplegia (false localizing)", TABLE_CELL)],
[P("Tonsillar herniation", TABLE_CELL), P("Cerebellar tonsils through foramen magnum. Signs: apnea, bradycardia, hypertension (Cushing's triad = late sign of raised ICP)", TABLE_CELL)],
]
t16 = Table(ref_data, colWidths=[4.0*cm, 11.8*cm])
ts16 = tbl_style(C_DARK_BLUE)
ts16.add("ROWBACKGROUNDS", (0,1), (-1,-1), [C_LIGHT_BLUE, C_WHITE])
t16.setStyle(ts16)
story.append(t16)
story.append(SP(10))
story.append(HR(C_GREY_LINE, 1))
story.append(SP(4))
story.append(P(
"Orris Medical Reference | Essential Neuroanatomy for CNS Disorders | 2026 | "
"For educational use. Always verify clinical information with current guidelines.",
CAPTION))
# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /tmp/workspace/neuroanatomy-pdf && python build_pdf.py 2>&1
~/neuroanatomy-pdf/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/neuroanatomy-pdf/build_pdf.py'
cd /tmp/workspace/neuroanatomy-pdf && python build_pdf.py 2>&1
ls -lh /tmp/workspace/neuroanatomy-pdf/Neuroanatomy_Quick_Reference.pdf
Neuroanatomy Quick Reference
PDF Document · PDF
| Section | Contents |
|---|---|
| 1. Major Tracts | Full table: DCML, CST, spinothalamic, rubrospinal, vestibulospinal - location, modality, crossing level, clinical loss |
| 2. Spinal Cord Syndromes | Brown-Séquard, Central Cord, Anterior/Posterior Cord, SCD, Conus, Cauda Equina - all compared side by side |
| 3. UMN vs LMN | Tone, power, reflexes, wasting, fasciculations, distribution - full comparison table |
| 4. Internal Capsule | Every limb and genu mapped: fibres carried + deficit if damaged |
| 5. Cranial Nerves | All 12 CNs: type, nucleus, exit foramen, and key clinical disorders |
| 6. Brainstem Syndromes | Weber, Benedikt, Claude, Millard-Gubler, Foville, Wallenberg, Dejerine |
| 7. Vascular Territories | ACA, MCA, PCA, Basilar, PICA, AICA, SCA, lenticulostriates with occlusion syndromes |
| 8. Visual Pathway | Schematic diagram + field defect table for every level pre to post-chiasm |
| 9. Basal Ganglia & Cerebellum | BG circuits, Parkinson's/Huntington's, cerebellar zones + DANISH mnemonic |
| 10. Thalamic Nuclei | VPL, VPM, VL, VA, MD, Anterior, LGN, MGN - function + clinical relevance |
| 11. Limbic System & Language | Papez circuit, aphasia types (Broca/Wernicke/Conduction), Gerstmann's |
| 12. Autonomic & Hypothalamus | Sympathetic/parasympathetic pathways, Horner's localization |
| 13. Lesion Localization Guide | 14 clinical patterns mapped to anatomical sites |
| 14. Mnemonics + Reference Card | All key memory hooks + CSF, herniation syndromes, watershed zones |