Can you make notes of pyogenic liver abscess from srb
Source note: SRB's Manual of Surgery is not available in this library. These notes are compiled from Sabiston Textbook of Surgery (12th ed.), Mulholland & Greenfield's Surgery (7th ed.), and Sleisenger & Fordtran's GI & Liver Disease — all equally authoritative surgical references.
| Route | Mechanism | Common Causes |
|---|---|---|
| Biliary tree (most common identifiable) | Ascending suppurative cholangitis from bile stasis → bacterial colonization | Choledocholithiasis, malignant biliary obstruction, Caroli disease, biliary-enteric anastomosis, biliary ascariasis |
| Portal vein (Pylephlebitis) | Intra-abdominal infection → portal vein bacteraemia | Appendicitis, diverticulitis, pancreatitis, IBD, pelvic inflammatory disease, perforated viscus, omphalitis (newborns) |
| Hepatic artery (systemic bacteraemia) | Any systemic infection seeds the liver via hepatic artery | Endocarditis, pneumonia, osteomyelitis, septicaemia |
| Direct extension | Contiguous spread from adjacent infection | Suppurative cholecystitis, subphrenic/perinephric abscess, bowel perforation into liver |
| Trauma | Penetrating or blunt injury → intrahepatic haematoma → superinfection | Also: hepatic artery embolisation, thermal ablation (especially with prior biliary-enteric anastomosis) |
| Cryptogenic | No identifiable source | Most common in modern series (40–43%); possible sources include oral flora/severe periodontal disease (especially alcoholics) |
Historical note: Ochsner and DeBakey (1938) described 47 cases — appendicitis via portal vein was then the dominant cause. Today, biliary disease and cryptogenic causes predominate in Western countries. In Asia, recurrent pyogenic cholangitis (intrahepatic stones) remains important.
| Test | Finding |
|---|---|
| WBC | Leukocytosis (70–90%) |
| Haemoglobin | Normochromic, normocytic anaemia |
| Alkaline phosphatase (ALP) | Mildly elevated in ~80% |
| Total bilirubin | Elevated in 20–50% |
| Transaminases | Mildly elevated in ~60% |
| Albumin | Hypoalbuminaemia (reflects chronicity) |
| PT/INR | Mildly elevated in chronic cases |
| ESR | Elevated |
None of these tests are specific — they raise suspicion that leads to imaging.
| Condition | Distinguishing features |
|---|---|
| Amebic abscess | Young male, travel history, single lesion right lobe, positive serology, responds to metronidazole alone |
| Echinococcal cyst | Endemic area, daughter cysts on imaging, positive serology |
| Simple hepatic cyst | Thin wall, no enhancement, no symptoms |
| Hepatocellular carcinoma | AFP elevated, arterial enhancement + washout on CT |
| Hepatic metastasis | Known primary, multiple lesions |
| Inflammatory pseudotumour | Young men, history of infection, biopsy needed |
| Feature | Pyogenic | Amebic |
|---|---|---|
| Age | >50 years | 20–40 years |
| Sex ratio | 1.5:1 (M:F) | ≥10:1 (M:F) |
| Number | Often multiple | Usually single |
| Location | Either lobe | Right lobe, near diaphragm |
| Presentation | Subacute | Acute |
| Jaundice | Mild (late) | Moderate |
| Serology | Negative | Positive (ELISA) |
| Pus character | Purulent (foul-smelling) | "Anchovy sauce" (odourless unless superinfected) |
| Treatment | Drainage + IV antibiotics | Metronidazole (no drainage usually needed) |
Can you make a pdf of above notes
ls -la /home/daytona/workspace/
mkdir -p /home/daytona/workspace/pyogenic-liver-abscess && ls /home/daytona/workspace/
~/pyogenic-liver-abscess/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib.colors import HexColor, black, white
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
OUTPUT = "/home/daytona/workspace/pyogenic-liver-abscess/Pyogenic_Liver_Abscess_Notes.pdf"
# Colors
DARK_BLUE = HexColor("#1a3a5c")
MED_BLUE = HexColor("#2563a8")
LIGHT_BLUE = HexColor("#dbeafe")
ACCENT_GOLD = HexColor("#b45309")
TABLE_HEADER= HexColor("#1e3a5f")
TABLE_ALT = HexColor("#f0f5ff")
BORDER_BLUE = HexColor("#3b82f6")
RED = HexColor("#b91c1c")
GREEN = HexColor("#166534")
LIGHT_GREY = HexColor("#f8fafc")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.5*cm, bottomMargin=2.5*cm,
title="Pyogenic Liver Abscess — Surgical Notes",
author="Orris Medical"
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle("Title", parent=styles["Normal"],
fontSize=22, textColor=white, fontName="Helvetica-Bold",
alignment=TA_CENTER, spaceAfter=4)
subtitle_style = ParagraphStyle("Subtitle", parent=styles["Normal"],
fontSize=11, textColor=HexColor("#cfe0ff"), fontName="Helvetica",
alignment=TA_CENTER, spaceAfter=2)
h1_style = ParagraphStyle("H1", parent=styles["Normal"],
fontSize=13, textColor=white, fontName="Helvetica-Bold",
spaceBefore=10, spaceAfter=4, leftIndent=0,
backColor=DARK_BLUE, borderPad=6)
h2_style = ParagraphStyle("H2", parent=styles["Normal"],
fontSize=11, textColor=DARK_BLUE, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3, leftIndent=0,
borderPad=2)
body_style = ParagraphStyle("Body", parent=styles["Normal"],
fontSize=9.5, textColor=HexColor("#1e293b"), fontName="Helvetica",
leading=14, spaceAfter=4, alignment=TA_JUSTIFY)
bullet_style = ParagraphStyle("Bullet", parent=styles["Normal"],
fontSize=9.5, textColor=HexColor("#1e293b"), fontName="Helvetica",
leading=13, spaceAfter=2, leftIndent=14, bulletIndent=4)
note_style = ParagraphStyle("Note", parent=styles["Normal"],
fontSize=9, textColor=HexColor("#7c3aed"), fontName="Helvetica-Oblique",
leading=13, spaceAfter=4, leftIndent=10)
key_style = ParagraphStyle("Key", parent=styles["Normal"],
fontSize=9.5, textColor=HexColor("#166534"), fontName="Helvetica-Bold",
leading=13, spaceAfter=3, leftIndent=14, bulletIndent=4,
backColor=HexColor("#f0fdf4"), borderPad=4)
source_style = ParagraphStyle("Source", parent=styles["Normal"],
fontSize=8, textColor=HexColor("#64748b"), fontName="Helvetica-Oblique",
alignment=TA_CENTER, spaceBefore=6)
def section_header(text):
"""Blue banner heading."""
tbl = Table([[Paragraph(f" {text}", ParagraphStyle("H1inner",
fontSize=12, textColor=white, fontName="Helvetica-Bold",
leading=16, leftIndent=4))]],
colWidths=[17*cm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("ROUNDEDCORNERS", [4]),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
return tbl
def sub_header(text):
return Paragraph(f'<font color="#2563a8"><b>▶ {text}</b></font>', h2_style)
def bullet(text):
return Paragraph(f"• {text}", bullet_style)
def key_point(num, text):
return Paragraph(f"<b>{num}.</b> {text}", key_style)
def body(text):
return Paragraph(text, body_style)
def note(text):
return Paragraph(f"<i>{text}</i>", note_style)
def spacer(h=0.25):
return Spacer(1, h*cm)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=BORDER_BLUE, spaceAfter=4, spaceBefore=4)
# ── TABLES ──────────────────────────────────────────────────────────────────
def make_table(headers, rows, col_widths=None):
data = [[Paragraph(f"<b><font color='white'>{h}</font></b>",
ParagraphStyle("TH", fontSize=9, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=12)) for h in headers]]
for i, row in enumerate(rows):
data.append([Paragraph(str(c),
ParagraphStyle("TD", fontSize=9, fontName="Helvetica",
leading=12, spaceAfter=1)) for c in row])
if col_widths is None:
col_widths = [17*cm / len(headers)] * len(headers)
t = Table(data, colWidths=col_widths, repeatRows=1)
style = [
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("ROWBACKGROUNDS", (0,1), (-1,-1), [white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#93c5fd")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTSIZE", (0,0), (-1,-1), 9),
]
t.setStyle(TableStyle(style))
return t
# ── TITLE BLOCK ─────────────────────────────────────────────────────────────
def title_block():
tbl = Table(
[[Paragraph("PYOGENIC LIVER ABSCESS", title_style)],
[Paragraph("Comprehensive Surgical Notes", subtitle_style)],
[Paragraph("Sabiston · Mulholland & Greenfield · Sleisenger & Fordtran", subtitle_style)]],
colWidths=[17*cm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [6]),
]))
return tbl
# ═══════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════════════════
story = []
# Title
story.append(title_block())
story.append(spacer(0.5))
# Definition
story.append(section_header("1. DEFINITION"))
story.append(spacer(0.2))
story.append(body(
"A <b>pyogenic liver abscess (PLA)</b> is a focal collection of purulent bacterial material and "
"necroinflammatory debris within the liver parenchyma. It may be <b>solitary or multiple</b> "
"and is caused by one or more aerobic or anaerobic bacteria."
))
# Epidemiology
story.append(spacer(0.3))
story.append(section_header("2. EPIDEMIOLOGY"))
story.append(spacer(0.2))
epi = [
("Annual incidence", "~2.3 cases per 100,000 persons"),
("Prevalence", "Most common type of visceral abscess (13% of intra-abdominal abscesses)"),
("Age shift", "Historically 20–30s (appendicitis era) → now predominantly <b>50–60s</b> (biliary/cryptogenic era)"),
("Sex ratio", "Male : Female ≈ <b>1.5 : 1</b>; no significant ethnic/geographic difference"),
("Lobe", "<b>Right lobe ~75%</b> of cases (greater portal venous flow)"),
("Key comorbidities", "Cirrhosis, diabetes mellitus, chronic renal failure, malignancy"),
]
t = Table(
[[Paragraph(f"<b>{k}</b>", ParagraphStyle("EK", fontSize=9, fontName="Helvetica-Bold", leading=12)),
Paragraph(v, ParagraphStyle("EV", fontSize=9, fontName="Helvetica", leading=12))] for k, v in epi],
colWidths=[4.5*cm, 12.5*cm]
)
t.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0), (-1,-1), [LIGHT_BLUE, white]),
("GRID", (0,0), (-1,-1), 0.4, BORDER_BLUE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(t)
# Aetiology
story.append(spacer(0.3))
story.append(section_header("3. AETIOLOGY & ROUTES OF INFECTION"))
story.append(spacer(0.2))
ae_headers = ["Route", "Mechanism", "Common Causes"]
ae_rows = [
["Biliary tree\n(most common identifiable)", "Ascending suppurative cholangitis → bile stasis → bacterial colonisation",
"Choledocholithiasis, malignant biliary obstruction, Caroli disease, biliary-enteric anastomosis, biliary ascariasis"],
["Portal vein (Pylephlebitis)", "Intra-abdominal infection → portal vein bacteraemia ascending to liver",
"Appendicitis, diverticulitis, pancreatitis, IBD, PID, perforated viscus, omphalitis (neonates)"],
["Hepatic artery (systemic bacteraemia)", "Any systemic infection seeds liver via hepatic artery",
"Endocarditis, pneumonia, osteomyelitis, septicaemia"],
["Direct extension", "Contiguous spread from adjacent infection",
"Suppurative cholecystitis, subphrenic/perinephric abscess, bowel perforation into liver"],
["Trauma / iatrogenic", "Intrahepatic haematoma / necrosis → superinfection",
"Penetrating/blunt trauma, hepatic artery embolisation, thermal ablation (especially with prior biliary-enteric anastomosis)"],
["Cryptogenic (most common overall)", "No identifiable source (~40% of cases)",
"Possible: oral flora / severe periodontal disease (especially alcoholics); undetected GI malignancy"],
]
story.append(make_table(ae_headers, ae_rows, [3.5*cm, 5.5*cm, 8*cm]))
story.append(spacer(0.2))
story.append(note(
"Historical note: Ochsner & DeBakey (1938) — appendicitis via portal vein was the dominant cause. "
"Today, biliary disease and cryptogenic causes predominate in Western countries. "
"In Asia, recurrent pyogenic cholangitis (intrahepatic stones) remains important."
))
# Risk Factors
story.append(spacer(0.3))
story.append(section_header("4. RISK FACTORS"))
story.append(spacer(0.2))
rf_left = [
"Diabetes mellitus (most important comorbidity)",
"Cirrhosis",
"Chronic renal failure",
"Malignancy / immunosuppression",
"Liver transplantation",
]
rf_right = [
"Previous hepatobiliary/pancreatic disease or surgery",
"Chronic granulomatous disease (children — susceptibility to S. aureus)",
"Atrophic gastritis / elderly (altered bowel flora)",
"Colorectal cancer: <b>fourfold increased incidence</b> of GI malignancy in PLA patients (especially Klebsiella pneumoniae)",
]
rf_data = []
for i in range(max(len(rf_left), len(rf_right))):
l = bullet(rf_left[i]) if i < len(rf_left) else Paragraph("", body_style)
r = bullet(rf_right[i]) if i < len(rf_right) else Paragraph("", body_style)
rf_data.append([l, r])
rf_table = Table(rf_data, colWidths=[8.5*cm, 8.5*cm])
rf_table.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
]))
story.append(rf_table)
# Microbiology
story.append(spacer(0.3))
story.append(section_header("5. MICROBIOLOGY"))
story.append(spacer(0.2))
story.append(body("Most PLAs are <b>polymicrobial</b> (enteric + anaerobic organisms)."))
story.append(spacer(0.15))
micro_headers = ["Category", "Organisms", "Notes"]
micro_rows = [
["Gram-negative aerobes\n(most common)", "E. coli (most frequent), Klebsiella pneumoniae, Enterobacter spp., Pseudomonas spp., Proteus spp., Citrobacter spp.",
"K. pneumoniae virulent strains → abscess without hepatobiliary disease; metastatic septic complications (endophthalmitis, meningitis)"],
["Gram-positive aerobes", "Streptococcus milleri (anginosus) group, Enterococcus spp., S. aureus, S. pyogenes",
"S. aureus most common in children and septicaemia; Chronic granulomatous disease"],
["Anaerobes", "Bacteroides fragilis (most common anaerobe), Fusobacterium necrophorum, anaerobic streptococci, Peptostreptococcus, Prevotella spp.",
"Improved cultivation → more anaerobic isolates detected"],
["Special situations", "Salmonella Typhi (recurrent pyogenic cholangitis); Candida spp. (immunocompromised); Mycobacterium tuberculosis (rare); Actinomyces, Clostridium (uncommon)",
"Fungal abscesses in haematologic malignancy"],
]
story.append(make_table(micro_headers, micro_rows, [3.5*cm, 7*cm, 6.5*cm]))
# Clinical Features
story.append(spacer(0.3))
story.append(section_header("6. CLINICAL FEATURES"))
story.append(spacer(0.2))
story.append(sub_header("Symptoms"))
symp = [
("<b>Fever with chills/rigors</b>", "Most common symptom (up to 90%); may be spiking or low-grade (insidious)"),
("<b>Right upper quadrant pain</b>", "Dull, constant; increases with movement. Referred to right shoulder or cough if abscess near dome"),
("Anorexia, nausea, malaise", "Constitutional symptoms; weight loss if chronic"),
("Presentation", "<b>Subacute/insidious</b> in most; symptoms may persist >1 month before diagnosis. Multiple abscesses → acute presentation with sepsis/shock"),
]
sym_t = Table(
[[Paragraph(k, ParagraphStyle("SK", fontSize=9, fontName="Helvetica", leading=12)),
Paragraph(v, ParagraphStyle("SV", fontSize=9, fontName="Helvetica", leading=12))] for k, v in symp],
colWidths=[5*cm, 12*cm]
)
sym_t.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0), (-1,-1), [white, LIGHT_BLUE]),
("GRID", (0,0), (-1,-1), 0.3, BORDER_BLUE),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(sym_t)
story.append(spacer(0.2))
story.append(sub_header("Signs"))
signs = [
"Fever",
"Tender hepatomegaly (accentuated by percussion/movement) — most consistent sign",
"Jaundice — late feature; early only if biliary disease is the underlying cause",
"Splenomegaly — unusual; only in chronic abscess",
"Portal hypertension — may follow recovery if portal vein was thrombosed (pylephlebitis)",
]
for s in signs:
story.append(bullet(s))
# Investigations
story.append(spacer(0.3))
story.append(section_header("7. INVESTIGATIONS"))
story.append(spacer(0.2))
story.append(sub_header("A. Blood Tests"))
lab_headers = ["Test", "Finding", "Frequency"]
lab_rows = [
["WBC", "Leukocytosis", "70–90%"],
["Haemoglobin", "Normochromic, normocytic anaemia", "Common"],
["Alkaline Phosphatase (ALP)", "Mildly elevated", "~80%"],
["Total Bilirubin", "Elevated", "20–50%"],
["Transaminases (AST/ALT)", "Mildly elevated", "~60%"],
["Serum Albumin", "Hypoalbuminaemia (reflects chronicity)", "Variable"],
["PT / INR", "Mildly elevated in chronic cases", "Variable"],
["ESR", "Elevated", "Common"],
]
story.append(make_table(lab_headers, lab_rows, [5.5*cm, 7.5*cm, 4*cm]))
story.append(spacer(0.1))
story.append(note("None of these tests are specific — they raise suspicion that leads to imaging."))
story.append(spacer(0.2))
story.append(sub_header("B. Cultures (Critical)"))
cult = [
"<b>Blood cultures</b>: positive in ~<b>50%</b> of cases — must be drawn <b>before antibiotics</b>",
"<b>Aspirate cultures</b> (aerobic + anaerobic): yield ~90% (lower if antibiotics already started)",
"<b>Serology for Entamoeba histolytica</b> (ELISA): in patients with epidemiologic risk factors",
]
for c in cult:
story.append(bullet(c))
story.append(spacer(0.2))
story.append(sub_header("C. Imaging"))
img_headers = ["Modality", "Sensitivity", "Findings / Notes"]
img_rows = [
["Chest X-ray", "~50% abnormal", "Elevated right hemidiaphragm, right pleural effusion, right basal atelectasis"],
["Plain Abdominal X-ray", "Rarely helpful", "Air-fluid levels in cavity; portal venous gas (grave sign — high mortality)"],
["Ultrasound (first-line)", "80–95%", "Hypoechoic round/oval lesion; distinguishes solid from cystic; guides aspiration. Limitation: poor for dome lesions; operator-dependent"],
["CT (contrast-enhanced)\n— Investigation of Choice", "95–100%", "Hypodense lesion with rim enhancement (<20%); detects small/multiple abscesses and gas in cavity; identifies underlying cause. Gas in abscess = increased mortality"],
["MRI", "Higher than CT for small lesions", "Low T1, high T2 signal; gadolinium enhancement. No advantage over CT for diagnosis; better for biliary tree assessment"],
["ERCP", "—", "Indicated when biliary stones or cholestasis present on imaging"],
]
story.append(make_table(img_headers, img_rows, [3.8*cm, 3cm, 10.2*cm]))
# Differential Diagnosis
story.append(spacer(0.3))
story.append(section_header("8. DIFFERENTIAL DIAGNOSIS"))
story.append(spacer(0.2))
story.append(sub_header("Pyogenic vs. Amebic Liver Abscess"))
comp_headers = ["Feature", "PYOGENIC", "AMEBIC"]
comp_rows = [
["Age", ">50 years", "20–40 years"],
["Sex ratio (M:F)", "1.5 : 1", "≥ 10 : 1"],
["Number", "Often MULTIPLE", "Usually SINGLE"],
["Location", "Either lobe (Right > Left)", "Right lobe, near diaphragm"],
["Presentation", "Subacute (insidious)", "Acute"],
["Jaundice", "Mild (late)", "Moderate"],
["Serology (E. histolytica)", "Negative", "Positive"],
["Pus character", "Purulent, foul-smelling", "'Anchovy sauce' — odourless (unless superinfected)"],
["Treatment", "Drainage + IV antibiotics", "Metronidazole alone (no drainage usually needed)"],
]
ct = make_table(comp_headers, comp_rows, [4.5*cm, 6.25*cm, 6.25*cm])
story.append(ct)
story.append(spacer(0.2))
story.append(sub_header("Other Differentials"))
other_dd = [
("Echinococcal cyst", "Endemic area, daughter cysts on imaging, positive serology"),
("Simple hepatic cyst", "Thin wall, no enhancement, no symptoms, no fever"),
("Hepatocellular carcinoma", "AFP elevated, arterial enhancement + washout on CT"),
("Hepatic metastasis", "Known primary, multiple lesions, no fever"),
("Inflammatory pseudotumour", "Young men, history of infection, biopsy needed for diagnosis"),
]
for cond, feat in other_dd:
story.append(bullet(f"<b>{cond}</b>: {feat}"))
# Treatment
story.append(spacer(0.3))
story.append(section_header("9. TREATMENT"))
story.append(spacer(0.2))
story.append(body("Treatment requires a <b>multimodal approach</b>: antibiotics + drainage + treatment of the underlying cause."))
story.append(spacer(0.15))
story.append(sub_header("Step 1 — Resuscitation & Supportive Care"))
story.append(bullet("IV fluids, correction of electrolytes"))
story.append(bullet("Send blood cultures × 2 <b>before</b> starting antibiotics"))
story.append(spacer(0.15))
story.append(sub_header("Step 2 — Empiric IV Antibiotics (Start Immediately)"))
abx_headers = ["Regimen", "Coverage", "Notes"]
abx_rows = [
["Ampicillin + Aminoglycoside + Metronidazole", "Gram-positive, gram-negative, anaerobes", "Classic triple therapy; avoid aminoglycoside in renal impairment"],
["3rd-gen Cephalosporin (e.g., Ceftriaxone) + Metronidazole", "Enteric gram-negatives + anaerobes", "Preferred regimen in most centres"],
["Piperacillin-Tazobactam", "Broad-spectrum (gram-positive + negative + anaerobes)", "Good single-agent option"],
]
story.append(make_table(abx_headers, abx_rows, [5*cm, 5*cm, 7*cm]))
story.append(spacer(0.1))
story.append(bullet("Narrow to targeted therapy once culture & sensitivity available"))
story.append(bullet("<b>Duration</b>: 14 days IV → oral for a total of <b>4–6 weeks</b>"))
story.append(bullet("Antibiotics alone (no drainage) → mortality <b>59–100%</b> — not acceptable"))
story.append(spacer(0.2))
story.append(sub_header("Step 3 — Drainage"))
drain_headers = ["Method", "Success Rate", "Details"]
drain_rows = [
["Percutaneous Catheter Drainage (PCD)\n— TREATMENT OF CHOICE",
"66–90%",
"US/CT-guided; catheter left in situ until output minimal (~7 days). Aspirate → Gram stain + aerobic/anaerobic culture. Relatively contraindicated: ascites, coagulopathy, proximity to vital structures"],
["Percutaneous Needle Aspiration\n(without indwelling catheter)",
"60–90%\n(often needs >1 session)",
"Majority require multiple aspirations (25% need ≥3). RCT: catheter 100% vs aspiration 60% success. Single aspiration trial is reasonable for small abscesses"],
["Surgical Drainage\n(Open or Laparoscopic)",
"High (reserved for failures)",
"Indicated: failed PCD; need to treat surgical primary cause (appendicitis, diverticulitis); ruptured abscess; multiple abscesses not amenable to PCD; large abscess >5 cm where PCD fails"],
["ERCP / Biliary Drainage",
"—",
"Indicated when underlying biliary obstruction (stones, stricture, malignancy) is identified — addresses the primary source"],
]
story.append(make_table(drain_headers, drain_rows, [4.5*cm, 3cm, 9.5*cm]))
story.append(spacer(0.2))
story.append(sub_header("Step 4 — Treat the Underlying Cause"))
story.append(bullet("Biliary disease (ERCP, cholecystectomy, biliary stenting)"))
story.append(bullet("GI malignancy — colonoscopy/endoscopy if K. pneumoniae or cryptogenic PLA"))
story.append(bullet("Diverticulitis, appendicitis — surgical management as appropriate"))
# Complications
story.append(spacer(0.3))
story.append(section_header("10. COMPLICATIONS"))
story.append(spacer(0.2))
comp_left = [
"Rupture — peritoneal cavity (peritonitis)",
"Rupture — pleural cavity (empyema thoracis)",
"Rupture — pericardium (purulent pericarditis)",
"Septicaemia / septic shock",
]
comp_right = [
"Portal vein thrombosis → portal hypertension",
"Subphrenic abscess",
"Biliary fistula",
"Metastatic septic emboli (K. pneumoniae: endophthalmitis, meningitis)",
]
comp_data = []
for i in range(max(len(comp_left), len(comp_right))):
l = bullet(comp_left[i]) if i < len(comp_left) else Paragraph("", body_style)
r = bullet(comp_right[i]) if i < len(comp_right) else Paragraph("", body_style)
comp_data.append([l, r])
comp_t = Table(comp_data, colWidths=[8.5*cm, 8.5*cm])
comp_t.setStyle(TableStyle([("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 2)]))
story.append(comp_t)
# Prognosis
story.append(spacer(0.3))
story.append(section_header("11. PROGNOSIS"))
story.append(spacer(0.2))
prog = [
"Ochsner & DeBakey era (pre-antibiotic): mortality <b>70–80%</b>",
"Modern mortality: <b>5–30%</b> with aggressive antibiotic therapy and drainage",
]
for p in prog:
story.append(bullet(p))
story.append(spacer(0.15))
story.append(sub_header("Poor Prognostic Factors"))
poor = ["Jaundice", "Hypoalbuminaemia", "Multiple abscesses", "Underlying malignancy", "Gas in abscess cavity (plain X-ray finding)", "Delay in diagnosis / treatment", "Rupture"]
poor_data = [[bullet(poor[i]) if i < len(poor) else Paragraph("", body_style),
bullet(poor[i+1]) if i+1 < len(poor) else Paragraph("", body_style)]
for i in range(0, len(poor), 2)]
poor_t = Table(poor_data, colWidths=[8.5*cm, 8.5*cm])
poor_t.setStyle(TableStyle([("VALIGN", (0,0), (-1,-1), "TOP"), ("TOPPADDING", (0,0), (-1,-1), 2)]))
story.append(poor_t)
# Key Points
story.append(spacer(0.3))
story.append(section_header("12. KEY POINTS (SRB-STYLE SUMMARY)"))
story.append(spacer(0.2))
key_points = [
"Most common <b>visceral abscess</b>; right lobe predominance (75%)",
"<b>Biliary disease</b> = most common identifiable cause; <b>cryptogenic</b> predominates overall (~40%)",
"Most common organisms: <b>E. coli</b> and <b>K. pneumoniae</b>; mostly <b>polymicrobial</b>",
"Classic presentation: <b>Fever + RUQ pain + tender hepatomegaly</b> (+ jaundice if biliary origin)",
"Presentation is usually <b>subacute/insidious</b>; multiple abscesses → more acute with sepsis",
"<b>Contrast-enhanced CT</b> = investigation of choice (sensitivity 95–100%)",
"<b>Blood cultures × 2</b> before antibiotics (positive in ~50%)",
"<b>Percutaneous catheter drainage + IV antibiotics</b> = standard of care",
"Surgery reserved for <b>failed PCD</b>, ruptured abscess, or concurrent surgical pathology",
"<b>Klebsiella PLA</b> → screen for colorectal malignancy (fourfold risk); risk of metastatic septic foci",
"Differentiate from <b>amebic abscess</b>: young male, single, right lobe, anchovy sauce pus, positive serology, responds to metronidazole alone without drainage",
"Antibiotic duration: <b>2 weeks IV → 4–6 weeks total</b>",
]
for i, kp in enumerate(key_points, 1):
story.append(key_point(i, kp))
story.append(spacer(0.05))
# Sources
story.append(spacer(0.4))
story.append(hr())
story.append(Paragraph(
"Sources: Sabiston Textbook of Surgery (The Biological Basis of Modern Surgical Practice) · "
"Mulholland & Greenfield's Surgery: Scientific Principles and Practice, 7th ed. · "
"Sleisenger & Fordtran's Gastrointestinal and Liver Disease",
source_style
))
# ── BUILD PDF ──────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated: {OUTPUT}")
cd /home/daytona/workspace/pyogenic-liver-abscess && python generate_pdf.py