Teach me Renal calculus for exam point of view short and easy and impactful with diagrams including all the important things like definitions cause type and treatment diagnosis everything

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Reading File
Reading File
Reading File
Loading Image
Loading Image
Loading Image
I now have all the content needed. Let me compile the complete, exam-ready guide.

πŸͺ¨ Renal Calculi (Nephrolithiasis / Urolithiasis) - Complete Exam Guide


1. DEFINITION

Renal calculi = solid crystalline deposits that form within the kidney when the urinary concentration of stone-forming ions exceeds their solubility (supersaturation), leading to nucleation and crystal aggregation in a protein matrix.
Also called: urolithiasis, nephrolithiasis, kidney stones.

2. EPIDEMIOLOGY (High-Yield Numbers)

FactValue
Lifetime risk - men~15%
Lifetime risk - women~10%
Peak incidence4th-5th decade
Annual incidence>1 per 1000 persons
Most common stoneCalcium oxalate (60%)
  • More common in hot, dry climates (concentrated urine)
  • More common in whites vs other ethnic groups
  • Obesity (BMI >30) is a major risk factor

3. STONE TYPES & COMPOSITION

Quick Reference Table

Stone Type%Appearance on X-raypHKey Association
Calcium oxalate60%RadiopaqueAcidicMost common overall
Hydroxyapatite (Ca-phosphate)20%RadiopaqueAlkalineHyperparathyroidism
Struvite (MgNH4PO4)7%Radiopaque (staghorn)Alkaline (>7)Urease-splitting bacteria
Uric acid7%RadiolucentAcidic (<5.5)Gout, high-purine diet
Cystine1-3%Faintly opaqueAcidicCystinuria (genetic)
Drug stones<1%Variable-Indinavir, triamterene
Exam Mnemonic - Radiopaque stones: "Can Sometimes Be Radiopaque" = Calcium oxalate, Struvite, Brushite, (all calcium-containing). Radiolucent = Uric Acid (and indinavir).

4. PATHOPHYSIOLOGY (Stone Formation Steps)

Normal urine
     ↓
Supersaturation (↑ stone-forming ions OR ↓ urine volume)
     ↓
Nucleation (ions bond β†’ crystal seeds form)
     ↓
Crystal Growth & Aggregation
     ↓
Stone formation
Promoters of stone formation:
  • Hypercalciuria, hyperoxaluria, hyperuricosuria
  • Hypocitraturia (citrate is a key INHIBITOR)
  • Low urine volume (dehydration)
  • High urine pH (promotes Ca-phosphate, struvite)
  • Low urine pH (promotes uric acid, Ca-oxalate)
Natural inhibitors (that prevent stones):
  • Citrate (chelates calcium)
  • Tamm-Horsfall protein
  • Osteopontin
  • Pyrophosphate, nephrocalcin

5. CAUSES & RISK FACTORS

A. Calcium Stones (Hypercalciuria - 3 Types)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              HYPERCALCIURIA TYPES                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ABSORPTIVE     β”‚ RENAL          β”‚ RESORPTIVE             β”‚
β”‚ (most common,  β”‚ (Impaired Ca   β”‚ (1Β° Hyperparathy-      β”‚
β”‚ 20-40%)        β”‚ reabsorption   β”‚ roidism, 3-5%)         β”‚
β”‚ ↑ GI Ca absorb β”‚ in tubules,    β”‚ ↑ PTH β†’ bone           β”‚
β”‚ β†’ ↑ urinary Ca β”‚ 5-8%)          β”‚ resorption             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Other causes of calcium stones:
  • Hyperoxaluria - dietary (spinach, nuts, tea, cocoa), enteric (Crohn's, celiac - malabsorbed fats bind Ca, free oxalate absorbed), primary (genetic - AGXT gene mutation)
  • Hypocitraturia - RTA (renal tubular acidosis), diarrhea, hypokalemia
  • Hyperuricosuria - purine-rich diet, gout

B. Struvite Stones (Infection Stones)

  • Caused by urease-producing bacteria: Proteus mirabilis (#1), Klebsiella, Pseudomonas, Staphylococcus
  • Urease splits urea β†’ ammonia β†’ alkaline urine (pH >7) β†’ precipitates MgNH4PO4
  • Forms staghorn calculi (fills entire renal pelvis + calyces)
  • Almost always associated with recurrent UTIs

C. Uric Acid Stones

  • Causes: gout, high-purine diet (red meat, organ meats, shellfish), myeloproliferative disorders, tumor lysis syndrome, diabetes/obesity
  • Acidic urine pH <5.5 promotes uric acid precipitation (uric acid is poorly soluble in acid)
  • Unique: radiolucent on plain X-ray but visible on CT

D. Cystine Stones

  • Autosomal recessive defect in cystine-dibasic amino acid transporter (SLC3A1, SLC7A9 genes)
  • Amino acids affected: Cystine, Ornithine, Lysine, Arginine β†’ "COLA" mnemonic
  • Cystine is insoluble β†’ forms staghorn-like stones
  • Appears hexagonal crystals on urine microscopy

6. CLINICAL FEATURES

Classic Presentation

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           RENAL COLIC - CLASSIC FEATURES                 β”‚
β”‚                                                          β”‚
β”‚  β€’ Sudden, SEVERE, COLICKY flank pain                    β”‚
β”‚  β€’ Radiates: flank β†’ groin β†’ labia/scrotum              β”‚
β”‚  β€’ "Worst pain of my life" (restless, can't lie still)  β”‚
β”‚  β€’ Nausea & vomiting                                     β”‚
β”‚  β€’ Hematuria (gross or microscopic) - 90%               β”‚
β”‚  β€’ Dysuria/urgency (if stone near UVJ)                  β”‚
β”‚  β€’ NO peritoneal signs (patient constantly moves)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pain Location by Stone Location

      [Renal pelvis/calyces]
             ↓
      Flank pain / CVA tenderness
             ↓
      [Upper ureter]
             ↓
      Flank β†’ upper abdomen (may mimic appendicitis/cholecystitis)
             ↓
      [Mid-ureter crossing iliac vessels]  ← Common obstruction site
             ↓
      Lower abdomen / pelvis
             ↓
      [Ureterovesical junction (UVJ)]  ← Most common site of obstruction
             ↓
      Urgency, frequency, dysuria, groin pain

3 Points Where Stones Get Stuck (EXAM FAVORITE!)

  1. Ureteropelvic junction (UPJ)
  2. Ureter crossing iliac vessels (pelvic brim)
  3. Ureterovesical junction (UVJ) - narrowest, most common

7. DIAGNOSIS

Step 1 - Urine Tests

  • Urinalysis: hematuria (90%), crystalluria (RBCs + crystals), pyuria (if infected)
  • Urine pH: acidic in uric acid stones; alkaline (>7) in struvite; helps narrow stone type
  • Urine culture: to rule out infection (especially struvite stones)
  • 24-hour urine collection (for recurrent stones): calcium, oxalate, uric acid, citrate, phosphate, sodium, creatinine

Step 2 - Blood Tests

  • BMP/CMP: serum Ca, uric acid, BUN/Cr (renal function)
  • PTH: if hypercalcemia present (to exclude hyperparathyroidism)
  • CBC: leukocytosis if infected stone

Step 3 - Imaging

Gold standard: Non-contrast CT (NCCT) abdomen/pelvis
Non-contrast CT showing an 8mm obstructing calculus at the left ureteropelvic junction (arrow) with surrounding inflammatory changes.
CT KUB: 8mm obstructing calculus at the left UPJ (arrow) - gold standard imaging. Source: National Kidney Foundation Primer on Kidney Diseases, 8e
  • Sensitivity & specificity >95% for all stone types (including radiolucent uric acid stones)
  • Shows hydronephrosis, periureteral stranding, stone size/location
  • "Low-dose CT protocol" available to reduce radiation

Plain X-ray (KUB - Kidney, Ureter, Bladder):
KUB X-ray showing two calcifications overlying the upper right kidney (arrows) with a percutaneous nephroureterostomy catheter visible.
KUB X-ray: radiopaque calculi in right kidney (arrows). Source: National Kidney Foundation Primer on Kidney Diseases, 8e
  • Detects radiopaque stones (Ca-oxalate, Ca-phosphate, struvite, cystine)
  • MISSES radiolucent stones (uric acid, indinavir)
  • Sensitivity ~60% - less reliable than CT

Ultrasound:
Renal ultrasound showing a hyperechoic calculus with posterior acoustic shadowing in the left kidney (arrow).
Renal ultrasound: hyperechoic stone with acoustic shadow (arrow). Source: National Kidney Foundation Primer on Kidney Diseases, 8e
  • First-line in: pregnant patients, children, recurrent disease (no radiation)
  • Detects hydronephrosis and larger stones >5mm
  • Less sensitive than CT for small/ureteral stones
  • Finding: hyperechoic focus + posterior acoustic shadowing

Imaging Summary Table

ModalitySensitivityBest ForMisses
NCCT>95%Gold standard, all stonesRadiation
KUB X-ray~60%Follow-up of radiopaque stonesUric acid stones
Ultrasound~45-78%Pregnancy, kids, hydronephrosisSmall/ureteral stones
IVP/IVUGoodAnatomy, radiolucent stonesLargely replaced by CT
MRIPoorNot standard for stonesMost calculi (no MR signal)

8. TREATMENT

Algorithm Based on Stone Size

Stone Detected
     β”‚
     β”œβ”€β”€β”€ ≀4 mm ──→ 95% pass spontaneously
     β”‚              Medical expulsive therapy (MET)
     β”‚              Hydration, pain control
     β”‚
     β”œβ”€β”€β”€ 4-6 mm ──→ ~50% pass spontaneously
     β”‚               MET + Ξ±-blocker (tamsulosin)
     β”‚               Wait up to 4 weeks
     β”‚
     β”œβ”€β”€β”€ 6-10 mm ──→ Unlikely to pass spontaneously
     β”‚                Consider procedural intervention
     β”‚
     └─── >10 mm ──→ Intervention needed
                     Choose based on location/type

A. Conservative/Medical Management (Acute Colic)

TreatmentPurpose
IV/oral hydrationDilute urine, encourage stone passage
NSAIDs (ketorolac, ibuprofen)First-line pain control (better than opioids)
Opioids (morphine)Rescue analgesia
Ξ±-blockers (tamsulosin 0.4 mg)Relax ureteral smooth muscle β†’ ↑ passage rate
Anti-emetics (ondansetron)Nausea/vomiting

B. Interventional Procedures

ProcedureBest ForMechanism
ESWL (Extracorporeal Shock Wave Lithotripsy)Stones <2 cm, renal pelvis, upper ureterExternal shock waves fragment stone
URS (Ureteroscopy + laser lithotripsy)Ureteral stones, any sizeEndoscope + holmium laser
PCNL (Percutaneous Nephrolithotomy)Large stones >2 cm, staghorn calculiNephroscope through flank
Open/laparoscopic surgeryComplex/rare casesRarely needed

C. Emergency Indications (IMMEDIATE intervention)

  • Infected obstructing stone (urosepsis) - most urgent
  • Bilateral obstruction or solitary kidney
  • Refractory pain/vomiting
  • Worsening renal function

9. STONE-SPECIFIC MEDICAL PREVENTION

Stone TypePrevention Strategy
Calcium oxalate↑ fluids (>2-2.5 L/day), low-oxalate diet, normal (not low) Ca intake, thiazide diuretics (for hypercalciuria), potassium citrate (for hypocitraturia)
Calcium phosphateThiazide diuretics, potassium citrate
Uric acidAlkalinize urine (potassium citrate β†’ pH 6-7), allopurinol (for hyperuricosuria), low-purine diet
StruviteAntibiotics (treat underlying infection), acetohydroxamic acid (urease inhibitor), surgical removal
CystineHigh fluid intake (>3 L/day), alkalinize urine, D-penicillamine or tiopronin (chelates cystine)

10. COMPLICATIONS

ComplicationKey Point
Urinary obstruction→ Hydronephrosis → obstructive nephropathy
Pyelonephritis/urosepsisInfected obstructing stone = surgical emergency
CKD/renal failureRecurrent stones β†’ progressive nephron loss
Recurrence~50% within 5-10 years if no prevention
Ureteral strictureFrom repeated stone passage

11. HIGH-YIELD EXAM FAST FACTS

FactAnswer
Most common stoneCalcium oxalate
Only radiolucent stoneUric acid (also indinavir)
Stone in alkaline urineStruvite, Calcium phosphate
Stone in acidic urineUric acid, Calcium oxalate
Staghorn calculus =Struvite (or rarely cystine)
"COLA" amino acids lost in cystinuriaCystine, Ornithine, Lysine, Arginine
Crystal shape: uric acidRhomboid/needle shaped
Crystal shape: cystineHexagonal (pathognomonic)
Crystal shape: Ca-oxalate dihydrateEnvelope/bipyramid
Crystal shape: struviteCoffin-lid shaped
Gold standard imagingNon-contrast CT
First-line imaging in pregnancyUltrasound
Most common site of obstructionUreterovesical junction (UVJ)
Inhibitor of stone formationCitrate
Bacteria causing struviteProteus mirabilis (#1)
MET agentTamsulosin (Ξ±-blocker)
Large stone (>2cm) treatmentPCNL

12. QUICK MEMORY DIAGRAM - Stone Types at a Glance

                    KIDNEY STONES
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚               β”‚                β”‚
   CALCIUM (80%)    URIC ACID (7%)   STRUVITE (7%)
   β”œβ”€ Oxalate 60%   Radiolucent      Urease bacteria
   β”œβ”€ Phosphate 20%  pH <5.5         pH >7 (alkaline)
   └─ Brushite 2%   Gout/obesity    Staghorn calculi
        
   CYSTINE (1-3%)        DRUG STONES (<1%)
   Genetic/AR            Indinavir,
   Hexagonal crystals    Triamterene
   COLA amino acids

Sources: Goldman-Cecil Medicine, 26e | Campbell-Walsh-Wein Urology | National Kidney Foundation Primer on Kidney Diseases, 8e | Robbins Pathologic Basis of Disease

Generate a PDF quick reference card summarizing stone classifications, diagnostic criteria, and treatment protocols

Reading File
Running Command

mkdir -p /tmp/workspace/renal-calculi && ls /tmp/workspace/

Writing File

~/renal-calculi/generate_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Table, TableStyle, Spacer,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfgen import canvas
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate

OUTPUT = "/tmp/workspace/renal-calculi/Renal_Calculi_Quick_Reference.pdf"

# ── Colour palette ────────────────────────────────────────────────────────────
NAVY       = colors.HexColor("#1B3A6B")
STEEL      = colors.HexColor("#2E6DA4")
LIGHT_BLUE = colors.HexColor("#D6E8F7")
TEAL       = colors.HexColor("#1A7A7A")
LIGHT_TEAL = colors.HexColor("#D0EFEF")
ORANGE     = colors.HexColor("#C0540A")
ORANGE_LT  = colors.HexColor("#FDE8D8")
RED        = colors.HexColor("#B22222")
RED_LT     = colors.HexColor("#FAE0E0")
GREEN      = colors.HexColor("#1B6B2F")
GREEN_LT   = colors.HexColor("#D8F0DE")
PURPLE     = colors.HexColor("#5B2C8D")
PURPLE_LT  = colors.HexColor("#EAD8F8")
GOLD       = colors.HexColor("#B8860B")
GOLD_LT    = colors.HexColor("#FFF8DC")
GREY_DARK  = colors.HexColor("#333333")
GREY_MID   = colors.HexColor("#666666")
GREY_LIGHT = colors.HexColor("#F4F6FA")
WHITE      = colors.white

# ── Page dimensions ───────────────────────────────────────────────────────────
W, H = A4   # 595.27 x 841.89 pts
MARGIN = 1.5 * cm

# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def style(name, **kw):
    s = ParagraphStyle(name, **kw)
    return s

HDR1 = style("HDR1", fontSize=18, fontName="Helvetica-Bold",
             textColor=WHITE, alignment=TA_CENTER, leading=22)
HDR2 = style("HDR2", fontSize=11, fontName="Helvetica-Bold",
             textColor=WHITE, alignment=TA_LEFT, leading=14)
HDR3 = style("HDR3", fontSize=9.5, fontName="Helvetica-Bold",
             textColor=NAVY, alignment=TA_LEFT, leading=12)
BODY = style("BODY", fontSize=8.2, fontName="Helvetica",
             textColor=GREY_DARK, leading=11)
BODY_B = style("BODY_B", fontSize=8.2, fontName="Helvetica-Bold",
               textColor=GREY_DARK, leading=11)
SMALL = style("SMALL", fontSize=7.5, fontName="Helvetica",
              textColor=GREY_MID, leading=10)
SMALL_B = style("SMALL_B", fontSize=7.5, fontName="Helvetica-Bold",
                textColor=GREY_DARK, leading=10)
CELL  = style("CELL",  fontSize=7.8, fontName="Helvetica",
              textColor=GREY_DARK, leading=10, alignment=TA_LEFT)
CELL_B = style("CELL_B", fontSize=7.8, fontName="Helvetica-Bold",
               textColor=GREY_DARK, leading=10)
CELL_W = style("CELL_W", fontSize=8, fontName="Helvetica-Bold",
               textColor=WHITE, leading=10, alignment=TA_LEFT)
ALERT = style("ALERT", fontSize=8, fontName="Helvetica-Bold",
              textColor=RED, leading=10)
MNEM  = style("MNEM", fontSize=8, fontName="Helvetica-BoldOblique",
              textColor=PURPLE, leading=10)

usable_w = W - 2 * MARGIN   # β‰ˆ 165 mm

# ── Helper: section header bar ────────────────────────────────────────────────
def section_header(text, bg=NAVY, fg=WHITE):
    tbl = Table([[Paragraph(text, style("_sh", fontSize=10,
                                        fontName="Helvetica-Bold",
                                        textColor=fg, leading=13))]],
                colWidths=[usable_w])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",  (0,0), (-1,-1), 4),
        ("BOTTOMPADDING",(0,0), (-1,-1), 4),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING",(0,0), (-1,-1), 6),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
    ]))
    return tbl

# ── Helper: two-col layout ────────────────────────────────────────────────────
def two_col(left_items, right_items, ratio=(1, 1)):
    total = sum(ratio)
    lw = usable_w * ratio[0] / total - 3
    rw = usable_w * ratio[1] / total - 3
    rows = max(len(left_items), len(right_items))
    data = []
    for i in range(rows):
        l = left_items[i]  if i < len(left_items)  else ""
        r = right_items[i] if i < len(right_items) else ""
        data.append([l, r])
    tbl = Table(data, colWidths=[lw, rw], hAlign="LEFT")
    tbl.setStyle(TableStyle([
        ("VALIGN", (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING", (0,0), (-1,-1), 0),
        ("RIGHTPADDING",(0,0), (-1,-1), 4),
        ("TOPPADDING",  (0,0), (-1,-1), 0),
        ("BOTTOMPADDING",(0,0), (-1,-1), 0),
    ]))
    return tbl

# ══════════════════════════════════════════════════════════════════════════════
# Build story
# ══════════════════════════════════════════════════════════════════════════════
story = []

# ── TITLE BANNER ──────────────────────────────────────────────────────────────
title_data = [[
    Paragraph("πŸͺ¨  RENAL CALCULI", style("T1", fontSize=20,
              fontName="Helvetica-Bold", textColor=WHITE, leading=24)),
    Paragraph("Quick Reference Card", style("T2", fontSize=11,
              fontName="Helvetica-BoldOblique", textColor=LIGHT_BLUE,
              alignment=TA_RIGHT, leading=14)),
]]
title_tbl = Table(title_data, colWidths=[usable_w * 0.6, usable_w * 0.4])
title_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), NAVY),
    ("TOPPADDING",  (0,0), (-1,-1), 10),
    ("BOTTOMPADDING",(0,0), (-1,-1), 10),
    ("LEFTPADDING", (0,0), (-1,-1), 10),
    ("RIGHTPADDING",(0,0), (-1,-1), 10),
    ("VALIGN",      (0,0), (-1,-1), "MIDDLE"),
]))
story.append(title_tbl)

sub_data = [[
    Paragraph("Nephrolithiasis / Urolithiasis", style("S1", fontSize=9,
              fontName="Helvetica", textColor=WHITE, leading=11)),
    Paragraph("Classification Β· Diagnosis Β· Treatment Β· Prevention",
              style("S2", fontSize=8, fontName="Helvetica-Oblique",
                    textColor=LIGHT_BLUE, alignment=TA_RIGHT, leading=11)),
]]
sub_tbl = Table(sub_data, colWidths=[usable_w * 0.55, usable_w * 0.45])
sub_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), STEEL),
    ("TOPPADDING",  (0,0), (-1,-1), 4),
    ("BOTTOMPADDING",(0,0), (-1,-1), 4),
    ("LEFTPADDING", (0,0), (-1,-1), 10),
    ("RIGHTPADDING",(0,0), (-1,-1), 10),
    ("VALIGN",      (0,0), (-1,-1), "MIDDLE"),
]))
story.append(sub_tbl)
story.append(Spacer(1, 6))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 1 – DEFINITION & EPIDEMIOLOGY
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("1. DEFINITION & EPIDEMIOLOGY", NAVY))
story.append(Spacer(1, 4))

def_items = [
    Paragraph("<b>Definition:</b> Crystalline deposits formed in the kidney when urine becomes "
              "supersaturated with stone-forming ions, exceeding their solubility "
              "β†’ nucleation β†’ crystal growth β†’ stone.", BODY),
    Spacer(1, 4),
    Paragraph("<b>Mechanism:</b> Supersaturation β†’ Nucleation (homo/heterogeneous) β†’ "
              "Aggregation β†’ Stone (inhibitors: citrate, Tamm-Horsfall protein, osteopontin)", BODY),
]

epi_rows = [
    [Paragraph("Fact", CELL_W), Paragraph("Value", CELL_W)],
    [Paragraph("Lifetime risk – Men", CELL_B), Paragraph("~15%", CELL)],
    [Paragraph("Lifetime risk – Women", CELL_B), Paragraph("~10%", CELL)],
    [Paragraph("Peak incidence", CELL_B), Paragraph("4th–5th decade", CELL)],
    [Paragraph("Annual incidence", CELL_B), Paragraph(">1 per 1,000 persons", CELL)],
    [Paragraph("Most common stone", CELL_B), Paragraph("Calcium oxalate (60%)", CELL)],
    [Paragraph("Key risk factors", CELL_B), Paragraph("Obesity, hot climate, low fluid intake, family Hx", CELL)],
]
epi_tbl = Table(epi_rows, colWidths=[usable_w*0.42, usable_w*0.58])
epi_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), STEEL),
    ("BACKGROUND", (0,1), (-1,1), LIGHT_BLUE),
    ("BACKGROUND", (0,2), (-1,2), WHITE),
    ("BACKGROUND", (0,3), (-1,3), LIGHT_BLUE),
    ("BACKGROUND", (0,4), (-1,4), WHITE),
    ("BACKGROUND", (0,5), (-1,5), LIGHT_BLUE),
    ("BACKGROUND", (0,6), (-1,6), WHITE),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#BBCDE0")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))

story.append(two_col(def_items, [epi_tbl], ratio=(55, 45)))
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2 – STONE CLASSIFICATION
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2. STONE CLASSIFICATION (Composition & Key Features)", TEAL))
story.append(Spacer(1, 4))

hdr = [Paragraph(h, CELL_W) for h in
       ["Stone Type", "% of All", "X-Ray", "Urine pH", "Crystal Shape", "Key Association"]]
stone_rows = [
    hdr,
    [Paragraph("Calcium Oxalate", CELL_B),
     Paragraph("60%", CELL),
     Paragraph("Radiopaque", CELL),
     Paragraph("Acidic", CELL),
     Paragraph("Envelope/bipyramid (dihydrate)\nDumbbell (monohydrate)", SMALL),
     Paragraph("Hypercalciuria, hyperoxaluria, hypocitraturia", CELL)],
    [Paragraph("Calcium Phosphate\n(Hydroxyapatite)", CELL_B),
     Paragraph("20%", CELL),
     Paragraph("Radiopaque", CELL),
     Paragraph("Alkaline", CELL),
     Paragraph("Amorphous / needle", SMALL),
     Paragraph("Hyperparathyroidism, RTA type 1", CELL)],
    [Paragraph("Struvite\n(MgNHβ‚„POβ‚„)", CELL_B),
     Paragraph("7%", CELL),
     Paragraph("Radiopaque", CELL),
     Paragraph("Alkaline >7", CELL),
     Paragraph("Coffin-lid", SMALL),
     Paragraph("Urease bacteria (Proteus #1)\nStaghorn calculi, recurrent UTIs", CELL)],
    [Paragraph("Uric Acid", CELL_B),
     Paragraph("7%", CELL),
     Paragraph("Radiolucent β˜…", CELL),
     Paragraph("Acidic <5.5", CELL),
     Paragraph("Rhomboid/needle", SMALL),
     Paragraph("Gout, obesity, high-purine diet,\ntumor lysis, diabetes", CELL)],
    [Paragraph("Cystine", CELL_B),
     Paragraph("1–3%", CELL),
     Paragraph("Faint opaque", CELL),
     Paragraph("Acidic", CELL),
     Paragraph("Hexagonal β˜…β˜…", SMALL),
     Paragraph("Cystinuria (AR) – COLA: Cystine,\nOrnithine, Lysine, Arginine", CELL)],
    [Paragraph("Drug Stones", CELL_B),
     Paragraph("<1%", CELL),
     Paragraph("Radiolucent\n(indinavir)", CELL),
     Paragraph("Variable", CELL),
     Paragraph("Variable", SMALL),
     Paragraph("Indinavir, triamterene, ephedrine,\nsilica", CELL)],
]
stone_tbl = Table(stone_rows, colWidths=[
    usable_w*0.16, usable_w*0.07, usable_w*0.10,
    usable_w*0.10, usable_w*0.17, usable_w*0.40
])
stone_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_TEAL, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#A0C8C8")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("FONTNAME",   (0,1), (-1,-1), "Helvetica"),
    ("FONTSIZE",   (0,1), (-1,-1), 7.8),
]))
story.append(stone_tbl)
story.append(Paragraph(
    "β˜… Uric acid stones are the ONLY radiolucent stones on plain X-ray but are visible on CT  "
    "β˜…β˜… Hexagonal crystals on urine microscopy are pathognomonic for cystinuria",
    style("fn", fontSize=7, fontName="Helvetica-Oblique",
          textColor=GREY_MID, leading=9)))
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3 – CAUSES / RISK FACTORS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("3. CAUSES & RISK FACTORS", ORANGE))
story.append(Spacer(1, 4))

# Hypercalciuria box
hyper_rows = [
    [Paragraph("HYPERCALCIURIA (3 types)", CELL_W), Paragraph("Prevalence", CELL_W), Paragraph("Mechanism", CELL_W)],
    [Paragraph("Absorptive (most common)", CELL_B), Paragraph("20–40%", CELL), Paragraph("↑ GI Ca absorption β†’ ↑ urinary Ca", CELL)],
    [Paragraph("Renal", CELL_B), Paragraph("5–8%", CELL), Paragraph("Impaired tubular Ca reabsorption", CELL)],
    [Paragraph("Resorptive (1Β° HPT)", CELL_B), Paragraph("3–5%", CELL), Paragraph("↑ PTH β†’ bone Ca release β†’ ↑ urine Ca", CELL)],
]
hyper_tbl = Table(hyper_rows, colWidths=[usable_w*0.35, usable_w*0.15, usable_w*0.50])
hyper_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), ORANGE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [ORANGE_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#E0A080")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))

# Other causes
other_rows = [
    [Paragraph("Condition", CELL_W), Paragraph("Mechanism / Association", CELL_W)],
    [Paragraph("Hyperoxaluria", CELL_B),
     Paragraph("Dietary (spinach, nuts, tea) | Enteric (Crohn's, celiac – malabsorbed fat binds Ca, free oxalate absorbed) | Primary (AGXT gene defect)", CELL)],
    [Paragraph("Hypocitraturia", CELL_B),
     Paragraph("RTA type 1, chronic diarrhea, hypokalemia – citrate is key stone INHIBITOR", CELL)],
    [Paragraph("Hyperuricosuria", CELL_B),
     Paragraph("High purine diet, gout, myeloproliferative disease – promotes Ca-oxalate & uric acid stones", CELL)],
    [Paragraph("Dehydration / Low UO", CELL_B),
     Paragraph("Hot climate, occupation, exercise β†’ concentrated urine β†’ supersaturation", CELL)],
    [Paragraph("Urease bacteria", CELL_B),
     Paragraph("Proteus mirabilis, Klebsiella, Pseudomonas β†’ alkaline pH β†’ struvite", CELL)],
    [Paragraph("Cystinuria (AR)", CELL_B),
     Paragraph("SLC3A1 / SLC7A9 mutations β†’ defective COLA transport β†’ cystine in urine", CELL)],
]
other_tbl = Table(other_rows, colWidths=[usable_w*0.22, usable_w*0.78])
other_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), colors.HexColor("#7A3A0A")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [ORANGE_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#E0A080")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))

story.append(hyper_tbl)
story.append(Spacer(1, 4))
story.append(other_tbl)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4 – CLINICAL FEATURES
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4. CLINICAL FEATURES", RED))
story.append(Spacer(1, 4))

# Symptoms column
sx_items = [
    Paragraph("<b>Classic Renal Colic:</b>", BODY_B),
    Paragraph("β€’ Sudden, severe, colicky flank pain", BODY),
    Paragraph("β€’ Radiates: flank β†’ groin β†’ labia/scrotum", BODY),
    Paragraph("β€’ Restless (can't get comfortable)", BODY),
    Paragraph("β€’ Nausea & vomiting", BODY),
    Paragraph("β€’ Haematuria (90% – gross or micro)", BODY),
    Paragraph("β€’ Dysuria/urgency (stone near UVJ)", BODY),
    Spacer(1, 4),
    Paragraph("<b>No peritoneal signs</b> (patient constantly moves)", ALERT),
]

# 3 points of obstruction
obs_data = [
    [Paragraph("Site", CELL_W), Paragraph("Location / Pain", CELL_W)],
    [Paragraph("β‘  UPJ", CELL_B), Paragraph("Ureteropelvic junction β†’ flank pain", CELL)],
    [Paragraph("β‘‘ Iliac brim", CELL_B), Paragraph("Ureter crosses iliac vessels β†’ lower abdomen", CELL)],
    [Paragraph("β‘’ UVJ β˜…", CELL_B), Paragraph("Ureterovesical junction (narrowest) β†’ urgency, groin pain – MOST COMMON OBSTRUCTION SITE", CELL)],
]
obs_tbl = Table(obs_data, colWidths=[usable_w*0.20, usable_w*0.80])
obs_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), RED),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [RED_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#D08080")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))

obs_block = [
    Paragraph("<b>3 Sites of Stone Impaction (Exam Favourite)</b>", BODY_B),
    Spacer(1, 3),
    obs_tbl,
]

story.append(two_col(sx_items, obs_block, ratio=(45, 55)))
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5 – DIAGNOSTIC CRITERIA
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5. DIAGNOSTIC CRITERIA & INVESTIGATIONS", PURPLE))
story.append(Spacer(1, 4))

diag_rows = [
    [Paragraph("Investigation", CELL_W), Paragraph("Findings / Purpose", CELL_W), Paragraph("Notes", CELL_W)],
    [Paragraph("Urinalysis", CELL_B),
     Paragraph("Haematuria (90%), crystalluria, pyuria (if infected), urine pH", CELL),
     Paragraph("Essential first step", CELL)],
    [Paragraph("Urine culture", CELL_B),
     Paragraph("Rule out/confirm infection, especially struvite", CELL),
     Paragraph("Alkaline pH + bacteriuria = struvite until proven otherwise", CELL)],
    [Paragraph("24-hr urine (recurrent stones)", CELL_B),
     Paragraph("Calcium, oxalate, uric acid, citrate, phosphate, Na, Cr", CELL),
     Paragraph("Guides prevention therapy", CELL)],
    [Paragraph("Serum BMP/Ca/Uric acid", CELL_B),
     Paragraph("Renal function, hypercalcaemia, hyperuricaemia", CELL),
     Paragraph("Check Cr before contrast", CELL)],
    [Paragraph("PTH", CELL_B),
     Paragraph("If serum Ca elevated β†’ exclude 1Β° hyperparathyroidism", CELL),
     Paragraph("Resorptive hypercalciuria", CELL)],
    [Paragraph("β˜… NCCT (Non-contrast CT) KUB", CELL_B),
     Paragraph("GOLD STANDARD – >95% sensitivity & specificity. Detects all stone types, hydronephrosis, ureteral stranding", CELL),
     Paragraph("Preferred in ED. Visible: ALL stones incl. uric acid", CELL)],
    [Paragraph("KUB X-ray (Plain)", CELL_B),
     Paragraph("Radiopaque stones only (~60% sensitive). Useful for follow-up of known radiopaque stones", CELL),
     Paragraph("MISSES uric acid/indinavir stones", CELL)],
    [Paragraph("Ultrasound", CELL_B),
     Paragraph("Detects hydronephrosis, larger stones >5 mm. Hyperechoic + posterior acoustic shadowing", CELL),
     Paragraph("1st line in PREGNANCY & CHILDREN (no radiation)", CELL)],
    [Paragraph("IVP/IVU", CELL_B),
     Paragraph("Anatomic detail, radiolucent stones visible as filling defects", CELL),
     Paragraph("Largely replaced by NCCT", CELL)],
    [Paragraph("MRI", CELL_B),
     Paragraph("Poor sensitivity for calculi (no MR signal from most stones)", CELL),
     Paragraph("Not standard", CELL)],
]
diag_tbl = Table(diag_rows, colWidths=[usable_w*0.22, usable_w*0.46, usable_w*0.32])
diag_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), PURPLE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [PURPLE_LT, WHITE]),
    # Highlight CT row
    ("BACKGROUND", (0,6), (-1,6), colors.HexColor("#D0B8F5")),
    ("FONTNAME", (0,6), (0,6), "Helvetica-Bold"),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#C0A0E0")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(diag_tbl)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6 – TREATMENT PROTOCOLS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("6. TREATMENT PROTOCOLS", GREEN))
story.append(Spacer(1, 4))

# Treatment algorithm as a highlighted box
algo_data = [
    [Paragraph("SIZE", CELL_W),
     Paragraph("SPONTANEOUS PASSAGE", CELL_W),
     Paragraph("FIRST-LINE APPROACH", CELL_W)],
    [Paragraph("≀ 4 mm", CELL_B),
     Paragraph("~95% pass", CELL),
     Paragraph("Conservative: hydration + NSAIDs + tamsulosin. Wait up to 4 weeks", CELL)],
    [Paragraph("4–6 mm", CELL_B),
     Paragraph("~50% pass", CELL),
     Paragraph("MET with Ξ±-blocker (tamsulosin 0.4 mg). Monitor 4 weeks", CELL)],
    [Paragraph("6–10 mm", CELL_B),
     Paragraph("Unlikely", CELL),
     Paragraph("Plan intervention. MET while waiting; consider ESWL or URS", CELL)],
    [Paragraph("> 10 mm", CELL_B),
     Paragraph("Will not pass", CELL),
     Paragraph("Intervention required (see procedural table)", CELL)],
]
algo_tbl = Table(algo_data, colWidths=[usable_w*0.12, usable_w*0.20, usable_w*0.68])
algo_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREEN),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [GREEN_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#80C090")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(algo_tbl)
story.append(Spacer(1, 4))

# Acute management + Procedural
acute_rows = [
    [Paragraph("Acute Pain Management", CELL_W), Paragraph("", CELL_W)],
    [Paragraph("NSAIDs (ketorolac/ibuprofen)", CELL_B), Paragraph("First-line analgesia (↓ ureteral spasm, superior to opioids)", CELL)],
    [Paragraph("Opioids (morphine)", CELL_B), Paragraph("Rescue analgesia when NSAIDs insufficient", CELL)],
    [Paragraph("Tamsulosin (Ξ±-blocker)", CELL_B), Paragraph("Medical expulsive therapy – relaxes ureteral smooth muscle", CELL)],
    [Paragraph("Anti-emetics (ondansetron)", CELL_B), Paragraph("For nausea/vomiting", CELL)],
    [Paragraph("IV hydration", CELL_B), Paragraph("Dilute urine, encourage passage", CELL)],
]
acute_tbl = Table(acute_rows, colWidths=[usable_w*0.38, usable_w*0.62])
acute_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREEN),
    ("SPAN",       (0,0), (-1,0)),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [GREEN_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#80C090")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))

proc_rows = [
    [Paragraph("Procedure", CELL_W), Paragraph("Indication", CELL_W), Paragraph("Mechanism", CELL_W)],
    [Paragraph("ESWL", CELL_B),
     Paragraph("Stones <2 cm, renal pelvis, upper ureter", CELL),
     Paragraph("External shock waves fragment stone", CELL)],
    [Paragraph("URS + Laser", CELL_B),
     Paragraph("Ureteral stones (any size), failed ESWL", CELL),
     Paragraph("Endoscope + holmium laser lithotripsy", CELL)],
    [Paragraph("PCNL", CELL_B),
     Paragraph("Large stones >2 cm, staghorn calculi", CELL),
     Paragraph("Nephroscope via percutaneous flank access", CELL)],
    [Paragraph("Open/Laparoscopic", CELL_B),
     Paragraph("Complex/rare cases only", CELL),
     Paragraph("Rarely needed today", CELL)],
]
proc_tbl = Table(proc_rows, colWidths=[usable_w*0.15, usable_w*0.45, usable_w*0.40])
proc_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), colors.HexColor("#1B5C30")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [GREEN_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#80C090")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))

story.append(two_col(
    [Paragraph("<b>Acute / Medical Management</b>", BODY_B), Spacer(1,3), acute_tbl],
    [Paragraph("<b>Interventional Procedures</b>", BODY_B), Spacer(1,3), proc_tbl],
    ratio=(45, 55)
))
story.append(Spacer(1, 4))

# Emergency box
emerg_data = [[
    Paragraph("⚠ EMERGENCY INDICATIONS (Immediate Intervention Required):", ALERT),
    Paragraph("β€’ Infected obstructing stone / Urosepsis (most urgent)   "
              "β€’ Bilateral obstruction   "
              "β€’ Solitary kidney obstruction   "
              "β€’ Refractory pain/vomiting   "
              "β€’ Deteriorating renal function",
              style("em2", fontSize=7.8, fontName="Helvetica", textColor=GREY_DARK, leading=11))
]]
emerg_tbl = Table(emerg_data, colWidths=[usable_w])
emerg_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), RED_LT),
    ("BOX",        (0,0), (-1,-1), 1.2, RED),
    ("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(emerg_tbl)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7 – PREVENTION (Stone-specific)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("7. STONE-SPECIFIC PREVENTION", GOLD))
story.append(Spacer(1, 4))

prev_rows = [
    [Paragraph("Stone Type", CELL_W),
     Paragraph("Dietary Measures", CELL_W),
     Paragraph("Medical Therapy", CELL_W)],
    [Paragraph("Calcium Oxalate", CELL_B),
     Paragraph("↑ fluids >2.5 L/day; normal (not low) Ca diet; low oxalate, low Na, low protein", CELL),
     Paragraph("Thiazide diuretics (hypercalciuria); Potassium citrate (hypocitraturia); Pyridoxine (hyperoxaluria)", CELL)],
    [Paragraph("Calcium Phosphate", CELL_B),
     Paragraph("↑ fluids; low Na", CELL),
     Paragraph("Thiazide diuretics; Potassium citrate", CELL)],
    [Paragraph("Uric Acid", CELL_B),
     Paragraph("Low-purine diet (avoid red meat, organ meats, shellfish); ↑ fluids", CELL),
     Paragraph("Potassium citrate (alkalinise urine pH 6–7); Allopurinol (hyperuricosuria)", CELL)],
    [Paragraph("Struvite", CELL_B),
     Paragraph("Adequate hydration; treat UTIs promptly", CELL),
     Paragraph("Antibiotics; Acetohydroxamic acid (urease inhibitor); Surgical stone removal", CELL)],
    [Paragraph("Cystine", CELL_B),
     Paragraph("High fluid intake >3 L/day (most important!); limit Na & protein", CELL),
     Paragraph("Alkalinise urine; D-penicillamine or Tiopronin (chelates cystine)", CELL)],
]
prev_tbl = Table(prev_rows, colWidths=[usable_w*0.17, usable_w*0.42, usable_w*0.41])
prev_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GOLD),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [GOLD_LT, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#D0B000")),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(prev_tbl)
story.append(Spacer(1, 7))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 8 – HIGH-YIELD EXAM FACTS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("8. HIGH-YIELD EXAM FACTS & MNEMONICS", NAVY))
story.append(Spacer(1, 4))

hyfacts_l = [
    [Paragraph("Q", CELL_W), Paragraph("A", CELL_W)],
    [Paragraph("Most common stone?", CELL_B), Paragraph("Calcium oxalate (60%)", CELL)],
    [Paragraph("Only radiolucent stone?", CELL_B), Paragraph("Uric acid (+ indinavir)", CELL)],
    [Paragraph("Staghorn calculus =?", CELL_B), Paragraph("Struvite (infection stone)", CELL)],
    [Paragraph("Stone in alkaline urine?", CELL_B), Paragraph("Struvite, Ca-phosphate", CELL)],
    [Paragraph("Stone in acidic urine?", CELL_B), Paragraph("Uric acid, Ca-oxalate", CELL)],
    [Paragraph("Gold standard imaging?", CELL_B), Paragraph("Non-contrast CT (NCCT)", CELL)],
    [Paragraph("Imaging in pregnancy?", CELL_B), Paragraph("Ultrasound", CELL)],
    [Paragraph("Most common obstruction site?", CELL_B), Paragraph("Ureterovesical junction (UVJ)", CELL)],
    [Paragraph("Key stone inhibitor?", CELL_B), Paragraph("Citrate", CELL)],
    [Paragraph("Urease bacteria #1?", CELL_B), Paragraph("Proteus mirabilis", CELL)],
    [Paragraph("Medical expulsive therapy?", CELL_B), Paragraph("Tamsulosin (Ξ±-blocker)", CELL)],
    [Paragraph("Large stone >2 cm treatment?", CELL_B), Paragraph("PCNL", CELL)],
]
hyfacts_tbl_l = Table(hyfacts_l, colWidths=[usable_w*0.32, usable_w*0.28])
hyfacts_tbl_l.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), NAVY),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, WHITE]),
    ("GRID",       (0,0), (-1,-1), 0.4, colors.HexColor("#BBCDE0")),
    ("TOPPADDING",    (0,0), (-1,-1), 2.5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2.5),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))

# Mnemonics box
mnem_items = [
    Paragraph("<b>MNEMONICS</b>", BODY_B),
    Spacer(1, 4),
    Paragraph("<b>COLA</b> (Cystinuria – amino acids lost)", MNEM),
    Paragraph("Cystine Β· Ornithine Β· Lysine Β· Arginine", SMALL),
    Spacer(1, 4),
    Paragraph("<b>Radiolucent = U</b>nidentified on X-ray = <b>U</b>ric Acid", MNEM),
    Spacer(1, 4),
    Paragraph("<b>STRUVITE</b> bugs = Urease-splitting", MNEM),
    Paragraph("Proteus, Klebsiella, Pseudomonas, Staph saprophyticus", SMALL),
    Spacer(1, 4),
    Paragraph("<b>Crystal shapes (exam key):</b>", BODY_B),
    Paragraph("β€’ Hexagonal β†’ Cystine", SMALL_B),
    Paragraph("β€’ Coffin-lid β†’ Struvite", SMALL),
    Paragraph("β€’ Envelope/bipyramid β†’ CaOx dihydrate", SMALL),
    Paragraph("β€’ Rhomboid/needle β†’ Uric acid", SMALL),
    Spacer(1, 4),
    Paragraph("<b>Complications:</b>", BODY_B),
    Paragraph("Obstruction β†’ Hydronephrosis β†’ Obstructive nephropathy β†’ CKD", SMALL),
    Paragraph("Infected stone + obstruction = UROSEPSIS (surgical emergency)", ALERT),
    Spacer(1, 4),
    Paragraph("<b>Recurrence rate:</b> ~50% within 5–10 yrs without prevention", SMALL),
]

story.append(two_col([hyfacts_tbl_l], mnem_items, ratio=(60, 40)))
story.append(Spacer(1, 8))

# ── FOOTER ────────────────────────────────────────────────────────────────────
story.append(HRFlowable(width=usable_w, thickness=0.8, color=NAVY))
story.append(Spacer(1, 3))
footer_data = [[
    Paragraph("Sources: Goldman-Cecil Medicine 26e | Campbell-Walsh-Wein Urology | "
              "NKF Primer on Kidney Diseases 8e | Robbins Pathologic Basis of Disease",
              style("ft", fontSize=6.8, fontName="Helvetica-Oblique",
                    textColor=GREY_MID, leading=9)),
    Paragraph("Renal Calculi Quick Reference Β· Orris",
              style("ft2", fontSize=6.8, fontName="Helvetica-Bold",
                    textColor=GREY_MID, alignment=TA_RIGHT, leading=9)),
]]
footer_tbl = Table(footer_data, colWidths=[usable_w*0.72, usable_w*0.28])
footer_tbl.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING",   (0,0), (-1,-1), 0),
    ("BOTTOMPADDING",(0,0), (-1,-1), 0),
]))
story.append(footer_tbl)

# ── Build PDF ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=MARGIN,
    rightMargin=MARGIN,
    topMargin=MARGIN,
    bottomMargin=MARGIN,
    title="Renal Calculi Quick Reference Card",
    author="Orris",
    subject="Nephrolithiasis – Classification, Diagnosis, Treatment",
)
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
Running Command

cd /tmp/workspace/renal-calculi && python generate_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/renal-calculi/Renal_Calculi_Quick_Reference.pdf

Your PDF quick reference card is ready!

Renal Calculi Quick Reference

PDF Document Β· PDF


Here's what's packed into the single A4 card:
SectionContent
1. Definition & EpidemiologyMechanism of stone formation, lifetime risk, peak age, key risk factors table
2. Stone ClassificationAll 6 stone types - % occurrence, X-ray opacity, urine pH, crystal shape, key associations in a colour-coded table
3. Causes & Risk Factors3 types of hypercalciuria (absorptive/renal/resorptive) with prevalence, plus hyperoxaluria, hypocitraturia, cystinuria
4. Clinical FeaturesClassic renal colic symptoms + the 3 sites of stone impaction (UPJ, iliac brim, UVJ)
5. Diagnostic CriteriaAll imaging modalities (CT, KUB, US, IVP, MRI) with sensitivity, uses, and limitations; lab investigations
6. Treatment ProtocolsSize-based treatment algorithm (≀4mm to >10mm), acute medical management, procedural options (ESWL/URS/PCNL), emergency indications box
7. Stone-specific PreventionDietary + medical prevention for each stone type
8. High-yield Exam FactsQ&A rapid-fire table + mnemonics (COLA, crystal shapes, complication chain)
This is a shared conversation. Sign in to Orris to start your own chat.