18 year old male patient with pain in left inguinal region
inguinal pain young male differential diagnosis
| Condition | Key Features |
|---|---|
| Adductor muscle strain/tear | Medial upper thigh pain, worse with adduction; common in sport |
| Iliopsoas strain/bursitis | Deep groin/anterior hip pain with hip flexion |
| Osteitis pubis | Midline pubic pain, bilateral tenderness at symphysis |
| Hip labral tear / FAI | Anterior groin pain, worse with hip flexion-internal rotation |
| Femoral-acetabular impingement | Deep groin pain, "C-sign," positive FABER/FADIR tests |
| Pubic stress fracture | Pain on weight-bearing; seen on MRI/CT |
| Test | Indication |
|---|---|
| Scrotal Doppler ultrasound | Torsion, epididymitis, varicocele, hernia (if uncertain) |
| Urine analysis + culture | Epididymitis/UTI |
| STI swab / NAAT | Adolescent male with epididymitis |
| MRI pelvis/groin | Athletic pubalgia, labral tear, FAI, occult stress fracture |
| Inguinal herniography / ultrasound | Occult hernia |
| Sign | Diagnosis | Action |
|---|---|---|
| Absent cremasteric reflex + acute pain | Testicular torsion | Immediate surgical exploration - do NOT delay for USS |
| Irreducible, tender inguinal bulge | Incarcerated hernia | Urgent surgical review |
| Tender, erythematous inguinal swelling + systemic toxicity | Strangulated hernia | Emergency surgery |
| High-riding, transversely-lying testis + nausea/vomiting | Testicular torsion | OR within 4-6 hours |
No prescription??
Tab. Ibuprofen 400 mg
Sig: 1 tablet TDS after meals × 5 days
(for pain relief and local inflammation)
Tab. Paracetamol 500 mg
Sig: 1-2 tablets TDS × 5 days
Tab. Pantoprazole 40 mg
Sig: 1 tablet OD before breakfast × 5 days
Syrup Lactulose 15 mL
Sig: BD at bedtime × 7 days
OR
Tab. Ispaghula husk (Isabgol / Psyllium)
Sig: 1 sachet in water BD × 7 days
Straining is a key aggravating factor for inguinal hernias. Preventing constipation reduces discomfort and the risk of incarceration.
| Approach | Procedure |
|---|---|
| Open (classic) | Lichtenstein tension-free mesh repair (most common in adults) |
| Laparoscopic | TAPP (Transabdominal Preperitoneal) or TEP (Totally Extraperitoneal) |
In an uncomplicated reducible inguinal hernia, there is no specific drug that treats the hernia itself. Pharmacotherapy is purely symptomatic (pain relief, stool softening). The prescription should always be paired with a surgical referral - that is the only cure.
Can't give this??
| Drug | Dose | Frequency | Purpose |
|---|---|---|---|
| Inj. Xone (Ceftriaxone) | 1g IV | BD | Broad-spectrum antibiotic |
| Inj. Pan (Pantoprazole) | 40mg IV | OD | Gastric protection |
| - | (antispasmodic - cancelled) | ||
| Inj. Tramadol | 100mg IV/IM | BD | Opioid analgesia |
| Inj. Emset (Ondansetron) | 4mg IV | TDS | Antiemetic |
| DNS | 1 bottle IV | Maintenance fluid | |
| RL | 1 bottle IV | Maintenance fluid | |
| NS | 1 bottle IV | Maintenance fluid |
If this is a pure reducible hernia with no infection, the ceftriaxone should be reconsidered. A single pre-operative dose of ceftriaxone 1g is standard prophylaxis for hernia repair - but not BD ongoing.
1. Inj. Ceftriaxone 1g IV BD × 3-5 days (if infection/pre-op)
2. Inj. Tramadol 100mg IV/IM BD (analgesia - with monitoring)
3. Inj. Ondansetron (Emset) 4mg IV TDS (antiemetic)
4. Inj. Pantoprazole 40mg IV OD (gastric protection)
5. IVF: DNS 500mL + RL 500mL + NS 500mL (maintenance hydration)
6. Tab. Lactulose 15mL BD / Ispaghula BD (stool softener - avoid straining)
7. Surgical consult for elective/semi-urgent hernia repair
And what prescription we have written before
| Drug | Dose | Frequency | Duration |
|---|---|---|---|
| Tab. Ibuprofen | 400mg | TDS after meals | 5 days |
| Tab. Pantoprazole | 40mg | OD before breakfast | 5 days |
| Syrup Lactulose | 15mL | BD | 7 days |
| Feature | My Prescription | Image Prescription |
|---|---|---|
| Setting | Outpatient / conservative | Inpatient / admitted |
| Route | Oral | Injectable (IV/IM) |
| Analgesia | Tab. Ibuprofen 400mg TDS | Inj. Tramadol 100mg BD |
| Gastric cover | Tab. Pantoprazole 40mg OD | Inj. Pantoprazole 40mg OD |
| Antiemetic | Not included | Inj. Ondansetron 4mg TDS |
| Antibiotic | Not included | Inj. Ceftriaxone 1g BD |
| Antispasmodic | Not included | |
| IV Fluids | Not included | DNS + RL + NS (1 bottle each) |
| Stool softener | Lactulose / Ispaghula | Not included |
What are the contraindications to tramadol in this patient?
| Contraindication | Relevance to This Patient |
|---|---|
| Epilepsy / seizure disorder | Tramadol significantly lowers seizure threshold. Must ask about history before prescribing. |
| Concurrent MAOI use (or within 14 days) | Risk of serotonin syndrome - potentially fatal. Ask about psychiatric medications. |
| Acute intoxication with alcohol, hypnotics, opioids, or CNS depressants | Additive CNS/respiratory depression. |
| Uncontrolled respiratory depression / severe asthma | Tramadol suppresses respiratory drive. |
| Hypersensitivity to tramadol | Previous allergic reaction - ask. |
| Age under 12 years | Not applicable here (patient is 18). |
| Post-tonsillectomy/adenoidectomy pain in children | Not applicable here. |
| Caution | Why It Matters |
|---|---|
| Head injury / raised ICP | Tramadol can cause miosis, vomiting, and sedation masking neurological signs. |
| Hepatic impairment | Tramadol is hepatically metabolized (CYP2D6, CYP3A4). Accumulation risk. |
| Renal impairment | Active metabolites accumulate - reduce dose / extend interval. In an 18-year-old, unlikely but check if any known kidney disease. |
| History of substance abuse / opioid dependence | Tramadol has abuse potential. |
| Concurrent SSRIs / SNRIs / TCAs / triptans | Risk of serotonin syndrome - fever, agitation, tremor, myoclonus, autonomic instability. Ask about antidepressant use. |
| Concurrent drugs that lower seizure threshold | Antipsychotics, bupropion, etc. |
| CYP2D6 ultra-rapid metabolizers | Convert tramadol to morphine faster - risk of opioid toxicity. |
| Constipation / bowel obstruction | Tramadol (like all opioids) reduces gut motility - worsens constipation, which is already a concern in hernia patients. Add laxative/stool softener. |
You written pcm if gastric intolerance But you must write in detail which type of
Tab. Paracetamol 650 mg (not 500 mg)
Sig: 1 tablet TDS × 5 days (after meals)
Max: Do not exceed 4g (4000mg) per day
650 mg is preferred over 500 mg in adults for adequate analgesia. 500 mg is a sub-therapeutic dose for moderate pain in an adult male.
| Formulation | Brand Examples | When to Use |
|---|---|---|
| Tab. Paracetamol 500 mg | Calpol, Metacin | Mild pain, children/elderly |
| Tab. Paracetamol 650 mg | Crocin Pain Relief, Dolo 650 | Preferred in adults for moderate pain |
| Tab. Paracetamol 1000 mg (1g) | Calpol 1g | Severe pain, short-term, max 4 doses/day |
| Syrup Paracetamol 125mg/5mL | Calpol Syrup | Pediatric use |
| Suppository (PR) | - | When oral route not possible (vomiting) |
| Inj. Paracetamol 1g/100mL IV | Perfalgan, Intraparacetamol | Inpatient - rapid onset, NPO patients, pre/post-op |
| Gastric Condition | Reason to Avoid NSAIDs |
|---|---|
| Peptic ulcer disease (PUD) | NSAIDs inhibit COX-1 → reduced prostaglandin E2 → impaired gastric mucosal protection → ulceration, bleeding |
| GERD / gastritis | NSAIDs worsen mucosal irritation |
| History of GI bleed | NSAIDs increase bleeding risk (COX-1 inhibition → reduced thromboxane A2 → platelet dysfunction) |
| H. pylori positive | Combined NSAID + H. pylori = very high ulcer risk |
| IBD (Crohn's / UC) | NSAIDs can trigger flares |
Tab. Ibuprofen 400 mg TDS after meals × 5 days
OR (if gastric intolerance/ulcer/gastritis/GI bleed history)
Tab. Paracetamol 650 mg TDS after meals × 5 days
(Max 4g/day; avoid if liver disease)
Tab. Pantoprazole 40 mg OD before breakfast × 5 days
(If on Ibuprofen - mandatory gastric cover)
(With Paracetamol - may omit if no gastric symptoms)
Tab. Ispaghula husk 1 sachet in water BD × 7 days
(Stool softener - avoid straining)
Never write just "Paracetamol" - always specify:
- Strength (500mg vs 650mg vs 1g)
- Route (oral / IV / PR)
- Frequency (TDS / QID)
- Duration
- Max daily dose warning (especially if patient also taking combination cold/flu drugs that contain paracetamol)
Create a detailed PDF on analgesic choice algorithm for surgical pain
mkdir -p /home/daytona/workspace/analgesic-pdf && ls /home/daytona/workspace/
~/analgesic-pdf/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
OUTPUT = "/home/daytona/workspace/analgesic-pdf/Analgesic_Choice_Algorithm_Surgical_Pain.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm,
leftMargin=1.8*cm,
topMargin=2*cm,
bottomMargin=2*cm,
)
# ── Colour palette ──────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MED_BLUE = colors.HexColor("#2563a8")
LIGHT_BLUE = colors.HexColor("#dbeafe")
STEP1_COL = colors.HexColor("#16a34a") # green – mild
STEP2_COL = colors.HexColor("#d97706") # amber – moderate
STEP3_COL = colors.HexColor("#dc2626") # red – severe
TEAL = colors.HexColor("#0d9488")
PURPLE = colors.HexColor("#7c3aed")
LIGHT_GRAY = colors.HexColor("#f1f5f9")
MID_GRAY = colors.HexColor("#64748b")
WHITE = colors.white
ORANGE = colors.HexColor("#ea580c")
styles = getSampleStyleSheet()
def style(name="Normal", **kw):
return ParagraphStyle(name, parent=styles[name], **kw)
title_style = style("Title",
fontSize=22, textColor=WHITE, alignment=TA_CENTER,
spaceAfter=4, fontName="Helvetica-Bold")
subtitle_style = style("Normal",
fontSize=11, textColor=colors.HexColor("#bfdbfe"),
alignment=TA_CENTER, spaceAfter=2, fontName="Helvetica")
section_head = style("Normal",
fontSize=13, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_LEFT, spaceAfter=4, spaceBefore=6,
leftIndent=6)
body = style("Normal",
fontSize=9.5, textColor=colors.HexColor("#1e293b"),
leading=14, spaceAfter=3, fontName="Helvetica")
body_bold = style("Normal",
fontSize=9.5, textColor=DARK_BLUE,
leading=14, spaceAfter=3, fontName="Helvetica-Bold")
small = style("Normal",
fontSize=8.5, textColor=MID_GRAY,
leading=12, spaceAfter=2, fontName="Helvetica-Oblique")
bullet = style("Normal",
fontSize=9.5, textColor=colors.HexColor("#1e293b"),
leading=14, spaceAfter=2, fontName="Helvetica",
leftIndent=12, bulletIndent=2)
table_header_style = ParagraphStyle("th",
fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=12)
table_cell_style = ParagraphStyle("td",
fontSize=8.5, textColor=colors.HexColor("#1e293b"),
fontName="Helvetica", alignment=TA_LEFT, leading=12)
table_cell_center = ParagraphStyle("tdc",
fontSize=8.5, textColor=colors.HexColor("#1e293b"),
fontName="Helvetica", alignment=TA_CENTER, leading=12)
warning_style = style("Normal",
fontSize=9, textColor=colors.HexColor("#7f1d1d"),
fontName="Helvetica-Bold", leading=13,
leftIndent=8, spaceAfter=3)
note_style = style("Normal",
fontSize=8.5, textColor=colors.HexColor("#374151"),
fontName="Helvetica-Oblique", leading=13,
leftIndent=8, spaceAfter=3)
# ── Helper: coloured section banner ──────────────────────────────
def section_banner(title, bg=MED_BLUE):
data = [[Paragraph(title, section_head)]]
t = Table(data, colWidths=[17.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return t
def colored_box(content_list, bg=LIGHT_BLUE, border=MED_BLUE):
inner = Table([[c] for c in content_list], colWidths=[16.6*cm])
inner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("LINEAFTER", (0,0), (0,-1), 3, border),
]))
return inner
# ═══════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════
story = []
# ── COVER HEADER ─────────────────────────────────────────────────
cover_data = [[
Paragraph("ANALGESIC CHOICE ALGORITHM", title_style),
Paragraph("Surgical Pain Management", subtitle_style),
Paragraph("Evidence-Based Guide for Pre-operative, Intra-operative & Post-operative Analgesia", subtitle_style),
]]
cover = Table([[Paragraph("ANALGESIC CHOICE ALGORITHM", title_style)],
[Paragraph("Surgical Pain Management", subtitle_style)],
[Paragraph("Evidence-Based Guide for Pre-operative, Intra-operative & Post-operative Analgesia", subtitle_style)]],
colWidths=[17.4*cm])
cover.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (-1,-1), 16),
("RIGHTPADDING", (0,0), (-1,-1), 16),
]))
story.append(cover)
story.append(Spacer(1, 0.4*cm))
# ── SECTION 1: PAIN ASSESSMENT ───────────────────────────────────
story.append(section_banner("1. PAIN ASSESSMENT — THE FIRST STEP"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("<b>Always assess before prescribing:</b>", body_bold))
assess_data = [
[Paragraph("<b>Tool</b>", table_header_style),
Paragraph("<b>Use In</b>", table_header_style),
Paragraph("<b>Score / Output</b>", table_header_style)],
[Paragraph("VAS (Visual Analogue Scale)", table_cell_style),
Paragraph("Adults, cooperative patients", table_cell_style),
Paragraph("0–10 line; 0=no pain, 10=worst", table_cell_style)],
[Paragraph("NRS (Numerical Rating Scale)", table_cell_style),
Paragraph("Most clinical settings", table_cell_style),
Paragraph("0–10 number; ≤3 mild, 4–6 mod, ≥7 severe", table_cell_style)],
[Paragraph("Wong-Baker FACES", table_cell_style),
Paragraph("Children, low literacy", table_cell_style),
Paragraph("0–10 faces", table_cell_style)],
[Paragraph("CPOT (Critical-Care Pain Obs Tool)", table_cell_style),
Paragraph("ICU / non-verbal patients", table_cell_style),
Paragraph("0–8; ≥3 = significant pain", table_cell_style)],
]
assess_table = Table(assess_data, colWidths=[5*cm, 6*cm, 6.4*cm])
assess_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#cbd5e1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
story.append(assess_table)
story.append(Spacer(1, 0.3*cm))
# ── SECTION 2: WHO ANALGESIC LADDER ──────────────────────────────
story.append(section_banner("2. WHO ANALGESIC LADDER (adapted for Surgical Pain)"))
story.append(Spacer(1, 0.2*cm))
ladder_data = [
[Paragraph("<b>STEP 1</b>\nMild Pain\nNRS 1–3", table_header_style),
Paragraph("<b>STEP 2</b>\nModerate Pain\nNRS 4–6", table_header_style),
Paragraph("<b>STEP 3</b>\nSevere Pain\nNRS 7–10", table_header_style)],
[
Paragraph("• Paracetamol 650 mg–1g TDS/QID\n• Ibuprofen 400 mg TDS (with food)\n• Diclofenac 50 mg TDS\n• Naproxen 250–500 mg BD\n\n<i>± Adjuvants</i>", table_cell_style),
Paragraph("• Tramadol 50–100 mg TDS/QID\n• Codeine 30–60 mg QID\n• Buprenorphine SL 0.2 mg TDS\n\n+ Step 1 drug (multimodal)\n\n<i>± Adjuvants</i>", table_cell_style),
Paragraph("• Morphine 5–10 mg IV/IM/SC\n• Fentanyl IV (titrated)\n• Pethidine 50–100 mg IM\n• Oxycodone PO/IV\n• PCA (patient-controlled)\n\n+ Step 1 drug\n<i>± Adjuvants</i>", table_cell_style),
],
[Paragraph("<font color='#15803d'><b>GREEN — Start here\nfor mild/outpatient</b></font>", table_cell_center),
Paragraph("<font color='#b45309'><b>AMBER — Add weak\nopioid</b></font>", table_cell_center),
Paragraph("<font color='#b91c1c'><b>RED — Strong opioid\n± regional block</b></font>", table_cell_center)],
]
ladder_table = Table(ladder_data, colWidths=[5.8*cm, 5.8*cm, 5.8*cm])
ladder_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), STEP1_COL),
("BACKGROUND", (1,0), (1,0), STEP2_COL),
("BACKGROUND", (2,0), (2,0), STEP3_COL),
("BACKGROUND", (0,1), (0,1), colors.HexColor("#dcfce7")),
("BACKGROUND", (1,1), (1,1), colors.HexColor("#fef9c3")),
("BACKGROUND", (2,1), (2,1), colors.HexColor("#fee2e2")),
("BACKGROUND", (0,2), (0,2), colors.HexColor("#f0fdf4")),
("BACKGROUND", (1,2), (1,2), colors.HexColor("#fffbeb")),
("BACKGROUND", (2,2), (2,2), colors.HexColor("#fff1f2")),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#94a3b8")),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(ladder_table)
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("↑ Titrate UP if pain uncontrolled after 30–60 min reassessment | ↓ Step DOWN as pain improves", small))
story.append(Spacer(1, 0.35*cm))
# ── SECTION 3: ANALGESIC CHOICE BY SETTING ───────────────────────
story.append(section_banner("3. ANALGESIC CHOICE BY CLINICAL SETTING", bg=TEAL))
story.append(Spacer(1, 0.2*cm))
setting_data = [
[Paragraph("<b>Setting</b>", table_header_style),
Paragraph("<b>Preferred Analgesics</b>", table_header_style),
Paragraph("<b>Avoid / Caution</b>", table_header_style)],
[Paragraph("Outpatient\n(mild hernia, wound pain)", table_cell_style),
Paragraph("PCM 650mg TDS + Ibuprofen 400mg TDS (with PPI)", table_cell_style),
Paragraph("Strong opioids", table_cell_style)],
[Paragraph("Admitted — pre-op\n(awaiting surgery)", table_cell_style),
Paragraph("PCM IV/PO + Tramadol 50–100mg BD/TDS + Ondansetron", table_cell_style),
Paragraph("NSAIDs if pre-op (bleeding risk)\nMorphine if bowel obs query", table_cell_style)],
[Paragraph("Intra-operative\n(GA/regional)", table_cell_style),
Paragraph("Fentanyl IV + Ketorolac IV + local infiltration\nNeuraxial (spinal/epidural)", table_cell_style),
Paragraph("Tramadol intra-op (PONV risk)", table_cell_style)],
[Paragraph("Post-operative\nDay 0–1 (severe)", table_cell_style),
Paragraph("Morphine PCA or IV PRN + regular PCM IV\n+ Ketorolac 15–30mg IV TDS\n+ Ondansetron 4mg TDS", table_cell_style),
Paragraph("NSAIDs if renal risk, anastomosis, elderly", table_cell_style)],
[Paragraph("Post-operative\nDay 2–3 (moderate)", table_cell_style),
Paragraph("Step down: Tramadol PO + PCM 650mg TDS + Diclofenac 50mg TDS", table_cell_style),
Paragraph("Avoid strong opioids if mobilising", table_cell_style)],
[Paragraph("Post-operative\nDay 4+ (mild, discharge)", table_cell_style),
Paragraph("PCM 650mg TDS ± Ibuprofen 400mg TDS (short course)", table_cell_style),
Paragraph("Opioids (constipation, falls risk)", table_cell_style)],
[Paragraph("Paediatric\n(<12 years)", table_cell_style),
Paragraph("PCM weight-based (15mg/kg QID)\nIbuprofen 5–10mg/kg TDS\nMorphine IV 0.05–0.1mg/kg PRN", table_cell_style),
Paragraph("Tramadol, Codeine\n(respiratory risk)", table_cell_style)],
[Paragraph("Elderly (>65 years)", table_cell_style),
Paragraph("PCM 500–650mg TDS (first choice)\nReduce opioid doses by 25–50%", table_cell_style),
Paragraph("NSAIDs (renal, GI, CV risk)\nTramadol (delirium, falls, seizure)", table_cell_style)],
[Paragraph("Renal Impairment", table_cell_style),
Paragraph("PCM (safest)\nFentanyl (safest opioid)\nHydromorphone", table_cell_style),
Paragraph("NSAIDs (absolute)\nMorphine (active metabolite M6G accumulates)\nTramadol (reduce dose/interval)", table_cell_style)],
[Paragraph("Hepatic Impairment", table_cell_style),
Paragraph("NSAIDs (short-term, mild disease)\nTramadol (reduce dose)\nFentanyl", table_cell_style),
Paragraph("PCM — REDUCE dose (max 2g/day)\nMorphine (encephalopathy risk)", table_cell_style)],
[Paragraph("Peptic Ulcer / GI bleed", table_cell_style),
Paragraph("PCM (safest)\nTramadol (if needed)\nWeak opioids", table_cell_style),
Paragraph("All NSAIDs (absolute contraindication without PPI cover)", table_cell_style)],
[Paragraph("Pregnancy\n(surgical emergency)", table_cell_style),
Paragraph("PCM (all trimesters — safest)\nMorphine (short-term, supervised)\nRegional anaesthesia preferred", table_cell_style),
Paragraph("NSAIDs (3rd trimester: premature closure ductus arteriosus)\nTramadol, Codeine (avoid near term)", table_cell_style)],
[Paragraph("Epilepsy", table_cell_style),
Paragraph("PCM, NSAIDs, Morphine, Fentanyl", table_cell_style),
Paragraph("Tramadol (lowers seizure threshold — CONTRAINDICATED)\nPethidine (norpethidine → seizures)", table_cell_style)],
]
setting_table = Table(setting_data, colWidths=[3.8*cm, 7.2*cm, 6.4*cm])
setting_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#cbd5e1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(setting_table)
story.append(Spacer(1, 0.35*cm))
# ── PAGE BREAK ────────────────────────────────────────────────────
story.append(PageBreak())
# ── SECTION 4: DRUG PROFILES ─────────────────────────────────────
story.append(section_banner("4. KEY DRUG PROFILES", bg=PURPLE))
story.append(Spacer(1, 0.2*cm))
drug_data = [
[Paragraph("<b>Drug</b>", table_header_style),
Paragraph("<b>Class</b>", table_header_style),
Paragraph("<b>Dose (Adult)</b>", table_header_style),
Paragraph("<b>Onset</b>", table_header_style),
Paragraph("<b>Contraindications</b>", table_header_style),
Paragraph("<b>Key Cautions</b>", table_header_style)],
[Paragraph("Paracetamol\n(PCM)", table_cell_style),
Paragraph("Non-opioid\nCNS-COX inhibitor", table_cell_style),
Paragraph("PO: 500–1000mg QID\nIV: 1g QID\nMax 4g/day", table_cell_style),
Paragraph("PO: 30–60 min\nIV: 5–10 min", table_cell_style),
Paragraph("Severe hepatic failure", table_cell_style),
Paragraph("Reduce to 2g/day in hepatic/renal impairment, elderly, alcohol use", table_cell_style)],
[Paragraph("Ibuprofen", table_cell_style),
Paragraph("NSAID\n(non-selective COX-1/2)", table_cell_style),
Paragraph("400–600 mg TDS\nAfter meals\n(max 2.4g/day)", table_cell_style),
Paragraph("PO: 30 min", table_cell_style),
Paragraph("PUD, GI bleed, CKD, 3rd trimester, post-CABG, severe asthma", table_cell_style),
Paragraph("Always add PPI; avoid pre-op; CV risk with long-term use", table_cell_style)],
[Paragraph("Diclofenac", table_cell_style),
Paragraph("NSAID\n(COX-1/2)", table_cell_style),
Paragraph("50 mg TDS PO\n75mg IM BD\nSR 75mg BD", table_cell_style),
Paragraph("PO: 30 min\nIM: 15 min", table_cell_style),
Paragraph("PUD, CKD, GI bleed, 3rd trimester", table_cell_style),
Paragraph("Highest CV risk among NSAIDs; hepatotoxicity risk", table_cell_style)],
[Paragraph("Ketorolac", table_cell_style),
Paragraph("NSAID\n(potent, parenteral)", table_cell_style),
Paragraph("15–30 mg IV/IM TDS\nMax 5 days", table_cell_style),
Paragraph("IV: 5–10 min", table_cell_style),
Paragraph("CKD, PUD, bleeding disorder, pre-op, >65 yrs (15mg max)", table_cell_style),
Paragraph("Best parenteral NSAID for post-op; strictly max 5 days", table_cell_style)],
[Paragraph("Tramadol", table_cell_style),
Paragraph("Weak opioid\n+ SNRI", table_cell_style),
Paragraph("50–100 mg TDS/QID\nIV/IM: 50–100mg slow\nMax 400mg/day", table_cell_style),
Paragraph("PO: 30–60 min\nIV: 10–20 min", table_cell_style),
Paragraph("Epilepsy, MAOI use, severe respiratory depression, age <12", table_cell_style),
Paragraph("Serotonin syndrome with SSRIs; PONV; seizure threshold↓; abuse potential", table_cell_style)],
[Paragraph("Codeine", table_cell_style),
Paragraph("Weak opioid\n(prodrug → morphine)", table_cell_style),
Paragraph("30–60 mg QID\n(max 240mg/day)", table_cell_style),
Paragraph("PO: 30–45 min", table_cell_style),
Paragraph("Children post-tonsillectomy, CYP2D6 poor metabolisers, breastfeeding", table_cell_style),
Paragraph("Ultra-rapid metabolisers: risk of toxicity; ineffective in poor metabolisers", table_cell_style)],
[Paragraph("Morphine", table_cell_style),
Paragraph("Strong opioid\n(μ-agonist)", table_cell_style),
Paragraph("IV: 2–5 mg PRN\nIM/SC: 5–10 mg\nPO: 5–10 mg 4-hrly", table_cell_style),
Paragraph("IV: 5 min\nIM: 15–20 min\nPO: 30–60 min", table_cell_style),
Paragraph("Severe respiratory depression, head injury, MAOIs, paralytic ileus", table_cell_style),
Paragraph("Avoid in CKD (M6G accumulates); always have naloxone available", table_cell_style)],
[Paragraph("Fentanyl", table_cell_style),
Paragraph("Strong opioid\n(lipophilic μ-agonist)", table_cell_style),
Paragraph("IV: 1–2 mcg/kg\nPatch: 12–100 mcg/h\nIN: 1–2 mcg/kg", table_cell_style),
Paragraph("IV: 1–2 min\nPatch: 12–24h", table_cell_style),
Paragraph("Severe respiratory depression; opioid-naive patients (patch)", table_cell_style),
Paragraph("Safest opioid in renal/hepatic impairment; chest wall rigidity with rapid IV", table_cell_style)],
[Paragraph("Ondansetron\n(Emset)", table_cell_style),
Paragraph("5-HT3 antagonist\n(antiemetic)", table_cell_style),
Paragraph("4–8 mg IV/IM/PO TDS", table_cell_style),
Paragraph("IV: <5 min", table_cell_style),
Paragraph("Prolonged QT syndrome", table_cell_style),
Paragraph("ECG check in cardiac patients; co-prescribe with opioids routinely", table_cell_style)],
]
drug_table = Table(drug_data, colWidths=[2.3*cm, 2.3*cm, 3*cm, 1.8*cm, 4*cm, 4*cm])
drug_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), PURPLE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, colors.HexColor("#f5f3ff")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#ddd6fe")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTSIZE", (0,0), (-1,-1), 8),
]))
story.append(drug_table)
story.append(Spacer(1, 0.35*cm))
# ── SECTION 5: MULTIMODAL ANALGESIA ──────────────────────────────
story.append(section_banner("5. MULTIMODAL ANALGESIA (ERAS PRINCIPLE)", bg=ORANGE))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Combining analgesics from different classes achieves better pain control at lower doses of each drug, "
"reducing side effects. This is the cornerstone of Enhanced Recovery After Surgery (ERAS) protocols.",
body))
mm_data = [
[Paragraph("<b>Component</b>", table_header_style),
Paragraph("<b>Examples</b>", table_header_style),
Paragraph("<b>Benefit</b>", table_header_style)],
[Paragraph("Non-opioid base", table_cell_style),
Paragraph("PCM + NSAID (or COX-2 inhibitor)", table_cell_style),
Paragraph("Reduces opioid requirement by 20–30%", table_cell_style)],
[Paragraph("Regional / neuraxial", table_cell_style),
Paragraph("Spinal, epidural, TAP block, wound infiltration", table_cell_style),
Paragraph("Excellent local/regional control, opioid-sparing", table_cell_style)],
[Paragraph("Weak opioid", table_cell_style),
Paragraph("Tramadol, Codeine", table_cell_style),
Paragraph("Bridges moderate pain; PRN basis", table_cell_style)],
[Paragraph("Adjuvants", table_cell_style),
Paragraph("Gabapentin 300mg pre-op, Ketamine sub-anaesthetic IV,\nDexamethasone, Clonidine", table_cell_style),
Paragraph("Preemptive analgesia, anti-hyperalgesia, PONV reduction", table_cell_style)],
[Paragraph("Strong opioid (PRN only)", table_cell_style),
Paragraph("Morphine PCA, Fentanyl IV", table_cell_style),
Paragraph("Rescue analgesia for breakthrough severe pain", table_cell_style)],
]
mm_table = Table(mm_data, colWidths=[3.5*cm, 7.5*cm, 6.4*cm])
mm_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), ORANGE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, colors.HexColor("#fff7ed")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#fed7aa")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mm_table)
story.append(Spacer(1, 0.35*cm))
# ── SECTION 6: SPECIAL SITUATIONS – QUICK DECISION TABLE ─────────
story.append(section_banner("6. SPECIAL SITUATIONS — QUICK REFERENCE", bg=colors.HexColor("#0f766e")))
story.append(Spacer(1, 0.2*cm))
sp_data = [
[Paragraph("<b>Situation</b>", table_header_style),
Paragraph("<b>Use</b>", table_header_style),
Paragraph("<b>Avoid</b>", table_header_style),
Paragraph("<b>Notes</b>", table_header_style)],
[Paragraph("Seizure disorder", table_cell_style),
Paragraph("PCM, NSAIDs, Fentanyl, Morphine", table_cell_style),
Paragraph("Tramadol, Pethidine", table_cell_style),
Paragraph("Both lower seizure threshold", table_cell_style)],
[Paragraph("On SSRIs / SNRIs", table_cell_style),
Paragraph("PCM, NSAIDs, Morphine", table_cell_style),
Paragraph("Tramadol, Pethidine", table_cell_style),
Paragraph("Serotonin syndrome risk", table_cell_style)],
[Paragraph("On MAOIs", table_cell_style),
Paragraph("PCM, Morphine (caution)", table_cell_style),
Paragraph("Tramadol, Pethidine (ABSOLUTE)", table_cell_style),
Paragraph("Hypertensive crisis, serotonin syndrome", table_cell_style)],
[Paragraph("Asthma (NSAID-sensitive)", table_cell_style),
Paragraph("PCM, Opioids (titrated)", table_cell_style),
Paragraph("Aspirin, NSAIDs (Samter's triad)", table_cell_style),
Paragraph("~10% asthmatics are NSAID-sensitive", table_cell_style)],
[Paragraph("Anticoagulated patient", table_cell_style),
Paragraph("PCM, Opioids", table_cell_style),
Paragraph("NSAIDs, Ketorolac (bleeding risk)", table_cell_style),
Paragraph("Check INR before any procedural analgesia", table_cell_style)],
[Paragraph("NPO / cannot swallow", table_cell_style),
Paragraph("PCM IV, Morphine IV, Fentanyl IV,\nKetorolac IV, regional block", table_cell_style),
Paragraph("Oral formulations", table_cell_style),
Paragraph("IV PCM = fastest non-opioid onset", table_cell_style)],
[Paragraph("Suspected bowel obstruction", table_cell_style),
Paragraph("Fentanyl IV (least gut motility effect)\nRegional/neuraxial", table_cell_style),
Paragraph("Morphine, Codeine (reduce gut motility)\nNSAIDs (if perforation risk)", table_cell_style),
Paragraph("Adequate analgesia does NOT mask diagnosis; provide it", table_cell_style)],
]
sp_table = Table(sp_data, colWidths=[3.2*cm, 5*cm, 4.8*cm, 4.4*cm])
sp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#0f766e")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, colors.HexColor("#f0fdfa")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#99f6e4")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(sp_table)
story.append(Spacer(1, 0.3*cm))
# ── SECTION 7: RED FLAGS & OPIOID MONITORING ─────────────────────
story.append(PageBreak())
story.append(section_banner("7. RED FLAGS — OPIOID SIDE EFFECTS & MONITORING", bg=colors.HexColor("#b91c1c")))
story.append(Spacer(1, 0.2*cm))
rf_data = [
[Paragraph("<b>Side Effect</b>", table_header_style),
Paragraph("<b>Sign / Symptom</b>", table_header_style),
Paragraph("<b>Action</b>", table_header_style)],
[Paragraph("Respiratory depression\n(MOST DANGEROUS)", table_cell_style),
Paragraph("RR <10/min, SpO2 <92%, drowsy, miosis", table_cell_style),
Paragraph("STOP opioid. O2. Naloxone 0.4mg IV, repeat every 2–3 min (max 10mg). Call anaesthesia.", table_cell_style)],
[Paragraph("Oversedation", table_cell_style),
Paragraph("RASS score < -2, unrousable", table_cell_style),
Paragraph("Hold dose. Stimulate. Naloxone if severe. Monitor vitals.", table_cell_style)],
[Paragraph("Nausea / Vomiting", table_cell_style),
Paragraph("Post-dose nausea, retching", table_cell_style),
Paragraph("Ondansetron 4mg IV. Consider antiemetic pre-medication with next dose.", table_cell_style)],
[Paragraph("Urinary retention", table_cell_style),
Paragraph("Inability to void, bladder distension", table_cell_style),
Paragraph("Catheterise. Consider reducing opioid. Tamsulosin in males.", table_cell_style)],
[Paragraph("Opioid-induced constipation", table_cell_style),
Paragraph("No bowel movement >3 days, bloating", table_cell_style),
Paragraph("Lactulose BD + Senna TDS. Consider methylnaltrexone if refractory.", table_cell_style)],
[Paragraph("Pruritus (itching)", table_cell_style),
Paragraph("Generalised itch, especially with spinal opioids", table_cell_style),
Paragraph("Naloxone low dose (0.04mg IV). Chlorphenamine. Rotate opioid.", table_cell_style)],
[Paragraph("Serotonin Syndrome\n(Tramadol + SSRI)", table_cell_style),
Paragraph("Fever, agitation, tremor, myoclonus, hyperreflexia, tachycardia", table_cell_style),
Paragraph("STOP offending drug. Cyproheptadine 4–8mg. ICU if severe.", table_cell_style)],
]
rf_table = Table(rf_data, colWidths=[3.5*cm, 6*cm, 7.9*cm])
rf_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#b91c1c")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, colors.HexColor("#fff1f2")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#fca5a5")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(rf_table)
story.append(Spacer(1, 0.35*cm))
# ── SECTION 8: STEP-DOWN PROTOCOL ────────────────────────────────
story.append(section_banner("8. POST-OPERATIVE STEP-DOWN PROTOCOL", bg=MED_BLUE))
story.append(Spacer(1, 0.2*cm))
stepdown_data = [
[Paragraph("<b>POD</b>", table_header_style),
Paragraph("<b>Pain Level</b>", table_header_style),
Paragraph("<b>Recommended Regimen</b>", table_header_style),
Paragraph("<b>Route</b>", table_header_style)],
[Paragraph("Day 0\n(0–6h post-op)", table_cell_style),
Paragraph("Severe\n(NRS 7–10)", table_cell_style),
Paragraph("PCM 1g IV QID + Ketorolac 15–30mg IV TDS + Morphine IV PRN (PCA)\n+ Ondansetron 4mg TDS", table_cell_style),
Paragraph("IV", table_cell_style)],
[Paragraph("Day 0–1\n(6–24h post-op)", table_cell_style),
Paragraph("Moderate-Severe\n(NRS 5–7)", table_cell_style),
Paragraph("PCM 1g IV QID + Ketorolac 30mg IV TDS + Tramadol 50–100mg IV PRN", table_cell_style),
Paragraph("IV", table_cell_style)],
[Paragraph("Day 1–2", table_cell_style),
Paragraph("Moderate\n(NRS 4–6)", table_cell_style),
Paragraph("PCM 650mg PO QID + Ibuprofen 400mg PO TDS + Tramadol 50mg PO TDS PRN", table_cell_style),
Paragraph("Oral", table_cell_style)],
[Paragraph("Day 3–4", table_cell_style),
Paragraph("Mild-Moderate\n(NRS 3–5)", table_cell_style),
Paragraph("PCM 650mg TDS + Ibuprofen 400mg TDS (both after meals + PPI)", table_cell_style),
Paragraph("Oral", table_cell_style)],
[Paragraph("Day 5+\n(Discharge)", table_cell_style),
Paragraph("Mild\n(NRS 1–3)", table_cell_style),
Paragraph("PCM 500–650mg TDS PRN. Advise stop NSAIDs after 5 days.", table_cell_style),
Paragraph("Oral", table_cell_style)],
]
stepdown_table = Table(stepdown_data, colWidths=[2.5*cm, 2.8*cm, 9.1*cm, 3*cm])
stepdown_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MED_BLUE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.HexColor("#fee2e2"), colors.HexColor("#fef9c3"),
colors.HexColor("#fef9c3"), colors.HexColor("#dcfce7"),
colors.HexColor("#dcfce7")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#cbd5e1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(stepdown_table)
story.append(Spacer(1, 0.35*cm))
# ── SECTION 9: QUICK MEMORY AIDS ─────────────────────────────────
story.append(section_banner("9. QUICK MEMORY AIDS", bg=colors.HexColor("#7c3aed")))
story.append(Spacer(1, 0.2*cm))
aids = [
("<b>PCM is ALWAYS safe first</b> — unless severe hepatic failure. Start there for every surgical patient.", WHITE, colors.HexColor("#4c1d95")),
("<b>No NSAIDs in 4 Ks:</b> Kidney disease · Known PUD · Koagulation (bleeding) · K-trimester (3rd)", WHITE, colors.HexColor("#1e40af")),
("<b>No Tramadol in 4 Ss:</b> Seizures · SSRIs on board · Severe resp. depression · age <12 (kids)", WHITE, colors.HexColor("#065f46")),
("<b>No Pethidine in CNS:</b> Norpethidine metabolite causes seizures & CNS excitation. Avoid in elderly and renal failure.", WHITE, colors.HexColor("#7f1d1d")),
("<b>Fentanyl = safest opioid in organ impairment</b> (renal or hepatic) — hepatic metabolism, inactive metabolites", WHITE, colors.HexColor("#713f12")),
("<b>Multimodal always beats monotherapy</b> — combine PCM + NSAID + weak opioid to minimise each drug's dose", WHITE, colors.HexColor("#1e3a5f")),
]
for text, fg, bg in aids:
row = Table([[Paragraph(text, ParagraphStyle("aid", fontSize=9, textColor=fg,
fontName="Helvetica-Bold", leading=13, leftIndent=6))]], colWidths=[17.4*cm])
row.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("BOTTOMMARGIN", (0,0), (-1,-1), 3),
]))
story.append(row)
story.append(Spacer(1, 0.1*cm))
story.append(Spacer(1, 0.3*cm))
# ── FOOTER ────────────────────────────────────────────────────────
footer_data = [[
Paragraph(
"References: Bailey & Love's Short Practice of Surgery 28e · Fischer's Mastery of Surgery 8e · "
"Schwartz's Principles of Surgery 11e · WHO Analgesic Ladder · ERAS Society Guidelines 2023 | "
"For clinical use by licensed practitioners only. Always verify doses against current formulary.",
ParagraphStyle("foot", fontSize=7.5, textColor=WHITE, fontName="Helvetica-Oblique",
alignment=TA_CENTER, leading=11))
]]
footer = Table(footer_data, colWidths=[17.4*cm])
footer.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
story.append(footer)
# ── BUILD ─────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
cd /home/daytona/workspace/analgesic-pdf && python generate_pdf.py
Analgesic Choice Algorithm Surgical Pain
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Pain Assessment | VAS, NRS, Wong-Baker FACES, CPOT tools with scoring |
| 2. WHO Analgesic Ladder | 3-step ladder adapted for surgical pain with colour coding |
| 3. Choice by Clinical Setting | Outpatient → Pre-op → Intra-op → Post-op Day 0-4 → Discharge; plus Paediatric, Elderly, Renal, Hepatic, Pregnancy, Epilepsy |
| 4. Drug Profiles | PCM, Ibuprofen, Diclofenac, Ketorolac, Tramadol, Codeine, Morphine, Fentanyl, Ondansetron - doses, onset, contraindications |
| 5. Multimodal Analgesia | ERAS principle - non-opioid base + regional + adjuvants |
| 6. Special Situations | Seizures, SSRIs, MAOIs, Asthma, Anticoagulation, NPO, Bowel obstruction |
| 7. Red Flags | Opioid side effects and emergency management (including naloxone protocol) |
| 8. Step-Down Protocol | POD 0 to discharge - exact regimens with route |
| 9. Quick Memory Aids | "No NSAIDs in 4 Ks", "No Tramadol in 4 Ss", colour-coded rules |