Can you make notes on pyogenic liver abscess from standard surgery textbook in pdf form
mkdir -p /home/daytona/workspace/pyogenic-liver-abscess && ls /home/daytona/workspace/pyogenic-liver-abscess/
~/pyogenic-liver-abscess/generate_notes.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfbase import pdfmetrics
# ── Document setup ───────────────────────────────────────────────────────────
OUTPUT = "/home/daytona/workspace/pyogenic-liver-abscess/Pyogenic_Liver_Abscess_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm,
title="Pyogenic Liver Abscess – Surgical Notes",
author="Orris Medical Library"
)
# ── Colour palette ────────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MID_BLUE = colors.HexColor("#2b6cb0")
LIGHT_BLUE = colors.HexColor("#ebf4ff")
ACCENT = colors.HexColor("#e53e3e")
GREEN = colors.HexColor("#276749")
LIGHT_GRN = colors.HexColor("#f0fff4")
AMBER = colors.HexColor("#744210")
LIGHT_AMB = colors.HexColor("#fffbeb")
GREY_BG = colors.HexColor("#f7fafc")
BORDER = colors.HexColor("#bee3f8")
# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
H_TITLE = ParagraphStyle("H_TITLE", parent=base["Title"],
fontSize=22, textColor=colors.white, alignment=TA_CENTER,
spaceAfter=4, fontName="Helvetica-Bold", leading=28)
H_SUB = ParagraphStyle("H_SUB", parent=base["Normal"],
fontSize=11, textColor=colors.HexColor("#bee3f8"), alignment=TA_CENTER,
spaceAfter=2, fontName="Helvetica", leading=15)
H1 = ParagraphStyle("H1", parent=base["Heading1"],
fontSize=13, textColor=colors.white, fontName="Helvetica-Bold",
spaceBefore=12, spaceAfter=4, leading=17,
backColor=DARK_BLUE, borderPad=5,
leftIndent=-6, rightIndent=-6)
H2 = ParagraphStyle("H2", parent=base["Heading2"],
fontSize=11, textColor=DARK_BLUE, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3, leading=14,
borderPad=2)
BODY = ParagraphStyle("BODY", parent=base["Normal"],
fontSize=9.5, textColor=colors.HexColor("#2d3748"),
leading=14, spaceAfter=5, alignment=TA_JUSTIFY,
fontName="Helvetica")
BULLET = ParagraphStyle("BULLET", parent=BODY,
leftIndent=14, bulletIndent=4, spaceAfter=3,
bulletText="•")
SUB_BULLET = ParagraphStyle("SUB_BULLET", parent=BODY,
leftIndent=28, bulletIndent=18, spaceAfter=2,
bulletText="–")
CAPTION = ParagraphStyle("CAPTION", parent=base["Normal"],
fontSize=8, textColor=colors.HexColor("#718096"),
fontName="Helvetica-Oblique", alignment=TA_CENTER,
spaceAfter=6, leading=11)
KEY_BOX = ParagraphStyle("KEY_BOX", parent=BODY,
backColor=LIGHT_BLUE, borderPad=6,
leftIndent=8, rightIndent=8)
WARN_BOX = ParagraphStyle("WARN_BOX", parent=BODY,
backColor=colors.HexColor("#fff5f5"), borderPad=6,
leftIndent=8, rightIndent=8, textColor=ACCENT)
SOURCE = ParagraphStyle("SOURCE", parent=base["Normal"],
fontSize=7.5, textColor=colors.HexColor("#718096"),
fontName="Helvetica-Oblique", spaceAfter=2)
# ── Helper: header banner ─────────────────────────────────────────────────────
def banner(title, subtitle=""):
tbl_data = [[Paragraph(title, H_TITLE)]]
if subtitle:
tbl_data.append([Paragraph(subtitle, H_SUB)])
t = Table(tbl_data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("ROUNDEDCORNERS", [8]),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
]))
return t
def h1(text):
tbl = Table([[Paragraph(f" {text}", H1)]], colWidths=[17*cm])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4]),
]))
return tbl
def h2(text):
return Paragraph(f"<font color='#{MID_BLUE.hexval()[2:]}'>▐</font> {text}", H2)
def body(text):
return Paragraph(text, BODY)
def bullet(text, sub=False):
style = SUB_BULLET if sub else BULLET
return Paragraph(text, style)
def spacer(h=0.3):
return Spacer(1, h*cm)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=BORDER, spaceAfter=4)
def info_box(items, bg=LIGHT_BLUE, border=BORDER):
"""Shaded box with bullet items."""
rows = [[Paragraph(f"• {i}", BODY)] for i in items]
t = Table(rows, colWidths=[16.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,0), 8),
("BOTTOMPADDING", (0,-1), (-1,-1), 8),
("TOPPADDING", (0,1), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-2), 3),
("LINEBELOW", (0,-1), (-1,-1), 0.5, border),
("LINEBEFORE", (0,0), (0,-1), 2, MID_BLUE),
]))
return t
def two_col_table(left_header, right_header, rows_data, lbg=LIGHT_BLUE, rbg=LIGHT_GRN):
header = [
Paragraph(f"<b>{left_header}</b>", ParagraphStyle("th", parent=BODY,
textColor=colors.white, fontName="Helvetica-Bold")),
Paragraph(f"<b>{right_header}</b>", ParagraphStyle("th", parent=BODY,
textColor=colors.white, fontName="Helvetica-Bold")),
]
data = [header]
for l, r in rows_data:
data.append([Paragraph(l, BODY), Paragraph(r, BODY)])
col_w = [8.2*cm, 8.2*cm]
t = Table(data, colWidths=col_w, repeatRows=1)
n = len(data)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.4, BORDER),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
("ROWBACKGROUNDS", (0,1), (-1,-1), [GREY_BG, colors.white]),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ─── TITLE PAGE ──────────────────────────────────────────────────────────────
story.append(spacer(1))
story.append(banner("PYOGENIC LIVER ABSCESS",
"Comprehensive Surgical Notes | Based on Standard Surgery Textbooks"))
story.append(spacer(0.4))
story.append(Paragraph(
"<i>Sources: Sabiston Textbook of Surgery (21e) • Current Surgical Therapy (14e) "
"• Mulholland & Greenfield's Surgery (7e)</i>",
CAPTION))
story.append(hr())
story.append(spacer(0.2))
# ─── 1. DEFINITION & OVERVIEW ────────────────────────────────────────────────
story.append(h1("1. DEFINITION & OVERVIEW"))
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 hepatic parenchyma. It may be "
"<b>solitary or multiple</b> and caused by one or more aerobic and/or anaerobic organisms. "
"PLAs represent the most common type of visceral abscess, accounting for ~13% of "
"intra-abdominal abscesses, with an annual incidence of <b>2.3 per 100,000 persons</b> "
"and a slight male preponderance (M:F ≈ 1.5:1)."
))
story.append(body(
"In the pre-antibiotic era (Ochsner & DeBakey, 1938) PLAs were predominantly seen "
"in young adults secondary to appendicitis. Today, they predominantly affect patients "
"in their <b>50s–60s</b>, with biliary tract disease and cryptogenic causes dominating."
))
story.append(spacer(0.3))
# ─── 2. AETIOLOGY & PATHOGENESIS ─────────────────────────────────────────────
story.append(h1("2. AETIOLOGY & PATHOGENESIS"))
story.append(spacer(0.2))
story.append(h2("Routes of Infection"))
story.append(body(
"The liver is regularly exposed to portal venous bacterial loads. An abscess forms "
"when the inoculum <b>overwhelms hepatic clearance</b>, leading to tissue invasion, "
"neutrophil infiltration, and abscess organisation."
))
routes = [
("Biliary tree (ascending)", "Most common identifiable cause. Biliary obstruction → stasis → ascending suppurative cholangitis. Causes: cholelithiasis, malignant obstruction (especially in the West), Caroli disease, biliary instrumentation, liver transplant with biliary complications."),
("Portal vein (pyaemia)", "Intra-abdominal infection (appendicitis, diverticulitis, Crohn's) seeds the portal system → portal pyaemia. Was the dominant route historically."),
("Hepatic artery (haematogenous)", "Systemic bacteraemia (e.g., infective endocarditis, remote skin infection) seeds liver via the hepatic artery."),
("Direct extension", "Contiguous spread from cholecystitis, subphrenic abscess, or perforated duodenal ulcer."),
("Trauma", "Blunt or penetrating hepatic injury with secondary infection; post-surgical."),
("Cryptogenic", "No identifiable source in ~40–43% of modern series. Often monomicrobial Klebsiella pneumoniae. Associated with colorectal cancer (up to 4× higher incidence)."),
]
story.append(two_col_table("Route", "Details / Organisms", routes))
story.append(spacer(0.3))
story.append(h2("Historical Shift in Aetiology (Sabiston)"))
tbl_hist = [
("1927–38", "622", "42%", "—", "17%", "20%"),
("1945–82", "521", "17%", "9%", "38%", "16%"),
("1970–99", "1264", "5%", "3%", "38%", "43%"),
]
hist_header = [Paragraph(f"<b>{h}</b>", ParagraphStyle("thh", parent=BODY,
textColor=colors.white, fontName="Helvetica-Bold"))
for h in ["Era", "N", "Portal Vein", "Hepatic A.", "Biliary", "Cryptogenic"]]
hist_data = [hist_header] + [[Paragraph(c, BODY) for c in r] for r in tbl_hist]
ht = Table(hist_data, colWidths=[3*cm, 1.8*cm, 2.5*cm, 2.5*cm, 2.5*cm, 2.5*cm])
ht.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.4, BORDER),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("ROWBACKGROUNDS", (0,1), (-1,-1), [GREY_BG, colors.white]),
("ALIGN", (1,0), (-1,-1), "CENTER"),
]))
story.append(ht)
story.append(spacer(0.3))
# ─── 3. RISK FACTORS ─────────────────────────────────────────────────────────
story.append(h1("3. RISK FACTORS"))
story.append(spacer(0.2))
story.append(info_box([
"Diabetes mellitus (most consistent independent risk factor)",
"Advanced age (50s–60s most affected)",
"Biliary malignancy or instrumentation (ERCP, biliary stents)",
"Pre-existing hepatobiliary or pancreatic disease",
"Cirrhosis and chronic liver disease",
"Immunosuppression (including post-transplant immunosuppression)",
"Liver transplantation",
"Chronic renal failure",
"Proton pump inhibitor use (independent risk factor; loss of gastric acid → bacterial overgrowth → biliary colonisation)",
"Underlying colorectal malignancy — especially with Klebsiella pneumoniae cryptogenic PLA",
]))
story.append(Paragraph(
"<b>⚑ Clinical Pearl:</b> Cryptogenic PLAs with Klebsiella pneumoniae warrant "
"colonoscopy to exclude occult colorectal cancer.",
ParagraphStyle("pearl", parent=BODY, backColor=LIGHT_AMB, borderPad=6,
textColor=AMBER, leftIndent=8, rightIndent=8)))
story.append(spacer(0.3))
# ─── 4. MICROBIOLOGY ─────────────────────────────────────────────────────────
story.append(h1("4. MICROBIOLOGY"))
story.append(spacer(0.2))
story.append(body(
"Most PLAs are <b>polymicrobial</b>, reflecting mixed enteric and anaerobic flora. "
"The microbiology mirrors the underlying aetiology:"
))
micro_data = [
("Biliary origin", "<i>E. coli, Klebsiella</i> spp., <i>Enterococcus</i> spp."),
("Enteric/portal origin", "<i>Bacteroides fragilis</i> and other anaerobes; mixed flora"),
("Cryptogenic (monomicrobial)", "<i>Klebsiella pneumoniae</i> — especially in Asia and increasingly in the West; associated with endophthalmitis, meningitis (invasive Klebsiella syndrome)"),
("Haematogenous", "<i>Staphylococcus aureus</i>, Streptococci spp."),
("Immunocompromised host", "Add <i>Candida</i> spp. (fungal co-infection)"),
("North American series", "Streptococci spp. are the most common isolated pathogens in several US population-based studies"),
]
story.append(two_col_table("Source / Context", "Predominant Organisms", micro_data))
story.append(spacer(0.3))
# ─── 5. CLINICAL FEATURES ─────────────────────────────────────────────────────
story.append(h1("5. CLINICAL FEATURES"))
story.append(spacer(0.2))
story.append(h2("Symptoms"))
story.append(info_box([
"Fever / rigors — most frequent symptom (up to 90% of cases)",
"Right upper quadrant (RUQ) pain — 50–75%; may radiate to right shoulder",
"Malaise, anorexia, weight loss",
"Nausea, chills",
"Jaundice — present in 50% (especially biliary aetiology)",
]))
story.append(spacer(0.2))
story.append(h2("Signs"))
story.append(info_box([
"Hepatomegaly / RUQ tenderness ± guarding",
"High-spiking fever (classic 'picket-fence' pattern in untreated cases)",
"Signs of sepsis in severe presentations",
"Pleural effusion (right-sided) — present in ~50% on CXR",
"Elevated right hemidiaphragm on CXR",
]))
story.append(spacer(0.2))
story.append(h2("Laboratory Findings"))
labs = [
("WBC", "Leukocytosis — ~90% of cases"),
("Alkaline phosphatase", "Elevated — ~80% (most sensitive liver enzyme marker)"),
("Bilirubin", "Hyperbilirubinaemia — ~50%"),
("Transaminases (AST/ALT)", "Elevated — ~50%"),
("Albumin", "Hypoalbuminaemia (chronic/severe cases)"),
("FBC", "Normochromic normocytic anaemia"),
("Blood cultures", "Positive in >50% of cases — obtain BEFORE antibiotics"),
("Stool/serology", "Entamoeba histolytica serology if epidemiologic risk factors present"),
]
story.append(two_col_table("Investigation", "Finding / Significance", labs))
story.append(spacer(0.3))
# ─── 6. DIAGNOSIS & IMAGING ───────────────────────────────────────────────────
story.append(h1("6. DIAGNOSIS & IMAGING"))
story.append(spacer(0.2))
story.append(body(
"Imaging is critical for diagnosis and guides management. "
"The classic radiological finding is a <b>hypoattenuating lesion</b> with "
"possible loculations and peripheral rim enhancement on contrast CT."
))
imaging_data = [
("Chest X-Ray", "First-line in resource-limited settings; right pleural effusion or elevated right hemidiaphragm in ~50%"),
("Ultrasound (US)", "Sensitivity ~85–90%; identifies >90% of abscesses; guides drainage; preferred initial test in paediatrics and pregnancy; less sensitive for small/deep lesions"),
("CT Abdomen + IV Contrast", "Sensitivity ~95% — gold standard; detects small abscesses, characterises loculation, identifies underlying aetiology (biliary stones, malignancy); shows rim enhancement (specific but uncommon)"),
("MRI", "Alternative to CT; no radiation; best for complex biliary anatomy (MRCP); useful if CT inconclusive"),
("Tagged WBC Scan (⁹⁹mTc)", "Rarely used; helpful for equivocal cases"),
("ERCP / MRCP", "If biliary communication suspected or biliary aetiology needs evaluation"),
("HIDA Scan", "Evaluates biliary tree communication after drain placement if bile drains"),
]
story.append(two_col_table("Modality", "Role & Findings", imaging_data))
story.append(spacer(0.2))
story.append(Paragraph(
"<b>CT Characteristics of PLA:</b> Hypoattenuating (low-density) lesion; "
"may have a hyperdense wall; peripheral rim enhancement (uncommon but specific); "
"possible gas loculi (gas-forming organisms); right lobe affected in majority (75–80%).",
KEY_BOX))
story.append(spacer(0.3))
# ─── 7. DIFFERENTIAL DIAGNOSIS ───────────────────────────────────────────────
story.append(h1("7. DIFFERENTIAL DIAGNOSIS"))
story.append(spacer(0.2))
diff_data = [
("Amebic liver abscess (ALA)", "Travel/endemic area exposure; male >> female; serology positive for E. histolytica; 'anchovy paste' aspirate; single, large, right lobe; responds to metronidazole WITHOUT drainage"),
("Hepatocellular carcinoma", "Background cirrhosis, AFP elevation, arterial phase enhancement with washout"),
("Hepatic cyst (simple/hydatid)", "Thin-walled, no fever unless superinfected; hydatid cyst — echinococcus serology, daughter cysts"),
("Biliary cystadenoma", "Multiloculated; septations; no systemic sepsis"),
("Metastatic disease", "Known primary malignancy; multiple lesions; no fever/leukocytosis unless superinfected"),
("Cholangitis", "Charcot's triad; raised ALP/GGT; no focal hepatic lesion initially"),
]
story.append(two_col_table("Differential", "Distinguishing Features", diff_data))
story.append(spacer(0.3))
# ─── 8. MANAGEMENT ────────────────────────────────────────────────────────────
story.append(h1("8. MANAGEMENT"))
story.append(spacer(0.2))
story.append(body(
"Management is <b>multimodal</b>: simultaneous antibiotic therapy + drainage "
"+ treatment of underlying source. Early diagnosis and prompt intervention are "
"key determinants of outcome."
))
story.append(spacer(0.1))
story.append(h2("A. Antibiotic Therapy"))
story.append(body(
"<b>Blood cultures and abscess cultures must be obtained before antibiotics are started.</b> "
"Empiric therapy is then directed to culture sensitivity results."
))
story.append(info_box([
"Empiric regimen should cover: Streptococci, gram-negative enteric bacilli (E. coli, Klebsiella), and anaerobes",
"First-line options: Piperacillin/tazobactam (monotherapy) OR Ceftriaxone + Metronidazole",
"Extended-spectrum beta-lactamase (ESBL) coverage (e.g., carbapenem) in patients with prior biliary instrumentation, hepatobiliary surgery, or liver transplant",
"De-escalate to directed therapy once culture/sensitivity results available",
"Duration: typically 14 days IV → oral antibiotics for a total of 4–6 weeks (guided by clinical response and follow-up imaging)",
], bg=LIGHT_GRN, border=colors.HexColor("#9ae6b4")))
story.append(spacer(0.2))
story.append(h2("B. Percutaneous Drainage (First-Line)"))
story.append(body(
"Image-guided percutaneous drainage is <b>both diagnostic and therapeutic</b> "
"and is the standard of care for PLAs."
))
perc_data = [
("<b>Abscess >5 cm</b>", "Percutaneous catheter drainage — superior outcomes vs. aspiration alone; recommended as first-line"),
("<b>Abscess <3 cm</b>", "Trial of antibiotics alone reasonable; aspiration if technically feasible to guide therapy"),
("<b>Abscess 3–5 cm</b>", "Aspiration or catheter drainage; catheter preferred for loculated lesions"),
("<b>Very large (>10 cm)</b>", "Percutaneous catheter drainage remains first-line; may require multiple catheters; high rate of ipsilateral pleural effusion"),
("<b>Multiple abscesses</b>", "Attempt percutaneous approach first; higher failure rate but still warrants percutaneous trial before surgery"),
]
story.append(two_col_table("Abscess Size / Type", "Recommendation", perc_data))
story.append(spacer(0.15))
story.append(info_box([
"Catheters remain in situ until output is minimal and clear (typically up to 7 days)",
"Bile in drain → suspect biliary communication → MRCP/ERCP/HIDA scan → may require sphincterotomy or biliary drainage",
"Success rate: 66–90% for percutaneous catheter drainage",
"Relative contraindications: significant ascites, coagulopathy, proximity to vital structures",
], bg=LIGHT_AMB, border=colors.HexColor("#fbd38d")))
story.append(spacer(0.2))
story.append(h2("C. Surgical Drainage"))
story.append(body(
"Surgery is <b>reserved for ~10–20% of patients</b> who fail percutaneous approaches "
"or have specific indications."
))
story.append(info_box([
"Indications: failed percutaneous drainage, ruptured abscess with peritonitis, multiloculated abscess not amenable to percutaneous access, simultaneous intra-abdominal pathology requiring surgery (e.g., perforated diverticulitis, appendicitis)",
"Approach: laparoscopic drainage preferred when feasible; laparotomy for complex/ruptured cases",
"Liver resection: occasionally required for large multiloculated abscesses (especially right lobe) failing all other methods, or when underlying hepatic pathology (e.g., intrahepatic stones) requires resection",
"Note: hepatic resection for abscess alone carries risk of acute septic shock from manipulation of infected liver; not routinely preferred over drainage alone",
]))
story.append(spacer(0.2))
story.append(h2("D. ERCP / Endoscopic Treatment"))
story.append(info_box([
"Indicated when PLA is caused by biliary obstruction (stones, strictures)",
"ERCP + sphincterotomy ± stenting to relieve biliary obstruction",
"Can be combined with percutaneous drainage for comprehensive management",
]))
story.append(spacer(0.3))
# ─── 9. MANAGEMENT ALGORITHM ──────────────────────────────────────────────────
story.append(h1("9. MANAGEMENT ALGORITHM (SUMMARY)"))
story.append(spacer(0.2))
algo = [
["Step", "Action"],
["1. Suspect PLA", "Fever + RUQ pain ± jaundice, leukocytosis, ↑ALP"],
["2. Imaging", "CT abdomen with IV contrast (ultrasound if CT unavailable/paediatric)"],
["3. Labs", "CBC, LFTs, coagulation, blood cultures (×2) BEFORE antibiotics, amoeba serology if risk"],
["4. Empiric ABx", "Pip-Tazo OR Ceftriaxone + Metronidazole (carbapenem if ESBL risk)"],
["5. Drainage", "• >5 cm → Percutaneous catheter drainage\n• <3 cm → Trial ABx ± aspiration\n• Ruptured → Emergency surgery"],
["6. Culture results", "Narrow/de-escalate antibiotics; adjust based on sensitivity"],
["7. Treat source", "ERCP for biliary cause; colonoscopy if cryptogenic/Klebsiella to exclude CRC"],
["8. Follow-up imaging", "Repeat CT/US at 4–6 weeks to confirm resolution"],
["9. Duration ABx", "14 days IV → total 4–6 weeks oral (guided by clinical response)"],
]
at = Table(algo, colWidths=[3.8*cm, 13.2*cm])
at.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("GRID", (0,0), (-1,-1), 0.4, BORDER),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
("ROWBACKGROUNDS", (0,1), (-1,-1), [GREY_BG, colors.white]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("BACKGROUND", (0,5), (-1,5), colors.HexColor("#ebf8ff")),
]))
story.append(at)
story.append(spacer(0.3))
# ─── 10. COMPLICATIONS ────────────────────────────────────────────────────────
story.append(h1("10. COMPLICATIONS"))
story.append(spacer(0.2))
story.append(info_box([
"Septic shock / multi-organ failure (most feared)",
"Rupture of abscess → purulent peritonitis / empyema (risk ↑ with abscess >10 cm)",
"Right pleural effusion / empyema thoracis (>50% with large abscesses)",
"Bacteraemia / septic emboli",
"Biliary fistula (especially with biliary-origin PLA)",
"Subphrenic abscess",
"Portal vein thrombosis (pyophlebitis)",
"Recurrence (~5–10% after drainage, especially if underlying biliary disease unaddressed)",
"Invasive Klebsiella syndrome (endophthalmitis, meningitis, lung abscess) — rare but life-threatening",
], bg=colors.HexColor("#fff5f5"), border=colors.HexColor("#feb2b2")))
story.append(spacer(0.3))
# ─── 11. PROGNOSIS ───────────────────────────────────────────────────────────
story.append(h1("11. PROGNOSIS & OUTCOMES"))
story.append(spacer(0.2))
story.append(body(
"Outcomes have improved dramatically with expedited diagnosis, broad-spectrum antibiotics, "
"and minimally invasive drainage. However, mortality remains significant."
))
story.append(info_box([
"Overall mortality: 4–10% in modern series (down from ~80% in the pre-antibiotic era)",
"Percutaneous drainage + antibiotics: effective in 80–90% of patients",
"Predictors of poor outcome / increased mortality:",
]))
story.append(info_box([
"Diabetes mellitus",
"Underlying malignancy",
"Cirrhosis / chronic liver disease",
"Abscess size >10 cm (independent risk factor — higher bacterial load, extrahepatic manifestations)",
"Delay in diagnosis and treatment",
"Multiple abscesses",
"Polymicrobial infection with resistant organisms",
], bg=colors.HexColor("#fff5f5"), border=colors.HexColor("#feb2b2")))
story.append(spacer(0.3))
# ─── 12. PLA vs ALA ──────────────────────────────────────────────────────────
story.append(h1("12. PLA vs. AMEBIC LIVER ABSCESS (ALA) — KEY DIFFERENCES"))
story.append(spacer(0.2))
compare = [
("Feature", "Pyogenic (PLA)", "Amebic (ALA)"),
("Organism", "Bacteria (mixed/polymicrobial)", "Entamoeba histolytica"),
("Geography", "Worldwide", "Tropical/subtropical; travel history"),
("Gender", "M:F ≈ 1.5:1", "M >> F (10:1)"),
("Age", "50s–60s", "20s–40s"),
("Number", "Often multiple", "Usually solitary (right lobe)"),
("Aspirate", "Pus — varies", "'Anchovy paste' (brown, odourless)"),
("Serology", "Blood cultures +ve", "E. histolytica serology +ve"),
("CT", "Hypodense ± loculations, rim enhancing", "Hypodense, peripherally located, right lobe"),
("Drainage", "Required", "NOT required (metronidazole alone)"),
("Treatment", "ABx + percutaneous/surgical drainage", "Metronidazole 750 mg TID × 7–10 days"),
]
ct = Table(compare, colWidths=[3.8*cm, 6.5*cm, 6.5*cm])
ct.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("GRID", (0,0), (-1,-1), 0.4, BORDER),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS", (1,1), (-1,-1), [GREY_BG, colors.white]),
("FONTSIZE", (0,0), (-1,-1), 9),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(ct)
story.append(spacer(0.3))
# ─── 13. EXAM HIGH-YIELD POINTS ───────────────────────────────────────────────
story.append(h1("13. HIGH-YIELD EXAM POINTS"))
story.append(spacer(0.2))
story.append(info_box([
"Most common type of visceral abscess — annual incidence 2.3/100,000",
"Biliary disease is now the most common identifiable cause (overtook portal/enteric causes post-antibiotics)",
"Cryptogenic PLAs (~40%): often Klebsiella pneumoniae — must exclude colorectal cancer",
"Classic presentation: fever + RUQ pain + leukocytosis + ↑ALP",
"CT with IV contrast — gold standard imaging (sensitivity ~95%)",
"Blood cultures positive in >50%: always take BEFORE starting antibiotics",
"Treatment = antibiotics + percutaneous catheter drainage (for >5 cm)",
"Antibiotics alone (no drainage) = prohibitively high mortality (59–100%)",
"Surgical drainage reserved for failures of percutaneous therapy (~10–20%)",
"Amebic abscess — DO NOT DRAIN; treat with metronidazole",
"Mortality 4–10% in modern era; worse with DM, malignancy, cirrhosis, large abscess",
"Proton pump inhibitors: independent risk factor for PLA",
"Post-drainage: watch for bile in drain → MRCP/ERCP to assess biliary communication",
], bg=LIGHT_BLUE, border=BORDER))
story.append(spacer(0.3))
# ─── REFERENCES ──────────────────────────────────────────────────────────────
story.append(hr())
story.append(Paragraph("<b>Sources</b>", H2))
refs = [
"Sabiston Textbook of Surgery: The Biological Basis of Modern Surgical Practice (21st ed.) — Chapter 89: Pyogenic Abscess",
"Current Surgical Therapy (14th ed.) — Pyogenic Liver Abscess section",
"Mulholland and Greenfield's Surgery: Scientific Principles and Practice (7th ed.) — Chapter 58: Pyogenic Liver Abscess",
]
for r in refs:
story.append(Paragraph(f"• {r}", SOURCE))
story.append(spacer(0.2))
story.append(Paragraph(
"These notes are compiled from standard surgical textbooks for educational purposes.",
CAPTION))
# ─── BUILD PDF ────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to {OUTPUT}")
cd /home/daytona/workspace/pyogenic-liver-abscess && python generate_notes.py 2>&1
ls -lh /home/daytona/workspace/pyogenic-liver-abscess/Pyogenic_Liver_Abscess_Notes.pdf
Pyogenic Liver Abscess Notes
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Definition & Overview | Incidence, demographics, historical shift |
| 2. Aetiology & Pathogenesis | All 6 routes with historical trend table |
| 3. Risk Factors | DM, age, biliary disease, PPI use, CRC link |
| 4. Microbiology | Organism by source; Klebsiella cryptogenic PLA |
| 5. Clinical Features | Symptoms, signs, lab findings with frequencies |
| 6. Diagnosis & Imaging | All modalities, CT characteristics, ERCP/MRCP |
| 7. Differential Diagnosis | PLA vs ALA, HCC, hydatid, cholangitis |
| 8. Management | ABx regimens, percutaneous drainage by size, surgical indications, ERCP |
| 9. Management Algorithm | Step-by-step decision table |
| 10. Complications | Rupture, empyema, portal thrombosis, Klebsiella syndrome |
| 11. Prognosis | Mortality 4–10%; predictors of poor outcome |
| 12. PLA vs ALA Comparison | Full comparison table |
| 13. High-Yield Exam Points | 13 key facts for exams |