Explain toxicdromes from forensic toxicology book narayana reddy
| Poisons/Drugs | Antihistamines, antiparkinsonian drugs, atropine, scopolamine, amantadine, antipsychotic drugs, antidepressants, antispasmodics, skeletal muscle relaxants, many plants (especially Datura), and fungi (e.g., Amanita muscaria) |
| Clinical Findings | Hyperthermia, dry skin, dilated pupils (mydriasis), vasodilation causing flushed skin, hypervigilant, hallucinating, delirium with mumbling speech, tachycardia, myoclonus, urinary retention, decreased bowel sounds |
| Poisons/Drugs | Organophosphates, carbamates, parasympathomimetic drugs, and some mushrooms |
| Clinical Findings | Confusion, CNS depression, salivation, lacrimation, urinary and fecal incontinence, vomiting, sweating, fasciculations, seizures, miosis, pulmonary edema, tachycardia/bradycardia |
| Poisons/Drugs | Cocaine, ecstasy (MDMA), amphetamines, caffeine, theophylline |
| Clinical Findings | Paranoia, delusions, tachycardia, hypertension, hyperpyrexia, hyperreflexia, sweating, mydriasis, seizures, arrhythmias |
| Poisons/Drugs | Morphine, pethidine, fentanyl, codeine, methadone |
| Clinical Findings | Miosis (pinpoint pupils), hypotension, bradycardia, hypothermia, CNS depression, pulmonary edema, respiratory depression, hyporeflexia, coma, rarely convulsions |
| Poisons/Drugs | Barbiturates, benzodiazepines, ethanol |
| Clinical Findings | Miosis, hypotension, bradycardia, hypothermia, confusion, CNS depression, hyporeflexia, coma |
| Feature | Anticholinergic | Cholinergic | Sympathomimetic | Opioid | Sedative/Hypnotic |
|---|---|---|---|---|---|
| Pupils | Mydriasis | Miosis | Mydriasis | Miosis (pinpoint) | Miosis |
| Skin | Dry, flushed | Diaphoretic | Diaphoretic | Normal | Normal |
| Bowel sounds | Decreased | Increased | Normal | Decreased | Normal/Decreased |
| Heart rate | Tachycardia | Brady/Tachy | Tachycardia | Bradycardia | Bradycardia |
| BP | Normal/Elevated | Variable | Hypertension | Hypotension | Hypotension |
| Temperature | Hyperthermia | Normal | Hyperpyrexia | Hypothermia | Hypothermia |
| CNS | Delirium/Hallucinations | Confusion/Seizures | Paranoia/Seizures | Depression/Coma | Depression/Coma |
"A toxidrome is a constellation of findings, resulting from any given poison. It serves to clue the clinician into the correct diagnosis."
Create a quick reference PDF of toxidromes with mnemonics and with antidote and management
mkdir -p /tmp/workspace/toxidromes && ls /tmp/workspace/toxidromes/
~/toxidromes/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.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
OUTPUT = "/tmp/workspace/toxidromes/Toxidromes_Quick_Reference.pdf"
# ── Colour palette ─────────────────────────────────────────────────────────
CLR_HEADER_BG = colors.HexColor("#1A3A5C") # deep navy
CLR_HEADER_FG = colors.white
CLR_ANTI_BG = colors.HexColor("#E8F4F8") # pale blue – anticholinergic
CLR_ANTI_ACC = colors.HexColor("#2196A8")
CLR_CHOL_BG = colors.HexColor("#E8F8EE") # pale green – cholinergic
CLR_CHOL_ACC = colors.HexColor("#2D8A4E")
CLR_SYMP_BG = colors.HexColor("#FFF3E0") # pale amber – sympathomimetic
CLR_SYMP_ACC = colors.HexColor("#E07B00")
CLR_OPIO_BG = colors.HexColor("#F3E8F8") # pale lavender – opioid
CLR_OPIO_ACC = colors.HexColor("#7B3FA0")
CLR_SEDT_BG = colors.HexColor("#FCF0F0") # pale rose – sedative
CLR_SEDT_ACC = colors.HexColor("#C0392B")
CLR_MNEM_BG = colors.HexColor("#FFFDE7") # cream – mnemonic boxes
CLR_MNEM_BORDER = colors.HexColor("#F9A825")
CLR_COMP_HDR = colors.HexColor("#2C3E50") # comparison table header
CLR_ROW_ALT = colors.HexColor("#F5F5F5")
CLR_ANTIDOTE_BG = colors.HexColor("#E3F2FD")
CLR_ANTIDOTE_ACC= colors.HexColor("#1565C0")
W, H = A4 # 595.27 x 841.89 pt
# ── Document setup ─────────────────────────────────────────────────────────
def header_footer(canvas, doc):
canvas.saveState()
# Header bar
canvas.setFillColor(CLR_HEADER_BG)
canvas.rect(0, H - 28, W, 28, fill=1, stroke=0)
canvas.setFillColor(colors.white)
canvas.setFont("Helvetica-Bold", 9)
canvas.drawString(18, H - 18, "TOXIDROMES QUICK REFERENCE | Forensic Toxicology")
canvas.setFont("Helvetica", 8)
canvas.drawRightString(W - 18, H - 18, "Based on Narayana Reddy 36th Ed. & Goodman & Gilman")
# Footer bar
canvas.setFillColor(CLR_HEADER_BG)
canvas.rect(0, 0, W, 20, fill=1, stroke=0)
canvas.setFillColor(colors.white)
canvas.setFont("Helvetica", 7)
canvas.drawCentredString(W / 2, 6, f"Page {doc.page} | For educational use only")
canvas.restoreState()
doc = BaseDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=18*mm, rightMargin=18*mm,
topMargin=22*mm, bottomMargin=14*mm,
)
frame = Frame(doc.leftMargin, doc.bottomMargin,
doc.width, doc.height, id="main")
doc.addPageTemplates([PageTemplate(id="main", frames=frame,
onPage=header_footer)])
# ── Styles ─────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
sTitle = S("sTitle", fontName="Helvetica-Bold", fontSize=20, textColor=CLR_HEADER_BG,
alignment=TA_CENTER, spaceAfter=4)
sSubtitle = S("sSubtitle", fontName="Helvetica", fontSize=10, textColor=colors.HexColor("#555555"),
alignment=TA_CENTER, spaceAfter=12)
sSectionHdr = S("sSectionHdr", fontName="Helvetica-Bold", fontSize=13,
textColor=colors.white, alignment=TA_LEFT, leading=16)
sBody = S("sBody", fontName="Helvetica", fontSize=8.5, leading=12,
textColor=colors.HexColor("#222222"))
sBold = S("sBold", fontName="Helvetica-Bold", fontSize=8.5, leading=12,
textColor=colors.HexColor("#222222"))
sMnem = S("sMnem", fontName="Helvetica-BoldOblique", fontSize=9, leading=13,
textColor=colors.HexColor("#5D4037"))
sMnemLetter = S("sMnemLetter", fontName="Helvetica-Bold", fontSize=9, leading=13,
textColor=colors.HexColor("#E07B00"))
sTableHdr = S("sTableHdr", fontName="Helvetica-Bold", fontSize=8, textColor=colors.white,
alignment=TA_CENTER, leading=10)
sTableCell = S("sTableCell", fontName="Helvetica", fontSize=7.5, leading=10,
textColor=colors.HexColor("#111111"))
sTableCellB = S("sTableCellB", fontName="Helvetica-Bold", fontSize=7.5, leading=10,
textColor=colors.HexColor("#111111"))
sWarning = S("sWarning", fontName="Helvetica-BoldOblique", fontSize=8, leading=11,
textColor=colors.HexColor("#C0392B"))
sRef = S("sRef", fontName="Helvetica-Oblique", fontSize=7, textColor=colors.HexColor("#888888"),
alignment=TA_CENTER, spaceBefore=4)
story = []
PW = doc.width # usable width
# ══════════════════════════════════════════════════════════════════════════════
# TITLE PAGE BLOCK
# ══════════════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 6*mm))
story.append(Paragraph("TOXIDROMES", sTitle))
story.append(Paragraph("Quick Reference Card | Mnemonics · Antidotes · Management", sSubtitle))
story.append(HRFlowable(width="100%", thickness=2, color=CLR_HEADER_BG, spaceAfter=8))
def definition_box():
data = [[Paragraph(
'<b>Definition:</b> A <b>toxidrome</b> is a constellation of clinical findings produced by a '
'particular class of poison. Recognising the toxidrome guides rapid diagnosis and specific '
'antidote therapy <i>before</i> laboratory results are available.',
S("def", fontName="Helvetica", fontSize=9, leading=13, textColor=CLR_HEADER_BG))]]
t = Table(data, colWidths=[PW])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#EEF4FB")),
("BOX", (0,0), (-1,-1), 1.2, CLR_HEADER_BG),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("ROUNDEDCORNERS", [4]),
]))
return t
story.append(definition_box())
story.append(Spacer(1, 6*mm))
# ══════════════════════════════════════════════════════════════════════════════
# HELPER: build a toxidrome card
# ══════════════════════════════════════════════════════════════════════════════
def section_header(text, accent_color):
data = [[Paragraph(text, sSectionHdr)]]
t = Table(data, colWidths=[PW])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), accent_color),
("LEFTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("ROUNDEDCORNERS", [4]),
]))
return t
def two_col(left_items, right_items, bg, accent, left_label="Clinical Features", right_label="Poisons / Drugs"):
"""Two-column inner table for features vs poisons."""
def cell(items, label):
inner = [[Paragraph(f"<b>{label}</b>",
S("lbl", fontName="Helvetica-Bold", fontSize=8,
textColor=accent, leading=11))]]
for item in items:
inner.append([Paragraph(f"• {item}", sBody)])
t = Table(inner, colWidths=[(PW/2 - 8)])
t.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 2),
("RIGHTPADDING", (0,0), (-1,-1), 2),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
]))
return t
outer = [[cell(left_items, left_label), cell(right_items, right_label)]]
t = Table(outer, colWidths=[PW/2 - 4, PW/2 - 4], hAlign="CENTER")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 0.8, accent),
("LINEAFTER", (0,0), (0,-1), 0.5, accent),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
return t
def mnemonic_box(title, lines):
"""Render mnemonic letters with expansion."""
content = [Paragraph(f"<b>Mnemonic: {title}</b>",
S("mh", fontName="Helvetica-Bold", fontSize=8.5,
textColor=colors.HexColor("#5D4037"), leading=12))]
for line in lines:
content.append(Paragraph(line, sBody))
data = [[c] for c in content]
t = Table(data, colWidths=[PW - 16])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), CLR_MNEM_BG),
("BOX", (0,0), (-1,-1), 1.2, CLR_MNEM_BORDER),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("ROUNDEDCORNERS", [4]),
]))
return t
def antidote_management_box(antidote_lines, management_lines, bg=CLR_ANTIDOTE_BG, acc=CLR_ANTIDOTE_ACC):
def col(label, items):
rows = [[Paragraph(f"<b>{label}</b>",
S("ah", fontName="Helvetica-Bold", fontSize=8,
textColor=acc, leading=11))]]
for item in items:
rows.append([Paragraph(f"• {item}", sBody)])
t = Table(rows, colWidths=[PW/2 - 8])
t.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 2),
("RIGHTPADDING", (0,0), (-1,-1), 2),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
]))
return t
outer = [[col("ANTIDOTE(S)", antidote_lines), col("MANAGEMENT PRINCIPLES", management_lines)]]
t = Table(outer, colWidths=[PW/2 - 4, PW/2 - 4], hAlign="CENTER")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1, acc),
("LINEAFTER", (0,0), (0,-1), 0.5, acc),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
return t
def GAP(n=4): return Spacer(1, n*mm)
# ══════════════════════════════════════════════════════════════════════════════
# 1. ANTICHOLINERGIC
# ══════════════════════════════════════════════════════════════════════════════
story.append(KeepTogether([
section_header("1. ANTICHOLINERGIC TOXIDROME", CLR_ANTI_ACC),
GAP(2),
two_col(
left_items=[
"Hyperthermia (hot as a hare)",
"Dry, flushed skin (dry as a bone, red as a beet)",
"Mydriasis – dilated pupils (blind as a bat)",
"Tachycardia",
"Delirium, hallucinations, mumbling speech (mad as a hatter)",
"Urinary retention",
"Decreased bowel sounds",
"Myoclonus",
],
right_items=[
"Antihistamines (diphenhydramine)",
"Atropine, scopolamine",
"Antiparkinsonian drugs (benztropine)",
"Antipsychotics (phenothiazines)",
"Tricyclic antidepressants",
"Antispasmodics",
"Skeletal muscle relaxants",
"Datura stramonium (Jimsonweed)",
"Amanita muscaria (fungi)",
],
bg=CLR_ANTI_BG, accent=CLR_ANTI_ACC,
left_label="Clinical Features", right_label="Common Causative Agents"
),
GAP(2),
mnemonic_box("\"HOT, DRY, BLIND, MAD, FULL\"",
["<b>H</b>ot as a hare • <b>D</b>ry as a bone • <b>R</b>ed as a beet",
"<b>B</b>lind as a bat (mydriasis) • <b>M</b>ad as a hatter (delirium)",
"<b>F</b>ull as a flask (urinary retention) • Bowel sounds absent"]),
GAP(2),
antidote_management_box(
antidote_lines=[
"Physostigmine 1–2 mg IV slow (specific antidote for delirium)",
"Benzodiazepines for agitation/seizures",
],
management_lines=[
"ABC – airway, IV access, monitoring",
"Active cooling for hyperthermia",
"Urinary catheter for retention",
"Avoid physostigmine in TCA overdose (risk of asystole)",
"Gastric lavage/activated charcoal if early & airway protected",
]
),
GAP(4),
]))
# ══════════════════════════════════════════════════════════════════════════════
# 2. CHOLINERGIC / ANTICHOLINESTERASE
# ══════════════════════════════════════════════════════════════════════════════
story.append(KeepTogether([
section_header("2. CHOLINERGIC / ANTICHOLINESTERASE TOXIDROME", CLR_CHOL_ACC),
GAP(2),
two_col(
left_items=[
"Miosis (pinpoint pupils)",
"Salivation, lacrimation",
"Urinary & fecal incontinence",
"Bronchospasm, bronchorrhoea, pulmonary oedema",
"Bradycardia (or tachycardia early)",
"Sweating, vomiting",
"Fasciculations, muscle weakness",
"Seizures, CNS depression, coma",
],
right_items=[
"Organophosphate pesticides (malathion, parathion)",
"Nerve agents (sarin, VX, tabun)",
"Carbamates",
"Parasympathomimetic drugs (pilocarpine, neostigmine)",
"Toxic mushrooms (Inocybe, Clitocybe spp.)",
],
bg=CLR_CHOL_BG, accent=CLR_CHOL_ACC,
left_label="Clinical Features", right_label="Common Causative Agents"
),
GAP(2),
mnemonic_box("SLUDGE / DUMBELS",
["<b>SLUDGE</b>: <b>S</b>alivation · <b>L</b>acrimation · <b>U</b>rination · <b>D</b>efecation · <b>G</b>I distress · <b>E</b>mesis",
"<b>DUMBELS</b>: <b>D</b>iarrhoea · <b>U</b>rination · <b>M</b>iosis · <b>B</b>radycardia/Bronchospasm",
" <b>E</b>mesis · <b>L</b>acrimation · <b>S</b>alivation/Sweating",
"Nicotinic: <b>MTWTF</b> – <b>M</b>ydriasis · <b>T</b>achycardia · <b>W</b>eakness · <b>T</b>remor · <b>F</b>asciculations"]),
GAP(2),
antidote_management_box(
antidote_lines=[
"Atropine 2–4 mg IV (large doses may be needed; endpoint: drying of secretions)",
"Pralidoxime (2-PAM) 30 mg/kg IV bolus, then 8–10 mg/kg/hr infusion",
" — Give within 24–48 hr to reactivate cholinesterase",
],
management_lines=[
"Full PPE – decontaminate patient first",
"Airway suction, early intubation if bronchospasm severe",
"High-flow O₂",
"Benzodiazepines for seizures",
"Monitor RBC cholinesterase levels",
"Avoid succinylcholine (prolonged paralysis)",
]
),
GAP(4),
]))
# ══════════════════════════════════════════════════════════════════════════════
# 3. SYMPATHOMIMETIC
# ══════════════════════════════════════════════════════════════════════════════
story.append(KeepTogether([
section_header("3. SYMPATHOMIMETIC TOXIDROME", CLR_SYMP_ACC),
GAP(2),
two_col(
left_items=[
"Tachycardia",
"Hypertension",
"Hyperpyrexia (high fever)",
"Mydriasis",
"Diaphoresis (sweating — KEY differentiator from anticholinergic)",
"Agitation, paranoia, delusions",
"Hyperreflexia",
"Seizures, arrhythmias",
],
right_items=[
"Cocaine",
"Amphetamines (including methamphetamine)",
"MDMA (ecstasy)",
"Theophylline",
"Caffeine (high dose)",
"Sympathomimetic decongestants (pseudoephedrine)",
],
bg=CLR_SYMP_BG, accent=CLR_SYMP_ACC,
left_label="Clinical Features", right_label="Common Causative Agents"
),
GAP(2),
mnemonic_box("\"FAST & HOT & WET\"",
["<b>FAST</b>: Tachycardia · Hypertension · Agitation · Sweating (differentiates from anticholinergic)",
"<b>HOT</b>: Hyperpyrexia (can be fatal — aggressive cooling needed)",
"<b>WET</b>: Diaphoresis present (unlike anticholinergic, skin is MOIST not dry)",
"Pupils dilated (mydriasis) — shared with anticholinergic"]),
GAP(2),
antidote_management_box(
antidote_lines=[
"No specific antidote",
"Benzodiazepines (diazepam/lorazepam) — first-line for all symptoms",
"Phentolamine (alpha-blocker) for severe hypertension",
],
management_lines=[
"Aggressive cooling for hyperthermia (ice packs, cooling blanket)",
"Benzodiazepines for seizures, agitation, and hypertension",
"Avoid beta-blockers alone (risk of unopposed alpha → hypertensive crisis)",
"Sodium bicarbonate for cocaine-induced QRS widening",
"Cardiac monitoring; avoid physostigmine",
]
),
GAP(4),
]))
# ══════════════════════════════════════════════════════════════════════════════
# 4. OPIOID
# ══════════════════════════════════════════════════════════════════════════════
story.append(KeepTogether([
section_header("4. OPIOID TOXIDROME", CLR_OPIO_ACC),
GAP(2),
two_col(
left_items=[
"Miosis — PINPOINT pupils (classic)",
"Respiratory depression ← most dangerous feature",
"CNS depression, stupor, coma",
"Bradycardia",
"Hypotension",
"Hypothermia",
"Pulmonary oedema",
"Hyporeflexia",
"Convulsions — RARE (meperidine is exception)",
],
right_items=[
"Morphine, heroin",
"Pethidine (meperidine)",
"Fentanyl, sufentanil",
"Codeine",
"Methadone",
"Tramadol",
"Oxycodone, hydrocodone",
],
bg=CLR_OPIO_BG, accent=CLR_OPIO_ACC,
left_label="Clinical Features", right_label="Common Causative Agents"
),
GAP(2),
mnemonic_box("TRIAD: \"PIN-POINT · PUMP DOWN · PASSED OUT\"",
["<b>Pin-point pupils</b> (miosis) — pathognomonic",
"<b>Pump down</b>: Respiratory depression (rate <12/min)",
"<b>Passed out</b>: CNS depression / coma",
"All three together = CLASSIC opioid toxidrome — treat immediately with NALOXONE"]),
GAP(2),
antidote_management_box(
antidote_lines=[
"Naloxone 0.4–2 mg IV/IM/IN — repeat every 2–3 min (max 10 mg)",
"Naloxone infusion for long-acting opioids (methadone, fentanyl)",
" — Infusion rate: 2/3 of effective reversal dose per hour",
],
management_lines=[
"Bag-valve-mask ventilation immediately if apnoeic",
"Early intubation if naloxone insufficient",
"Monitor for re-narcotisation (short T½ of naloxone vs long T½ of opioid)",
"Treat pulmonary oedema with O₂, PEEP if intubated",
"Avoid in opioid-dependent patients — precipitates acute withdrawal",
]
),
GAP(4),
]))
# ══════════════════════════════════════════════════════════════════════════════
# 5. SEDATIVE / HYPNOTIC
# ══════════════════════════════════════════════════════════════════════════════
story.append(KeepTogether([
section_header("5. SEDATIVE / HYPNOTIC TOXIDROME", CLR_SEDT_ACC),
GAP(2),
two_col(
left_items=[
"Miosis",
"CNS depression, confusion, stupor, coma",
"Respiratory depression (less severe than opioids)",
"Hypotension",
"Bradycardia",
"Hypothermia",
"Hyporeflexia, ataxia, dysarthria",
"Convulsions rare",
],
right_items=[
"Barbiturates (phenobarbitone, pentobarbitone)",
"Benzodiazepines (diazepam, clonazepam)",
"Ethanol (alcohol)",
"Gamma-hydroxybutyrate (GHB)",
"Chloral hydrate",
"Carisoprodol, meprobamate",
],
bg=CLR_SEDT_BG, accent=CLR_SEDT_ACC,
left_label="Clinical Features", right_label="Common Causative Agents"
),
GAP(2),
mnemonic_box("\"ABCD DOWN\" — everything is depressed",
["<b>A</b>ltered consciousness • <b>B</b>radycardia • <b>C</b>old (hypothermia) • <b>D</b>epressed breathing",
"Miosis present (like opioid, unlike anticholinergic/sympathomimetic)",
"<b>Key distinction from opioid:</b> Pulmonary oedema ABSENT; convulsions absent; naloxone has NO effect",
"Flumazenil reverses BZD only — short-acting, resedation likely"]),
GAP(2),
antidote_management_box(
antidote_lines=[
"Flumazenil 0.2 mg IV q1 min (max 1 mg) — for benzodiazepines ONLY",
" — Contraindicated if seizure risk (BZD-dependent, TCA co-ingestion)",
"No antidote for barbiturates or ethanol",
],
management_lines=[
"Airway: early intubation for severe respiratory depression",
"Urinary alkalinisation (sodium bicarbonate) for phenobarbitone",
"Haemodialysis for severe phenobarbitone toxicity",
"Thiamine 100 mg IV before glucose in ethanol toxicity",
"Supportive: IV fluids, vasopressors for hypotension",
"Activated charcoal if early (<1hr) and airway protected",
]
),
GAP(6),
]))
# ══════════════════════════════════════════════════════════════════════════════
# PAGE 2 — COMPARISON TABLE + ANTIDOTE SUMMARY
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(Paragraph("AT-A-GLANCE COMPARISON TABLE", sTitle))
story.append(GAP(3))
comp_headers = ["Feature", "Anticholinergic", "Cholinergic", "Sympathomimetic", "Opioid", "Sedative/Hypnotic"]
comp_data = [
["Pupils", "Mydriasis", "Miosis", "Mydriasis", "Miosis (pin-point)", "Miosis"],
["Skin", "Dry, flushed","Diaphoretic","Diaphoretic", "Normal/pale", "Normal"],
["Heart Rate", "Tachycardia","Brady/Tachy","Tachycardia", "Bradycardia", "Bradycardia"],
["BP", "↑ / Normal", "Variable", "Hypertension","Hypotension", "Hypotension"],
["Temperature", "Hyperthermic","Normal", "Hyperpyrexic","Hypothermic", "Hypothermic"],
["Bowel Sounds","Decreased", "Increased", "Normal", "Decreased", "Normal/Dec."],
["Resp. Rate", "Normal/↑", "↓ (bronchospasm)","Normal/↑","↓↓ (critical)", "↓"],
["CNS", "Delirium/Halluc.","Confusion/Seizures","Paranoia/Seizures","Depression/Coma","Depression/Coma"],
["Salivation", "Dry mouth", "Excess (SLUDGE)","Diaphoresis","Dry", "Dry"],
["Antidote", "Physostigmine","Atropine + 2-PAM","None (BZD)","Naloxone","Flumazenil (BZD only)"],
]
col_widths = [PW * x for x in [0.155, 0.145, 0.145, 0.165, 0.17, 0.22]]
table_rows = [[Paragraph(h, sTableHdr) for h in comp_headers]]
for i, row in enumerate(comp_data):
styled = [Paragraph(cell, sTableCellB if i == len(comp_data)-1 else sTableCell) for cell in row]
table_rows.append(styled)
comp_table = Table(table_rows, colWidths=col_widths, repeatRows=1)
comp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), CLR_COMP_HDR),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, CLR_ROW_ALT]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
# Highlight antidote row
("BACKGROUND", (0, len(comp_data)), (-1, len(comp_data)), colors.HexColor("#D6EAF8")),
("FONTNAME", (0, len(comp_data)), (-1, len(comp_data)), "Helvetica-Bold"),
]))
story.append(comp_table)
story.append(GAP(6))
# ── Antidote Quick Reference ─────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=1.5, color=CLR_ANTIDOTE_ACC, spaceAfter=4))
story.append(Paragraph("ANTIDOTE QUICK-REFERENCE (Goodman & Gilman / Goldman-Cecil)",
S("ah2", fontName="Helvetica-Bold", fontSize=12, textColor=CLR_ANTIDOTE_ACC,
alignment=TA_CENTER, spaceAfter=5)))
antidote_data = [
["Poison / Toxidrome", "Antidote", "Key Dose / Notes"],
["Anticholinergic (delirium)", "Physostigmine", "1–2 mg IV slow push; avoid in TCA OD"],
["Organophosphates / Nerve agents", "Atropine + Pralidoxime (2-PAM)", "Atropine: 2–4 mg IV (repeat until secretions dry)\n2-PAM: 30 mg/kg IV bolus → 8–10 mg/kg/hr"],
["Opioids", "Naloxone", "0.4–2 mg IV/IM/IN; repeat q2-3 min; infusion for long-acting opioids"],
["Benzodiazepines", "Flumazenil", "0.2 mg IV q1 min (max 1 mg); short-acting — watch for resedation"],
["Barbiturates / Ethanol", "Supportive only", "Urinary alkalinisation for phenobarbitone; thiamine before glucose in ethanol"],
["Paracetamol (acetaminophen)", "N-Acetylcysteine", "150 mg/kg IV in 200 mL over 60 min, then maintenance"],
["Benzodiazepines (seizures)", "Benzodiazepines (first-line for seizures)", "IV diazepam 5–10 mg or lorazepam 0.1 mg/kg"],
["Beta-blockers", "Glucagon", "5–10 mg IV bolus; high-dose insulin therapy"],
["Ca2+ channel blockers", "Calcium gluconate + Glucagon", "Ca gluconate 10 mL 10% IV; also high-dose insulin"],
["Tricyclic antidepressants", "Sodium bicarbonate", "1–2 mEq/kg IV bolus; target pH 7.45–7.55 for QRS widening"],
["Cyanide", "Hydroxocobalamin", "5 g IV over 15 min; also sodium thiosulphate"],
["CO poisoning", "100% O₂ / Hyperbaric O₂", "High-flow O₂ via NRB mask; HBO for severe toxicity"],
["Lead / Mercury / Arsenic", "Dimercaprol (BAL) / DMSA", "BAL 3–5 mg/kg IM q4h; oral DMSA 10 mg/kg q8h x5 days"],
["Iron overdose", "Deferoxamine", "15 mg/kg/hr IV; monitor urine for 'vin rosé' colour"],
["Methanol / Ethylene glycol", "Fomepizole / Ethanol", "Fomepizole 15 mg/kg IV loading dose; haemodialysis if severe"],
["Warfarin / Rodenticides", "Vitamin K₁ (phytomenadione)", "5–10 mg IV slow; FFP/PCC for immediate reversal"],
]
aw = [PW*0.30, PW*0.28, PW*0.42]
antidote_rows = []
for i, row in enumerate(antidote_data):
if i == 0:
antidote_rows.append([Paragraph(c, sTableHdr) for c in row])
else:
antidote_rows.append([
Paragraph(row[0], sTableCellB),
Paragraph(f"<b>{row[1]}</b>", S("av", fontName="Helvetica-Bold", fontSize=7.5,
textColor=CLR_ANTIDOTE_ACC, leading=10)),
Paragraph(row[2], sTableCell),
])
antidote_table = Table(antidote_rows, colWidths=aw, repeatRows=1)
antidote_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), CLR_ANTIDOTE_ACC),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, CLR_ANTIDOTE_BG]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#BBCCDD")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 4),
]))
story.append(antidote_table)
story.append(GAP(5))
# ── Reference footer ──────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=0.8, color=colors.HexColor("#AAAAAA"), spaceAfter=3))
story.append(Paragraph(
"Sources: The Essentials of Forensic Medicine and Toxicology, 36th Ed. (Narayana Reddy) — Table 24.2, p.479 | "
"Goodman & Gilman's Pharmacological Basis of Therapeutics | Goldman-Cecil Medicine | "
"Lippincott Pharmacology | Rosen's Emergency Medicine",
sRef
))
# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF built successfully:", OUTPUT)
cd /tmp/workspace/toxidromes && python build_pdf.py 2>&1
ls -lh /tmp/workspace/toxidromes/Toxidromes_Quick_Reference.pdf
Toxidromes Quick Reference
PDF Document · PDF
| Colour | Toxidrome | Key Mnemonic |
|---|---|---|
| Blue | Anticholinergic | "Hot, Dry, Blind, Mad, Full" |
| Green | Cholinergic/Organophosphate | SLUDGE / DUMBELS / MTWTF |
| Amber | Sympathomimetic | "Fast, Hot & Wet" |
| Lavender | Opioid | "Pin-point · Pump Down · Passed Out" |
| Rose | Sedative/Hypnotic | "ABCD Down" |