Give a pdf on jaundice topic in pathology
mkdir -p /home/daytona/workspace/jaundice-pathology && ls /home/daytona/workspace/jaundice-pathology/
~/jaundice-pathology/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib.colors import HexColor, black, white
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib import colors
OUTPUT = "/home/daytona/workspace/jaundice-pathology/Jaundice_Pathology.pdf"
# ── Color palette ──────────────────────────────────────────────────────────────
DEEP_BLUE = HexColor("#1A3A5C")
MID_BLUE = HexColor("#2D6A9F")
LIGHT_BLUE = HexColor("#D6E8F7")
ACCENT_GOLD = HexColor("#E8A020")
TABLE_HEAD = HexColor("#1A3A5C")
TABLE_ALT = HexColor("#EBF4FC")
SECTION_BG = HexColor("#F0F7FF")
RED_ACCENT = HexColor("#C0392B")
GREEN_ACCENT= HexColor("#1E8449")
# ── Page numbering canvas ──────────────────────────────────────────────────────
def on_page(canvas_obj, doc):
canvas_obj.saveState()
# Header bar
canvas_obj.setFillColor(DEEP_BLUE)
canvas_obj.rect(0, A4[1] - 1.2*cm, A4[0], 1.2*cm, fill=1, stroke=0)
canvas_obj.setFillColor(white)
canvas_obj.setFont("Helvetica-Bold", 9)
canvas_obj.drawString(1.5*cm, A4[1] - 0.82*cm, "JAUNDICE — PATHOLOGY")
canvas_obj.setFont("Helvetica", 8)
canvas_obj.drawRightString(A4[0] - 1.5*cm, A4[1] - 0.82*cm,
"Robbins & Kumar | Harrison's | Pathophysiology")
# Footer bar
canvas_obj.setFillColor(DEEP_BLUE)
canvas_obj.rect(0, 0, A4[0], 1.0*cm, fill=1, stroke=0)
canvas_obj.setFillColor(white)
canvas_obj.setFont("Helvetica", 8)
canvas_obj.drawCentredString(A4[0]/2, 0.35*cm,
f"Page {doc.page}")
canvas_obj.restoreState()
# ── Styles ─────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
title_style = ParagraphStyle("TitleStyle",
fontName="Helvetica-Bold", fontSize=28, textColor=white,
alignment=TA_CENTER, spaceAfter=0, spaceBefore=0)
subtitle_style = ParagraphStyle("SubtitleStyle",
fontName="Helvetica", fontSize=13, textColor=HexColor("#D6E8F7"),
alignment=TA_CENTER, spaceAfter=0, spaceBefore=4)
h1 = ParagraphStyle("H1", fontName="Helvetica-Bold", fontSize=15,
textColor=white, backColor=DEEP_BLUE, spaceBefore=14, spaceAfter=6,
leftIndent=-12, rightIndent=-12, borderPadding=(6, 12, 6, 12),
leading=20)
h2 = ParagraphStyle("H2", fontName="Helvetica-Bold", fontSize=12,
textColor=DEEP_BLUE, spaceBefore=10, spaceAfter=4,
borderPadding=(0,0,2,0), leading=16)
h3 = ParagraphStyle("H3", fontName="Helvetica-BoldOblique", fontSize=11,
textColor=MID_BLUE, spaceBefore=8, spaceAfter=3, leading=14)
body = ParagraphStyle("Body", fontName="Helvetica", fontSize=10,
leading=15, spaceAfter=5, alignment=TA_JUSTIFY, textColor=HexColor("#1C1C1C"))
bullet = ParagraphStyle("Bullet", fontName="Helvetica", fontSize=10,
leading=14, spaceAfter=3, leftIndent=18, bulletIndent=6,
alignment=TA_LEFT, textColor=HexColor("#1C1C1C"))
highlight_box = ParagraphStyle("HighlightBox", fontName="Helvetica", fontSize=10,
leading=14, spaceAfter=4, leftIndent=10, rightIndent=10,
backColor=SECTION_BG, borderPadding=(8,8,8,8),
alignment=TA_JUSTIFY, textColor=HexColor("#1C1C1C"))
key_point = ParagraphStyle("KeyPoint", fontName="Helvetica-Bold", fontSize=10,
leading=14, spaceAfter=4, leftIndent=10, rightIndent=10,
backColor=HexColor("#FFF3E0"), borderPadding=(8,8,8,8),
textColor=HexColor("#7D3C00"))
caption = ParagraphStyle("Caption", fontName="Helvetica-Oblique", fontSize=8.5,
textColor=HexColor("#555555"), alignment=TA_CENTER, spaceAfter=6)
# ── Helper: section header flowable ───────────────────────────────────────────
def sec(text):
return [Spacer(1, 0.3*cm),
Paragraph(f" {text}", h1),
Spacer(1, 0.15*cm)]
def subsec(text):
return [Spacer(1, 0.15*cm),
Paragraph(text, h2),
HRFlowable(width="100%", thickness=1, color=MID_BLUE, spaceAfter=4)]
def subsubsec(text):
return [Paragraph(text, h3)]
def para(text):
return Paragraph(text, body)
def bul(text):
return Paragraph(f"• {text}", bullet)
def highlight(text):
return Paragraph(text, highlight_box)
def keypoint(text):
return Paragraph(f"KEY POINT: {text}", key_point)
def spacer(h=0.2):
return Spacer(1, h*cm)
# ══════════════════════════════════════════════════════════════════════════════
# BUILD DOCUMENT
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER PAGE ─────────────────────────────────────────────────────────────────
cover_data = [[Paragraph("JAUNDICE", title_style)],
[Paragraph("Pathophysiology, Classification, Diagnosis & Management", subtitle_style)],
[Spacer(1, 0.3*cm)],
[Paragraph("Based on Robbins & Kumar Basic Pathology | Harrison's Principles of Internal Medicine 22E",
ParagraphStyle("src", fontName="Helvetica", fontSize=9,
textColor=HexColor("#AED6F1"), alignment=TA_CENTER))]]
cover_table = Table(cover_data, colWidths=[17*cm])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DEEP_BLUE),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (-1,-1), 20),
("RIGHTPADDING", (0,0), (-1,-1), 20),
("ROUNDEDCORNERS", [8]),
]))
story.append(Spacer(1, 3*cm))
story.append(cover_table)
story.append(Spacer(1, 1.0*cm))
# Gold accent band
accent_table = Table([[""]], colWidths=[17*cm], rowHeights=[0.5*cm])
accent_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), ACCENT_GOLD),
("ROUNDEDCORNERS", [4]),
]))
story.append(accent_table)
story.append(Spacer(1, 0.5*cm))
# Quick stat boxes
stat_data = [
[Paragraph("<b>Normal Bilirubin</b><br/>0.3 – 1.2 mg/dL", ParagraphStyle("s", fontName="Helvetica", fontSize=10, alignment=TA_CENTER, textColor=DEEP_BLUE)),
Paragraph("<b>Jaundice Visible at</b><br/>> 2 – 2.5 mg/dL", ParagraphStyle("s", fontName="Helvetica", fontSize=10, alignment=TA_CENTER, textColor=DEEP_BLUE)),
Paragraph("<b>Severe Disease</b><br/>Up to 30 – 40 mg/dL", ParagraphStyle("s", fontName="Helvetica", fontSize=10, alignment=TA_CENTER, textColor=DEEP_BLUE)),
Paragraph("<b>Neonatal Jaundice</b><br/>Matures ~2 weeks", ParagraphStyle("s", fontName="Helvetica", fontSize=10, alignment=TA_CENTER, textColor=DEEP_BLUE))]
]
stat_table = Table(stat_data, colWidths=[4.1*cm]*4)
stat_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("BOX", (0,0), (-1,-1), 1, MID_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.5, MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4]),
]))
story.append(stat_table)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 1 – DEFINITION & OVERVIEW
# ══════════════════════════════════════════════════════════════════════════════
story += sec("1. DEFINITION AND OVERVIEW")
story.append(para(
"Jaundice (icterus) is the yellow discoloration of skin, sclerae, and mucous membranes "
"caused by accumulation of bilirubin in tissues. It becomes clinically apparent when "
"serum bilirubin exceeds <b>2–2.5 mg/dL</b>. Levels as high as <b>30–40 mg/dL</b> can occur in "
"severe hepatobiliary disease. Jaundice is not a disease itself but a sign of an underlying "
"disorder affecting bilirubin production, transport, conjugation, or excretion."
))
story.append(keypoint(
"Jaundice is visible when serum bilirubin > 2–2.5 mg/dL. Sclerae are the most sensitive "
"site because of the high elastin content that binds bilirubin avidly."
))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2 – BILIRUBIN METABOLISM
# ══════════════════════════════════════════════════════════════════════════════
story += sec("2. BILIRUBIN METABOLISM")
story.append(para(
"Understanding bilirubin metabolism is fundamental to classifying jaundice pathologically."
))
story += subsec("2.1 Production")
story.append(para(
"Bilirubin is the end product of heme catabolism. Approximately <b>80–85%</b> is derived from "
"hemoglobin released during destruction of senescent red blood cells in the reticuloendothelial "
"system (spleen, liver, bone marrow). The remaining 15–20% comes from myoglobin, cytochromes, "
"and ineffective erythropoiesis."
))
story.append(para(
"The enzyme <b>heme oxygenase</b> oxidatively cleaves the alpha-methene bridge of the porphyrin "
"ring, producing <b>biliverdin</b>, carbon monoxide, and free iron. Biliverdin reductase then "
"reduces biliverdin to <b>bilirubin</b> (unconjugated / indirect bilirubin)."
))
story += subsec("2.2 Transport in Blood")
story.append(para(
"Unconjugated bilirubin is <b>virtually insoluble in water</b> due to tight internal hydrogen "
"bonding between its propionic acid carboxyl groups and the imino/lactam groups of the opposite "
"dipyrrolic half. To circulate in blood it binds <b>non-covalently to albumin</b>. Because it is "
"albumin-bound and insoluble, unconjugated bilirubin:"
))
story.append(bul("Cannot be filtered by the renal glomerulus"))
story.append(bul("Does NOT appear in urine (acholuria)"))
story.append(bul("Is not excreted in bile in its unconjugated form"))
story.append(spacer(0.15))
story += subsec("2.3 Hepatic Uptake and Conjugation")
story.append(para(
"At the hepatocyte sinusoidal membrane, unconjugated bilirubin dissociates from albumin "
"and is taken up via <b>carrier-mediated transport</b> (specific transporter not fully "
"characterized). Inside the hepatocyte, it binds cytosolic proteins (glutathione-S-transferases / "
"ligandin), which reduce back-diffusion into blood."
))
story.append(para(
"In the smooth endoplasmic reticulum, <b>bilirubin UDP-glucuronosyltransferase (UDPGT)</b> "
"conjugates bilirubin to glucuronic acid, yielding bilirubin <b>monoglucuronide</b> and "
"<b>diglucuronide</b> (conjugated / direct bilirubin). Conjugation disrupts the internal "
"hydrogen bonds, making bilirubin water-soluble and non-toxic."
))
story += subsec("2.4 Biliary Excretion")
story.append(para(
"Conjugated bilirubin is actively transported across the canalicular membrane into bile by "
"<b>MRP2 (multidrug resistance-associated protein 2)</b>. A small fraction is transported "
"into sinusoids by MRP3 and recaptured by OATP1B1/1B3 transporters (enterohepatic recycling "
"of conjugated bilirubin)."
))
story += subsec("2.5 Intestinal Processing and Urobilinogen")
story.append(para(
"Conjugated bilirubin is <b>not reabsorbed in the proximal bowel</b> due to its hydrophilicity. "
"In the distal ileum and colon, bacterial beta-glucuronidases hydrolyze it back to unconjugated "
"bilirubin, which is then reduced to a group of colorless compounds called <b>urobilinogens</b>. "
"About 80–90% of these are excreted in feces (oxidized to orange <b>urobilins</b>, which give "
"stool its color). The remaining 10–20% undergoes enterohepatic cycling:"
))
story.append(bul("Re-absorbed from colon, circulated to liver, re-excreted in bile"))
story.append(bul("A small fraction (<3 mg/dL) escapes hepatic re-uptake and is excreted in urine"))
story.append(spacer(0.2))
# Metabolism summary table
story.append(Spacer(1, 0.15*cm))
met_data = [
["Step", "Process", "Key Enzyme/Protein", "Location"],
["1", "Heme → Biliverdin", "Heme oxygenase", "RES (spleen/liver/marrow)"],
["2", "Biliverdin → Unconjugated Bilirubin", "Biliverdin reductase", "RES"],
["3", "Blood transport", "Albumin (non-covalent)", "Plasma"],
["4", "Hepatocyte uptake", "Carrier-mediated transport", "Hepatocyte sinusoidal membrane"],
["5", "Cytosolic binding", "Ligandin / GST", "Hepatocyte cytoplasm"],
["6", "Conjugation → Bilirubin glucuronide", "UDPGT", "Smooth ER"],
["7", "Biliary excretion", "MRP2", "Canalicular membrane"],
["8", "Gut reduction → Urobilinogen", "Bacterial beta-glucuronidase", "Colon"],
]
met_table = Table(met_data, colWidths=[1.0*cm, 5.0*cm, 5.5*cm, 5.5*cm])
met_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, MID_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(met_table)
story.append(Paragraph("Table 1: Steps in normal bilirubin metabolism", caption))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3 – CLASSIFICATION
# ══════════════════════════════════════════════════════════════════════════════
story += sec("3. CLASSIFICATION OF JAUNDICE")
story.append(para(
"Jaundice is classified anatomically into three types based on the site of the defect in "
"bilirubin metabolism. This classification guides diagnosis and management."
))
# Classification overview table
story.append(Spacer(1, 0.2*cm))
class_data = [
["Feature", "Pre-hepatic\n(Hemolytic)", "Hepatic\n(Hepatocellular)", "Post-hepatic\n(Obstructive/Cholestatic)"],
["Primary defect", "Excessive bilirubin production", "Defective uptake, conjugation, or excretion", "Bile duct obstruction"],
["Bilirubin type", "Unconjugated ↑↑", "Both types (↑ conjugated predominates in severe disease)", "Conjugated ↑↑"],
["Urine bilirubin", "Absent (acholuria)", "Present (bilirubinuria)", "Present (dark urine)"],
["Urine urobilinogen", "Increased", "Variable (↑ early; ↓ late in severe disease)", "Absent or very low"],
["Stool color", "Normal or dark", "Pale/light", "Pale/clay-colored"],
["Liver enzymes", "Normal", "AST/ALT markedly ↑", "ALP/GGT markedly ↑"],
["Bilirubin in urine", "No", "Yes (conjugated)", "Yes (conjugated)"],
["Pruritus", "Absent", "Variable", "Prominent (bile salts)"],
["Examples", "Hemolytic anemia, G6PD deficiency, spherocytosis, ineffective erythropoiesis", "Hepatitis, cirrhosis, drug-induced hepatitis, Gilbert, Crigler-Najjar, Dubin-Johnson", "Gallstones, pancreatic head cancer, cholangiocarcinoma, biliary stricture, PSC"],
]
class_table = Table(class_data, colWidths=[3.5*cm, 4.5*cm, 4.5*cm, 4.5*cm])
class_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, DEEP_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(class_table)
story.append(Paragraph("Table 2: Comparison of the three types of jaundice", caption))
story.append(Spacer(1, 0.3*cm))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4 – PRE-HEPATIC JAUNDICE
# ══════════════════════════════════════════════════════════════════════════════
story += sec("4. PRE-HEPATIC JAUNDICE (HEMOLYTIC)")
story.append(para(
"Pre-hepatic jaundice results from excessive production of bilirubin that overwhelms the "
"liver's conjugating capacity, or from impaired hepatic uptake/conjugation."
))
story += subsec("4.1 Pathophysiology")
story.append(para(
"In hemolytic disease, accelerated RBC destruction releases large amounts of heme, which is "
"catabolized to unconjugated bilirubin. Although the liver upregulates UDPGT, the conjugating "
"capacity is exceeded, leading to unconjugated hyperbilirubinemia. The excess unconjugated "
"bilirubin drives more urobilinogen production in the gut, resulting in increased urinary and "
"fecal urobilinogen."
))
story.append(keypoint(
"In pre-hepatic jaundice the bilirubin CANNOT be excreted in urine (it is unconjugated and "
"albumin-bound) — hence 'acholuric jaundice' despite elevated serum bilirubin."
))
story += subsec("4.2 Causes")
causes_pre = [
["Category", "Examples"],
["Inherited hemolytic", "Hereditary spherocytosis, G6PD deficiency, sickle cell disease, thalassemia, pyruvate kinase deficiency"],
["Acquired hemolytic", "Autoimmune hemolytic anemia (warm/cold), microangiopathic HA (TTP, HUS, DIC), malaria, paroxysmal nocturnal hemoglobinuria"],
["Ineffective erythropoiesis", "Iron deficiency, megaloblastic anemia, lead poisoning, thalassemia major"],
["Neonatal", "Physiologic jaundice, hemolytic disease of newborn (Rh/ABO incompatibility), G6PD deficiency"],
["Hereditary disorders of conjugation", "Gilbert syndrome (mild ↓ UDPGT), Crigler-Najjar type I (absent UDPGT — fatal), Crigler-Najjar type II (severely ↓ UDPGT)"],
]
causes_pre_table = Table(causes_pre, colWidths=[5*cm, 12*cm])
causes_pre_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, MID_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(causes_pre_table)
story.append(Paragraph("Table 3: Causes of pre-hepatic jaundice", caption))
story += subsec("4.3 Hereditary Hyperbilirubinemias (Detailed)")
# Gilbert syndrome
story += subsubsec("Gilbert Syndrome")
story.append(para(
"Common autosomal recessive condition affecting <b>4–16%</b> of various populations. Caused by a "
"mutation in the promoter of the <b>UGT1A1</b> gene, leading to mildly decreased glucuronosyltransferase "
"expression and mildly decreased hepatic conjugation. Manifests as fluctuating mild unconjugated "
"hyperbilirubinemia, often precipitated by fasting, stress, or illness. <b>Benign — no morbidity.</b>"
))
story += subsubsec("Crigler-Najjar Syndrome")
story.append(para(
"Caused by other mutations in <b>UGT1A1</b> that result in severe UDPGT deficiency. <b>Type I</b>: "
"complete absence of enzyme — <b>fatal in infancy</b> without liver transplantation (phototherapy "
"temporarily maintains safe bilirubin levels). <b>Type II (Arias syndrome)</b>: severely reduced "
"but not absent UDPGT — less severe, responds to phenobarbital."
))
story += subsubsec("Dubin-Johnson Syndrome")
story.append(para(
"Autosomal recessive disorder caused by defect in the <b>MRP2 canalicular transporter</b>, "
"impairing hepatocellular excretion of conjugated bilirubin. Results in conjugated "
"hyperbilirubinemia. Distinctive gross pathology: <b>dark-pigmented liver</b> (polymerized "
"epinephrine metabolites, not bilirubin). <b>Clinically benign</b>."
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5 – HEPATIC JAUNDICE
# ══════════════════════════════════════════════════════════════════════════════
story += sec("5. HEPATIC (HEPATOCELLULAR) JAUNDICE")
story.append(para(
"Hepatocellular jaundice results from diffuse damage to hepatocytes, impairing their capacity "
"to take up, conjugate, and/or excrete bilirubin. Both conjugated and unconjugated bilirubin "
"may accumulate depending on the nature and severity of the injury."
))
story += subsec("5.1 Pathophysiology")
story.append(para(
"Widespread hepatocyte necrosis or dysfunction disrupts one or more steps in bilirubin "
"metabolism. Damaged hepatocytes may regurgitate conjugated bilirubin back into sinusoidal "
"blood, causing conjugated hyperbilirubinemia and bilirubinuria. Impaired conjugation causes "
"unconjugated accumulation. Canalicular damage and intrahepatic cholestasis may coexist. "
"Both AST/ALT (hepatocyte damage) and ALP/GGT (cholestatic component) may be elevated."
))
story += subsec("5.2 Causes")
hep_causes = [
["Category", "Examples"],
["Viral hepatitis", "Hepatitis A, B, C, D, E; EBV hepatitis; CMV hepatitis"],
["Drug-induced liver injury (DILI)", "Predictable (dose-dependent): acetaminophen, methotrexate\nIdiosyncratic: isoniazid, halothane, statins, many others"],
["Toxic", "Amanita phalloides mushrooms, vinyl chloride, CCl4, kava"],
["Alcoholic liver disease", "Steatohepatitis → fibrosis → cirrhosis"],
["Autoimmune hepatitis", "Anti-smooth muscle Ab, ANA positive; elevated IgG"],
["Metabolic/hereditary", "Wilson's disease (↑ copper), hemochromatosis (↑ iron), alpha-1-antitrypsin deficiency"],
["Cirrhosis (end-stage)", "Any cause; impaired overall hepatocyte function"],
["Ischemic hepatitis", "Shock, cardiac failure, Budd-Chiari syndrome"],
]
hep_table = Table(hep_causes, colWidths=[5*cm, 12*cm])
hep_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, MID_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(hep_table)
story.append(Paragraph("Table 4: Causes of hepatocellular jaundice", caption))
story.append(Spacer(1, 0.2*cm))
story += subsec("5.3 Morphology of Hepatocellular Injury")
story.append(para(
"The morphologic features vary with the causative agent but common patterns include:"
))
story.append(bul("<b>Ballooning degeneration:</b> hepatocyte swelling due to inability to maintain ion pumps; "
"cytoplasm becomes pale and rarefied"))
story.append(bul("<b>Apoptosis (acidophil bodies / Councilman bodies):</b> shrunken, eosinophilic hepatocytes "
"with condensed nuclei, seen especially in viral hepatitis"))
story.append(bul("<b>Steatosis (fatty change):</b> large or small lipid vacuoles; prominent in alcoholic "
"and metabolic liver disease"))
story.append(bul("<b>Mallory-Denk bodies:</b> eosinophilic intracytoplasmic inclusions of aggregated "
"intermediate filaments (cytokeratin 8/18); classic for alcoholic hepatitis but also in NAFLD, "
"Wilson's, primary biliary cirrhosis"))
story.append(bul("<b>Necrosis patterns:</b> spotty lobular necrosis (viral), centrilobular (zone 3) "
"necrosis (ischemia/drug toxicity), bridging necrosis (severe hepatitis), massive necrosis "
"(fulminant hepatic failure)"))
story.append(bul("<b>Lobular disarray:</b> loss of normal hepatic plate architecture due to diffuse "
"hepatocyte dropout and regeneration"))
story.append(Spacer(1, 0.3*cm))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6 – POST-HEPATIC JAUNDICE / CHOLESTASIS
# ══════════════════════════════════════════════════════════════════════════════
story += sec("6. POST-HEPATIC JAUNDICE (CHOLESTASIS / OBSTRUCTIVE)")
story.append(PageBreak())
story.append(para(
"Post-hepatic jaundice is caused by obstruction of bile flow at any level from the intrahepatic "
"bile canaliculi to the ampulla of Vater. The hallmark is <b>conjugated hyperbilirubinemia</b> "
"with elevated alkaline phosphatase (ALP) and gamma-glutamyl transpeptidase (GGT), "
"because these enzymes are located on the apical (canalicular) membrane of hepatocytes and "
"cholangiocytes."
))
story += subsec("6.1 Pathophysiology of Cholestasis")
story.append(highlight(
"Cholestasis is defined as impaired bile flow, resulting in accumulation of bile constituents "
"(bilirubin, bile salts, cholesterol) in blood and tissues. It may be extrahepatic "
"(obstruction of major bile ducts) or intrahepatic (impairment of hepatocyte bile secretion "
"or small duct disease). The distinction is clinically critical because extrahepatic obstruction "
"is often surgically correctable, while intrahepatic cholestasis is not improved by surgery."
))
story.append(para(
"Elevated serum bile salts are responsible for the characteristic <b>pruritus</b> of cholestasis. "
"Malabsorption of fat-soluble vitamins (A, D, E, K) results from reduced bile entering the gut. "
"Vitamin K deficiency leads to a coagulopathy that is reversible with parenteral vitamin K "
"(distinguishing it from the coagulopathy of hepatocellular failure, which is not)."
))
story += subsec("6.2 Morphology of Cholestasis (Robbins Pathology)")
story.append(para(
"The morphologic features of cholestasis depend on severity, duration, and cause. "
"Characteristic findings include:"
))
story.append(bul("<b>Bile pigment accumulation:</b> elongated green-brown plugs of bile in dilated "
"bile canaliculi — the most characteristic finding"))
story.append(bul("<b>Feathery degeneration of hepatocytes:</b> a fine, foamy cytoplasmic appearance "
"as bile accumulates within hepatocytes"))
story.append(bul("<b>Kupffer cell bile pigment:</b> rupture of canaliculi leads to extravasation of "
"bile, which is rapidly phagocytosed by Kupffer cells"))
story.append(bul("<b>Apoptotic hepatocytes:</b> occasional acidophilic bodies may be seen"))
story.append(bul("<b>Ductular reaction:</b> proliferation of reactive bile ductules at the "
"portal-parenchymal interface in chronic or extrahepatic obstruction"))
story.append(bul("<b>Stromal edema and neutrophils:</b> hallmark of superimposed ascending cholangitis"))
story.append(Spacer(1, 0.15*cm))
story.append(para(
"If obstruction is prolonged and uncorrected, periportal fibrosis develops, eventually producing "
"<b>secondary (obstructive) biliary cirrhosis</b>. Periportal hepatocytes show extensive feathery "
"degeneration, often with Mallory hyaline bodies, and bile infarcts form from the detergent "
"effects of extravasated bile."
))
story += subsec("6.3 Causes of Post-Hepatic Jaundice")
post_causes = [
["Level", "Cause"],
["Common bile duct — stones", "Choledocholithiasis (most common cause in adults)"],
["Common bile duct — malignant", "Pancreatic head adenocarcinoma (classic painless jaundice), cholangiocarcinoma, ampullary carcinoma"],
["Common bile duct — benign stricture", "Post-cholecystectomy stricture, post-inflammatory stricture"],
["Biliary tree inflammation", "Primary sclerosing cholangitis (PSC), ascending cholangitis"],
["Pediatric causes", "Biliary atresia (most common surgical cause in neonates), choledochal cyst, Alagille syndrome (paucity of intrahepatic bile ducts), cystic fibrosis"],
["Extrinsic compression", "Lymphoma, metastatic lymph nodes, mirizzi syndrome"],
["Intrahepatic cholestasis", "Drug-induced (chlorpromazine, OCP), intrahepatic cholestasis of pregnancy, PBC, viral hepatitis cholestatic variant"],
]
post_table = Table(post_causes, colWidths=[5*cm, 12*cm])
post_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, MID_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(post_table)
story.append(Paragraph("Table 5: Causes of post-hepatic (obstructive) jaundice", caption))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7 – NEONATAL JAUNDICE
# ══════════════════════════════════════════════════════════════════════════════
story += sec("7. NEONATAL JAUNDICE")
story.append(para(
"Neonatal jaundice deserves special attention because of its frequency and the risk of "
"neurologic damage (kernicterus) from unconjugated bilirubin toxicity in the immature brain."
))
story += subsec("7.1 Physiologic Jaundice of the Newborn")
story.append(para(
"The hepatic machinery for conjugating and excreting bilirubin does not fully mature until "
"approximately <b>2 weeks of age</b>. As a result, nearly every newborn develops transient, "
"mild <b>unconjugated hyperbilirubinemia</b> — termed physiologic (neonatal) jaundice. This is "
"compounded by:"
))
story.append(bul("High rate of fetal RBC destruction (higher hemoglobin turnover at birth)"))
story.append(bul("Immature hepatic UDPGT activity"))
story.append(bul("<b>Breastfeeding jaundice:</b> bilirubin-deconjugating enzymes present in breast milk "
"can exacerbate hyperbilirubinemia (breast milk jaundice)"))
story.append(Spacer(0.1, 0.1*cm))
story.append(para(
"<b>Treatment:</b> Phototherapy with blue light converts bilirubin to a water-soluble isomer "
"that can be excreted in urine without conjugation, maintaining safe levels until hepatic "
"maturation. Sustained jaundice beyond 2 weeks in a neonate is abnormal and requires workup."
))
story += subsec("7.2 Kernicterus")
story.append(highlight(
"When serum unconjugated bilirubin exceeds the albumin-binding capacity, free (unbound) "
"unconjugated bilirubin crosses the immature blood-brain barrier and is deposited in neurons "
"of the basal ganglia, hippocampus, cerebellum, and brainstem nuclei, causing toxic injury. "
"This condition — kernicterus (bilirubin encephalopathy) — can lead to cerebral palsy, "
"sensorineural hearing loss, gaze palsy, and intellectual disability. It is the major "
"complication of hemolytic disease of the newborn (erythroblastosis fetalis) due to "
"Rh or ABO incompatibility."
))
story += subsec("7.3 Neonatal Cholestasis")
story.append(para(
"Prolonged <b>conjugated</b> hyperbilirubinemia in the neonate (neonatal cholestasis) affects "
"~1 in 2500 live births and is always pathological. Major causes:"
))
story.append(bul("<b>Biliary atresia:</b> fibro-inflammatory obliteration of the extrahepatic biliary tree; "
"most common surgical cause; presents in first 2–8 weeks; requires Kasai portoenterostomy"))
story.append(bul("<b>Neonatal hepatitis:</b> heterogeneous group including alpha-1-antitrypsin deficiency, "
"galactosemia, tyrosinemia, PFIC (progressive familial intrahepatic cholestasis), CMV, rubella, "
"toxoplasma, syphilis, and idiopathic causes (>10–15% of cases)"))
story.append(bul("<b>Alagille syndrome:</b> paucity of intrahepatic bile ducts (bile duct:portal tract ratio "
"<0.5); associated with JAG1/NOTCH2 mutations; butterfly vertebrae, peripheral pulmonic stenosis"))
story.append(Spacer(1, 0.3*cm))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 8 – DIAGNOSTIC APPROACH
# ══════════════════════════════════════════════════════════════════════════════
story += sec("8. DIAGNOSTIC APPROACH TO JAUNDICE")
story += subsec("8.1 History and Physical Examination")
history_data = [
["Finding", "Suggests"],
["History of blood transfusion/IV drug use", "Viral hepatitis (B, C)"],
["Alcohol use disorder", "Alcoholic hepatitis, cirrhosis"],
["Recent medication changes", "Drug-induced liver injury (DILI)"],
["Fever + rigors + RUQ pain + jaundice (Charcot's triad)", "Ascending cholangitis"],
["Painless progressive jaundice in elderly", "Pancreatic head or cholangiocarcinoma"],
["Colicky RUQ pain + jaundice", "Choledocholithiasis"],
["Pruritus without pain", "Intrahepatic cholestasis, PBC, sclerosing cholangitis"],
["Pregnancy", "Intrahepatic cholestasis of pregnancy, HELLP syndrome, acute fatty liver"],
["Family history of jaundice", "Hereditary disorder (Gilbert, Wilson's, hemolytic anemia)"],
]
hist_table = Table(history_data, colWidths=[8*cm, 9*cm])
hist_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, DEEP_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(hist_table)
story.append(Paragraph("Table 6: Clinically relevant history findings in jaundice", caption))
story += subsec("8.2 Laboratory Investigations")
story.append(para(
"Initial blood work should include serum bilirubin fractionation (direct/conjugated vs. "
"indirect/unconjugated), liver function tests, and a complete blood count."
))
lab_data = [
["Test", "Pre-hepatic", "Hepatocellular", "Cholestatic"],
["Total bilirubin", "↑ (mild–moderate)", "↑↑↑", "↑↑↑"],
["Direct bilirubin", "Normal or minimal ↑", "↑↑ (predominates late)", "↑↑↑"],
["Indirect bilirubin", "↑↑ (predominates)", "↑↑ (early)", "Normal / mild ↑"],
["AST / ALT", "Normal", "↑↑↑ (>1000 U/L in acute viral)", "Normal or mildly ↑"],
["ALP / GGT", "Normal", "Normal or mildly ↑", "↑↑↑ (ALP >3x ULN)"],
["PT/INR", "Normal", "↑ (hepatic failure)", "↑ (corrects with vit K)"],
["Albumin", "Normal", "↓ (chronic disease)", "Normal"],
["CBC", "Anemia ± reticulocytosis, spherocytes", "May be normal", "Normal"],
["Peripheral smear", "Spherocytes, schistocytes, sickle cells", "Normal or hypersplenism changes", "Normal"],
["Urine bilirubin", "Absent", "Present", "Present"],
["Urine urobilinogen", "↑↑", "Variable", "↓ or absent"],
["Haptoglobin", "↓ or absent", "Normal", "Normal"],
["LDH", "↑", "↑ (hepatic necrosis)", "Normal"],
]
lab_table = Table(lab_data, colWidths=[3.5*cm, 4.5*cm, 4.5*cm, 4.5*cm])
lab_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, DEEP_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(lab_table)
story.append(Paragraph("Table 7: Laboratory differentiation of jaundice types", caption))
story.append(PageBreak())
story += subsec("8.3 Diagnostic Algorithm (Harrison's Framework)")
story.append(para(
"The following stepwise approach is recommended for evaluating jaundice "
"(based on Harrison's Principles of Internal Medicine 22E):"
))
algo_steps = [
("Step 1", "Determine if bilirubin elevation is ISOLATED or associated with other liver test abnormalities"),
("Step 2", "Fractionate bilirubin: is it predominantly UNCONJUGATED or CONJUGATED?"),
("Step 3", "If unconjugated: is there hemolysis (CBC, reticulocytes, haptoglobin, LDH, peripheral smear) or a hereditary conjugation defect (Gilbert, Crigler-Najjar)?"),
("Step 4", "If conjugated + other LFT abnormalities: is the pattern HEPATOCELLULAR (↑AST/ALT) or CHOLESTATIC (↑ALP/GGT)?"),
("Step 5 — Cholestatic", "Perform ULTRASOUND first to detect biliary dilation. Dilation = extrahepatic obstruction; no dilation = intrahepatic cholestasis"),
("Step 6 — Extrahepatic", "Further imaging: CT, MRCP, ERCP (gold standard for choledocholithiasis), EUS, or PTC"),
("Step 7 — Intrahepatic", "Serologic tests: viral hepatitis panel, ANA, ASMA, AMA (for PBC), ceruloplasmin (Wilson's), ferritin/transferrin saturation (hemochromatosis), IgG4 (autoimmune)"),
("Step 8", "Liver biopsy when diagnosis remains uncertain after non-invasive workup"),
]
for step, desc in algo_steps:
algo_row_data = [[Paragraph(f"<b>{step}</b>", ParagraphStyle("s1", fontName="Helvetica-Bold", fontSize=9, textColor=white)),
Paragraph(desc, ParagraphStyle("s2", fontName="Helvetica", fontSize=9, textColor=HexColor("#1C1C1C")))]]
bg = DEEP_BLUE if "Step 1" in step or "Step 2" in step else MID_BLUE if "Step 3" in step or "Step 4" in step else HexColor("#4A90D9")
algo_row = Table(algo_row_data, colWidths=[3*cm, 14*cm])
algo_row.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), bg),
("BACKGROUND", (1,0), (1,0), SECTION_BG),
("BOX", (0,0), (-1,-1), 0.5, MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(algo_row)
story.append(Spacer(1, 0.1*cm))
story.append(Spacer(1, 0.3*cm))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 9 – IMAGING
# ══════════════════════════════════════════════════════════════════════════════
story += sec("9. IMAGING IN JAUNDICE")
story.append(para(
"Imaging is essential to distinguish extrahepatic from intrahepatic cholestasis and to "
"identify the cause and level of obstruction."
))
imaging_data = [
["Modality", "Role", "Key Advantages / Notes"],
["Ultrasound (USG)", "First-line imaging in all jaundiced patients", "Cheap, no radiation, detects biliary dilation with high sensitivity; poor visualization of distal CBD due to bowel gas"],
["CT abdomen", "Second-line; characterize mass, level of obstruction", "Better for pancreatic head, lymph nodes; shows level of obstruction well"],
["MRCP", "Non-invasive cholangiogram; replaced ERCP as initial test in most cases", "Excellent for visualizing bile ducts, stones, strictures, without radiation or contrast injection"],
["ERCP", "Gold standard for choledocholithiasis; also therapeutic", "Allows stone extraction, stent placement; invasive; risk of post-ERCP pancreatitis"],
["EUS", "Detection of distal CBD stones; allows FNA of masses", "Sensitivity comparable to MRCP for CBD obstruction; invasive but lower risk than ERCP"],
["PTC", "When ERCP fails (altered anatomy)", "Allows biliary drainage and stent placement percutaneously"],
["Liver biopsy", "Intrahepatic cholestasis with uncertain diagnosis", "Defines histologic pattern: hepatitis, PBC, PSC, DILI, hereditary disorders"],
]
img_table = Table(imaging_data, colWidths=[3.2*cm, 5.5*cm, 8.3*cm])
img_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, DEEP_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(imaging_data and img_table)
story.append(Paragraph("Table 8: Imaging modalities in jaundice", caption))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 10 – COMPLICATIONS
# ══════════════════════════════════════════════════════════════════════════════
story += sec("10. COMPLICATIONS OF JAUNDICE")
story += subsec("10.1 Complications of Unconjugated Hyperbilirubinemia")
story.append(bul("<b>Kernicterus (Bilirubin Encephalopathy):</b> unconjugated bilirubin crosses the "
"blood-brain barrier in neonates (and in adults with severely impaired BBB), depositing in "
"basal ganglia and brainstem nuclei, causing permanent neurologic damage — cerebral palsy, "
"sensorineural deafness, gaze palsies"))
story.append(bul("<b>Renal tubular effects:</b> unbound unconjugated bilirubin may be directly toxic "
"to renal tubular cells in hemolytic crises"))
story += subsec("10.2 Complications of Conjugated Hyperbilirubinemia / Cholestasis")
story.append(bul("<b>Pruritus:</b> bile salts deposited in skin cause severe, debilitating itching"))
story.append(bul("<b>Fat-soluble vitamin deficiencies:</b> reduced intraluminal bile acids impair "
"absorption of vitamins A (night blindness), D (metabolic bone disease / osteoporosis), "
"E (neuropathy), and K (coagulopathy)"))
story.append(bul("<b>Steatorrhea:</b> malabsorption of dietary fat due to reduced bile acid pool"))
story.append(bul("<b>Skin xanthomas:</b> focal deposition of cholesterol in skin from hypercholesterolemia "
"(cholesterol excretion impaired)"))
story.append(bul("<b>Secondary biliary cirrhosis:</b> prolonged extrahepatic obstruction leads to "
"periportal fibrosis → bridging fibrosis → cirrhosis"))
story.append(bul("<b>Ascending cholangitis (Charcot's triad / Reynolds pentad):</b> bacterial infection "
"of bile (E. coli, Klebsiella, Enterococcus) — fever, RUQ pain, jaundice; if septic shock "
"and confusion (Reynolds pentad) → medical emergency"))
story.append(bul("<b>Acute renal failure:</b> bile salts can cause renal vasoconstriction and direct "
"tubular toxicity (hepatorenal syndrome in cirrhotic patients)"))
story.append(Spacer(1, 0.3*cm))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 11 – TREATMENT OVERVIEW
# ══════════════════════════════════════════════════════════════════════════════
story += sec("11. PRINCIPLES OF MANAGEMENT")
story.append(para(
"Treatment of jaundice is directed at the underlying cause rather than the jaundice itself."
))
mgmt_data = [
["Type of Jaundice", "Management Principles"],
["Hemolytic (pre-hepatic)", "Treat underlying hemolytic disorder; folic acid supplementation; transfusion if severe; exchange transfusion for severe neonatal jaundice; phototherapy for neonatal unconjugated jaundice"],
["Gilbert syndrome", "No treatment needed; reassurance"],
["Crigler-Najjar type I", "Phototherapy 10–12 hr/day; liver transplantation is curative"],
["Crigler-Najjar type II", "Phenobarbital (induces residual UDPGT); phototherapy"],
["Viral hepatitis", "Supportive; antivirals for HBV/HCV; avoid hepatotoxins; liver transplant for fulminant failure"],
["Drug-induced", "Stop offending drug; N-acetylcysteine for acetaminophen toxicity; supportive care"],
["Alcoholic hepatitis", "Alcohol abstinence; steroids (prednisolone) for severe disease (Maddrey Discriminant Function >32); pentoxifylline as alternative"],
["Autoimmune hepatitis", "Prednisolone ± azathioprine"],
["Wilson's disease", "D-penicillamine or trientine; zinc to reduce absorption; liver transplant for fulminant failure"],
["Choledocholithiasis (obstructive)", "ERCP with sphincterotomy and stone extraction; cholecystectomy"],
["Malignant obstruction", "Biliary stenting (ERCP/PTC); surgical resection if operable; palliative drainage"],
["Biliary atresia (neonate)", "Kasai portoenterostomy; liver transplantation"],
["Primary Biliary Cholangitis (PBC)", "Ursodeoxycholic acid (UDCA); obeticholic acid for incomplete responders"],
["Primary Sclerosing Cholangitis (PSC)", "UDCA (controversial); endoscopic dilation of dominant strictures; liver transplantation"],
["Cholestasis — pruritus", "Cholestyramine (bile acid sequestrant), rifampicin, naltrexone, sertraline"],
]
mgmt_table = Table(mgmt_data, colWidths=[5*cm, 12*cm])
mgmt_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, TABLE_ALT]),
("BOX", (0,0), (-1,-1), 0.75, DEEP_BLUE),
("INNERGRID", (0,0), (-1,-1), 0.4, HexColor("#AAAAAA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mgmt_table)
story.append(Paragraph("Table 9: Management principles by type of jaundice", caption))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 12 – QUICK REVISION SUMMARY
# ══════════════════════════════════════════════════════════════════════════════
story += sec("12. QUICK REVISION SUMMARY")
story.append(Spacer(1, 0.2*cm))
# Mnemonics / key facts
key_facts = [
("Bilirubin Normal", "0.3 – 1.2 mg/dL total; <0.3 mg/dL direct"),
("Jaundice visible", "> 2 – 2.5 mg/dL"),
("Conjugated bilirubin", "Water-soluble, excreted in urine → bilirubinuria → dark urine"),
("Unconjugated bilirubin", "Water-insoluble, albumin-bound, NOT in urine → acholuric jaundice"),
("Pre-hepatic marker", "↑ Indirect bilirubin, ↑ LDH, ↓ haptoglobin, ↑ urobilinogen, normal ALP/ALT"),
("Hepatic marker", "↑↑ AST/ALT ('hepatocellular enzymes'), both fractions elevated"),
("Post-hepatic marker", "↑↑ ALP + GGT + Direct bilirubin; pale stool, dark urine, pruritus"),
("Charcot's triad", "Fever + RUQ pain + Jaundice = Ascending cholangitis"),
("Reynolds pentad", "Charcot's triad + Shock + Confusion = Suppurative cholangitis (emergency)"),
("Painless jaundice", "Pancreatic head malignancy until proven otherwise (Courvoisier's sign)"),
("Kernicterus risk", "Unconjugated bilirubin > albumin-binding capacity → free bilirubin → brain damage"),
("Courvoisier's law", "Painless jaundice + palpable non-tender gallbladder → malignant obstruction"),
("Gilbert syndrome", "Most common hereditary hyperbilirubinemia; ↓ UGT1A1 promoter; benign; exacerbated by fasting"),
("Dubin-Johnson", "Dark liver (pigmented) + conjugated hyperbilirubinemia; ↓ MRP2; benign"),
("Feathery degeneration", "Hepatocyte cytoplasmic swelling with bile pigment in cholestasis — pathognomonic morphology"),
("1st line imaging", "Ultrasound for all patients with jaundice"),
]
for term, fact in key_facts:
fact_row = Table([[Paragraph(f"<b>{term}</b>", ParagraphStyle("t1", fontName="Helvetica-Bold", fontSize=9, textColor=DEEP_BLUE)),
Paragraph(fact, ParagraphStyle("t2", fontName="Helvetica", fontSize=9, textColor=HexColor("#1C1C1C")))
]], colWidths=[5*cm, 12*cm])
fact_row.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIGHT_BLUE),
("BACKGROUND", (1,0), (1,0), white),
("BOX", (0,0), (-1,-1), 0.4, MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(fact_row)
story.append(Spacer(1, 0.05*cm))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════════
# REFERENCES
# ══════════════════════════════════════════════════════════════════════════════
story += sec("REFERENCES")
refs = [
"Kumar V, Abbas AK, Aster JC. Robbins & Kumar Basic Pathology, 11th Edition. Elsevier; 2023. "
"Chapter 14: Liver and Biliary Tract — Pathophysiology of Jaundice, pp. 619–621.",
"Loscalzo J, Fauci A, Kasper D, et al. Harrison's Principles of Internal Medicine, 22nd Edition. "
"McGraw-Hill; 2025. Chapter 52: Jaundice, Evaluation of the Patient with Jaundice, pp. 364–370.",
"Sleisenger MH, Fordtran JS. Gastrointestinal and Liver Disease: Pathophysiology, Diagnosis, "
"Management. 11th Edition. Elsevier; 2021.",
"Yamada T. Yamada's Textbook of Gastroenterology, 7th Edition. Wiley-Blackwell; 2022. "
"Chapter: Cholestatic Liver Injury and Hyperbilirubinemia.",
"Goldman L, Cooney KA. Goldman-Cecil Medicine, 27th Edition (International Edition). "
"Elsevier; 2024.",
]
for i, ref in enumerate(refs, 1):
story.append(Paragraph(f"{i}. {ref}", ParagraphStyle("ref", fontName="Helvetica", fontSize=9,
leading=13, spaceAfter=5, leftIndent=15, firstLineIndent=-15, textColor=HexColor("#1C1C1C"))))
# ── BUILD PDF ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
topMargin=1.6*cm,
bottomMargin=1.4*cm,
leftMargin=1.5*cm,
rightMargin=1.5*cm,
title="Jaundice — Pathology",
author="Orris Medical Library",
subject="Pathology of Jaundice",
)
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print("PDF generated:", OUTPUT)
cd /home/daytona/workspace/jaundice-pathology && python generate_pdf.py 2>&1