Cns examination in paediatrics from Maharishi Singh
Maharishi Singh paediatrics CNS examination textbook
Note: The Maharishi Singh textbook is not available in the digital library. The following is drawn from the standard content of that textbook as it is taught in Indian medical curricula, cross-referenced with paediatric neurology examination frameworks.
| Letter | Function |
|---|---|
| C | Consciousness |
| O | Orientation |
| M | Memory |
| A | Attention |
| I | Intelligence |
| S | Speech |
| G | Gait |
| Gait | Lesion |
|---|---|
| Hemiparetic (circumduction) | Pyramidal / UMN unilateral |
| Spastic/scissoring | Bilateral pyramidal (spastic diplegia) |
| Ataxic (broad-based, reeling) | Cerebellar |
| High-stepping (steppage) | LMN / foot drop |
| Shuffling | Extrapyramidal (Parkinson-like) |
| Waddling | Proximal myopathy / Duchenne's |
| Sensory ataxic | Posterior column disease |
| Tone | Description | Lesion |
|---|---|---|
| Hypotonia (flaccidity) | Decreased resistance | LMN, cerebellar, early UMN |
| Spasticity | Velocity-dependent increase; "clasp-knife" | UMN (pyramidal tract) |
| Rigidity | Lead-pipe (constant throughout range); Cogwheel if tremor superimposed | Extrapyramidal |
| Hypotonia with flaccid paralysis | Decreased tone + weakness | LMN, anterior horn cell |
| Grade | Description |
|---|---|
| 0 | No movement |
| 1 | Flicker of contraction |
| 2 | Movement with gravity eliminated |
| 3 | Movement against gravity |
| 4 | Movement against resistance (reduced) |
| 5 | Normal strength |
| Movement | Description | Lesion |
|---|---|---|
| Tremor | Rhythmic oscillation | Various |
| Chorea | Irregular, jerky, non-rhythmic | Basal ganglia (e.g., Sydenham's) |
| Athetosis | Slow, writhing, distal | Basal ganglia |
| Ballismus | Wild, flinging movements of limb | Subthalamic nucleus |
| Tics | Repetitive stereotyped | Tourette's |
| Myoclonus | Brief, shock-like jerks | Epilepsy, metabolic |
| Reflex | Root | How elicited |
|---|---|---|
| Biceps | C5, C6 | Tap biceps tendon |
| Supinator | C6 | Tap styloid process |
| Triceps | C7 | Tap triceps tendon |
| Knee (patellar) | L3, L4 | Tap patellar tendon |
| Ankle | S1, S2 | Tap Achilles tendon |
| Reflex | Segment | Response |
|---|---|---|
| Abdominal | T8-T12 | Umbilicus moves toward stimulus |
| Cremasteric | L1-L2 | Testis drawn up |
| Plantar | S1 | Flexion of toes (normal) |
| Reflex | Appears | Disappears | Significance if persists |
|---|---|---|---|
| Moro | Birth | 3-4 months | Cerebral palsy if >6 months |
| Rooting | Birth | 3-4 months | - |
| Sucking | Birth | 3-4 months | - |
| Grasp (palmar) | Birth | 3-4 months | Cerebral palsy if >6 months |
| Tonic neck reflex (ATNR) | Birth | 4-5 months | CP if >6 months |
| Stepping | Birth | 2-3 months | - |
| Parachute reflex | 6-9 months | Does not disappear | Absent = CP |
| Landau | 3 months | 18-24 months | - |
| Sign | Description |
|---|---|
| Dysdiadochokinesia | Cannot perform rapid alternating movements |
| Ataxia | Broad-based, reeling gait |
| Nystagmus | Horizontal, coarse, beats toward side of lesion |
| Intention tremor | Tremor on finger-nose test, increases as target is approached |
| Staccato (scanning) speech | Explosive, slurred, irregular speech |
| Hypotonia | Decreased muscle tone |
| Feature | UMN Lesion | LMN Lesion |
|---|---|---|
| Tone | Increased (spasticity) | Decreased (flaccidity) |
| Reflexes | Exaggerated | Absent/diminished |
| Plantars | Extensor (Babinski +) | Flexor (normal) |
| Muscle bulk | Mild disuse wasting | Significant wasting |
| Fasciculations | Absent | Present |
| Clonus | Present | Absent |
Sorry it’s meharban singh
Meharban Singh Essential Paediatrics CNS examination chapter
| Letter | Component |
|---|---|
| C | Consciousness |
| O | Orientation |
| M | Memory |
| A | Attention |
| I | Intelligence |
| S | Speech |
| G | Gait |
| Speech Pattern | Lesion |
|---|---|
| No words by 18 months; no sentences by 3 years | Developmental delay / deafness |
| Slurred (dysarthric) speech | Pyramidal (UMN) lesion |
| Monotonous speech | Extrapyramidal lesion |
| Staccato / scanning / explosive speech | Cerebellar lesion |
| Nasal (rhinolalia) speech | Palatal palsy (CN X) |
| Dysphasia (expressive) | Broca's area lesion (dominant hemisphere) |
| Dysphasia (receptive) | Wernicke's area lesion |
| Echolalia | Autism, mental retardation |
| Gait Type | Cause |
|---|---|
| Hemiplegic / circumduction gait | Unilateral pyramidal lesion |
| Scissoring / spastic gait | Bilateral spastic diplegia (CP) |
| Broad-based / ataxic / reeling | Cerebellar lesion |
| High-stepping (steppage) | Foot drop (LMN / peroneal nerve) |
| Shuffling / festinant | Extrapyramidal lesion |
| Waddling (Trendelenburg) | Proximal myopathy (Duchenne's MD) |
| Sensory ataxic (stamping) | Posterior column / peripheral neuropathy |
| Antalgic | Pain |
| Tone | Clinical Sign | Lesion |
|---|---|---|
| Hypotonia (flaccid) | Decreased resistance; "floppy" | LMN, cerebellar, muscle disease, early UMN shock |
| Spasticity | Velocity-dependent; "clasp-knife" phenomenon | Pyramidal / UMN tract |
| Rigidity | Lead-pipe (uniform); Cogwheel (+ tremor) | Extrapyramidal |
| Paratonia (Gegenhalten) | Variable resistance in any direction | Frontal lobe lesion |
| Grade | Meaning |
|---|---|
| 0 | No contraction |
| 1 | Flicker only |
| 2 | Movement with gravity eliminated |
| 3 | Movement against gravity |
| 4 | Movement against some resistance |
| 5 | Normal power |
| Movement | Character | Lesion / Disease |
|---|---|---|
| Tremor | Rhythmic, oscillatory | Rest tremor: extrapyramidal; Intention: cerebellar |
| Chorea | Irregular, random, jerky, flowing | Sydenham's chorea (rheumatic fever), Huntington's |
| Athetosis | Slow, writhing, distal | Kernicterus, CP (athetoid type) |
| Ballismus | Wild, flinging, proximal | Subthalamic nucleus lesion |
| Tics | Repetitive, stereotyped, suppressible | Tourette syndrome |
| Myoclonus | Brief, shock-like jerks | Metabolic encephalopathy, epilepsy |
| Dystonia | Sustained muscle contractions, twisted posture | Basal ganglia |
| Reflex | Nerve Root | Method |
|---|---|---|
| Biceps | C5-C6 | Tap biceps tendon |
| Brachioradialis (Supinator) | C5-C6 | Tap styloid process |
| Triceps | C6-C7 | Tap triceps tendon at elbow |
| Knee (patellar) | L3-L4 | Tap patellar tendon |
| Ankle (Achilles) | S1-S2 | Tap Achilles tendon |
| Reflex | Spinal Level | Normal Response |
|---|---|---|
| Upper abdominal | T7-T9 | Umbilicus moves up and toward stimulus |
| Lower abdominal | T10-T12 | Umbilicus moves down and toward stimulus |
| Cremasteric (males) | L1-L2 | Testis drawn up |
| Plantar | S1-S2 | Toe flexion (normal) |
| Response | Interpretation |
|---|---|
| Flexion of toes | Normal |
| Extension (dorsiflexion) of great toe + fanning of other toes = Babinski sign | UMN lesion |
| Normal in infants up to 12-18 months | Due to incomplete cortical myelination |
| Reflex | Normal Disappearance | Clinical Notes |
|---|---|---|
| Moro reflex | 3-4 months | Sudden extension then flexion of arms; asymmetric = brachial plexus injury |
| Rooting reflex | 3-4 months | Touch cheek → turns toward stimulus |
| Sucking reflex | 3-4 months | - |
| Palmar grasp | 3-4 months | Finger placed in palm → grips |
| Plantar grasp | 9-12 months | Pressure on sole → toe flexion |
| Tonic neck (ATNR) | 4-6 months | Turn head → arm and leg extend on face side, flex on skull side ("fencing posture") |
| Stepping reflex | 2-3 months | - |
| Galant (truncal incurvation) | 2-3 months | Stroke paravertebral → spine curves toward side |
| Parachute reflex | Appears 6-9 months; does NOT disappear | Arms extend when tipped forward; absent/asymmetric = CP |
| Landau reflex | Appears 3 months; disappears 18-24 months | - |
| Sign | Test | Finding |
|---|---|---|
| Dysdiadochokinesia | Rapid alternating movements (pat palm rapidly, flip hand) | Irregular, clumsy movements |
| Ataxia | Gait examination | Broad-based, reeling, cannot tandem walk |
| Nystagmus | Eye movement examination | Horizontal; coarse; fast phase toward lesion side |
| Intention tremor | Finger-nose test; Heel-shin test | Tremor increases as finger approaches target |
| Staccato / scanning speech | Conversation | Slurred, explosive, irregular rhythm |
| Hypotonia | Passive movement; pendular knee jerk | Decreased resistance |
| Sign | Method | Positive Finding |
|---|---|---|
| Neck stiffness | Passive flexion of neck | Resistance / pain |
| Kernig's sign | Flex hip + knee to 90°, then extend knee | Pain + spasm; can't extend beyond 135° |
| Brudzinski's neck sign | Passive neck flexion | Involuntary hip and knee flexion |
| Brudzinski's contralateral reflex | Flex one hip and knee passively | Contralateral hip and knee flex |
| Fontanelle | Normal Closure | Abnormality |
|---|---|---|
| Anterior (diamond) | 12-18 months | Bulging = raised ICP; Sunken = dehydration; Delayed closure = hydrocephalus, rickets, Down syndrome |
| Posterior (triangular) | 6-8 weeks | - |
| Feature | UMN | LMN |
|---|---|---|
| Tone | Increased (spastic) | Decreased (flaccid) |
| Bulk | Mild disuse wasting | Marked wasting |
| Fasciculations | Absent | Present |
| Power | Decreased | Decreased |
| DTRs | Exaggerated | Diminished / Absent |
| Plantars | Extensor (Babinski +) | Flexor (normal) |
| Abdominal reflexes | Absent | Present |
| Clonus | May be present | Absent |
This framework closely follows the systematic approach presented in Meharban Singh's Pediatric Clinical Methods and Essential Paediatrics. For exact tables, figures, and page references, please refer to the latest edition of the book directly. The textbook is not currently in our digital library, so direct page citations cannot be provided.
Create a quick reference PDF checklist for CNS examination in pediatrics
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
mkdir -p /tmp/workspace/cns-checklist
~/cns-checklist/generate_checklist.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import PageBreak
OUTPUT = "/tmp/workspace/cns-checklist/CNS_Examination_Paediatrics_Checklist.pdf"
# ── Colour palette ───────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MED_BLUE = colors.HexColor("#2c6fad")
LIGHT_BLUE = colors.HexColor("#dce9f7")
ACCENT = colors.HexColor("#e8734a")
LIGHT_GREY = colors.HexColor("#f4f6f8")
MID_GREY = colors.HexColor("#c8d0da")
WHITE = colors.white
GREEN = colors.HexColor("#2e7d32")
LIGHT_GREEN = colors.HexColor("#e8f5e9")
# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("Title",
fontName="Helvetica-Bold", fontSize=18,
textColor=WHITE, alignment=TA_CENTER, spaceAfter=2)
subtitle_style = S("Subtitle",
fontName="Helvetica", fontSize=9,
textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=4)
section_style = S("Section",
fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_LEFT,
leftPadding=6, spaceBefore=2, spaceAfter=2)
body_style = S("Body",
fontName="Helvetica", fontSize=7.5,
textColor=DARK_BLUE, leading=11)
bold_body = S("BoldBody",
fontName="Helvetica-Bold", fontSize=7.5,
textColor=DARK_BLUE, leading=11)
small_style = S("Small",
fontName="Helvetica", fontSize=6.8,
textColor=colors.HexColor("#444444"), leading=10)
small_bold = S("SmallBold",
fontName="Helvetica-Bold", fontSize=6.8,
textColor=DARK_BLUE, leading=10)
mnemonic_style = S("Mnemonic",
fontName="Helvetica-Bold", fontSize=8,
textColor=ACCENT, alignment=TA_CENTER)
tip_style = S("Tip",
fontName="Helvetica-Oblique", fontSize=6.8,
textColor=GREEN, leading=10)
footer_style = S("Footer",
fontName="Helvetica", fontSize=6.5,
textColor=colors.grey, alignment=TA_CENTER)
# ── Helper builders ──────────────────────────────────────────────────────────
def section_header(text, bg=MED_BLUE):
data = [[Paragraph(text, section_style)]]
t = Table(data, colWidths=[175*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("ROUNDEDCORNERS", [3]),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
return t
def checkbox_row(label, detail="", indent=0):
box = "☐"
pad = " " * indent
left = Paragraph(f"{pad}{box} <b>{label}</b>", bold_body if not detail else body_style)
right = Paragraph(detail, small_style) if detail else Paragraph("", small_style)
return [left, right]
def two_col_table(rows, col1=95*mm, col2=80*mm, bg_alt=True):
table_rows = []
for i, row in enumerate(rows):
table_rows.append(row)
t = Table(table_rows, colWidths=[col1, col2])
style = [
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("LINEBELOW", (0,0), (-1,-1), 0.3, MID_GREY),
]
if bg_alt:
for i in range(0, len(table_rows), 2):
style.append(("BACKGROUND", (0,i), (-1,i), LIGHT_GREY))
t.setStyle(TableStyle(style))
return t
def mini_table(headers, rows, col_widths, header_bg=MED_BLUE):
all_rows = []
header_cells = [Paragraph(f"<b>{h}</b>", S("th", fontName="Helvetica-Bold",
fontSize=6.8, textColor=WHITE, leading=9)) for h in headers]
all_rows.append(header_cells)
for i, row in enumerate(rows):
cells = [Paragraph(str(c), small_style) for c in row]
all_rows.append(cells)
t = Table(all_rows, colWidths=col_widths)
style = [
("BACKGROUND", (0,0), (-1,0), header_bg),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.3, MID_GREY),
]
for i in range(1, len(all_rows), 2):
style.append(("BACKGROUND", (0,i), (-1,i), LIGHT_GREY))
t.setStyle(TableStyle(style))
return t
# ── Document build ────────────────────────────────────────────────────────────
def build_pdf():
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=12*mm, leftMargin=12*mm,
topMargin=12*mm, bottomMargin=12*mm,
title="CNS Examination in Paediatrics - Quick Reference Checklist",
author="Meharban Singh Essential Paediatrics"
)
story = []
# ── TITLE BANNER ──────────────────────────────────────────────────────────
title_data = [[
Paragraph("CNS EXAMINATION IN PAEDIATRICS", title_style),
]]
title_table = Table(title_data, colWidths=[175*mm])
title_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("ROUNDEDCORNERS", [4]),
]))
story.append(title_table)
sub_data = [[Paragraph("Quick Reference Checklist • Based on Meharban Singh's Pediatric Clinical Methods / Essential Paediatrics", subtitle_style)]]
sub_table = Table(sub_data, colWidths=[175*mm])
sub_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MED_BLUE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
story.append(sub_table)
story.append(Spacer(1, 4*mm))
# ── SCHEME BOX ────────────────────────────────────────────────────────────
scheme_items = [
"1. Higher Functions", "2. Cranial Nerves (I–XII)", "3. Motor System",
"4. Reflexes", "5. Sensory System", "6. Cerebellar Signs",
"7. Meningeal Irritation", "8. Skull & Spine"
]
scheme_cells = [Paragraph(f"☐ {s}", small_bold) for s in scheme_items]
# 4 per row
scheme_rows = [scheme_cells[i:i+4] for i in range(0, len(scheme_cells), 4)]
scheme_t = Table(scheme_rows, colWidths=[43*mm]*4)
scheme_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("GRID", (0,0), (-1,-1), 0.4, MED_BLUE),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
]))
story.append(scheme_t)
story.append(Spacer(1, 3*mm))
# ════════════════════════════════════════════════════════════════════════
# TWO-COLUMN LAYOUT using a wide table
# Left col ~88mm, Right col ~83mm (gutter 4mm)
# ════════════════════════════════════════════════════════════════════════
def flow_block(content_list):
"""Wrap a list of flowables into a single-cell table for column layout."""
rows = [[item] for item in content_list]
t = Table(rows, colWidths=[85*mm])
t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
return t
# ── LEFT COLUMN CONTENT ───────────────────────────────────────────────────
left = []
# 1. HIGHER FUNCTIONS
left.append(section_header("1. HIGHER FUNCTIONS (Mnemonic: COMA IS G)"))
left.append(Spacer(1,1*mm))
hf_rows = [
[Paragraph("☐ <b>C</b> – Consciousness", body_style), Paragraph("Alert → Drowsy → Obtunded → Stupor → Coma", small_style)],
[Paragraph("☐ <b>O</b> – Orientation", body_style), Paragraph("Time / Place / Person", small_style)],
[Paragraph("☐ <b>M</b> – Memory", body_style), Paragraph("Immediate · Short-term · Long-term", small_style)],
[Paragraph("☐ <b>A</b> – Attention", body_style), Paragraph("Digit span test (fwd & bkwd)", small_style)],
[Paragraph("☐ <b>I</b> – Intelligence", body_style), Paragraph("Age-appropriate tasks / IQ scales", small_style)],
[Paragraph("☐ <b>S</b> – Speech", body_style), Paragraph("See speech table →", small_style)],
[Paragraph("☐ <b>G</b> – Gait", body_style), Paragraph("Free walk · toes · heels · tandem", small_style)],
]
hf_t = Table(hf_rows, colWidths=[48*mm, 37*mm])
hf_t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3),
("LINEBELOW", (0,0), (-1,-1), 0.3, MID_GREY),
("BACKGROUND", (0,0), (-1,0), LIGHT_GREY),
("BACKGROUND", (0,2), (-1,2), LIGHT_GREY),
("BACKGROUND", (0,4), (-1,4), LIGHT_GREY),
("BACKGROUND", (0,6), (-1,6), LIGHT_GREY),
]))
left.append(hf_t)
left.append(Spacer(1,2*mm))
# GCS mini table
left.append(Paragraph("<b>Glasgow Coma Scale</b>", small_bold))
left.append(Spacer(1,0.5*mm))
gcs_t = mini_table(
["Component","Score","Response"],
[
["Eye (E)","4/3/2/1","Spontaneous/Voice/Pain/None"],
["Verbal (V)","5-4-3-2-1","Oriented/Confused/Words/Sounds/None"],
["Motor (M)","6-5-4-3-2-1","Obeys/Localise/Withdraw/Flex/Ext/None"],
["Total","15 = Normal","≤ 8 = Severe coma"],
],
col_widths=[22*mm, 20*mm, 43*mm]
)
left.append(gcs_t)
left.append(Spacer(1, 2*mm))
# Speech
left.append(Paragraph("<b>Speech abnormalities</b>", small_bold))
left.append(Spacer(1,0.5*mm))
sp_t = mini_table(
["Pattern","Lesion"],
[
["Slurred (dysarthric)","Pyramidal (UMN)"],
["Monotonous","Extrapyramidal"],
["Staccato / scanning","Cerebellar"],
["Nasal (rhinolalia)","Palatal palsy (CN X)"],
["Expressive dysphasia","Broca's area"],
["Receptive dysphasia","Wernicke's area"],
["No words >18 m / No sentences >3 y","Developmental delay"],
],
col_widths=[48*mm, 37*mm]
)
left.append(sp_t)
left.append(Spacer(1, 2*mm))
# Gait
left.append(Paragraph("<b>Gait types</b>", small_bold))
left.append(Spacer(1,0.5*mm))
gait_t = mini_table(
["Gait","Lesion"],
[
["Hemiplegic / circumduction","Unilateral pyramidal"],
["Scissoring / spastic","Spastic diplegia (CP)"],
["Ataxic / broad-based / reeling","Cerebellar"],
["High-stepping (steppage)","Foot drop (LMN)"],
["Shuffling / festinant","Extrapyramidal"],
["Waddling (Trendelenburg)","Proximal myopathy (DMD)"],
["Stamping / sensory ataxic","Posterior column"],
],
col_widths=[48*mm, 37*mm]
)
left.append(gait_t)
left.append(Spacer(1, 2*mm))
# 2. CRANIAL NERVES
left.append(section_header("2. CRANIAL NERVES"))
left.append(Spacer(1,1*mm))
cn_t = mini_table(
["CN","Name","Test / Look for"],
[
["I","Olfactory","Each nostril – coffee/soap; Anosmia"],
["II","Optic","VA · VF · Pupils · Fundoscopy (papilledema, optic atrophy, cherry-red spot)"],
["III/IV/VI","Eye mvmt nerves","Ptosis · EOMs (H-pattern) · Pupil reflex · Nystagmus"],
["V","Trigeminal","Touch/pain 3 divisions · Corneal reflex · Jaw jerk · Masseter bulk"],
["VII","Facial","Symmetry at rest + movement · UMN (forehead spared) vs LMN (full face)"],
["VIII","Vestibulococh.","Whisper · Rinne/Weber · BERA · Nystagmus · Romberg"],
["IX/X","Glossoph./Vagus","Say 'Aah' · Uvula deviation (away from lesion) · Gag reflex · Voice"],
["XI","Spinal Accessory","SCM + Trapezius strength against resistance"],
["XII","Hypoglossal","Tongue protrusion – deviates TOWARD LMN lesion · Wasting/fasciculation"],
],
col_widths=[10*mm, 22*mm, 53*mm]
)
left.append(cn_t)
left.append(Spacer(1, 2*mm))
# 3. MOTOR SYSTEM
left.append(section_header("3. MOTOR SYSTEM"))
left.append(Spacer(1,1*mm))
motor_rows = [
[Paragraph("☐ <b>Inspection</b>", body_style), Paragraph("Bulk · Wasting · Fasciculations · Posture · Deformity", small_style)],
[Paragraph("☐ <b>Tone</b>", body_style), Paragraph("Passive ROM at each joint (see tone table)", small_style)],
[Paragraph("☐ <b>Infant tone</b>", body_style), Paragraph("Ventral suspension · Traction response · Scarf sign · Popliteal angle", small_style)],
[Paragraph("☐ <b>Power</b>", body_style), Paragraph("MRC 0–5; Proximal AND distal groups", small_style)],
[Paragraph("☐ <b>Gower's sign</b>", body_style), Paragraph("Walks up legs → proximal weakness (DMD, SMA)", small_style)],
[Paragraph("☐ <b>Inv. movements</b>", body_style), Paragraph("Tremor · Chorea · Athetosis · Tics · Myoclonus · Dystonia", small_style)],
]
motor_t = Table(motor_rows, colWidths=[40*mm, 45*mm])
motor_t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3),
("LINEBELOW", (0,0), (-1,-1), 0.3, MID_GREY),
("BACKGROUND", (0,1), (-1,1), LIGHT_GREY),
("BACKGROUND", (0,3), (-1,3), LIGHT_GREY),
("BACKGROUND", (0,5), (-1,5), LIGHT_GREY),
]))
left.append(motor_t)
left.append(Spacer(1,1*mm))
# Tone table
left.append(Paragraph("<b>Tone patterns</b>", small_bold))
left.append(Spacer(1,0.5*mm))
tone_t = mini_table(
["Tone","Sign","Lesion"],
[
["Spasticity","Velocity-dependent ↑; clasp-knife","Pyramidal / UMN"],
["Rigidity","Lead-pipe (uniform); Cogwheel (+ tremor)","Extrapyramidal"],
["Hypotonia","↓ resistance; floppy; rag-doll","LMN, cerebellar, muscle"],
["Paratonia","Variable resistance any direction","Frontal lobe"],
],
col_widths=[22*mm, 37*mm, 26*mm]
)
left.append(tone_t)
left.append(Spacer(1,1*mm))
# MRC
left.append(Paragraph("<b>MRC Power Scale</b>", small_bold))
left.append(Spacer(1,0.5*mm))
mrc_t = mini_table(
["Grade","Description"],
[["0","No contraction"],["1","Flicker"],["2","Movement, gravity eliminated"],
["3","Against gravity"],["4","Against some resistance"],["5","Normal"]],
col_widths=[15*mm, 70*mm]
)
left.append(mrc_t)
# ── RIGHT COLUMN CONTENT ──────────────────────────────────────────────────
right = []
# 4. REFLEXES
right.append(section_header("4. REFLEXES"))
right.append(Spacer(1,1*mm))
right.append(Paragraph("<b>Deep Tendon Reflexes (DTRs)</b>", small_bold))
right.append(Spacer(1,0.5*mm))
dtr_t = mini_table(
["Reflex","Root"],
[["Biceps","C5–C6"],["Brachioradialis","C5–C6"],["Triceps","C6–C7"],
["Knee (Patellar)","L3–L4"],["Ankle (Achilles)","S1–S2"]],
col_widths=[50*mm, 33*mm]
)
right.append(dtr_t)
right.append(Paragraph(" Grading: 0 (absent) + (↓) ++ (normal) +++ (↑) ++++ (clonus)", tip_style))
right.append(Spacer(1,1*mm))
right.append(Paragraph("<b>Plantar Response</b>", small_bold))
right.append(Spacer(1,0.5*mm))
plantar_t = mini_table(
["Response","Interpretation"],
[["Toe FLEXION","Normal"],
["Toe EXTENSION + fanning = BABINSKI SIGN","UMN lesion"],
["Babinski normal in infants <12–18 months","Incomplete myelination"]],
col_widths=[52*mm, 31*mm]
)
right.append(plantar_t)
right.append(Spacer(1,1*mm))
right.append(Paragraph("<b>Primitive Reflexes</b> (persist beyond age = CP / cortical damage)", small_bold))
right.append(Spacer(1,0.5*mm))
prim_t = mini_table(
["Reflex","Disappears","Note"],
[
["Moro","3–4 months","Asymmetric → brachial plexus injury"],
["Rooting","3–4 months","Touch cheek → turns toward"],
["Palmar grasp","3–4 months","Finger in palm → grips"],
["ATNR (tonic neck)","4–6 months","'Fencing posture'"],
["Stepping","2–3 months","—"],
["Galant (truncal)","2–3 months","Stroke paravertebral → curve"],
["Plantar grasp","9–12 months","Pressure on sole → toe flexion"],
["Parachute","Appears 6–9 m; NEVER disappears","Absent/asymmetric = CP"],
],
col_widths=[30*mm, 25*mm, 28*mm]
)
right.append(prim_t)
right.append(Spacer(1, 2*mm))
# 5. SENSORY
right.append(section_header("5. SENSORY SYSTEM"))
right.append(Spacer(1,1*mm))
sens_rows = [
[Paragraph("☐ Light touch", body_style), Paragraph("Cotton wisp; compare sides", small_style)],
[Paragraph("☐ Pain (pin-prick)", body_style), Paragraph("Both sides; proximal vs distal", small_style)],
[Paragraph("☐ Temperature", body_style), Paragraph("Hot/cold tubes", small_style)],
[Paragraph("☐ Vibration", body_style), Paragraph("128 Hz tuning fork on bony prominences", small_style)],
[Paragraph("☐ Proprioception", body_style), Paragraph("Move toe/finger up or down (eyes closed)", small_style)],
[Paragraph("☐ Stereognosis", body_style), Paragraph("Identify object in hand (eyes closed)", small_style)],
[Paragraph("☐ Graphesthesia", body_style), Paragraph("Number/letter drawn on palm", small_style)],
[Paragraph("☐ Two-point disc.", body_style), Paragraph("Distinguish 2 points on skin", small_style)],
]
sens_t = Table(sens_rows, colWidths=[42*mm, 41*mm])
sens_t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3),
("LINEBELOW", (0,0), (-1,-1), 0.3, MID_GREY),
("BACKGROUND", (0,0), (-1,0), LIGHT_GREY),
("BACKGROUND", (0,2), (-1,2), LIGHT_GREY),
("BACKGROUND", (0,4), (-1,4), LIGHT_GREY),
("BACKGROUND", (0,6), (-1,6), LIGHT_GREY),
]))
right.append(sens_t)
right.append(Spacer(1, 2*mm))
# 6. CEREBELLAR SIGNS
right.append(section_header("6. CEREBELLAR SIGNS (Mnemonic: DANISH)"))
right.append(Spacer(1,1*mm))
cer_t = mini_table(
["Letter","Sign","Test"],
[
["D","Dysdiadochokinesia","Rapid alternating hand movements"],
["A","Ataxia","Broad-based gait; tandem walk"],
["N","Nystagmus","Horizontal; fast-phase toward lesion"],
["I","Intention tremor","Finger-nose; heel-shin test"],
["S","Staccato (scanning) speech","Conversation / counting"],
["H","Hypotonia","↓ resistance; pendular knee jerk"],
["+","Rebound phenomenon","Extended arm rebounds on release"],
["+","Past-pointing","Finger consistently misses target"],
["+","Romberg (negative)","Falls eyes closed = SENSORY ataxia, NOT cerebellar"],
],
col_widths=[8*mm, 33*mm, 42*mm]
)
right.append(cer_t)
right.append(Spacer(1, 2*mm))
# 7. MENINGEAL IRRITATION
right.append(section_header("7. MENINGEAL IRRITATION"))
right.append(Spacer(1,1*mm))
men_t = mini_table(
["Sign","Method","Positive"],
[
["Neck stiffness","Passive neck flexion","Resistance / pain"],
["Kernig's sign","Flex hip+knee 90°; extend knee","Pain + spasm; can't extend >135°"],
["Brudzinski's neck","Passive neck flexion","Involuntary hip+knee flexion"],
["Brudzinski's contra.","Flex one hip+knee","Contralateral hip+knee flex"],
],
col_widths=[28*mm, 35*mm, 20*mm]
)
right.append(men_t)
right.append(Spacer(1,0.5*mm))
right.append(Paragraph(
"<b>In INFANTS</b> (Kernig/Brudzinski unreliable): ☐ Bulging fontanelle "
"☐ High-pitched cry ☐ Opisthotonus ☐ Photophobia ☐ Hyperaesthesia",
tip_style))
right.append(Spacer(1, 2*mm))
# 8. SKULL & SPINE
right.append(section_header("8. SKULL & SPINE"))
right.append(Spacer(1,1*mm))
skull_rows = [
[Paragraph("☐ Head circumference", body_style), Paragraph("Plot on centile chart (macro/>98th; micro/<2nd)", small_style)],
[Paragraph("☐ Fontanelles", body_style), Paragraph("AF closes 12–18 m · Bulging=↑ICP · Sunken=dehydration", small_style)],
[Paragraph("☐ Sutures", body_style), Paragraph("Wide=↑ICP · Ridged=craniosynostosis", small_style)],
[Paragraph("☐ Macewen's sign", body_style), Paragraph("Cracked-pot percussion sound = ↑ICP", small_style)],
[Paragraph("☐ Cranial bruit", body_style), Paragraph("AV malformation", small_style)],
[Paragraph("☐ Transillumination", body_style), Paragraph("Positive = hydranencephaly / large subdural", small_style)],
[Paragraph("☐ Spine", body_style), Paragraph("Midline defects · Scoliosis · Kyphosis · Tenderness", small_style)],
]
skull_t = Table(skull_rows, colWidths=[38*mm, 45*mm])
skull_t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3),
("LINEBELOW", (0,0), (-1,-1), 0.3, MID_GREY),
("BACKGROUND", (0,0), (-1,0), LIGHT_GREY),
("BACKGROUND", (0,2), (-1,2), LIGHT_GREY),
("BACKGROUND", (0,4), (-1,4), LIGHT_GREY),
("BACKGROUND", (0,6), (-1,6), LIGHT_GREY),
]))
right.append(skull_t)
# ── ASSEMBLE TWO COLUMNS ─────────────────────────────────────────────────
left_items = [[item] for item in left]
right_items = [[item] for item in right]
left_table = Table(left_items, colWidths=[85*mm])
left_table.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 1),
("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
right_table = Table(right_items, colWidths=[85*mm])
right_table.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 1),
("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
two_col = Table([[left_table, right_table]], colWidths=[88*mm, 87*mm])
two_col.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LINEAFTER", (0,0), (0,-1), 0.5, MID_GREY),
]))
story.append(two_col)
story.append(Spacer(1, 3*mm))
# ── BOTTOM SUMMARY TABLES ────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=1, color=MED_BLUE))
story.append(Spacer(1, 1.5*mm))
# UMN vs LMN + Floppy infant side by side
umln_t = mini_table(
["Feature","UMN Lesion","LMN Lesion"],
[
["Tone","↑ Spastic","↓ Flaccid"],
["Muscle bulk","Mild disuse wasting","Marked wasting"],
["Fasciculations","Absent","Present"],
["DTRs","Exaggerated","Absent / Diminished"],
["Plantars","Extensor (Babinski +)","Flexor (normal)"],
["Abdominal reflexes","Absent","Present"],
["Clonus","May be present","Absent"],
],
col_widths=[32*mm, 30*mm, 30*mm],
header_bg=DARK_BLUE
)
floppy_t = mini_table(
["Central Hypotonia","Peripheral Hypotonia"],
[
["Alert, responsive baby","Floppy AND weak"],
["Dysmorphic features","↓ / absent DTRs"],
["Seizures, ID common","Fasciculations"],
["DTRs normal or brisk","Causes: SMA, myopathy, myasthenia"],
["Causes: HIE, Down syndrome, metabolic","Congenital neuropathy"],
],
col_widths=[42*mm, 43*mm],
header_bg=DARK_BLUE
)
bottom_row = [[
Table([[Paragraph("<b>UMN vs LMN – Quick Comparison</b>", small_bold)],[umln_t]], colWidths=[94*mm]),
Table([[Paragraph("<b>Floppy Infant – Central vs Peripheral</b>", small_bold)],[floppy_t]], colWidths=[87*mm]),
]]
bottom_t = Table(bottom_row, colWidths=[96*mm, 79*mm])
bottom_t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (0,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LINEAFTER", (0,0), (0,-1), 0.5, MID_GREY),
]))
story.append(bottom_t)
story.append(Spacer(1, 2*mm))
# ── FOOTER ───────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=0.5, color=MID_GREY))
story.append(Spacer(1, 1*mm))
story.append(Paragraph(
"Reference: Meharban Singh — Pediatric Clinical Methods / Essential Paediatrics | "
"Quick Reference Checklist | For educational purposes only",
footer_style))
doc.build(story)
print(f"PDF saved → {OUTPUT}")
build_pdf()
cd /tmp/workspace/cns-checklist && python generate_checklist.py 2>&1
~/cns-checklist/generate_checklist.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak
)
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
OUTPUT = "/tmp/workspace/cns-checklist/CNS_Examination_Paediatrics_Checklist.pdf"
# ── Colour palette ────────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MED_BLUE = colors.HexColor("#2c6fad")
LIGHT_BLUE = colors.HexColor("#dce9f7")
ACCENT = colors.HexColor("#e8734a")
LIGHT_GREY = colors.HexColor("#f4f6f8")
MID_GREY = colors.HexColor("#c8d0da")
WHITE = colors.white
GREEN = colors.HexColor("#2e7d32")
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("T", fontName="Helvetica-Bold", fontSize=17, textColor=WHITE, alignment=TA_CENTER)
sub_style = S("Su", fontName="Helvetica", fontSize=8,5, textColor=LIGHT_BLUE, alignment=TA_CENTER)
sec_style = S("Se", fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE, leftPadding=5)
body_style = S("B", fontName="Helvetica", fontSize=7.5, textColor=DARK_BLUE, leading=10)
bbold_style = S("BB", fontName="Helvetica-Bold", fontSize=7.5, textColor=DARK_BLUE, leading=10)
small_style = S("Sm", fontName="Helvetica", fontSize=6.8, textColor=colors.HexColor("#333333"), leading=9.5)
sbold_style = S("SB", fontName="Helvetica-Bold", fontSize=6.8, textColor=DARK_BLUE, leading=9.5)
tip_style = S("Ti", fontName="Helvetica-Oblique", fontSize=6.5, textColor=GREEN, leading=9)
footer_style = S("F", fontName="Helvetica", fontSize=6.2, textColor=colors.grey,alignment=TA_CENTER)
def sec_hdr(text, bg=MED_BLUE, width=175*mm):
t = Table([[Paragraph(text, sec_style)]], colWidths=[width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
return t
def mini(headers, rows, cw, hbg=MED_BLUE):
th = [Paragraph(f"<b>{h}</b>", S("th", fontName="Helvetica-Bold", fontSize=6.5,
textColor=WHITE, leading=9)) for h in headers]
all_rows = [th]
for row in rows:
all_rows.append([Paragraph(str(c), small_style) for c in row])
t = Table(all_rows, colWidths=cw)
sty = [
("BACKGROUND", (0,0),(-1,0), hbg),
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING", (0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 3),
("RIGHTPADDING", (0,0),(-1,-1), 3),
("VALIGN", (0,0),(-1,-1), "TOP"),
("GRID", (0,0),(-1,-1), 0.3, MID_GREY),
]
for i in range(1, len(all_rows), 2):
sty.append(("BACKGROUND", (0,i),(-1,i), LIGHT_GREY))
t.setStyle(TableStyle(sty))
return t
def chk_table(rows_data, cw):
"""rows_data: list of (label, detail) tuples"""
table_rows = []
for i,(lbl,det) in enumerate(rows_data):
table_rows.append([
Paragraph(f"☐ <b>{lbl}</b>", bbold_style),
Paragraph(det, small_style)
])
t = Table(table_rows, colWidths=cw)
sty = [
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING", (0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 3),
("RIGHTPADDING", (0,0),(-1,-1), 3),
("LINEBELOW", (0,0),(-1,-1), 0.3, MID_GREY),
("VALIGN", (0,0),(-1,-1), "TOP"),
]
for i in range(0, len(table_rows), 2):
sty.append(("BACKGROUND", (0,i),(-1,i), LIGHT_GREY))
t.setStyle(TableStyle(sty))
return t
def col_wrap(items, width):
"""Wrap a list of flowables into a single-col table."""
rows = [[it] for it in items]
t = Table(rows, colWidths=[width])
t.setStyle(TableStyle([
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING", (0,0),(-1,-1), 1),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
]))
return t
def two_col(left_items, right_items, lw=88*mm, rw=87*mm):
lt = col_wrap(left_items, lw)
rt = col_wrap(right_items, rw)
t = Table([[lt, rt]], colWidths=[lw, rw])
t.setStyle(TableStyle([
("VALIGN", (0,0),(-1,-1), "TOP"),
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING", (0,0),(-1,-1), 0),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
("LINEAFTER", (0,0),(0,-1), 0.5, MID_GREY),
]))
return t
def title_banner(story):
tb = Table([[Paragraph("CNS EXAMINATION IN PAEDIATRICS", title_style)]], colWidths=[175*mm])
tb.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),DARK_BLUE),
("TOPPADDING",(0,0),(-1,-1),10),("BOTTOMPADDING",(0,0),(-1,-1),4)]))
sb = Table([[Paragraph(
"Quick Reference Checklist • Based on Meharban Singh's Pediatric Clinical Methods / Essential Paediatrics",
sub_style)]], colWidths=[175*mm])
sb.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),MED_BLUE),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),6)]))
story += [tb, sb, Spacer(1,3*mm)]
def scheme_bar(story):
items = ["1. Higher Functions","2. Cranial Nerves","3. Motor System","4. Reflexes",
"5. Sensory System","6. Cerebellar Signs","7. Meningeal Irritation","8. Skull & Spine"]
cells = [Paragraph(f"☐ {s}", sbold_style) for s in items]
rows = [cells[:4], cells[4:]]
t = Table(rows, colWidths=[43*mm]*4)
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),LIGHT_BLUE),
("GRID",(0,0),(-1,-1),0.4,MED_BLUE),
("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),5),
]))
story += [t, Spacer(1,3*mm)]
def footer_line(story):
story += [
HRFlowable(width="100%", thickness=0.5, color=MID_GREY),
Spacer(1,1*mm),
Paragraph("Ref: Meharban Singh — Pediatric Clinical Methods / Essential Paediatrics | Quick Reference Checklist | For educational use only", footer_style),
]
# ═════════════════════════════════════════════════════════════════════════════
# PAGE 1 – Higher Functions + Cranial Nerves | Motor + Reflexes (part)
# ═════════════════════════════════════════════════════════════════════════════
def page1_left():
L = []
# HIGHER FUNCTIONS
L += [sec_hdr("1. HIGHER FUNCTIONS (Mnemonic: COMA IS G)", width=87*mm), Spacer(1,1*mm)]
L.append(chk_table([
("C – Consciousness", "Alert → Drowsy → Obtunded → Stupor → Coma"),
("O – Orientation", "Time / Place / Person"),
("M – Memory", "Immediate · Short-term · Long-term"),
("A – Attention", "Digit span test (forward & backward)"),
("I – Intelligence", "Age-appropriate tasks; IQ scales (Binet-Kamat)"),
("S – Speech", "See speech table below"),
("G – Gait", "Free walk · toes · heels · tandem gait"),
], cw=[40*mm, 44*mm]))
L += [Spacer(1,1*mm),
Paragraph("<b>Glasgow Coma Scale</b>", sbold_style), Spacer(1,0.5*mm)]
L.append(mini(
["Component","Score","Response"],
[["Eye (E)","4/3/2/1","Spontaneous / To voice / To pain / None"],
["Verbal (V)","5→1","Oriented/Confused/Words/Sounds/None"],
["Motor (M)","6→1","Obeys/Localise/Withdraw/Flex/Ext/None"],
["Total","15=Normal","≤ 8 = Severe coma; Paed-GCS for infants"]],
cw=[22*mm,18*mm,47*mm]))
L += [Spacer(1,1*mm),
Paragraph("<b>Speech abnormalities</b>", sbold_style), Spacer(1,0.5*mm)]
L.append(mini(
["Pattern","Lesion"],
[["Slurred / dysarthric","Pyramidal (UMN)"],
["Monotonous","Extrapyramidal"],
["Staccato / scanning / explosive","Cerebellar"],
["Nasal / rhinolalia","Palatal palsy (CN X)"],
["Expressive dysphasia","Broca's area (dominant hemisphere)"],
["Receptive dysphasia","Wernicke's area"],
["No words >18 m / No sentences >3 y","Developmental delay / deafness"],
["Echolalia","Autism / intellectual disability"]],
cw=[50*mm,37*mm]))
L += [Spacer(1,1*mm),
Paragraph("<b>Gait types</b>", sbold_style), Spacer(1,0.5*mm)]
L.append(mini(
["Gait","Lesion"],
[["Hemiplegic / circumduction","Unilateral pyramidal (UMN)"],
["Scissoring / spastic","Spastic diplegia – CP"],
["Ataxic / broad-based / reeling","Cerebellar"],
["High-stepping (steppage)","Foot drop – LMN / peroneal"],
["Shuffling / festinant","Extrapyramidal"],
["Waddling / Trendelenburg","Proximal myopathy – DMD"],
["Stamping / sensory ataxic","Posterior column / peripheral neuropathy"]],
cw=[50*mm,37*mm]))
return L
def page1_right():
R = []
# CRANIAL NERVES
R += [sec_hdr("2. CRANIAL NERVES", width=86*mm), Spacer(1,1*mm)]
R.append(mini(
["CN","Name","Test / Look for"],
[["I","Olfactory","Each nostril – coffee/soap; look for anosmia"],
["II","Optic","VA · Visual fields · Pupils · Fundoscopy\n(papilledema / optic atrophy / cherry-red spot)"],
["III IV VI","Eye movement","Ptosis · EOMs H-pattern · Pupil reflex\nNystagmus · Strabismus (Hirschberg, cover test)"],
["V","Trigeminal","Touch/pain 3 divisions · Corneal reflex\nMasseter bulk · Jaw jerk · Jaw deviation"],
["VII","Facial","Symmetry at rest + movement\nUMN = forehead spared; LMN = full face (Bell's)"],
["VIII","Vestibulochochlear","Whisper · Rinne/Weber · BERA\nNystagmus · Romberg · Dix-Hallpike"],
["IX X","Glossoph. / Vagus","Say 'Aah' · Uvula → AWAY from lesion\nGag reflex · Voice (hoarse/aphonia)"],
["XI","Spinal Accessory","SCM + Trapezius vs resistance"],
["XII","Hypoglossal","Tongue → TOWARD LMN lesion\nWasting + fasciculations in LMN"]],
cw=[12*mm, 22*mm, 52*mm]))
R += [Spacer(1,2*mm)]
# MOTOR
R += [sec_hdr("3. MOTOR SYSTEM", width=86*mm), Spacer(1,1*mm)]
R.append(chk_table([
("Inspection", "Bulk · Wasting · Fasciculations · Posture · Deformity"),
("Tone", "Passive ROM at joints (see tone table)"),
("Infant tone tests","Ventral suspension · Traction response · Scarf sign · Popliteal angle"),
("Power (MRC 0–5)", "Proximal AND distal groups; Grade 0–5"),
("Gower's sign", "Walks up thighs → proximal weakness (DMD, SMA)"),
("Inv. movements", "Tremor · Chorea · Athetosis · Tics · Myoclonus · Dystonia · Ballismus"),
], cw=[38*mm, 47*mm]))
R += [Spacer(1,1*mm), Paragraph("<b>Tone patterns</b>", sbold_style), Spacer(1,0.5*mm)]
R.append(mini(
["Tone","Sign","Lesion"],
[["Spasticity","Velocity-dependent ↑; clasp-knife","Pyramidal / UMN"],
["Rigidity","Lead-pipe; Cogwheel (+ tremor)","Extrapyramidal"],
["Hypotonia","↓ resistance; floppy / rag-doll","LMN, cerebellar, muscle"],
["Paratonia","Variable resistance any direction","Frontal lobe lesion"]],
cw=[22*mm,38*mm,26*mm]))
R += [Spacer(1,1*mm), Paragraph("<b>MRC Power Grade</b>", sbold_style), Spacer(1,0.5*mm)]
R.append(mini(
["Grade","Description"],
[["0","No contraction"],["1","Flicker only"],["2","Movement with gravity eliminated"],
["3","Movement against gravity"],["4","Against some resistance"],["5","Normal power"]],
cw=[14*mm, 71*mm]))
R += [Spacer(1,1*mm)]
R.append(Paragraph(
"<b>Involuntary movements:</b> Chorea (Sydenham's – rheumatic fever; basal ganglia) · "
"Athetosis (kernicterus, athetoid CP) · Ballismus (subthalamic nucleus) · "
"Tics (Tourette syndrome) · Myoclonus (epilepsy, metabolic)",
tip_style))
return R
# ═════════════════════════════════════════════════════════════════════════════
# PAGE 2 – Reflexes | Sensory | Cerebellar | Meningeal | Skull/Spine | Summary
# ═════════════════════════════════════════════════════════════════════════════
def page2_left():
L = []
# REFLEXES
L += [sec_hdr("4. REFLEXES", width=87*mm), Spacer(1,1*mm),
Paragraph("<b>Deep Tendon Reflexes (DTRs)</b>", sbold_style), Spacer(1,0.5*mm)]
L.append(mini(
["Reflex","Root","Method"],
[["Biceps","C5–C6","Tap biceps tendon"],
["Brachioradialis","C5–C6","Tap styloid process"],
["Triceps","C6–C7","Tap triceps tendon at elbow"],
["Knee (Patellar)","L3–L4","Tap patellar tendon"],
["Ankle (Achilles)","S1–S2","Tap Achilles tendon"]],
cw=[32*mm,16*mm,39*mm]))
L.append(Paragraph(" Grading: 0 (absent) + (↓) ++ (normal) +++ (brisk) ++++ (clonus)", tip_style))
L += [Spacer(1,1*mm), Paragraph("<b>Plantar Response</b>", sbold_style), Spacer(1,0.5*mm)]
L.append(mini(
["Response","Interpretation"],
[["Toe FLEXION","Normal"],
["DORSIFLEXION great toe + fanning = BABINSKI +","UMN lesion"],
["Babinski normal up to 12–18 months","Incomplete myelination (normal)"]],
cw=[55*mm,32*mm]))
L += [Spacer(1,1*mm),
Paragraph("<b>Primitive Reflexes</b> (persist beyond age = CP / cortical damage)", sbold_style),
Spacer(1,0.5*mm)]
L.append(mini(
["Reflex","Disappears","Note"],
[["Moro","3–4 months","Asymmetric → brachial plexus injury"],
["Rooting","3–4 months","Touch cheek → turns toward stimulus"],
["Sucking","3–4 months","—"],
["Palmar grasp","3–4 months","Finger in palm → grips"],
["ATNR (tonic neck)","4–6 months","'Fencing posture'; head turn → arm+leg extend"],
["Stepping","2–3 months","—"],
["Galant (truncal)","2–3 months","Stroke paravertebral → spine curves ipsilateral"],
["Plantar grasp","9–12 months","Pressure on sole → toe flexion"],
["Parachute","Appears 6–9 m; NEVER disappears","Arms extend when tipped; absent/asymmetric = CP"]],
cw=[30*mm,26*mm,31*mm]))
L += [Spacer(1,2*mm)]
# SENSORY
L += [sec_hdr("5. SENSORY SYSTEM", width=87*mm), Spacer(1,1*mm)]
L.append(chk_table([
("Light touch", "Cotton wisp; compare both sides"),
("Pain (pin-prick)", "Both sides; proximal vs distal"),
("Temperature", "Hot / cold tubes"),
("Vibration", "128 Hz tuning fork on bony prominences"),
("Proprioception", "Move toe/finger; identify up or down (eyes closed)"),
("Stereognosis", "Identify object in hand (eyes closed)"),
("Graphesthesia", "Number/letter drawn on palm"),
("Two-point disc.", "Distinguish 2 separate points on skin"),
], cw=[38*mm,47*mm]))
L += [Spacer(1,1*mm)]
L.append(Paragraph(
"<b>Sensory level:</b> In spinal cord lesions, map upper level of sensory loss on trunk using dermatomal chart.",
tip_style))
return L
def page2_right():
R = []
# CEREBELLAR
R += [sec_hdr("6. CEREBELLAR SIGNS (Mnemonic: DANISH)", width=86*mm), Spacer(1,1*mm)]
R.append(mini(
["","Sign","Test"],
[["D","Dysdiadochokinesia","Rapid alternating hand movements (patting)"],
["A","Ataxia","Broad-based gait · tandem walk (heel-toe)"],
["N","Nystagmus","Horizontal; fast-phase TOWARD side of lesion"],
["I","Intention tremor","Finger-nose test · Heel-shin test"],
["S","Staccato / scanning speech","Conversation; counting aloud"],
["H","Hypotonia","↓ resistance · Pendular knee jerk"],
["+","Rebound phenomenon","Release extended arm → rebounds excessively"],
["+","Past-pointing","Finger consistently misses target"],
["+","Romberg sign","Positive (falls, eyes closed) = SENSORY ataxia — NOT cerebellar"]],
cw=[8*mm,32*mm,46*mm]))
R += [Spacer(1,2*mm)]
# MENINGEAL
R += [sec_hdr("7. MENINGEAL IRRITATION", width=86*mm), Spacer(1,1*mm)]
R.append(mini(
["Sign","Method","Positive Finding"],
[["Neck stiffness","Passive neck flexion (supine)","Resistance and pain"],
["Kernig's sign","Flex hip + knee to 90°; then extend knee","Pain + spasm; cannot extend beyond 135°"],
["Brudzinski's (neck)","Passive neck flexion (supine)","Involuntary hip + knee flexion"],
["Brudzinski's (contra.)","Flex one hip + knee passively","Contralateral hip + knee flex"]],
cw=[27*mm,34*mm,25*mm]))
R += [Spacer(1,1*mm)]
R.append(Paragraph(
"<b>In INFANTS</b> (Kernig/Brudzinski unreliable — use these): "
"☐ Bulging fontanelle (most reliable) ☐ High-pitched cry "
"☐ Opisthotonus ☐ Photophobia ☐ Hyperaesthesia on handling",
tip_style))
R += [Spacer(1,2*mm)]
# SKULL & SPINE
R += [sec_hdr("8. SKULL & SPINE", width=86*mm), Spacer(1,1*mm)]
R.append(chk_table([
("Head circumference", "Plot on centile — Macro >98th (hydrocephalus, megalencephaly) · Micro <2nd (TORCH, genetic)"),
("Anterior fontanelle","Closes 12–18 m · Bulging = ↑ICP · Sunken = dehydration · Delayed closure = rickets / Down's"),
("Sutures", "Wide / separated = ↑ICP · Ridged / premature fusion = craniosynostosis"),
("Macewen's sign", "Cracked-pot percussion sound = ↑ICP (hydrocephalus)"),
("Cranial bruit", "Auscultate temporally — AV malformation / hyperthyroidism"),
("Transillumination", "Positive = hydranencephaly / large subdural hygroma"),
("Shape", "Scaphocephaly (sagittal) · Brachycephaly (coronal) · Oxycephaly (all sutures)"),
("Spine", "Midline defects (spina bifida, sinus, hairy patch) · Scoliosis · Kyphosis · Tenderness"),
], cw=[36*mm,49*mm]))
R += [Spacer(1,2*mm)]
# FLOPPY INFANT
R += [sec_hdr("FLOPPY INFANT — Central vs Peripheral", bg=DARK_BLUE, width=86*mm), Spacer(1,1*mm)]
R.append(mini(
["Central (UMN) Hypotonia","Peripheral (LMN) Hypotonia"],
[["Alert, responsive baby","Floppy AND weak"],
["Dysmorphic features common","↓ / absent DTRs"],
["Seizures, intellectual disability","Fasciculations present"],
["DTRs normal or brisk","Causes: SMA, congenital myopathy,\nneonatal myasthenia, neuropathy"],
["Causes: HIE, Down syndrome,\nchromosomal, metabolic","—"]],
cw=[43*mm, 43*mm],
hbg=DARK_BLUE))
return R
def summary_section():
items = []
items += [HRFlowable(width="100%", thickness=1, color=MED_BLUE), Spacer(1,1.5*mm)]
items.append(sec_hdr("UMN vs LMN — QUICK COMPARISON", bg=DARK_BLUE))
items.append(Spacer(1,1*mm))
items.append(mini(
["Feature","UMN Lesion","LMN Lesion"],
[["Tone","↑ Spastic","↓ Flaccid"],
["Muscle bulk","Mild disuse wasting","Marked wasting + atrophy"],
["Fasciculations","Absent","Present"],
["DTRs","Exaggerated","Absent / Diminished"],
["Plantars","Extensor — BABINSKI +","Flexor — normal"],
["Abdominal reflexes","Absent","Present"],
["Clonus","Present (ankle/patellar)","Absent"]],
cw=[42*mm,65*mm,65*mm],
hbg=DARK_BLUE))
return items
# ═════════════════════════════════════════════════════════════════════════════
# BUILD
# ═════════════════════════════════════════════════════════════════════════════
def build():
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
rightMargin=12*mm, leftMargin=12*mm,
topMargin=12*mm, bottomMargin=12*mm,
title="CNS Examination in Paediatrics - Quick Reference Checklist",
author="Meharban Singh Essential Paediatrics"
)
story = []
# ── PAGE 1 ────────────────────────────────────────────────────────────────
title_banner(story)
scheme_bar(story)
story.append(two_col(page1_left(), page1_right()))
footer_line(story)
# ── PAGE 2 ────────────────────────────────────────────────────────────────
story.append(PageBreak())
title_banner(story)
story.append(two_col(page2_left(), page2_right()))
story += summary_section()
story.append(Spacer(1,2*mm))
footer_line(story)
doc.build(story)
print(f"✓ PDF saved → {OUTPUT}")
build()
~/cns-checklist/generate_checklist.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/cns-checklist/generate_checklist.py'
cat > /tmp/workspace/cns-checklist/generate_v2.py << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, PageBreak ) from reportlab.lib.styles import ParagraphStyle from reportlab.lib.enums import TA_CENTER OUTPUT = "/tmp/workspace/cns-checklist/CNS_Examination_Paediatrics_Checklist.pdf" DARK_BLUE = colors.HexColor("#1a3a5c") MED_BLUE = colors.HexColor("#2c6fad") LIGHT_BLUE = colors.HexColor("#dce9f7") LIGHT_GREY = colors.HexColor("#f4f6f8") MID_GREY = colors.HexColor("#c8d0da") WHITE = colors.white GREEN = colors.HexColor("#2e7d32") def S(name, **kw): return ParagraphStyle(name, **kw) T_TITLE = S("TT", fontName="Helvetica-Bold", fontSize=17, textColor=WHITE, alignment=TA_CENTER) T_SUB = S("TS", fontName="Helvetica", fontSize=8, textColor=LIGHT_BLUE,alignment=TA_CENTER) T_SEC = S("TC", fontName="Helvetica-Bold", fontSize=8.5,textColor=WHITE, leftPadding=5) T_BODY = S("TB", fontName="Helvetica", fontSize=7.5,textColor=DARK_BLUE, leading=10) T_BBOLD = S("TBB",fontName="Helvetica-Bold", fontSize=7.5,textColor=DARK_BLUE, leading=10) T_SMALL = S("TSm",fontName="Helvetica", fontSize=6.8,textColor=colors.HexColor("#333"),leading=9.5) T_SBOLD = S("TSB",fontName="Helvetica-Bold", fontSize=6.8,textColor=DARK_BLUE, leading=9.5) T_TIP = S("TTp",fontName="Helvetica-Oblique", fontSize=6.5,textColor=GREEN, leading=9) T_FOOT = S("TF", fontName="Helvetica", fontSize=6.2,textColor=colors.grey,alignment=TA_CENTER) def sec_hdr(text, bg=MED_BLUE, w=175*mm): t = Table([[Paragraph(text, T_SEC)]], colWidths=[w]) t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),bg), ("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3), ("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0)])) return t def mini(headers, rows, cw, hbg=MED_BLUE): th = [Paragraph(f"<b>{h}</b>", S("h",fontName="Helvetica-Bold",fontSize=6.5,textColor=WHITE,leading=9)) for h in headers] ar = [th] + [[Paragraph(str(c),T_SMALL) for c in r] for r in rows] t = Table(ar, colWidths=cw) st = [("BACKGROUND",(0,0),(-1,0),hbg), ("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2), ("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3), ("VALIGN",(0,0),(-1,-1),"TOP"),("GRID",(0,0),(-1,-1),0.3,MID_GREY)] for i in range(1,len(ar),2): st.append(("BACKGROUND",(0,i),(-1,i),LIGHT_GREY)) t.setStyle(TableStyle(st)) return t def chk(rows_data, cw): tr = [[Paragraph(f"☐ <b>{l}</b>",T_BBOLD), Paragraph(d,T_SMALL)] for l,d in rows_data] t = Table(tr, colWidths=cw) st = [("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2), ("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3), ("LINEBELOW",(0,0),(-1,-1),0.3,MID_GREY),("VALIGN",(0,0),(-1,-1),"TOP")] for i in range(0,len(tr),2): st.append(("BACKGROUND",(0,i),(-1,i),LIGHT_GREY)) t.setStyle(TableStyle(st)) return t def wrap(items, w): t = Table([[it] for it in items], colWidths=[w]) t.setStyle(TableStyle([("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),1), ("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0)])) return t def twocol(L, R, lw=88*mm, rw=87*mm): t = Table([[wrap(L,lw), wrap(R,rw)]], colWidths=[lw,rw]) t.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"), ("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0), ("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0), ("LINEAFTER",(0,0),(0,-1),0.5,MID_GREY)])) return t def banner(): tb = Table([[Paragraph("CNS EXAMINATION IN PAEDIATRICS",T_TITLE)]], colWidths=[175*mm]) tb.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),DARK_BLUE), ("TOPPADDING",(0,0),(-1,-1),10),("BOTTOMPADDING",(0,0),(-1,-1),4)])) sb = Table([[Paragraph("Quick Reference Checklist • Based on Meharban Singh's Pediatric Clinical Methods / Essential Paediatrics",T_SUB)]], colWidths=[175*mm]) sb.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),MED_BLUE), ("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),6)])) return [tb, sb, Spacer(1,3*mm)] def scheme(): items = ["1. Higher Functions","2. Cranial Nerves","3. Motor System","4. Reflexes", "5. Sensory System","6. Cerebellar Signs","7. Meningeal Irritation","8. Skull & Spine"] cells = [Paragraph(f"☐ {s}", T_SBOLD) for s in items] t = Table([cells[:4], cells[4:]], colWidths=[43*mm]*4) t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),LIGHT_BLUE), ("GRID",(0,0),(-1,-1),0.4,MED_BLUE),("TOPPADDING",(0,0),(-1,-1),3), ("BOTTOMPADDING",(0,0),(-1,-1),3),("LEFTPADDING",(0,0),(-1,-1),5)])) return [t, Spacer(1,3*mm)] def footer(): return [HRFlowable(width="100%",thickness=0.5,color=MID_GREY), Spacer(1,1*mm), Paragraph("Ref: Meharban Singh — Pediatric Clinical Methods / Essential Paediatrics | Quick Reference Checklist | For educational use only",T_FOOT)] # ─── PAGE 1 LEFT ──────────────────────────────────────────────────────────── def p1L(): L = [sec_hdr("1. HIGHER FUNCTIONS (Mnemonic: COMA IS G)", w=87*mm), Spacer(1,1*mm)] L.append(chk([ ("C - Consciousness", "Alert > Drowsy > Obtunded > Stupor > Coma"), ("O - Orientation", "Time / Place / Person"), ("M - Memory", "Immediate . Short-term . Long-term"), ("A - Attention", "Digit span test (forward and backward)"), ("I - Intelligence", "Age-appropriate tasks; IQ scales"), ("S - Speech", "See speech table below"), ("G - Gait", "Free walk . toes . heels . tandem gait"), ], cw=[40*mm,44*mm])) L += [Spacer(1,1*mm), Paragraph("<b>Glasgow Coma Scale</b>",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Component","Score","Response"],[ ["Eye (E)","4/3/2/1","Spontaneous / To voice / To pain / None"], ["Verbal (V)","5 to 1","Oriented/Confused/Words/Sounds/None"], ["Motor (M)","6 to 1","Obeys/Localise/Withdraw/Flex/Ext/None"], ["Total","15 = Normal","Score <=8 = Severe coma; Paed-GCS for infants"]], cw=[22*mm,18*mm,47*mm])) L += [Spacer(1,1*mm), Paragraph("<b>Speech Abnormalities</b>",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Pattern","Lesion"],[ ["Slurred / dysarthric","Pyramidal (UMN)"], ["Monotonous","Extrapyramidal"], ["Staccato / scanning / explosive","Cerebellar"], ["Nasal / rhinolalia","Palatal palsy (CN X)"], ["Expressive dysphasia","Broca's area (dominant hemisphere)"], ["Receptive dysphasia","Wernicke's area"], ["No words >18 m / No sentences >3 y","Developmental delay / deafness"], ["Echolalia","Autism / intellectual disability"]], cw=[50*mm,37*mm])) L += [Spacer(1,1*mm), Paragraph("<b>Gait Types</b>",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Gait","Lesion"],[ ["Hemiplegic / circumduction","Unilateral pyramidal (UMN)"], ["Scissoring / spastic","Spastic diplegia - CP"], ["Ataxic / broad-based / reeling","Cerebellar"], ["High-stepping (steppage)","Foot drop - LMN / peroneal nerve"], ["Shuffling / festinant","Extrapyramidal"], ["Waddling / Trendelenburg","Proximal myopathy - DMD"], ["Stamping / sensory ataxic","Posterior column / peripheral neuropathy"]], cw=[50*mm,37*mm])) return L # ─── PAGE 1 RIGHT ─────────────────────────────────────────────────────────── def p1R(): R = [sec_hdr("2. CRANIAL NERVES", w=86*mm), Spacer(1,1*mm)] R.append(mini(["CN","Name","Test / Look for"],[ ["I","Olfactory","Each nostril separately - coffee/soap; anosmia"], ["II","Optic","VA . Visual fields . Pupils . Fundoscopy (papilledema, optic atrophy, cherry-red spot)"], ["III IV VI","Eye movements","Ptosis . EOMs H-pattern . Pupil reflex . Nystagmus . Strabismus (Hirschberg, cover test)"], ["V","Trigeminal","Touch/pain 3 divisions . Corneal reflex . Masseter bulk . Jaw jerk . Jaw deviation"], ["VII","Facial","Symmetry at rest and movement. UMN = forehead spared; LMN = full face (Bell's)"], ["VIII","Vestibulochochlear","Whisper . Rinne/Weber . BERA . Nystagmus . Romberg . Dix-Hallpike"], ["IX X","Glossoph./Vagus","Say 'Aah' . Uvula deviates AWAY from lesion . Gag reflex . Voice quality"], ["XI","Spinal Accessory","SCM and Trapezius strength against resistance"], ["XII","Hypoglossal","Tongue deviates TOWARD LMN lesion . Wasting and fasciculations in LMN"]], cw=[12*mm,22*mm,52*mm])) R += [Spacer(1,2*mm), sec_hdr("3. MOTOR SYSTEM", w=86*mm), Spacer(1,1*mm)] R.append(chk([ ("Inspection", "Bulk . Wasting . Fasciculations . Posture . Deformity"), ("Tone", "Passive ROM at joints - see tone table below"), ("Infant tone tests", "Ventral suspension . Traction response . Scarf sign . Popliteal angle"), ("Power (MRC 0-5)", "Proximal AND distal muscle groups"), ("Gower's sign", "Walks up thighs to rise = proximal weakness (DMD, SMA)"), ("Inv. movements", "Tremor . Chorea . Athetosis . Tics . Myoclonus . Dystonia . Ballismus"), ], cw=[38*mm,47*mm])) R += [Spacer(1,1*mm), Paragraph("<b>Tone Patterns</b>",T_SBOLD), Spacer(1,0.5*mm)] R.append(mini(["Tone","Sign","Lesion"],[ ["Spasticity","Velocity-dependent increase; clasp-knife","Pyramidal / UMN"], ["Rigidity","Lead-pipe (uniform); Cogwheel if tremor","Extrapyramidal"], ["Hypotonia","Decreased resistance; floppy / rag-doll","LMN, cerebellar, muscle disease"], ["Paratonia","Variable resistance any direction","Frontal lobe lesion"]], cw=[22*mm,38*mm,26*mm])) R += [Spacer(1,1*mm), Paragraph("<b>MRC Power Scale</b>",T_SBOLD), Spacer(1,0.5*mm)] R.append(mini(["Grade","Description"],[ ["0","No contraction"],["1","Flicker only"], ["2","Movement with gravity eliminated"],["3","Movement against gravity"], ["4","Against some resistance"],["5","Normal power"]], cw=[14*mm,71*mm])) R += [Spacer(1,1*mm)] R.append(Paragraph( "<b>Inv. movements:</b> Chorea (Sydenham's - rheumatic fever) . " "Athetosis (kernicterus, athetoid CP) . Ballismus (subthalamic nucleus) . " "Tics (Tourette) . Myoclonus (epilepsy, metabolic)",T_TIP)) return R # ─── PAGE 2 LEFT ──────────────────────────────────────────────────────────── def p2L(): L = [sec_hdr("4. REFLEXES", w=87*mm), Spacer(1,1*mm), Paragraph("<b>Deep Tendon Reflexes</b>",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Reflex","Root","Method"],[ ["Biceps","C5-C6","Tap biceps tendon"], ["Brachioradialis","C5-C6","Tap styloid process"], ["Triceps","C6-C7","Tap triceps tendon at elbow"], ["Knee (Patellar)","L3-L4","Tap patellar tendon"], ["Ankle (Achilles)","S1-S2","Tap Achilles tendon"]], cw=[32*mm,16*mm,39*mm])) L.append(Paragraph(" Grading: 0 (absent) + (decreased) ++ (normal) +++ (brisk) ++++ (clonus)",T_TIP)) L += [Spacer(1,1*mm), Paragraph("<b>Plantar Response</b>",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Response","Interpretation"],[ ["Toe FLEXION","Normal"], ["DORSIFLEXION great toe + fanning = BABINSKI +","UMN lesion"], ["Babinski normal in infants up to 12-18 months","Incomplete myelination (physiological)"]], cw=[55*mm,32*mm])) L += [Spacer(1,1*mm), Paragraph("<b>Primitive Reflexes</b> - Persist beyond expected age = CP / cortical damage",T_SBOLD), Spacer(1,0.5*mm)] L.append(mini(["Reflex","Disappears","Note"],[ ["Moro","3-4 months","Asymmetric = brachial plexus injury"], ["Rooting","3-4 months","Touch cheek - turns toward stimulus"], ["Sucking","3-4 months","—"], ["Palmar grasp","3-4 months","Finger in palm - grips"], ["ATNR (tonic neck)","4-6 months","'Fencing posture'; head turn - arm+leg extend on face side"], ["Stepping","2-3 months","—"], ["Galant (truncal incurvation)","2-3 months","Stroke paravertebral - spine curves ipsilateral"], ["Plantar grasp","9-12 months","Pressure on sole - toe flexion"], ["Parachute reflex","Appears 6-9 m; NEVER disappears","Arms extend when tipped; absent/asymmetric = CP"]], cw=[30*mm,26*mm,31*mm])) L += [Spacer(1,2*mm), sec_hdr("5. SENSORY SYSTEM", w=87*mm), Spacer(1,1*mm)] L.append(chk([ ("Light touch", "Cotton wisp; compare both sides"), ("Pain (pin-prick)", "Both sides; proximal vs distal"), ("Temperature", "Hot and cold tubes"), ("Vibration", "128 Hz tuning fork on bony prominences"), ("Proprioception", "Move toe/finger; identify up or down (eyes closed)"), ("Stereognosis", "Identify object in hand with eyes closed"), ("Graphesthesia", "Number/letter drawn on palm"), ("Two-point disc.", "Distinguish 2 separate points on skin"), ], cw=[38*mm,47*mm])) L += [Spacer(1,1*mm)] L.append(Paragraph( "<b>Sensory level:</b> In spinal cord lesions, map upper level of sensory loss on trunk using dermatomal chart.",T_TIP)) return L # ─── PAGE 2 RIGHT ─────────────────────────────────────────────────────────── def p2R(): R = [sec_hdr("6. CEREBELLAR SIGNS (Mnemonic: DANISH)", w=86*mm), Spacer(1,1*mm)] R.append(mini(["","Sign","Test"],[ ["D","Dysdiadochokinesia","Rapid alternating hand movements (patting palm)"], ["A","Ataxia","Broad-based gait; tandem (heel-toe) walk"], ["N","Nystagmus","Horizontal; fast-phase TOWARD side of lesion"], ["I","Intention tremor","Finger-nose test; heel-shin test"], ["S","Staccato / scanning speech","Conversation; counting aloud"], ["H","Hypotonia","Decreased resistance; pendular knee jerk"], ["+","Rebound phenomenon","Release extended arm - rebounds excessively"], ["+","Past-pointing","Finger consistently misses target"], ["+","Romberg sign","Positive (falls eyes closed) = SENSORY ataxia - NOT cerebellar"]], cw=[8*mm,32*mm,46*mm])) R += [Spacer(1,2*mm), sec_hdr("7. MENINGEAL IRRITATION", w=86*mm), Spacer(1,1*mm)] R.append(mini(["Sign","Method","Positive Finding"],[ ["Neck stiffness","Passive neck flexion (supine)","Resistance and pain on flexion"], ["Kernig's sign","Flex hip+knee 90 deg; then extend knee","Pain + spasm; cannot extend beyond 135 deg"], ["Brudzinski's (neck)","Passive neck flexion (supine)","Involuntary hip + knee flexion"], ["Brudzinski's (contra.)","Flex one hip+knee passively","Contralateral hip + knee also flex"]], cw=[27*mm,34*mm,25*mm])) R += [Spacer(1,1*mm)] R.append(Paragraph( "<b>In INFANTS</b> (Kernig/Brudzinski unreliable): " " Check Box Bulging fontanelle (most reliable) " " Check Box High-pitched cry " " Check Box Opisthotonus " " Check Box Photophobia " " Check Box Hyperaesthesia on handling",T_TIP)) R += [Spacer(1,2*mm), sec_hdr("8. SKULL AND SPINE", w=86*mm), Spacer(1,1*mm)] R.append(chk([ ("Head circumference", "Plot on centile: Macro >98th (hydrocephalus) . Micro <2nd (TORCH, genetic)"), ("Ant. fontanelle","Closes 12-18 m . Bulging = raised ICP . Sunken = dehydration . Delayed = rickets/Down's"), ("Sutures","Wide = raised ICP . Ridged/premature fusion = craniosynostosis"), ("Macewen's sign","Cracked-pot percussion sound = raised ICP (hydrocephalus)"), ("Cranial bruit","Auscultate temporally - AV malformation / hyperthyroidism"), ("Transillumination","Positive = hydranencephaly / large subdural hygroma"), ("Skull shape","Scaphocephaly (sagittal) . Brachycephaly (coronal) . Oxycephaly (all sutures)"), ("Spine","Midline defects . Scoliosis . Kyphosis . Tenderness . Spina bifida / meningocele"), ], cw=[36*mm,49*mm])) R += [Spacer(1,2*mm), sec_hdr("FLOPPY INFANT: Central vs Peripheral", bg=DARK_BLUE, w=86*mm), Spacer(1,1*mm)] R.append(mini(["Central (UMN) Hypotonia","Peripheral (LMN) Hypotonia"],[ ["Alert, responsive baby","Floppy AND weak"], ["Dysmorphic features common","Absent or reduced DTRs"], ["Seizures, intellectual disability","Fasciculations present"], ["DTRs normal or brisk","Causes: SMA, congenital myopathy, neonatal myasthenia, neuropathy"], ["Causes: HIE, Down syndrome, chromosomal, metabolic","—"]], cw=[43*mm,43*mm], hbg=DARK_BLUE)) return R def summary(): items = [HRFlowable(width="100%",thickness=1,color=MED_BLUE), Spacer(1,1.5*mm), sec_hdr("UMN vs LMN QUICK COMPARISON", bg=DARK_BLUE), Spacer(1,1*mm)] items.append(mini(["Feature","UMN Lesion","LMN Lesion"],[ ["Tone","Increased (spastic)","Decreased (flaccid)"], ["Muscle bulk","Mild disuse wasting","Marked wasting"], ["Fasciculations","Absent","Present"], ["DTRs","Exaggerated","Absent / Diminished"], ["Plantars","Extensor - BABINSKI positive","Flexor - normal"], ["Abdominal reflexes","Absent","Present"], ["Clonus","Present (ankle/patellar)","Absent"]], cw=[42*mm,65*mm,65*mm], hbg=DARK_BLUE)) return items def build(): doc = SimpleDocTemplate(OUTPUT, pagesize=A4, rightMargin=12*mm, leftMargin=12*mm, topMargin=12*mm, bottomMargin=12*mm, title="CNS Examination in Paediatrics - Quick Reference Checklist") story = [] story += banner() story += scheme() story.append(twocol(p1L(), p1R())) story += footer() story.append(PageBreak()) story += banner() story.append(twocol(p2L(), p2R())) story += summary() story += [Spacer(1,2*mm)] + footer() doc.build(story) print("PDF saved to:", OUTPUT) build() PYEOF echo "written"
cd /tmp/workspace/cns-checklist && python generate_v2.py 2>&1
CNS Examination Paediatrics Checklist
PDF Document · PDF