Explain all
| Category | Examples |
|---|---|
| Bacterial | GI perforation, genital tract infection |
| Chemical | Bile, barium, gastric acid |
| Allergic | Starch peritonitis |
| Traumatic | Operative handling |
| Ischaemic | Strangulated bowel, vascular occlusion |
| Miscellaneous | Familial Mediterranean fever |
| Topic | Key Point |
|---|---|
| Anatomy | Parietal (somatic pain) + visceral (autonomic pain); pus collects in pelvis and subdiaphragmatic space |
| Physiology | Absorbs/produces fluid; bacteria cleared via diaphragmatic lymphatics |
| Acute Peritonitis | Localised vs. diffuse; guarding, rigidity, rebound |
| Treatment | ABC, IV antibiotics, NGT, catheter, surgery = source control + lavage |
| SBP | Cirrhosis + ascites; neutrophils >250/mm³; treat with cefotaxime |
| Sclerosing Peritonitis | Abdominal cocoon; PD-related; treat with tamoxifen |
| Biliary Peritonitis | Post-cholecystectomy bile leak; ERCP + stent or surgery |
| Postoperative Peritonitis | Anastomotic leak; CT → drain or re-laparotomy |
| Pelvic Abscess | Pelvis most common abscess site; drain transanally/transgluteally |
| Subphrenic Abscess | Pus under diaphragm; shoulder-tip pain; CT-guided drainage |
| Mesenteric Cysts | Benign, fluid-filled; excision |
| Mesenteric Panniculitis | "Misty mesentery"; sclerosing mesenteritis; mostly benign |
| Mesenteric Lymphadenitis | Yersinia; mimics appendicitis; self-limiting |
| Mesenteric Malignancy | Desmoid (Gardner's), carcinoid fibrosis, lymphoma |
| Mesenteric Trauma | Deceleration injury; CT; damage control if unstable |
| Peritoneal Malignancy | Primary (mesothelioma/asbestos); secondary (carcinomatosis); HIPEC |
| Omental Cyst | Benign, mobile mass; excision |
| Omental Torsion | Twisting → ischaemia; mimics appendicitis; CT diagnosis; excision |
| Omental Tumour | Usually metastatic (ovary/colon); omental cake on CT; omentectomy |
Create a study guide PDF on peritonitis diagnosis and management
mkdir -p /tmp/workspace/peritonitis-study-guide && ls /tmp/workspace/peritonitis-study-guide/
~/peritonitis-study-guide/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import ListFlowable, ListItem
OUTPUT = "/tmp/workspace/peritonitis-study-guide/Peritonitis_Study_Guide.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1A3A5C")
TEAL = colors.HexColor("#1B7A8A")
LIGHT_TEAL= colors.HexColor("#E6F4F7")
AMBER = colors.HexColor("#D4700A")
RED_ALERT = colors.HexColor("#C0392B")
LIGHT_RED = colors.HexColor("#FDECEA")
GREEN = colors.HexColor("#1E7E4B")
LIGHT_GRN = colors.HexColor("#E8F8EE")
LIGHT_NAVY= colors.HexColor("#E8EEF5")
MID_GREY = colors.HexColor("#6B7280")
LIGHT_GREY= colors.HexColor("#F3F4F6")
WHITE = colors.white
BLACK = colors.black
# ── Document ────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=18*mm, rightMargin=18*mm,
topMargin=20*mm, bottomMargin=20*mm,
title="Peritonitis – Diagnosis & Management Study Guide",
author="Orris Medical Education",
)
W = A4[0] - 36*mm # usable width
# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
def S(name, **kw):
s = ParagraphStyle(name, **kw)
return s
TITLE_S = S("Title",
fontName="Helvetica-Bold", fontSize=22, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=4)
SUBTITLE_S = S("Subtitle",
fontName="Helvetica", fontSize=11, textColor=colors.HexColor("#B0C4D8"),
alignment=TA_CENTER, spaceAfter=2)
H1 = S("H1",
fontName="Helvetica-Bold", fontSize=14, textColor=WHITE,
spaceBefore=8, spaceAfter=4, leftIndent=0,
backColor=NAVY, borderPad=(6,4,6,4))
H2 = S("H2",
fontName="Helvetica-Bold", fontSize=11, textColor=NAVY,
spaceBefore=10, spaceAfter=3, borderPad=2,
borderColor=TEAL, borderWidth=0)
H3 = S("H3",
fontName="Helvetica-Bold", fontSize=10, textColor=TEAL,
spaceBefore=6, spaceAfter=2)
BODY = S("Body",
fontName="Helvetica", fontSize=9.5, textColor=BLACK,
leading=14, spaceAfter=4, alignment=TA_JUSTIFY)
BODY_BOLD = S("BodyBold",
fontName="Helvetica-Bold", fontSize=9.5, textColor=BLACK, leading=14)
BULLET = S("Bullet",
fontName="Helvetica", fontSize=9.5, textColor=BLACK,
leading=13, leftIndent=14, firstLineIndent=-10, spaceAfter=2)
SUB_BULLET = S("SubBullet",
fontName="Helvetica", fontSize=9, textColor=colors.HexColor("#374151"),
leading=13, leftIndent=26, firstLineIndent=-10, spaceAfter=1)
CALLOUT = S("Callout",
fontName="Helvetica-BoldOblique", fontSize=9.5,
textColor=AMBER, leading=13, spaceAfter=4)
FOOTER_S = S("Footer",
fontName="Helvetica-Oblique", fontSize=7.5, textColor=MID_GREY,
alignment=TA_CENTER)
BADGE_S = S("Badge",
fontName="Helvetica-Bold", fontSize=8, textColor=WHITE,
alignment=TA_CENTER)
def bp(text, style=BULLET, bullet="•"):
return Paragraph(f"<b>{bullet}</b> {text}", style)
def sbp(text):
return Paragraph(f" – {text}", SUB_BULLET)
def h1(text):
return Paragraph(f" {text}", H1)
def h2(text):
return Paragraph(text, H2)
def h3(text):
return Paragraph(text, H3)
def body(text):
return Paragraph(text, BODY)
def sp(n=4):
return Spacer(1, n)
def rule(color=TEAL, thickness=1):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4, spaceBefore=2)
# ── Header banner helper ────────────────────────────────────────────────────
def banner(text, subtitle=None, bg=NAVY):
data = [[Paragraph(text, TITLE_S)]]
if subtitle:
data.append([Paragraph(subtitle, SUBTITLE_S)])
t = Table(data, colWidths=[W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [6]),
]))
return t
# ── Section header helper ────────────────────────────────────────────────────
def section_header(number, title, color=NAVY):
num_cell = Paragraph(f"<font color='white'><b>{number}</b></font>",
ParagraphStyle("num", fontName="Helvetica-Bold", fontSize=12,
alignment=TA_CENTER, textColor=WHITE))
title_cell = Paragraph(f"<b>{title}</b>",
ParagraphStyle("stitle", fontName="Helvetica-Bold", fontSize=13,
textColor=WHITE, leading=16))
t = Table([[num_cell, title_cell]], colWidths=[12*mm, W-12*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (0,0), 6),
("LEFTPADDING", (0,0), (1,0), 10),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
return t
# ── Alert box helper ─────────────────────────────────────────────────────────
def alert_box(title, items, bg=LIGHT_RED, border=RED_ALERT, title_color=RED_ALERT):
rows = [[Paragraph(f"<b><font color='{title_color.hexval()}'>⚠ {title}</font></b>",
ParagraphStyle("at", fontName="Helvetica-Bold", fontSize=10,
textColor=title_color, leading=14))]]
for item in items:
rows.append([Paragraph(f"• {item}", BULLET)])
t = Table(rows, colWidths=[W - 4])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1.5, border),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
def info_box(title, items, bg=LIGHT_TEAL, border=TEAL, title_color=TEAL):
return alert_box(title, items, bg=bg, border=border, title_color=title_color)
def key_box(title, items, bg=LIGHT_GRN, border=GREEN, title_color=GREEN):
return alert_box(title, items, bg=bg, border=border, title_color=title_color)
# ── Two-column table helper ──────────────────────────────────────────────────
def two_col_table(headers, rows, col_widths=None):
if col_widths is None:
col_widths = [W*0.35, W*0.65]
hdr_style = ParagraphStyle("th", fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_CENTER)
cell_style = ParagraphStyle("td", fontName="Helvetica", fontSize=9,
textColor=BLACK, leading=13)
data = [[Paragraph(h, hdr_style) for h in headers]]
for row in rows:
data.append([Paragraph(str(c), cell_style) for c in row])
t = Table(data, colWidths=col_widths, repeatRows=1)
n = len(data)
style = [
("BACKGROUND", (0,0), (-1,0), NAVY),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#D1D5DB")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]
for i in range(1, n):
bg = LIGHT_GREY if i % 2 == 0 else WHITE
style.append(("BACKGROUND", (0,i), (-1,i), bg))
t.setStyle(TableStyle(style))
return t
# ═══════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ═══════════════════════════════════════════════════════════════════════════
story = []
# ── COVER BANNER ─────────────────────────────────────────────────────────────
story.append(sp(8))
story.append(banner(
"PERITONITIS",
"Diagnosis & Management — Study Guide",
bg=NAVY
))
story.append(sp(4))
# Metadata strip
meta_rows = [[
Paragraph("<b>Source</b><br/>Bailey & Love's Surgery 28e<br/>Harrison's Internal Medicine 22e", BODY),
Paragraph("<b>Level</b><br/>Medical Student / Surgical SHO", BODY),
Paragraph("<b>Topic</b><br/>Peritoneum — Chapter 32", BODY),
]]
meta_t = Table(meta_rows, colWidths=[W/3, W/3, W/3])
meta_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_NAVY),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(meta_t)
story.append(sp(10))
# ── TABLE OF CONTENTS (visual) ────────────────────────────────────────────
toc_items = [
("1", "Definition & Classification", "p.1"),
("2", "Pathophysiology", "p.1"),
("3", "Aetiology & Routes of Infection", "p.2"),
("4", "Clinical Features", "p.2"),
("5", "Investigations", "p.3"),
("6", "Management & Treatment", "p.3"),
("7", "Special Types of Peritonitis", "p.4"),
("8", "Complications", "p.5"),
("9", "High-Yield Summary & Memory Aids", "p.5"),
]
toc_title = Paragraph("<b>Contents</b>",
ParagraphStyle("toc_title", fontName="Helvetica-Bold", fontSize=11,
textColor=NAVY, spaceAfter=4))
story.append(toc_title)
toc_data = []
for num, topic, page in toc_items:
toc_data.append([
Paragraph(f"<font color='white'><b>{num}</b></font>",
ParagraphStyle("tn", fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_CENTER)),
Paragraph(topic, ParagraphStyle("tt", fontName="Helvetica", fontSize=9,
textColor=NAVY, leading=13)),
Paragraph(page, ParagraphStyle("tp", fontName="Helvetica", fontSize=9,
textColor=MID_GREY, alignment=TA_CENTER)),
])
toc_t = Table(toc_data, colWidths=[10*mm, W-25*mm, 15*mm])
toc_style = [
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("LINEBELOW", (0,0), (-1,-1), 0.5, colors.HexColor("#D1D5DB")),
]
for i, _ in enumerate(toc_data):
toc_style.append(("BACKGROUND", (0,i), (0,i), TEAL))
toc_style.append(("BACKGROUND", (1,i), (-1,i), LIGHT_GREY if i%2==0 else WHITE))
toc_t.setStyle(TableStyle(toc_style))
story.append(toc_t)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════
# SECTION 1 — DEFINITION & CLASSIFICATION
# ═══════════════════════════════════════════════════════════════════════
story.append(section_header("1", "Definition & Classification"))
story.append(sp(6))
story.append(body(
"<b>Peritonitis</b> is inflammation of the peritoneum — the serous membrane lining "
"the abdominal cavity and covering the viscera. It is a surgical emergency associated "
"with high morbidity and mortality if not promptly diagnosed and treated."
))
story.append(sp(4))
# Classification table
story.append(h2("Classification"))
cls_data = [
["Basis", "Types"],
["Extent", "Localised (focal) vs Diffuse (generalised)"],
["Onset", "Acute vs Chronic"],
["Cause", "Primary (spontaneous) vs Secondary (viscus perforation/leak) vs Tertiary (recurrent, post-treatment)"],
["Aetiology", "Bacterial, Chemical, Fungal, Granulomatous (TB), Ischaemic"],
]
story.append(two_col_table(["Basis", "Types"],
[r[1:] for r in cls_data[1:]], col_widths=[W*0.3, W*0.7]))
story.append(sp(6))
# Localised vs Diffuse cards
loc_data = [
[
Paragraph("<b>Localised Peritonitis</b>", ParagraphStyle("lh", fontName="Helvetica-Bold",
fontSize=10, textColor=TEAL)),
Paragraph("<b>Diffuse (Generalised) Peritonitis</b>", ParagraphStyle("dh", fontName="Helvetica-Bold",
fontSize=10, textColor=RED_ALERT)),
],
[
Paragraph(
"• Focal area of peritoneum inflamed<br/>"
"• Parietal involvement → somatic pain (well localised)<br/>"
"• Guarding + rebound tenderness = peritonism<br/>"
"• Subdiaphragmatic → shoulder-tip pain (C5 referred)<br/>"
"• Pelvic → tenderness on PR/PV exam<br/>"
"• Vital signs may be near normal",
BULLET),
Paragraph(
"• Whole parietal peritoneum involved<br/>"
"• Life-threatening — requires urgent surgery<br/>"
"• Causes: perforated viscus, ruptured AAA, anastomotic leak<br/>"
"• 'Board-like' rigidity, Hippocratic facies<br/>"
"• Generalised ileus → distension<br/>"
"• Septic shock (SIRS → MODS) in late stages",
BULLET),
]
]
loc_t = Table(loc_data, colWidths=[W/2 - 2, W/2 - 2], spaceBefore=4)
loc_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIGHT_TEAL),
("BACKGROUND", (1,0), (1,0), LIGHT_RED),
("BACKGROUND", (0,1), (0,1), WHITE),
("BACKGROUND", (1,1), (1,1), colors.HexColor("#FFF8F8")),
("BOX", (0,0), (0,-1), 1, TEAL),
("BOX", (1,0), (1,-1), 1, RED_ALERT),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(loc_t)
# ═══════════════════════════════════════════════════════════════════════
# SECTION 2 — PATHOPHYSIOLOGY
# ═══════════════════════════════════════════════════════════════════════
story.append(sp(12))
story.append(section_header("2", "Pathophysiology", color=TEAL))
story.append(sp(6))
story.append(body(
"When the peritoneum is injured or contaminated, a complex cascade occurs:"
))
story.append(sp(3))
patho_steps = [
("<b>Trigger:</b>", "Bacteria, chemical irritant (bile, gastric acid), or ischaemia activates the peritoneum"),
("<b>Vascular response:</b>", "Hyperaemia → increased capillary permeability → protein-rich exudate pours into cavity"),
("<b>Fibrin deposition:</b>", "Fibrin glues loops of bowel/omentum together → walling off infection (localisation)"),
("<b>Neutrophil influx:</b>", "PMNs engulf bacteria; turbid fluid → frank pus if not drained"),
("<b>Ileus:</b>", "Reflexive bowel paralysis → distension → further bacterial translocation"),
("<b>Fluid shifts:</b>", "Massive third-spacing → hypovolaemia → oliguria"),
("<b>Systemic:</b>", "Bacterial translocation + endotoxaemia → SIRS → MODS → death if untreated"),
]
for bold_part, rest in patho_steps:
story.append(Paragraph(f"• {bold_part} {rest}", BULLET))
story.append(sp(6))
story.append(info_box("Key Physiological Fact",
["Peritoneal fluid normally travels upward toward the diaphragm during expiration",
"Bacteria are absorbed in minutes through diaphragmatic lymphatic pores",
"This explains why abscesses form at remote sites (subphrenic, pelvic) from the primary pathology",
"The omentum (\"abdominal policeman\") migrates to wall off infection"]))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 3 — AETIOLOGY & ROUTES
# ═══════════════════════════════════════════════════════════════════════
story.append(sp(12))
story.append(section_header("3", "Aetiology & Routes of Infection"))
story.append(sp(6))
story.append(h2("Causes at a Glance"))
cause_data = [
["Category", "Examples"],
["GI Perforation (most common)", "Perforated peptic ulcer, perforated appendix, diverticular perforation, perforated colon (obstruction)"],
["Anastomotic Leak", "Post-colorectal surgery — commonest cause of postoperative peritonitis"],
["Transmural translocation", "Pancreatitis, ischaemic bowel, Crohn's disease (no frank perforation)"],
["Chemical", "Bile peritonitis (post-cholecystectomy), barium perforation, gastric acid"],
["Female genital tract", "PID, ruptured ectopic pregnancy, salpingitis (Chlamydia, gonococci)"],
["Exogenous", "Peritoneal dialysis catheters, abdominal drains, open trauma"],
["Haematogenous (rare)", "Septicaemia — spontaneous bacterial peritonitis in cirrhosis"],
["Granulomatous", "Tuberculosis, fungal (immunocompromised patients)"],
["Hereditary", "Familial Mediterranean fever (FMF) — autosomal recessive, MEFV gene"],
]
story.append(two_col_table(["Category", "Examples"],
[r[1:] for r in cause_data[1:]], col_widths=[W*0.32, W*0.68]))
story.append(sp(8))
story.append(alert_box("Don't Miss",
["Anastomotic leak — insidious deterioration after initial post-op recovery",
"SBP in cirrhotic patients — often asymptomatic; always tap the ascites",
"FMF in young patients of Arab/Armenian/Jewish descent — mimics appendicitis"]))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 4 — CLINICAL FEATURES
# ═══════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("4", "Clinical Features"))
story.append(sp(6))
story.append(h2("Symptoms"))
for s in [
"<b>Abdominal pain</b> — worse on movement, coughing, deep breathing",
"<b>Nausea and vomiting</b>",
"<b>Anorexia, malaise, fever, lassitude</b>",
"<b>Shoulder-tip pain</b> — subdiaphragmatic irritation (referred to C5)",
"<b>Pelvic pressure / diarrhoea with mucus</b> — pelvic peritonitis",
]:
story.append(bp(s))
story.append(sp(6))
story.append(h2("Signs"))
signs_data = [
["Sign", "Significance"],
["Involuntary guarding", "Reflex abdominal wall muscle contraction — reduces peritoneal irritation"],
["Rebound tenderness", "Pain on releasing examiner's hand — parietal peritoneum involvement"],
["Board-like rigidity", "Severe generalised peritonitis; rectus contraction → scaphoid abdomen in thin patients"],
["Hippocratic facies", "Sunken eyes, pale/grey complexion — gravely ill patient in diffuse peritonitis"],
["Absent bowel sounds", "Ileus — paralytic from peritoneal inflammation"],
["PR / PV tenderness", "Pelvic peritonitis — appendix or Fallopian tube pathology"],
["Tachycardia, pyrexia", "Systemic inflammatory response"],
["Hypotension", "Late sign — third-spacing, septic shock"],
]
story.append(two_col_table(["Sign", "Significance"],
[r[1:] for r in signs_data[1:]], col_widths=[W*0.35, W*0.65]))
story.append(sp(8))
story.append(key_box("Clinical Pearl",
["Signs may be ABSENT or MINIMAL in: obese patients, elderly, immunosuppressed, corticosteroid users",
"Always perform PR examination — may be the only positive finding in pelvic peritonitis",
"'Peritonism' = guarding + rebound tenderness (not full peritonitis)"]))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 5 — INVESTIGATIONS
# ═══════════════════════════════════════════════════════════════════════
story.append(sp(12))
story.append(section_header("5", "Investigations", color=TEAL))
story.append(sp(6))
inv_data = [
["Investigation", "Findings / Purpose"],
["CT Abdomen/Pelvis (IV contrast) ★★★", "Investigation of CHOICE — free gas, free fluid, abscess, source identification, anastomotic leak (Gastrografin)"],
["Erect CXR", "Free gas under diaphragm (subdiaphragmatic air) — confirms visceral perforation"],
["Lateral decubitus XR", "Alternative to erect CXR in very unwell patients — gas rises to highest point"],
["Blood tests (FBC, CRP, PCT)", "Raised WCC, CRP, procalcitonin — support diagnosis; not specific"],
["U&E, LFTs, coagulation", "Baseline, guide resuscitation, identify organ dysfunction"],
["Blood cultures (x2)", "Prior to antibiotics — identify causative organism"],
["Serum lactate", "Raised in sepsis/poor perfusion — prognostic marker"],
["Ultrasound", "Useful for tubo-ovarian pathology; less specific than CT for peritonitis"],
["Diagnostic paracentesis (SBP)", "Ascitic neutrophil count >250/mm³ = SBP; send for MC&S"],
["Diagnostic laparoscopy", "If imaging inconclusive — direct visualisation and biopsy"],
]
story.append(two_col_table(["Investigation", "Findings / Purpose"],
[r[1:] for r in inv_data[1:]], col_widths=[W*0.38, W*0.62]))
story.append(sp(6))
story.append(alert_box("Imaging Key Points",
["Free gas under diaphragm on erect CXR = perforated viscus until proven otherwise",
"CT is gold standard — do NOT delay for imaging if patient is haemodynamically unstable",
"In SBP: culture may be NEGATIVE in 60% — do NOT wait for positive culture to treat"]))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 6 — MANAGEMENT
# ═══════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("6", "Management & Treatment"))
story.append(sp(6))
story.append(h2("ABCDE Resuscitation First"))
for s in [
"<b>Airway/Breathing:</b> High-flow O₂, consider intubation if GCS drops",
"<b>Circulation:</b> Large-bore IV access x2; aggressive crystalloid resuscitation; blood cultures before antibiotics",
"<b>Disability:</b> Neurological status; analgesia (IV opioids — does NOT mask signs)",
"<b>Everything else:</b> NGT (decompress stomach, prevent aspiration), urinary catheter (hourly urine output monitoring)",
]:
story.append(bp(s))
story.append(sp(8))
story.append(h2("Step-by-Step Management"))
steps = [
("STEP 1", "Resuscitation", "IV fluids (crystalloid), correct electrolyte imbalance, treat shock", TEAL),
("STEP 2", "Analgesia", "IV morphine / fentanyl — early analgesia is safe and does not mask signs", TEAL),
("STEP 3", "NG Tube", "Nasogastric drainage to decompress stomach, reduce aspiration risk", TEAL),
("STEP 4", "Urinary Catheter", "Monitor hourly urine output (target ≥0.5 ml/kg/hr)", TEAL),
("STEP 5", "Antibiotics", "Broad-spectrum empirical antibiotics IMMEDIATELY — cover Gram-negatives + anaerobes", RED_ALERT),
("STEP 6", "Imaging", "CT abdomen/pelvis with IV contrast — identify source", TEAL),
("STEP 7", "Surgical/Procedural", "Source control — remove or exclude cause; peritoneal lavage ± drainage", RED_ALERT),
("STEP 8", "ICU", "Organ support if MODS — ventilation, vasopressors, renal replacement therapy", NAVY),
]
step_data = []
for code, title, detail, color in steps:
step_data.append([
Paragraph(f"<font color='white'><b>{code}</b></font>",
ParagraphStyle("sc", fontName="Helvetica-Bold", fontSize=8,
textColor=WHITE, alignment=TA_CENTER)),
Paragraph(f"<b>{title}</b>", ParagraphStyle("st", fontName="Helvetica-Bold",
fontSize=9.5, textColor=color)),
Paragraph(detail, ParagraphStyle("sd", fontName="Helvetica", fontSize=9,
textColor=BLACK, leading=13)),
])
step_t = Table(step_data, colWidths=[18*mm, 35*mm, W-55*mm])
step_style = [
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("LINEBELOW", (0,0), (-1,-1), 0.5, colors.HexColor("#D1D5DB")),
]
for i, (_, _, _, color) in enumerate(steps):
step_style.append(("BACKGROUND", (0,i), (0,i), color))
step_style.append(("BACKGROUND", (1,i), (-1,i), LIGHT_GREY if i%2==0 else WHITE))
step_t.setStyle(TableStyle(step_style))
story.append(step_t)
story.append(sp(8))
story.append(h2("Antibiotic Regimens"))
abx_data = [
["Scenario", "First-Line Antibiotic(s)", "Notes"],
["Community-acquired (mild–mod)", "Piperacillin-tazobactam (Tazocin) OR Co-amoxiclav + metronidazole", "Cover Gram-neg rods + anaerobes"],
["Severe / ICU", "Meropenem or imipenem ± metronidazole", "Carbapenem for resistant organisms"],
["SBP (cirrhosis)", "Cefotaxime 2g IV 8-hourly (5 days)", "Avoid aminoglycosides (nephrotoxic); alternatives: ciprofloxacin, co-amoxiclav"],
["Fungal peritonitis", "Fluconazole or caspofungin", "Rare — consider in immunocompromised / long-term PD"],
["TB peritonitis", "RIPE: Rifampicin + Isoniazid + Pyrazinamide + Ethambutol", "Bowel obstruction may resolve without surgery"],
]
story.append(two_col_table(["Scenario", "First-Line Antibiotic(s)", "Notes"],
[r[1:] for r in abx_data[1:]], col_widths=[W*0.28, W*0.42, W*0.30]))
story.append(sp(8))
story.append(h2("Surgical Principles — 'Source Control'"))
for s in [
"<b>Goal:</b> Remove or exclude the source of contamination",
"<b>Localised abscess:</b> CT/US-guided percutaneous drainage (preferred if technically feasible)",
"<b>Diffuse peritonitis:</b> Laparotomy (or laparoscopy in selected cases) — repair/resect source",
"<b>Peritoneal lavage:</b> Copious warm saline lavage of the peritoneal cavity",
"<b>Damage control surgery:</b> In haemodynamically unstable patients — control bleeding/contamination, pack abdomen, return for definitive repair 24–48h later",
"<b>Open abdomen:</b> May be left open (temporary closure) in severe contamination to facilitate re-look laparotomies",
]:
story.append(bp(s))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 7 — SPECIAL TYPES
# ═══════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("7", "Special Types of Peritonitis", color=NAVY))
story.append(sp(6))
special_types = [
{
"title": "Spontaneous Bacterial Peritonitis (SBP)",
"color": RED_ALERT,
"bg": LIGHT_RED,
"points": [
"<b>Definition:</b> Bacterial infection of ascitic fluid WITHOUT obvious intra-abdominal source",
"<b>Setting:</b> Cirrhosis with ascites (most common); also nephrotic syndrome",
"<b>Organisms:</b> E. coli (Gram-neg), Streptococci/Enterococci (Gram-pos); culture NEGATIVE in 60%",
"<b>Diagnosis:</b> Paracentesis → ascitic neutrophil count <b>>250/mm³</b>",
"<b>Treatment:</b> Cefotaxime 2g IV (3rd-gen cephalosporin) — start BEFORE culture results",
"<b>Prophylaxis:</b> Long-term norfloxacin/ciprofloxacin after first episode",
]
},
{
"title": "Biliary Peritonitis",
"color": AMBER,
"bg": colors.HexColor("#FFF8E6"),
"points": [
"<b>Cause:</b> Bile leak — post-cholecystectomy (cystic duct clip slippage), post-hepatectomy, bile duct injury",
"<b>Features:</b> Peritonism after biliary surgery; variable severity",
"<b>Investigation:</b> CT/ERCP to identify source",
"<b>Treatment (localised):</b> Percutaneous drain + ERCP stent across leak",
"<b>Treatment (diffuse/high-volume):</b> Surgical exploration + lavage + drainage",
]
},
{
"title": "Sclerosing (Encapsulating) Peritonitis",
"color": TEAL,
"bg": LIGHT_TEAL,
"points": [
"<b>Also called:</b> Encapsulating Peritoneal Sclerosis (EPS), 'abdominal cocoon'",
"<b>Cause:</b> Long-term peritoneal dialysis (PD) — most common; practolol (withdrawn drug)",
"<b>Features:</b> Dense fibrosis encasing bowel loops → recurrent bowel obstruction",
"<b>CT:</b> Calcification, encasement of small bowel loops",
"<b>Treatment:</b> Tamoxifen (anti-fibrotic) ± surgical lysis of adhesions",
]
},
{
"title": "Tuberculous Peritonitis",
"color": GREEN,
"bg": LIGHT_GRN,
"points": [
"<b>Features:</b> Abdominal pain, sweats, malaise, weight loss, loculated ascites",
"<b>Findings:</b> Caseating peritoneal nodules at laparoscopy",
"<b>Distinguish from:</b> Peritoneal carcinomatosis (histology/cytology essential)",
"<b>Treatment:</b> RIPE therapy (Rifampicin, Isoniazid, Pyrazinamide, Ethambutol)",
"<b>Note:</b> Bowel obstruction may resolve with anti-TB drugs — avoid surgery if possible",
]
},
{
"title": "Familial Mediterranean Fever (FMF)",
"color": NAVY,
"bg": LIGHT_NAVY,
"points": [
"<b>Inheritance:</b> Autosomal recessive; MEFV gene → defective pyrin protein (regulates IL-1β in neutrophils)",
"<b>Populations:</b> Arab, Armenian, Jewish",
"<b>Features:</b> Episodic abdominal pain + fever + joint pain; resolves in 24–72h",
"<b>Complication:</b> Amyloidosis (long-term)",
"<b>Mimics:</b> Appendicitis — commonly misdiagnosed in childhood",
"<b>Treatment:</b> Colchicine — reduces attacks and prevents amyloidosis",
]
},
{
"title": "Postoperative Peritonitis",
"color": RED_ALERT,
"bg": LIGHT_RED,
"points": [
"<b>Commonest cause:</b> Anastomotic leak after colorectal/GI surgery",
"<b>Other causes:</b> Inadvertent bowel injury, infected haematoma",
"<b>Presentation:</b> Slow deterioration after initial post-op recovery; sepsis picture",
"<b>CT signs of leak:</b> Extraluminal gas, free contrast (Gastrografin) near anastomosis",
"<b>Treatment:</b> CT-guided drain (localised) OR re-laparotomy + source control (diffuse)",
]
},
]
for st in special_types:
# Type header
hdr_t = Table([[Paragraph(f"<b>{st['title']}</b>",
ParagraphStyle("sh", fontName="Helvetica-Bold", fontSize=10,
textColor=st['color']))]],
colWidths=[W])
hdr_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), st['bg']),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 1.5, st['color']),
]))
content_rows = [[Paragraph(p, BULLET)] for p in st['points']]
content_t = Table(content_rows, colWidths=[W])
content_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), WHITE),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("BOX", (0,0), (-1,-1), 1, st['color']),
]))
story.append(KeepTogether([hdr_t, content_t]))
story.append(sp(6))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 8 — COMPLICATIONS
# ═══════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("8", "Complications", color=RED_ALERT))
story.append(sp(6))
comp_data = [
["Complication", "Mechanism / Notes"],
["Pelvic abscess", "Most common site — pelvis fills by gravity when upright; drain transanally/transgluteally"],
["Subphrenic abscess", "Pus under diaphragm — shoulder-tip pain; CT-guided drain; adage: 'pus somewhere, pus nowhere, pus under diaphragm'"],
["Residual/recurrent abscess", "Inadequate initial drainage; may need re-intervention"],
["Septic shock (SIRS → MODS)", "Endotoxaemia → vasodilation → multi-organ failure; ICU management"],
["Intra-abdominal adhesions", "Late complication — fibrin bands → small bowel obstruction (may require surgery years later)"],
["Entero-cutaneous fistula", "Anastomotic breakdown or bowel injury → fistula formation"],
["Paralytic ileus", "Prolonged bowel paralysis — managed conservatively (NGT, NBM, IV fluids)"],
["Wound dehiscence / incisional hernia", "Infection + raised IAP compromise wound healing"],
["Mortality", "Diffuse peritonitis with MODS: mortality 30–50% even with optimal management"],
]
story.append(two_col_table(["Complication", "Mechanism / Notes"],
[r[1:] for r in comp_data[1:]], col_widths=[W*0.35, W*0.65]))
story.append(sp(8))
story.append(h2("Tertiary Peritonitis"))
story.append(body(
"<b>Tertiary peritonitis</b> is a persistent or recurrent peritoneal infection following "
"apparently adequate source control. It occurs in ICU patients with ongoing sepsis and "
"is characterised by low-grade organisms (Candida, Enterococcus, Pseudomonas, "
"coagulase-negative Staphylococci). It carries a very high mortality (~50–70%). "
"Management involves prolonged antibiotics, antifungals, and repeated re-look laparotomies."
))
# ═══════════════════════════════════════════════════════════════════════
# SECTION 9 — HIGH-YIELD SUMMARY & MEMORY AIDS
# ═══════════════════════════════════════════════════════════════════════
story.append(sp(12))
story.append(section_header("9", "High-Yield Summary & Memory Aids"))
story.append(sp(6))
# Quick-fire facts
story.append(h2("High-Yield Facts"))
facts = [
"Investigation of choice: <b>CT abdomen/pelvis (IV contrast)</b>",
"Free gas under diaphragm → <b>perforated viscus</b> until proven otherwise",
"SBP diagnosis: ascitic neutrophil <b>>250/mm³</b> — culture is negative in 60%",
"SBP treatment: <b>Cefotaxime</b> (3rd-gen cephalosporin) — avoids nephrotoxic aminoglycosides",
"Diffuse peritonitis: <b>'Board-like' rigidity + Hippocratic facies</b>",
"Pelvic abscess: most common abscess site — drain <b>transanally or transgluteally</b>",
"Subphrenic abscess: <b>shoulder-tip pain</b> (C5 referred); adage — 'pus somewhere, pus nowhere...'",
"FMF gene: <b>MEFV → pyrin protein → regulates IL-1β</b>; treat with colchicine",
"Sclerosing peritonitis = EPS = abdominal cocoon → <b>tamoxifen</b>",
"HIPEC = <b>41–42°C</b> chemotherapy for 90 min after cytoreductive surgery (pseudomyxoma, mesothelioma)",
"Omental torsion: right-sided pain, mimics appendicitis → <b>CT shows fat stranding with whirl sign</b>",
"Damage control surgery = control contamination, <b>pack abdomen</b>, return 24–48h for definitive repair",
]
for f in facts:
story.append(bp(f))
story.append(sp(8))
# Mnemonics
story.append(h2("Mnemonics"))
mnem_data = [
[
Paragraph("<b>PERITONITIS</b><br/>(causes)", ParagraphStyle("mt", fontName="Helvetica-Bold",
fontSize=10, textColor=TEAL, alignment=TA_CENTER)),
Paragraph(
"<b>P</b>erforation of viscus<br/>"
"<b>E</b>xogenous (drains, PD, trauma)<br/>"
"<b>R</b>upture (AAA, ectopic)<br/>"
"<b>I</b>schaemia (strangulated bowel)<br/>"
"<b>T</b>ransmural (pancreatitis)<br/>"
"<b>O</b>varian / PID<br/>"
"<b>N</b>eoplasm (rare primary)<br/>"
"<b>I</b>nfection spontaneous (SBP)<br/>"
"<b>T</b>B / Granulomatous<br/>"
"<b>I</b>atrogenic (post-op leak)<br/>"
"<b>S</b>clerosing / Familial (FMF)",
ParagraphStyle("mc", fontName="Helvetica", fontSize=9, leading=14, textColor=BLACK)),
],
[
Paragraph("<b>Management</b><br/>('LAST')", ParagraphStyle("mt2", fontName="Helvetica-Bold",
fontSize=10, textColor=NAVY, alignment=TA_CENTER)),
Paragraph(
"<b>L</b>avage the cavity (peritoneal)<br/>"
"<b>A</b>ntibiotics (broad-spectrum, early)<br/>"
"<b>S</b>ource control (remove cause)<br/>"
"<b>T</b>ube (NGT) + resuscitation",
ParagraphStyle("mc2", fontName="Helvetica", fontSize=9, leading=14, textColor=BLACK)),
],
]
mnem_t = Table(mnem_data, colWidths=[W*0.25, W*0.75])
mnem_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIGHT_TEAL),
("BACKGROUND", (0,1), (0,1), LIGHT_NAVY),
("BACKGROUND", (1,0), (1,0), WHITE),
("BACKGROUND", (1,1), (1,1), LIGHT_GREY),
("BOX", (0,0), (-1,0), 1, TEAL),
("BOX", (0,1), (-1,1), 1, NAVY),
("LINEBELOW", (0,0), (-1,0), 1, colors.white),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mnem_t)
story.append(sp(10))
# Rapid fire differentials
story.append(h2("Conditions That Mimic Peritonitis"))
mimics = [
["Condition", "Distinguishing Clue"],
["Acute mesenteric lymphadenitis", "Children/young adults; Yersinia; US shows enlarged nodes, normal appendix"],
["Familial Mediterranean Fever", "Episodic; settles in 24–72h; Mediterranean ethnicity; MEFV mutation"],
["Pneumonia (right lower lobe)", "Chest signs; CXR consolidation; no rigidity"],
["Diabetic ketoacidosis", "Hyperglycaemia, ketonaemia; abdominal pain resolves with treatment"],
["Acute porphyria", "Neuropsychiatric features; no signs of perforation on imaging"],
["Retroperitoneal haematoma", "Flank bruising; no free peritoneal fluid"],
]
story.append(two_col_table(["Condition", "Distinguishing Clue"],
[r[1:] for r in mimics[1:]], col_widths=[W*0.4, W*0.6]))
story.append(sp(10))
# Footer
story.append(HRFlowable(width="100%", thickness=1, color=NAVY, spaceAfter=4))
story.append(Paragraph(
"Study Guide prepared by Orris Medical Education • Source: Bailey & Love's Short Practice of Surgery 28e, "
"Harrison's Principles of Internal Medicine 22e • For educational use only",
FOOTER_S
))
# ── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated: {OUTPUT}")
cd /tmp/workspace/peritonitis-study-guide && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/peritonitis-study-guide/Peritonitis_Study_Guide.pdf
Peritonitis Study Guide
PDF Document · PDF