Explain toxicdromes from forensic toxicology book narayana reddy

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
I have all the information needed from the Narayana Reddy book. Here is the complete explanation:

Toxidromes - The Essentials of Forensic Medicine and Toxicology (Narayana Reddy, 36th Edition)

Definition

A toxidrome is a constellation of clinical findings resulting from any given poison or class of poison. It helps the clinician arrive at the correct diagnosis even before specific toxicological tests are available (Table 24.2, p. 479).
The book presents five classical toxidromes in forensic toxicology:

TABLE 24.2: Toxidromes

1. Anticholinergic Toxidrome

Poisons/DrugsAntihistamines, antiparkinsonian drugs, atropine, scopolamine, amantadine, antipsychotic drugs, antidepressants, antispasmodics, skeletal muscle relaxants, many plants (especially Datura), and fungi (e.g., Amanita muscaria)
Clinical FindingsHyperthermia, dry skin, dilated pupils (mydriasis), vasodilation causing flushed skin, hypervigilant, hallucinating, delirium with mumbling speech, tachycardia, myoclonus, urinary retention, decreased bowel sounds
Memory aid: "Hot as a hare, dry as a bone, red as a beet, blind as a bat, mad as a hatter" - the classic anticholinergic mnemonic.

2. Cholinergic / Anticholinesterase Toxidrome

Poisons/DrugsOrganophosphates, carbamates, parasympathomimetic drugs, and some mushrooms
Clinical FindingsConfusion, CNS depression, salivation, lacrimation, urinary and fecal incontinence, vomiting, sweating, fasciculations, seizures, miosis, pulmonary edema, tachycardia/bradycardia
Memory aid: SLUDGE - Salivation, Lacrimation, Urination, Defecation, GI distress, Emesis. Also DUMBELS - Diarrhea, Urination, Miosis, Bradycardia/Bronchospasm, Emesis, Lacrimation, Salivation. This is a high-priority toxidrome in forensic medicine given the prevalence of organophosphate pesticide poisoning.

3. Sympathomimetic / Withdrawal Toxidrome

Poisons/DrugsCocaine, ecstasy (MDMA), amphetamines, caffeine, theophylline
Clinical FindingsParanoia, delusions, tachycardia, hypertension, hyperpyrexia, hyperreflexia, sweating, mydriasis, seizures, arrhythmias
Key distinction from anticholinergic: Both cause mydriasis and tachycardia, but the sympathomimetic toxidrome produces diaphoresis (sweating), whereas the anticholinergic toxidrome produces dry skin.

4. Opioid Toxidrome

Poisons/DrugsMorphine, pethidine, fentanyl, codeine, methadone
Clinical FindingsMiosis (pinpoint pupils), hypotension, bradycardia, hypothermia, CNS depression, pulmonary edema, respiratory depression, hyporeflexia, coma, rarely convulsions
Classic triad: Miosis + respiratory depression + altered consciousness. Naloxone is the specific antidote that reverses this toxidrome. The book notes convulsions are rare in opioid toxidrome - an important differentiating point.

5. Sedative / Hypnotics Toxidrome

Poisons/DrugsBarbiturates, benzodiazepines, ethanol
Clinical FindingsMiosis, hypotension, bradycardia, hypothermia, confusion, CNS depression, hyporeflexia, coma
Distinction from opioid toxidrome: Very similar picture, but sedative/hypnotics do not typically produce pulmonary edema and convulsions are extremely rare. Respiratory depression is less severe than with opioids unless combined with other CNS depressants.

Summary Comparison Table

FeatureAnticholinergicCholinergicSympathomimeticOpioidSedative/Hypnotic
PupilsMydriasisMiosisMydriasisMiosis (pinpoint)Miosis
SkinDry, flushedDiaphoreticDiaphoreticNormalNormal
Bowel soundsDecreasedIncreasedNormalDecreasedNormal/Decreased
Heart rateTachycardiaBrady/TachyTachycardiaBradycardiaBradycardia
BPNormal/ElevatedVariableHypertensionHypotensionHypotension
TemperatureHyperthermiaNormalHyperpyrexiaHypothermiaHypothermia
CNSDelirium/HallucinationsConfusion/SeizuresParanoia/SeizuresDepression/ComaDepression/Coma

Context in the Book

Narayana Reddy introduces toxidromes under the Diagnosis of Poisoning in the Living section (Chapter 24). The text states:
"A toxidrome is a constellation of findings, resulting from any given poison. It serves to clue the clinician into the correct diagnosis."
This is presented alongside other diagnostic pointers for acute poisoning - such as odors (garlicky: organophosphates/arsenic; fishy/musty: aluminum phosphide), color of postmortem staining (cherry-red: CO; chocolate: methemoglobin-forming agents), and samples to collect in living patients (stomach wash, 10 ml blood with sodium fluoride, urine).
- The Essentials of Forensic Medicine and Toxicology, 36th Edition (Narayana Reddy), p. 479, Table 24.2

Create a quick reference PDF of toxidromes with mnemonics and with antidote and management

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/toxidromes && ls /tmp/workspace/toxidromes/

Writing File

~/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)
Running Command

cd /tmp/workspace/toxidromes && python build_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/toxidromes/Toxidromes_Quick_Reference.pdf

Your PDF is ready:

Toxidromes Quick Reference

PDF Document · PDF


Here's what the 2-page quick reference contains:
Page 1 - Five Toxidrome Cards (each colour-coded):
ColourToxidromeKey Mnemonic
BlueAnticholinergic"Hot, Dry, Blind, Mad, Full"
GreenCholinergic/OrganophosphateSLUDGE / DUMBELS / MTWTF
AmberSympathomimetic"Fast, Hot & Wet"
LavenderOpioid"Pin-point · Pump Down · Passed Out"
RoseSedative/Hypnotic"ABCD Down"
Each card has:
  • Clinical features (bullet list)
  • Causative agents
  • Mnemonic box
  • Antidote(s) with doses + Management principles
Page 2:
  • Full comparison table (pupils, skin, HR, BP, temperature, bowel sounds, CNS, antidote) across all 5 toxidromes
  • Comprehensive antidote quick-reference table with 16 poisons including doses and endpoints (covering paracetamol, cyanide, CO, heavy metals, TCAs, methanol, warfarin and more)
Sources: Narayana Reddy 36th Ed. (Table 24.2, p.479) · Goodman & Gilman · Goldman-Cecil Medicine · Lippincott Pharmacology · Rosen's Emergency Medicine
This is a shared conversation. Sign in to Orris to start your own chat.