Gastroesophageal reflux disease. Definition, classification, aetiology, pathogenesis, clinical features, positive diagnosis, differential diagnosis, complications, treatment, prevention, prognosis. Barrett oesophagus. Oesophageal Motility Disorders (Oesophageal spasm, Achalasia). The differential diagnosis. Make a note pdf
mkdir -p /tmp/workspace/gerd-notes && ls /tmp/workspace/
~/gerd-notes/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
OUTPUT_PATH = "/tmp/workspace/gerd-notes/GERD_Barrett_Motility_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm,
title="GERD, Barrett Oesophagus & Oesophageal Motility Disorders",
author="Medical Notes"
)
styles = getSampleStyleSheet()
# Custom styles
NAVY = colors.HexColor("#1a237e")
TEAL = colors.HexColor("#006064")
DARK_RED = colors.HexColor("#b71c1c")
LIGHT_BLUE_BG = colors.HexColor("#e3f2fd")
LIGHT_GREEN_BG = colors.HexColor("#e8f5e9")
LIGHT_RED_BG = colors.HexColor("#fce4ec")
LIGHT_YELLOW_BG = colors.HexColor("#fffde7")
LIGHT_GREY_BG = colors.HexColor("#f5f5f5")
title_style = ParagraphStyle(
"NoteTitle", parent=styles["Title"],
fontSize=18, leading=22, textColor=NAVY,
spaceAfter=6, alignment=TA_CENTER, fontName="Helvetica-Bold"
)
subtitle_style = ParagraphStyle(
"Subtitle", parent=styles["Normal"],
fontSize=10, textColor=colors.grey, alignment=TA_CENTER, spaceAfter=14
)
h1_style = ParagraphStyle(
"H1", parent=styles["Heading1"],
fontSize=14, leading=18, textColor=colors.white,
spaceBefore=14, spaceAfter=4, fontName="Helvetica-Bold",
backColor=NAVY, leftIndent=-0.5*cm, rightIndent=-0.5*cm,
borderPad=4
)
h2_style = ParagraphStyle(
"H2", parent=styles["Heading2"],
fontSize=12, leading=15, textColor=TEAL,
spaceBefore=10, spaceAfter=3, fontName="Helvetica-Bold",
borderPad=2
)
h3_style = ParagraphStyle(
"H3", parent=styles["Heading3"],
fontSize=10.5, leading=13, textColor=DARK_RED,
spaceBefore=7, spaceAfter=2, fontName="Helvetica-Bold"
)
body_style = ParagraphStyle(
"Body", parent=styles["Normal"],
fontSize=9.5, leading=13.5, alignment=TA_JUSTIFY,
spaceAfter=5, fontName="Helvetica"
)
bullet_style = ParagraphStyle(
"Bullet", parent=styles["Normal"],
fontSize=9.5, leading=13, leftIndent=14, firstLineIndent=-10,
spaceAfter=3, fontName="Helvetica"
)
bullet2_style = ParagraphStyle(
"Bullet2", parent=styles["Normal"],
fontSize=9.5, leading=13, leftIndent=28, firstLineIndent=-10,
spaceAfter=2, fontName="Helvetica"
)
note_style = ParagraphStyle(
"Note", parent=styles["Normal"],
fontSize=9, leading=12, leftIndent=8, rightIndent=8,
spaceBefore=4, spaceAfter=6, fontName="Helvetica-Oblique",
textColor=colors.HexColor("#4a148c"), backColor=LIGHT_YELLOW_BG,
borderPad=4
)
box_style = ParagraphStyle(
"Box", parent=styles["Normal"],
fontSize=9.5, leading=13, leftIndent=8, rightIndent=8,
spaceBefore=4, spaceAfter=6, fontName="Helvetica",
backColor=LIGHT_BLUE_BG, borderPad=5
)
def H1(text):
return Paragraph(f" {text}", h1_style)
def H2(text):
return Paragraph(text, h2_style)
def H3(text):
return Paragraph(text, h3_style)
def P(text):
return Paragraph(text, body_style)
def B(text, level=1):
bullet_char = "•" if level == 1 else "–"
s = bullet_style if level == 1 else bullet2_style
return Paragraph(f"{bullet_char} {text}", s)
def NOTE(text):
return Paragraph(f"<i>▶ {text}</i>", note_style)
def BOX(text):
return Paragraph(text, box_style)
def HR():
return HRFlowable(width="100%", thickness=0.5, color=colors.lightgrey, spaceAfter=4)
story = []
# ─────────────────────────── COVER ──────────────────────────────
story.append(Spacer(1, 1.5*cm))
story.append(Paragraph("GASTROESOPHAGEAL REFLUX DISEASE", title_style))
story.append(Paragraph("Barrett Oesophagus • Oesophageal Motility Disorders", title_style))
story.append(Paragraph("Differential Diagnosis · Comprehensive Medical Notes", subtitle_style))
story.append(HRFlowable(width="80%", thickness=2, color=NAVY, spaceAfter=8))
story.append(Spacer(1, 0.4*cm))
# Quick Reference Box
toc_data = [
[Paragraph("<b>Contents</b>", ParagraphStyle("toch", fontName="Helvetica-Bold", fontSize=10, textColor=NAVY))],
[Paragraph("1. Gastroesophageal Reflux Disease (GERD)\n — Definition · Classification · Aetiology · Pathogenesis\n — Clinical Features · Positive Diagnosis · Differential Diagnosis\n — Complications · Treatment · Prevention · Prognosis", body_style)],
[Paragraph("2. Barrett Oesophagus\n — Definition · Epidemiology · Pathobiology · Diagnosis · Surveillance · Treatment", body_style)],
[Paragraph("3. Oesophageal Motility Disorders\n — Achalasia: Epidemiology · Pathogenesis · Features · Diagnosis · Treatment\n — Diffuse Oesophageal Spasm (DES): Features · Diagnosis · Treatment", body_style)],
[Paragraph("4. Differential Diagnosis Summary Table", body_style)],
]
toc_table = Table(toc_data, colWidths=[17*cm])
toc_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), LIGHT_BLUE_BG),
("BACKGROUND", (0,1), (-1,-1), LIGHT_GREY_BG),
("BOX", (0,0), (-1,-1), 0.5, NAVY),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
story.append(toc_table)
story.append(Spacer(1, 0.5*cm))
story.append(NOTE("Sources: Goldman-Cecil Medicine; Sleisenger & Fordtran's GI & Liver Disease; Yamada's Gastroenterology; Cummings Otolaryngology; Robbins Pathology; Current Surgical Therapy"))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════
# SECTION 1 — GERD
# ═══════════════════════════════════════════════════════════════
story.append(H1("1. GASTROESOPHAGEAL REFLUX DISEASE (GERD)"))
story.append(Spacer(1, 0.2*cm))
# ── 1.1 Definition ──
story.append(H2("1.1 Definition"))
story.append(P(
"GERD develops when the reflux of stomach contents into the oesophagus causes "
"<b>troublesome symptoms or complications</b> (Montreal Consensus, 2006). It is a "
"chronic disorder characterised by heartburn that occurs when gastric acid or bile "
"reflux passes through the stomach into the oesophagus, inducing inflammation of the "
"oesophageal mucosa."
))
story.append(NOTE("The definition focuses on symptom burden, not merely the presence of reflux, which occurs in healthy individuals as well."))
story.append(Spacer(1, 0.2*cm))
# ── 1.2 Classification ──
story.append(H2("1.2 Classification"))
story.append(H3("By Endoscopic Appearance (Los Angeles Classification)"))
la_data = [
[Paragraph("<b>Grade</b>", body_style), Paragraph("<b>Endoscopic Finding</b>", body_style)],
["A", "One or more mucosal breaks ≤5 mm, not continuous between tops of mucosal folds"],
["B", "One or more mucosal breaks >5 mm, not continuous between tops of folds"],
["C", "Mucosal breaks continuous between tops of ≥2 folds, but involving <75% of circumference"],
["D", "Mucosal breaks involving ≥75% of the oesophageal circumference"],
]
la_table = Table(la_data, colWidths=[2*cm, 15*cm])
la_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_BLUE_BG]),
("BOX", (0,0), (-1,-1), 0.5, TEAL),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
story.append(la_table)
story.append(Spacer(1, 0.2*cm))
story.append(H3("By Phenotype (Montreal Classification)"))
story.append(B("<b>Oesophageal Syndromes:</b>"))
story.append(B("Symptomatic syndromes: (1) typical reflux syndrome, (2) reflux chest pain syndrome", level=2))
story.append(B("Oesophageal injury syndromes: reflux oesophagitis, reflux stricture, Barrett oesophagus, oesophageal adenocarcinoma", level=2))
story.append(B("<b>Extra-oesophageal Syndromes:</b>"))
story.append(B("Established associations: reflux cough, reflux laryngitis, reflux asthma, reflux dental erosions", level=2))
story.append(B("Proposed associations: pharyngitis, sinusitis, idiopathic pulmonary fibrosis, recurrent otitis media", level=2))
story.append(Spacer(1, 0.2*cm))
story.append(H3("By Endoscopic Status"))
story.append(B("ERD (Erosive Reflux Disease): visible mucosal breaks on endoscopy"))
story.append(B("NERD (Non-Erosive Reflux Disease): normal-appearing mucosa with GERD symptoms (~70% of patients)"))
story.append(Spacer(1, 0.3*cm))
# ── 1.3 Aetiology / Risk Factors ──
story.append(H2("1.3 Aetiology & Risk Factors"))
aet_data = [
[Paragraph("<b>Category</b>", body_style), Paragraph("<b>Factors</b>", body_style)],
["Mechanical", "Hiatal hernia (most important structural factor), low LES pressure, transient LES relaxations (tLESRs)"],
["Obesity", "Central/abdominal obesity increases intra-abdominal pressure, reduces LES length, increases gastric acid; OR for GERD = 2.15 (overweight OR 1.43, obese OR 1.94)"],
["Dietary", "Fatty foods, chocolate, carminatives, coffee, alcohol, citrus, spicy foods, large meals"],
["Lifestyle", "Smoking (reduces LES pressure, impairs acid clearance), recumbency after meals"],
["Drugs", "Calcium channel blockers, nitrates, anticholinergics, theophylline, opiates, bisphosphonates"],
["Pregnancy", "Hormonal LES relaxation + increased intra-abdominal pressure"],
["Genetic", "Positive family history; monozygotic > dizygotic twin concordance"],
["Age/Sex", "Prevalence increases with age; central obesity stronger in women (oestrogen effect)"],
["H. pylori", "Inverse association — eradication may worsen GERD in some"],
]
aet_table = Table(aet_data, colWidths=[3.5*cm, 13.5*cm])
aet_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_GREEN_BG]),
("BOX", (0,0), (-1,-1), 0.5, TEAL),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(aet_table)
story.append(Spacer(1, 0.3*cm))
# ── 1.4 Pathogenesis ──
story.append(H2("1.4 Pathogenesis"))
story.append(P(
"The oesophagus is normally protected by: (1) the anti-reflux barrier at the GEJ, "
"(2) oesophageal clearance mechanisms, and (3) epithelial defensive factors. GERD results "
"from disruption of these mechanisms."
))
story.append(H3("Anti-reflux Barrier Failure"))
story.append(B("Lower oesophageal sphincter (LES): normal resting pressure 10–45 mmHg; GERD patients have tLESRs (transient LES relaxations) as the dominant mechanism — vagally mediated reflex triggered by gastric distension"))
story.append(B("Hiatal hernia: separates crural diaphragm from LES, widens GEJ opening, reduces LES pressure, creates a reservoir for acid; associated with larger defects in GERD complicated by Barrett's"))
story.append(B("Acid pocket: unbuffered acid in gastric cardia after meals — larger and more proximally displaced (into hernia sac) in GERD patients"))
story.append(H3("Oesophageal Clearance Failure"))
story.append(B("Two-step acid clearance: volume clearance by peristalsis + neutralisation by alkaline swallowed saliva"))
story.append(B("Impaired peristalsis (e.g. scleroderma, obesity) prolongs acid contact time"))
story.append(H3("Chemical Injury"))
story.append(B("Gastric acid (pH <4) causes direct mucosal injury"))
story.append(B("Bile acids (duodenogastric reflux) act synergistically with acid — particularly important in Barrett's and adenocarcinoma pathogenesis"))
story.append(B("Obesity: increases intragastric pressure, abdominal girth → mechanical compression → increased tLESRs"))
story.append(Spacer(1, 0.3*cm))
# ── 1.5 Clinical Features ──
story.append(H2("1.5 Clinical Features"))
story.append(H3("Typical (Oesophageal) Symptoms"))
story.append(B("<b>Heartburn</b> (pyrosis): retrosternal burning sensation, worst postprandially and on recumbency — the cardinal symptom"))
story.append(B("<b>Regurgitation</b>: effortless return of gastric contents into the mouth/pharynx; often acid or bitter taste"))
story.append(B("<b>Waterbrash</b>: sudden mouth filling with saliva (salivary hypersecretion reflex)"))
story.append(B("<b>Dysphagia</b>: suggests complication (peptic stricture, erosive oesophagitis, motility disorder, cancer)"))
story.append(B("<b>Odynophagia</b>: painful swallowing, suggests severe oesophagitis or ulceration"))
story.append(H3("Atypical / Extra-oesophageal Symptoms"))
story.append(B("Chronic cough (reflux laryngitis/aspiration), hoarseness, globus sensation, throat clearing"))
story.append(B("Non-cardiac chest pain (must exclude cardiac cause first)"))
story.append(B("Asthma exacerbation, sinusitis, recurrent otitis media"))
story.append(B("Dental enamel erosion (palatal surfaces of maxillary teeth, exposed dentin, temperature sensitivity)"))
story.append(H3("Alarm Symptoms (require urgent investigation)"))
story.append(B("<b>Dysphagia, odynophagia</b> — structural lesion/cancer"))
story.append(B("<b>Weight loss, anaemia, GI bleeding</b>"))
story.append(B("<b>Vomiting, early satiety</b>"))
story.append(B("Age >55 with new onset symptoms"))
story.append(Spacer(1, 0.3*cm))
# ── 1.6 Positive Diagnosis ──
story.append(H2("1.6 Positive Diagnosis"))
story.append(H3("Empirical PPI Trial"))
story.append(P(
"In patients with typical symptoms and no alarm features, a <b>therapeutic trial of PPI for 4–8 weeks</b> "
"is the first-line diagnostic approach. Symptom improvement strongly supports GERD diagnosis. "
"Sensitivity ~70–80%, specificity ~55–60%."
))
story.append(H3("Endoscopy (Upper GI Endoscopy / OGD)"))
story.append(B("Indications: alarm symptoms, failure of empirical PPI, suspicion of Barrett's, long-standing GERD"))
story.append(B("Findings: erythema, erosions, ulcers, stricture, Barrett's mucosa (salmon-pink columnar lining)"))
story.append(B("Grades reflux oesophagitis by Los Angeles classification"))
story.append(B("Normal endoscopy does NOT exclude GERD (70% have NERD)"))
story.append(H3("24-Hour Ambulatory pH Monitoring"))
story.append(B("Gold standard for documenting pathological acid exposure"))
story.append(B("DeMeester score >14.72 is abnormal; oesophageal pH <4 for >4.2% of the time is pathological"))
story.append(B("Correlates symptoms with reflux episodes (symptom index)"))
story.append(H3("pH-Impedance Monitoring"))
story.append(B("Detects both acid and non-acid (weakly acidic, alkaline) reflux"))
story.append(B("Useful in patients on PPI therapy with persistent symptoms"))
story.append(H3("Oesophageal Manometry"))
story.append(B("Measures LES pressure and oesophageal peristalsis"))
story.append(B("Used to exclude motility disorders before anti-reflux surgery; not diagnostic of GERD itself"))
story.append(H3("Barium Swallow"))
story.append(B("Demonstrates hiatal hernia, stricture, mucosal irregularity"))
story.append(B("Low sensitivity for mild GERD; not first-line"))
story.append(Spacer(1, 0.3*cm))
# ── 1.7 Differential Diagnosis ──
story.append(H2("1.7 Differential Diagnosis"))
dd_data = [
[Paragraph("<b>Condition</b>", body_style), Paragraph("<b>Distinguishing Features</b>", body_style)],
["Peptic ulcer disease", "Epigastric pain, food-pain relationship; endoscopy/H. pylori testing"],
["Non-cardiac chest pain / IHD", "Exercise-related, ECG changes, troponin; cardiac evaluation essential"],
["Achalasia", "Dysphagia to solids AND liquids, regurgitation of undigested food, bird-beak on barium; manometry"],
["Diffuse oesophageal spasm", "Intermittent chest pain + dysphagia, corkscrew on barium; manometry"],
["Oesophageal cancer", "Progressive dysphagia, weight loss, alarm features; endoscopy + biopsy"],
["Eosinophilic oesophagitis", "Young male, atopy, dysphagia to solids; endoscopy shows rings/furrows; biopsy ≥15 eos/HPF"],
["Functional heartburn", "Symptoms without acid exposure on pH monitoring; no response to PPI"],
["Gastroparesis", "Nausea, vomiting, early satiety, postprandial fullness; gastric emptying study"],
["Bile reflux gastritis", "Bilious vomiting, endoscopy shows bile in stomach; typically post-gastrectomy"],
["Rumination syndrome", "Effortless regurgitation/rechewing shortly after meals; pH-impedance studies"],
]
dd_table = Table(dd_data, colWidths=[4.5*cm, 12.5*cm])
dd_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_RED),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_RED_BG]),
("BOX", (0,0), (-1,-1), 0.5, DARK_RED),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(dd_table)
story.append(Spacer(1, 0.3*cm))
# ── 1.8 Complications ──
story.append(H2("1.8 Complications"))
story.append(B("<b>Reflux oesophagitis:</b> mucosal erosions, ulceration — most common"))
story.append(B("<b>Peptic stricture:</b> fibrotic narrowing of distal oesophagus → progressive dysphagia to solids"))
story.append(B("<b>Barrett's oesophagus:</b> columnar metaplasia of squamous oesophageal epithelium → risk of adenocarcinoma"))
story.append(B("<b>Oesophageal adenocarcinoma:</b> risk 0.12%/year in Barrett's; rising incidence linked to obesity"))
story.append(B("<b>Oesophageal ulceration and haemorrhage:</b> can cause iron-deficiency anaemia"))
story.append(B("<b>Extra-oesophageal:</b> dental erosions, laryngitis, chronic cough, asthma exacerbation, aspiration pneumonia"))
story.append(Spacer(1, 0.3*cm))
# ── 1.9 Treatment ──
story.append(H2("1.9 Treatment"))
story.append(H3("Step 1 — Lifestyle & Non-Pharmacological Measures"))
story.append(B("Elevate head of bed 6–8 inches (most evidence-based lifestyle measure)"))
story.append(B("Weight loss if overweight (reduces reflux by decreasing abdominal pressure)"))
story.append(B("Avoid late meals; refrain from lying down 2–3 hours after eating"))
story.append(B("Smoking cessation and alcohol reduction (both lower LES pressure, impair acid clearance)"))
story.append(B("Reduce meal size; avoid fatty foods, chocolate, carminatives, citrus, spicy foods"))
story.append(B("Left lateral decubitus sleep position"))
story.append(B("Avoid drugs that lower LES pressure (calcium channel blockers, nitrates, theophylline)"))
story.append(NOTE("Evidence: only head-of-bed elevation, left lateral positioning, and weight loss have robust evidence in controlled studies."))
story.append(H3("Step 2 — Antacids / Over-the-Counter (mild, infrequent symptoms)"))
story.append(B("Antacids (aluminium/magnesium hydroxide): buffer gastric acid rapidly but transiently; useful for immediate relief"))
story.append(B("Alginate-antacid combinations: form a raft on gastric contents, reduces postprandial reflux"))
story.append(B("H2-receptor antagonists (OTC): ranitidine, famotidine — moderate acid suppression, tolerance develops"))
story.append(H3("Step 3 — Proton Pump Inhibitors (PPIs) — Mainstay of Medical Therapy"))
story.append(B("Most effective therapy: omeprazole 20 mg, pantoprazole 40 mg, esomeprazole 40 mg, lansoprazole 30 mg — once daily 30 minutes before breakfast"))
story.append(B("Heal erosive oesophagitis in 80–90% at 8 weeks (superior to H2 blockers)"))
story.append(B("For maintenance: continue at lowest effective dose; step-down or on-demand therapy for NERD"))
story.append(B("In erosive oesophagitis (grade C/D) or Barrett's: long-term PPI recommended"))
story.append(NOTE("Risks of long-term PPI: hypomagnesaemia, C. difficile, small risk of hip fracture, SIBO; reassess regularly."))
story.append(H3("Step 4 — Add-On / Adjunctive Therapy"))
story.append(B("Prokinetics (metoclopramide, domperidone): improve LES tone and gastric emptying; limited evidence, side effects"))
story.append(B("Baclofen (GABA-B agonist): reduces tLESRs; useful in refractory GERD; limited tolerability"))
story.append(B("Antidepressants (low-dose TCAs): reduce oesophageal hypersensitivity in functional heartburn/NERD"))
story.append(H3("Step 5 — Surgical / Endoscopic Anti-Reflux Therapy"))
story.append(B("<b>Laparoscopic Nissen fundoplication:</b> 360° fundal wrap around LES — gold standard surgical procedure; effective long-term but causes dysphagia/gas bloat"))
story.append(B("<b>Partial fundoplication (Toupet/Dor):</b> fewer side effects, preferred in patients with impaired peristalsis"))
story.append(B("<b>LINX system:</b> magnetic bead bracelet placed around LES laparoscopically"))
story.append(B("<b>Transoral incisionless fundoplication (TIF):</b> endoscopic option"))
story.append(B("Indications: PPI failure/dependence, patient preference, significant regurgitation unresponsive to PPI"))
story.append(Spacer(1, 0.3*cm))
# ── 1.10 Prevention ──
story.append(H2("1.10 Prevention"))
story.append(B("Weight management: primary prevention — obesity correction reduces incidence and severity"))
story.append(B("Dietary modifications: reduce known trigger foods, smaller meals, avoid late-night eating"))
story.append(B("Smoking cessation"))
story.append(B("Avoidance of drugs that lower LES pressure where possible"))
story.append(B("Regular aerobic exercise (associated with reduced GERD risk)"))
story.append(B("H. pylori screening: eradication may not prevent GERD but avoids ulcer complications"))
story.append(Spacer(1, 0.3*cm))
# ── 1.11 Prognosis ──
story.append(H2("1.11 Prognosis"))
story.append(P(
"GERD is a <b>chronic, relapsing condition</b>. Most patients require ongoing maintenance therapy. "
"Without treatment, symptoms recur in 80% within 6 months. With adequate PPI therapy, oesophagitis "
"heals in 80–90% and symptoms are controlled in the majority. The main long-term concern is progression "
"to Barrett's oesophagus (~5–15% of GERD patients undergoing endoscopy) and, in a small proportion, "
"oesophageal adenocarcinoma. Annual cancer risk in Barrett's without dysplasia is approximately 0.12–0.33%. "
"Anti-reflux surgery provides long-term symptom control in approximately 85–90% of appropriately selected patients."
))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════
# SECTION 2 — BARRETT OESOPHAGUS
# ═══════════════════════════════════════════════════════════════
story.append(H1("2. BARRETT OESOPHAGUS"))
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.1 Definition"))
story.append(P(
"Barrett oesophagus is an <b>acquired metaplastic condition</b> in which the normal stratified squamous "
"epithelium of the distal oesophagus is replaced by <b>specialised intestinal columnar epithelium</b> "
"(intestinal metaplasia with goblet cells). It is the most significant complication of chronic GERD "
"and is a recognised precursor to oesophageal adenocarcinoma."
))
story.append(B("<b>Diagnostic criteria (endoscopic + histological):</b>"))
story.append(B("Squamocolumnar junction displaced ≥1 cm proximal to the gastroesophageal junction (GEJ)", level=2))
story.append(B("Biopsy demonstrates intestinal metaplasia (goblet cells — identified by H&E or accentuated with alcian blue stain)", level=2))
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.2 Classification by Segment Length"))
seg_data = [
[Paragraph("<b>Type</b>", body_style), Paragraph("<b>Length</b>", body_style), Paragraph("<b>Clinical Significance</b>", body_style)],
["Short-segment Barrett's (SSBE)", "<3 cm above GEJ", "Lower but real cancer risk; surveillance needed"],
["Long-segment Barrett's (LSBE)", "≥3 cm above GEJ", "Higher risk of dysplasia and adenocarcinoma"],
]
seg_table = Table(seg_data, colWidths=[5*cm, 4*cm, 8*cm])
seg_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_GREEN_BG]),
("BOX", (0,0), (-1,-1), 0.5, TEAL),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(seg_table)
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.3 Epidemiology"))
story.append(B("Found in 5–15% of GERD patients undergoing endoscopy; population prevalence ~1.3–1.6%"))
story.append(B("~45% of patients with Barrett's have no reflux symptoms"))
story.append(B("Predominantly middle-aged White men; ~25% women or <50 years"))
story.append(B("Prevalence plateaus between 7th and 9th decades"))
story.append(B("<b>Risk factors:</b> frequent/long-standing GERD, smoking, male sex, older age, central obesity (independent risk factor even after adjusting for BMI/GERD), white race"))
story.append(B("Obesity (BMI >30): OR 4.0 for Barrett's; abdominal adiposity particularly important (linked to adipokines — increased leptin, decreased adiponectin)"))
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.4 Pathobiology"))
story.append(P(
"Barrett's results from severe oesophageal mucosal injury. Patients typically have greater acid AND bile "
"exposure (on pH monitoring) and almost always have a hiatal hernia. The cell of origin of columnar "
"metaplasia is debated: candidates include dedifferentiation of squamous epithelium, stem cells from the "
"basal layer, oesophageal submucosal glands, gastric cardia, residual embryonal stem cells, or bone marrow."
))
story.append(B("<b>CDX2 transcription factor:</b> induced by acid and bile salts — promotes columnar epithelium in the distal oesophagus"))
story.append(B("<b>Dysplasia grading:</b> Non-dysplastic → Low-grade dysplasia (LGD) → High-grade dysplasia (HGD) → Adenocarcinoma"))
story.append(B("Annual progression rate: non-dysplastic Barrett's ~0.12–0.33%/year to cancer; HGD ~6–7%/year"))
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.5 Clinical Manifestations"))
story.append(P(
"Barrett's patients are clinically difficult to distinguish from uncomplicated GERD patients. Features "
"suggesting higher risk include:"
))
story.append(B("GERD onset at younger age with longer duration"))
story.append(B("Increased severity of nocturnal reflux symptoms"))
story.append(B("Prior GERD complications (oesophagitis, ulceration, stricture, bleeding)"))
story.append(NOTE("Paradoxically, patients with Barrett's may have IMPAIRED oesophageal acid sensitivity and even lack GERD symptoms — hence the importance of screening programmes."))
story.append(H2("2.6 Diagnosis"))
story.append(B("<b>Endoscopic appearance:</b> salmon-pink columnar mucosa replacing pale squamous mucosa; squamocolumnar junction displaced proximal to GEJ"))
story.append(B("Prague C&M classification: C = circumferential extent, M = maximal extent of columnar epithelium"))
story.append(B("<b>Biopsy:</b> confirms intestinal metaplasia — goblet cells (H&E or alcian blue stain) — mandatory for diagnosis"))
story.append(B("<b>Seattle protocol:</b> 4-quadrant biopsies every 2 cm; targeted biopsies of any visible lesions"))
story.append(B("<b>Advanced imaging:</b> NBI (narrow band imaging), chromoendoscopy, confocal laser endomicroscopy to detect dysplasia"))
story.append(Spacer(1, 0.2*cm))
story.append(H2("2.7 Surveillance & Treatment"))
story.append(H3("Surveillance Endoscopy Intervals"))
surv_data = [
[Paragraph("<b>Finding</b>", body_style), Paragraph("<b>Recommended Interval</b>", body_style)],
["Non-dysplastic Barrett's (SSBE)", "Every 3–5 years"],
["Non-dysplastic Barrett's (LSBE)", "Every 2–3 years"],
["Low-grade dysplasia (confirmed)", "Every 6–12 months OR endoscopic therapy"],
["High-grade dysplasia", "Endoscopic eradication therapy recommended"],
]
surv_table = Table(surv_data, colWidths=[8*cm, 9*cm])
surv_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_RED),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_RED_BG]),
("BOX", (0,0), (-1,-1), 0.5, DARK_RED),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(surv_table)
story.append(Spacer(1, 0.2*cm))
story.append(H3("Medical Treatment"))
story.append(B("<b>PPI therapy:</b> recommended for all Barrett's patients — controls symptoms, heals oesophagitis, may reduce cancer risk (though evidence is indirect)"))
story.append(B("<b>Aspirin/NSAIDs:</b> observational data suggest chemopreventive effect; not yet standard"))
story.append(B("Lifestyle: as for GERD; weight loss particularly important given obesity-Barrett's link"))
story.append(H3("Endoscopic Eradication Therapy (EET)"))
story.append(B("<b>Radiofrequency ablation (RFA):</b> first-line for flat dysplasia; eradicates Barrett's epithelium; success rate ~80–90%"))
story.append(B("<b>Endoscopic mucosal resection (EMR):</b> for nodular/raised lesions; allows histological staging"))
story.append(B("<b>Endoscopic submucosal dissection (ESD):</b> en bloc resection of larger lesions"))
story.append(B("<b>Photodynamic therapy (PDT):</b> older modality, largely replaced by RFA"))
story.append(H3("Surgical Treatment"))
story.append(B("Oesophagectomy: for HGD with multifocal disease, or T1 adenocarcinoma with submucosal invasion beyond EET capability; or failed endoscopic treatment"))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════
# SECTION 3 — OESOPHAGEAL MOTILITY DISORDERS
# ═══════════════════════════════════════════════════════════════
story.append(H1("3. OESOPHAGEAL MOTILITY DISORDERS"))
story.append(Spacer(1, 0.2*cm))
# ── 3.1 Overview ──
story.append(H2("3.1 Classification Overview"))
mot_overview_data = [
[Paragraph("<b>Disorder</b>", body_style), Paragraph("<b>Key Manometric Finding</b>", body_style), Paragraph("<b>Chicago Classification v4.0</b>", body_style)],
["Achalasia Type I (Classic)", "Aperistalsis + no IRP relaxation; no oesophageal pressurisation", "IRP >15 mmHg, no peristalsis, no pressurisation"],
["Achalasia Type II (w/ compression)", "Aperistalsis + panesophageal pressurisation ≥20%", "IRP >15 mmHg, pan-oesophageal pressurisation"],
["Achalasia Type III (Spastic)", "Premature/spastic contractions + failed LES relaxation", "IRP >15 mmHg, ≥20% premature contractions"],
["Diffuse Oesophageal Spasm (DES)", "Premature contractions ≥20% swallows; normal IRP", "IRP normal; ≥20% premature contractions; DL <4.5 s"],
["Jackhammer Oesophagus", "Hypercontractile peristalsis (DCI >8000)", "At least one swallow with DCI >8000 mmHg·s·cm"],
["EGJ Outflow Obstruction", "Elevated IRP with preserved peristalsis", "IRP >15 mmHg; preserved peristalsis"],
["Absent Peristalsis", "100% failed peristalsis; normal IRP", "No effective contractions; IRP normal"],
]
mot_table = Table(mot_overview_data, colWidths=[4.5*cm, 6.5*cm, 6*cm])
mot_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_BLUE_BG]),
("BOX", (0,0), (-1,-1), 0.5, NAVY),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mot_table)
story.append(Spacer(1, 0.3*cm))
# ── 3.2 ACHALASIA ──
story.append(H2("3.2 ACHALASIA"))
story.append(H3("Definition"))
story.append(P(
"Achalasia is the <b>prototypic oesophageal motility disorder</b>, characterised by "
"<b>impaired LES relaxation</b> (insufficient relaxation with swallowing) combined with "
"<b>aperistalsis</b> in the smooth muscle oesophagus. If there are premature spastic contractions, "
"the condition is referred to as <b>spastic (Type III) achalasia</b>."
))
story.append(H3("Epidemiology"))
story.append(B("Prevalence: 10 per 100,000 in the United States; equal sex distribution"))
story.append(B("Most common presentation: ages 30–60 years; can occur in infants to nonagenarians"))
story.append(B("All races affected equally"))
story.append(H3("Pathogenesis"))
story.append(P(
"Neuropathology: loss of ganglion cells in the myenteric (Auerbach) plexus within the smooth muscle "
"segment of the oesophagus (including LES). The degree of ganglion cell loss parallels disease duration."
))
story.append(B("<b>Inhibitory neuron dysfunction:</b> selective deficiency of inhibitory neurotransmitters — particularly <b>nitric oxide (NO)</b> and VIP — in the LES. These neurons mediate deglutitive LES relaxation; their loss → failure of LES to relax"))
story.append(B("<b>Autoimmune hypothesis:</b> cytotoxic T-cell infiltration of myenteric plexus; anti-myenteric neuron antibodies; association with specific HLA alleles"))
story.append(B("<b>Viral trigger:</b> HSV-1 detected in LES tissue; suspected as trigger for autoimmune response in genetically susceptible individuals"))
story.append(B("<b>CCK paradox:</b> normally CCK stimulates inhibitory neurons → reduces LES pressure; in achalasia CCK paradoxically INCREASES LES pressure"))
story.append(B("<b>Disease progression:</b> EGJ outflow obstruction → Type II → Type I → end-stage (dilated sigmoid oesophagus)"))
story.append(B("<b>Secondary (Pseudoachalasia):</b> gastric/oesophageal cancer infiltrating LES, paraneoplastic (anti-Hu antibodies in small cell lung cancer), Chagas disease (T. cruzi), sarcoidosis, amyloidosis"))
story.append(H3("Clinical Features"))
story.append(B("<b>Dysphagia</b> (cardinal symptom): to BOTH solids AND liquids from the outset — key differentiator from mechanical obstruction (which is initially solids only)"))
story.append(B("<b>Regurgitation:</b> of undigested, non-acidic food/saliva (stasis in oesophagus)"))
story.append(B("<b>Chest pain:</b> particularly in Type III/spastic achalasia"))
story.append(B("<b>Heartburn:</b> caused by oesophageal stasis of fermented food content (not acid reflux)"))
story.append(B("<b>Weight loss</b>"))
story.append(B("<b>Aspiration pneumonia/cough:</b> from nocturnal regurgitation of oesophageal contents"))
story.append(B("<b>Nocturnal cough and respiratory symptoms</b>"))
story.append(NOTE("Diagnosis is often delayed because heartburn leads to misdiagnosis as GERD."))
story.append(H3("Diagnosis"))
story.append(B("<b>Oesophageal manometry (HRM — High-Resolution Manometry):</b> GOLD STANDARD"))
story.append(B("Elevated LES residual pressure (IRP >15 mmHg) + aperistalsis (Type I), or pan-oesophageal pressurisation (Type II), or premature contractions (Type III)", level=2))
story.append(B("<b>Barium swallow (oesophagram):</b> dilated oesophagus with stasis of barium, 'bird's-beak' (smooth tapered narrowing at GEJ); 'sigmoid oesophagus' in advanced disease"))
story.append(B("<b>Endoscopy (OGD):</b> mandatory to EXCLUDE secondary causes (cancer, pseudoachalasia); 'puckered' GEJ with resistance to passage; retained food"))
story.append(B("<b>Chest X-ray:</b> widened mediastinum, air-fluid level, absent gastric bubble"))
story.append(B("<b>CT chest/abdomen:</b> to exclude extrinsic malignancy when pseudoachalasia suspected"))
story.append(B("<b>Timed barium swallow:</b> measures oesophageal emptying; used to monitor response to treatment"))
story.append(H3("Treatment"))
story.append(P("Since neuropathology cannot be reversed, treatment aims to reduce LES obstruction and improve oesophageal emptying."))
treat_ach_data = [
[Paragraph("<b>Treatment</b>", body_style), Paragraph("<b>Details & Efficacy</b>", body_style)],
["Botulinum toxin injection", "Endoscopic injection into LES; blocks cholinergic transmission; 90% initial response; recurs in 6–24 months; for high-risk patients or diagnostic confirmation"],
["Pharmacologic (temporary)", "Nitrates (sublingual nitroglycerine) or calcium channel blockers (nifedipine 10–30 mg) before meals — reduce LES pressure by ~50%; inconsistent, short-lived"],
["Pneumatic dilation (PD)", "30–40 mm balloon inflated at LES; tears muscle fibres; 70% remission at 5 years with 1 dilation; preferred for Type II (100% efficacy); risk of perforation ~1%"],
["Laparoscopic Heller myotomy (LHM)", "Surgical division of LES muscle (+ partial fundoplication); ~90% success; preferred for Type III; durable long-term; risk of GERD post-op"],
["POEM (Per-Oral Endoscopic Myotomy)", "Endoscopic tunnel technique; highly effective, especially Type III (92%); DES (88%); comparable to surgery; increasing use as first-line"],
["Oesophagectomy", "End-stage achalasia with sigmoid oesophagus; failed all other treatments"],
]
treat_ach_table = Table(treat_ach_data, colWidths=[4.5*cm, 12.5*cm])
treat_ach_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_BLUE_BG]),
("BOX", (0,0), (-1,-1), 0.5, NAVY),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(treat_ach_table)
story.append(NOTE("European RCT: Pneumatic dilation ~90% effective vs. Heller myotomy ~90%, no statistically significant difference overall. For Type II: PD 100% vs. myotomy 93%. For Type III: myotomy preferred."))
story.append(Spacer(1, 0.3*cm))
# ── 3.3 DES ──
story.append(H2("3.3 DIFFUSE OESOPHAGEAL SPASM (DES)"))
story.append(H3("Definition & Epidemiology"))
story.append(P(
"DES is characterised by <b>simultaneous, non-propulsive, high-amplitude oesophageal contractions</b> "
"occurring in the context of intermittent <b>normal peristalsis</b>. It is found in fewer than 5% of "
"patients undergoing manometry for chest pain or dysphagia."
))
story.append(H3("Pathogenesis"))
story.append(B("Deficiency of <b>nitric oxide (NO)</b> in the oesophageal body → loss of timed inhibitory control of peristalsis"))
story.append(B("Results in rapid (premature) propagation of contractions → simultaneous contractions in ≥20% of swallows"))
story.append(B("Distinct from achalasia: LES relaxation is NORMAL (IRP is normal)"))
story.append(H3("Clinical Features"))
story.append(B("<b>Intermittent chest pain:</b> often severe, can mimic angina; may be triggered by eating or emotional stress"))
story.append(B("<b>Dysphagia:</b> intermittent, to both solids and liquids"))
story.append(B("Symptoms may coexist with GERD (reflux triggers spasm)"))
story.append(B("Often associated with anxiety/psychological distress"))
story.append(H3("Diagnosis"))
story.append(B("<b>Manometry (HRM):</b> GOLD STANDARD — premature (simultaneous) contractions in ≥20% of swallows (distal latency <4.5 s); normal IRP"))
story.append(B("<b>Barium swallow:</b> 'corkscrew oesophagus' — multiple simultaneous contractions obliterating the lumen (pathognomonic but not always present)"))
story.append(B("<b>Endoscopy:</b> usually normal; EUS may show thickening of circular/longitudinal muscle layers"))
story.append(B("<b>Provocation tests:</b> edrophonium, ergonovine — can provoke chest pain and reproduce abnormal contractions (rarely used clinically)"))
story.append(H3("Treatment"))
story.append(B("Reassurance: benign condition, not life-threatening — crucial first step"))
story.append(B("<b>Smooth muscle relaxants:</b>"))
story.append(B("Sublingual nitroglycerine 0.3 mg OR hyoscyamine 0.125 mg sublingually", level=2))
story.append(B("Nifedipine 10 mg sublingual or diltiazem — calcium channel blockers", level=2))
story.append(B("Sildenafil 50 mg orally — potent relaxation of smooth muscle", level=2))
story.append(B("<b>PPIs:</b> if coexistent GERD (reflux triggers spasm — PPIs improve symptoms in ~50%)"))
story.append(B("<b>Low-dose tricyclic antidepressants</b> (imipramine 10–50 mg nightly): reduces visceral pain perception + anticholinergic effect"))
story.append(B("<b>Botulinum toxin injection:</b> into oesophageal body; 50% response in RCT vs. 10% placebo; moderate evidence"))
story.append(B("<b>POEM (extended myotomy):</b> for refractory DES with clear manometric diagnosis; pooled response rate ~88%; myotomy extends along full smooth muscle segment"))
story.append(B("Surgery: rarely indicated; thoracoscopic long myotomy for refractory cases; POEM largely replaced this"))
story.append(NOTE("Most cases of oesophageal chest pain are due to GERD, not DES — PPIs should be tried first."))
story.append(Spacer(1, 0.3*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════
# SECTION 4 — DIFFERENTIAL DIAGNOSIS SUMMARY
# ═══════════════════════════════════════════════════════════════
story.append(H1("4. DIFFERENTIAL DIAGNOSIS — SUMMARY TABLE"))
story.append(Spacer(1, 0.2*cm))
story.append(P("Key differentiating features between GERD, Barrett's, Achalasia, and Diffuse Oesophageal Spasm:"))
story.append(Spacer(1, 0.15*cm))
diff_data = [
[
Paragraph("<b>Feature</b>", body_style),
Paragraph("<b>GERD</b>", body_style),
Paragraph("<b>Achalasia</b>", body_style),
Paragraph("<b>DES</b>", body_style),
Paragraph("<b>Barrett's</b>", body_style),
],
["Main symptom", "Heartburn, regurgitation", "Dysphagia (solids + liquids)", "Intermittent chest pain ± dysphagia", "Often asymptomatic; GERD symptoms"],
["Dysphagia type", "Solids (if stricture)", "Solids AND liquids from onset", "Intermittent, both", "Solids (if stricture/cancer)"],
["Regurgitation", "Acidic, digested food", "Undigested food, non-acidic", "Uncommon", "Acidic (if GERD present)"],
["Weight loss", "Uncommon", "Common", "Uncommon", "With cancer"],
["Chest pain", "Burning, retrosternal", "Present in Type III", "Severe, intermittent, angina-like", "Uncommon"],
["Onset of dysphagia", "Progresses slowly (mechanical)", "Solids AND liquids from start", "Intermittent", "Progressive (late stage)"],
["Barium swallow", "Hiatal hernia, reflux", "Bird-beak, dilated oesophagus", "Corkscrew oesophagus", "Normal or stricture"],
["Manometry", "Low LES pressure / normal", "Elevated IRP, aperistalsis", "Normal IRP, ≥20% premature contractions", "Usually normal"],
["Endoscopy", "Oesophagitis / normal (NERD)", "Retained food, puckered LES", "Usually normal", "Salmon-pink columnar mucosa"],
["Key test", "24h pH monitoring / PPI trial", "HRM manometry + barium", "HRM manometry", "OGD + biopsy (goblet cells)"],
["Treatment", "PPI, lifestyle, fundoplication", "PD / POEM / Heller myotomy", "Nitrates, CCBs, POEM", "PPI + endoscopic ablation (RFA/EMR)"],
["Cancer risk", "Low (via Barrett's progression)", "Low (squamous cell ca. long-term)", "None", "0.12–0.33%/yr adenocarcinoma"],
]
diff_table = Table(diff_data, colWidths=[3.5*cm, 3.3*cm, 3.3*cm, 3.3*cm, 3.6*cm])
diff_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, LIGHT_BLUE_BG]),
("BOX", (0,0), (-1,-1), 0.5, NAVY),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "TOP"),
# Highlight the 'Feature' column
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("BACKGROUND", (0,1), (0,-1), colors.HexColor("#e8eaf6")),
]))
story.append(diff_table)
story.append(Spacer(1, 0.3*cm))
# Additional key differentiators
story.append(H2("Key Clinical Pearls for Differential Diagnosis"))
story.append(B("<b>GERD vs. Achalasia:</b> In GERD, dysphagia (if present) is to solids only and implies a complication (stricture). In achalasia, dysphagia is to BOTH solids and liquids from the onset. Regurgitated food in achalasia is undigested and non-acidic; in GERD it is acidic."))
story.append(B("<b>GERD vs. DES:</b> Both cause chest pain. DES pain is more severe, intermittent, and often precipitated by swallowing; GERD pain is burning, postprandial, positional. The 'corkscrew' on barium and premature contractions on manometry clinch DES."))
story.append(B("<b>Achalasia vs. DES:</b> Both cause dysphagia and chest pain. Key difference: LES relaxation is ABNORMAL in achalasia (elevated IRP) but NORMAL in DES. DES may respond to smooth muscle relaxants; achalasia requires LES disruption."))
story.append(B("<b>Barrett's vs. GERD:</b> Barrett's is a complication of GERD. Clinically indistinguishable without endoscopy + biopsy. Paradoxically, Barrett's patients may have LESS heartburn (reduced acid sensitivity of metaplastic epithelium)."))
story.append(B("<b>Pseudoachalasia vs. Primary Achalasia:</b> Short history (<1 year), age >60, rapid weight loss, visible tumour → suspect pseudoachalasia (cancer). EUS and CT chest/abdomen essential."))
story.append(B("<b>Non-cardiac chest pain:</b> Always exclude cardiac ischaemia FIRST (ECG, troponin, stress test) before attributing chest pain to GERD or DES."))
story.append(B("<b>Eosinophilic oesophagitis (EoE) vs. GERD:</b> Young male, atopy history, food impaction/dysphagia, endoscopic rings, furrows, white exudates; biopsy ≥15 eosinophils/HPF; PPI-refractory."))
story.append(Spacer(1, 0.3*cm))
# Footer note
story.append(HR())
story.append(Paragraph(
"<i>References: Goldman-Cecil Medicine (2024); Sleisenger & Fordtran's Gastrointestinal and Liver Disease; "
"Yamada's Textbook of Gastroenterology 7th ed.; Cummings Otolaryngology; Robbins Pathology; "
"Current Surgical Therapy 14th ed. | Generated: July 2026</i>",
ParagraphStyle("footer", parent=styles["Normal"], fontSize=7.5, textColor=colors.grey, alignment=TA_CENTER)
))
# ── Build ──
doc.build(story)
print(f"PDF saved to: {OUTPUT_PATH}")
cd /tmp/workspace/gerd-notes && python generate_pdf.py
ls -lh /tmp/workspace/gerd-notes/GERD_Barrett_Motility_Notes.pdf
GERD Barrett Motility Notes
PDF Document · PDF
Small intestine pathology. Malabsorption syndrome. Definition, classification, aetiology, clinical feature, positive diagnosis. Diarrhea, definition, classification, aetiology, pathogenesis, clinical feature, positive and differential diagnosis, treatment, prevention, prognosis. Gluten enteropathy. Definition, classification, aetiology, pathogenesis, clinical feature, diagnosis, treatment, prevention, prognosis. Make a pdf note for studying for university and for fmge exams ,usmle exam
mkdir -p /tmp/workspace/si-notes && ls /tmp/workspace/
~/si-notes/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
OUTPUT_PATH = "/tmp/workspace/si-notes/SmallIntestine_Malabsorption_Diarrhea_Celiac.pdf"
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm,
title="Small Intestine Pathology – Malabsorption, Diarrhoea, Gluten Enteropathy",
author="Medical Notes | FMGE/USMLE/University Study"
)
styles = getSampleStyleSheet()
# Palette
NAVY = colors.HexColor("#1a237e")
TEAL = colors.HexColor("#00695c")
DARK_RED= colors.HexColor("#b71c1c")
PURPLE = colors.HexColor("#4a148c")
ORANGE = colors.HexColor("#e65100")
LB = colors.HexColor("#e3f2fd") # light blue bg
LG = colors.HexColor("#e8f5e9") # light green bg
LR = colors.HexColor("#fce4ec") # light red bg
LY = colors.HexColor("#fffde7") # light yellow
LP = colors.HexColor("#f3e5f5") # light purple
LO = colors.HexColor("#fff3e0") # light orange
LGREY = colors.HexColor("#f5f5f5")
title_style = ParagraphStyle("NT", parent=styles["Title"], fontSize=17, leading=22,
textColor=NAVY, spaceAfter=4, alignment=TA_CENTER, fontName="Helvetica-Bold")
subtitle_style = ParagraphStyle("NS", parent=styles["Normal"], fontSize=9.5,
textColor=colors.grey, alignment=TA_CENTER, spaceAfter=12)
h1_style = ParagraphStyle("H1", parent=styles["Heading1"], fontSize=13, leading=17,
textColor=colors.white, spaceBefore=12, spaceAfter=4, fontName="Helvetica-Bold",
backColor=NAVY, borderPad=5)
h2_style = ParagraphStyle("H2", parent=styles["Heading2"], fontSize=11.5, leading=14,
textColor=TEAL, spaceBefore=9, spaceAfter=3, fontName="Helvetica-Bold")
h3_style = ParagraphStyle("H3", parent=styles["Heading3"], fontSize=10.5, leading=13,
textColor=DARK_RED, spaceBefore=6, spaceAfter=2, fontName="Helvetica-Bold")
body_style = ParagraphStyle("Body", parent=styles["Normal"], fontSize=9.5, leading=13.5,
alignment=TA_JUSTIFY, spaceAfter=4, fontName="Helvetica")
bullet_style = ParagraphStyle("Bul", parent=styles["Normal"], fontSize=9.5, leading=13,
leftIndent=14, firstLineIndent=-10, spaceAfter=3, fontName="Helvetica")
bullet2_style = ParagraphStyle("Bul2", parent=styles["Normal"], fontSize=9.5, leading=13,
leftIndent=28, firstLineIndent=-10, spaceAfter=2, fontName="Helvetica")
note_style = ParagraphStyle("Note", parent=styles["Normal"], fontSize=9, leading=12,
leftIndent=7, rightIndent=7, spaceBefore=3, spaceAfter=5,
fontName="Helvetica-Oblique", textColor=PURPLE, backColor=LY, borderPad=4)
hb_style = ParagraphStyle("HB", parent=styles["Normal"], fontSize=9, leading=12,
leftIndent=7, rightIndent=7, spaceBefore=3, spaceAfter=5,
fontName="Helvetica-Bold", textColor=DARK_RED, backColor=LR, borderPad=4)
exam_style = ParagraphStyle("Exam", parent=styles["Normal"], fontSize=9, leading=12,
leftIndent=7, rightIndent=7, spaceBefore=3, spaceAfter=5,
fontName="Helvetica-Bold", textColor=ORANGE, backColor=LO, borderPad=4)
footer_style = ParagraphStyle("Footer", parent=styles["Normal"], fontSize=7.5,
textColor=colors.grey, alignment=TA_CENTER)
def H1(text): return Paragraph(f" {text}", h1_style)
def H2(text): return Paragraph(text, h2_style)
def H3(text): return Paragraph(text, h3_style)
def P(text): return Paragraph(text, body_style)
def B(text, l=1):
ch = "•" if l==1 else "–"
return Paragraph(f"{ch} {text}", bullet_style if l==1 else bullet2_style)
def NOTE(t): return Paragraph(f"<i>▶ {t}</i>", note_style)
def HIGH(t): return Paragraph(f"⚠ {t}", hb_style)
def EXAM(t): return Paragraph(f"★ EXAM: {t}", exam_style)
def HR(): return HRFlowable(width="100%", thickness=0.4, color=colors.lightgrey, spaceAfter=3)
def SP(h=0.2): return Spacer(1, h*cm)
def make_table(data, col_widths, header_color=TEAL, row_colors=None):
if row_colors is None:
row_colors = [colors.white, LB]
t = Table(data, colWidths=col_widths)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), header_color),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("ROWBACKGROUNDS", (0,1), (-1,-1), row_colors),
("BOX", (0,0), (-1,-1), 0.5, header_color),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
story = []
# ─── COVER ───
story += [SP(1.5),
Paragraph("SMALL INTESTINE PATHOLOGY", title_style),
Paragraph("Malabsorption Syndrome • Diarrhoea • Gluten Enteropathy (Coeliac Disease)", title_style),
Paragraph("University Study Notes | FMGE / USMLE High-Yield Review", subtitle_style),
HRFlowable(width="80%", thickness=2, color=NAVY, spaceAfter=8), SP(0.3)]
toc_data = [
[Paragraph("<b>Contents</b>", ParagraphStyle("toch", fontName="Helvetica-Bold", fontSize=10, textColor=NAVY))],
[Paragraph("Section 1: Small Intestine Pathology — Overview & Normal Physiology of Absorption", body_style)],
[Paragraph("Section 2: Malabsorption Syndrome — Definition · Classification · Aetiology · Clinical Features · Diagnosis", body_style)],
[Paragraph("Section 3: Diarrhoea — Definition · Classification · Aetiology · Pathogenesis · Clinical Features\n Positive & Differential Diagnosis · Treatment · Prevention · Prognosis", body_style)],
[Paragraph("Section 4: Gluten Enteropathy (Coeliac Disease) — Full coverage incl. Marsh grading, Serology,\n Diagnosis, Treatment, Complications, Prognosis", body_style)],
[Paragraph("Section 5: High-Yield Tables — FMGE/USMLE Mnemonics & Quick-Review Differentials", body_style)],
]
toc_t = Table(toc_data, colWidths=[17.4*cm])
toc_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LB),
("BACKGROUND", (0,1), (0,-1), LGREY),
("BOX", (0,0), (-1,-1), 0.5, NAVY),
("INNERGRID", (0,0), (-1,-1), 0.25, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
story += [toc_t, SP(0.4)]
story.append(NOTE("Sources: Goldman-Cecil Medicine 26th ed.; Sleisenger & Fordtran's GI & Liver Disease; Ganong's Review of Medical Physiology 26th ed.; Henry's Clinical Diagnosis & Management by Laboratory Methods; Harrison's Principles 22nd ed.; Yamada's Gastroenterology 7th ed. | July 2026"))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════
# SECTION 1 — SMALL INTESTINE OVERVIEW
# ═══════════════════════════════════════════════════════════
story.append(H1("SECTION 1: SMALL INTESTINE — NORMAL PHYSIOLOGY OF ABSORPTION"))
story += [SP(0.2)]
story.append(H2("1.1 Normal Fluid & Electrolyte Balance"))
story.append(P("About <b>8–10 litres</b> of fluid enter the duodenum every 24 hours (dietary + secreted). The small intestine absorbs the majority; about <b>1.5 L enters the large intestine</b>, and only <b>100–150 mL</b> is excreted in faeces. Any increase in secretion, decrease in absorption, or increased motility results in diarrhoea."))
story.append(H2("1.2 Segments & Their Absorptive Roles"))
abs_data = [
[Paragraph("<b>Segment</b>", body_style), Paragraph("<b>Length</b>", body_style), Paragraph("<b>Main Absorptive Function</b>", body_style)],
["Duodenum (D1–D4)", "~25 cm", "Iron, calcium, folate, fat-soluble vitamins; major site of digestive enzyme action"],
["Jejunum", "~2.5 m", "Majority of nutrient absorption: carbohydrates, proteins, fats, water-soluble vitamins"],
["Ileum", "~3.5 m", "Vitamin B12 (via intrinsic factor receptors), bile salt reabsorption, fat-soluble vitamins; compensatory absorption"],
]
story.append(make_table(abs_data, [3*cm, 2.5*cm, 11.9*cm]))
story += [SP(0.2)]
story.append(H2("1.3 Anatomic Reserve"))
story.append(P("The small intestine has an <b>absorptive capacity far exceeding normal requirements</b>. Removal of up to 50% of small bowel is generally well tolerated. When >50% is resected or bypassed (<b>short bowel syndrome</b>), clinically significant malnutrition and wasting occur. Resection of the terminal ileum specifically causes <b>bile acid malabsorption</b> → fat malabsorption AND colonic diarrhoea (bile salts activate Cl⁻ secretion in colonocytes)."))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════
# SECTION 2 — MALABSORPTION SYNDROME
# ═══════════════════════════════════════════════════════════
story.append(H1("SECTION 2: MALABSORPTION SYNDROME"))
story += [SP(0.15)]
story.append(H2("2.1 Definition"))
story.append(P("Malabsorption syndrome is a <b>clinical state resulting from impaired absorption of one or more nutrients</b> (macro- or micronutrients, vitamins, minerals) from the gastrointestinal tract. Various disease processes impair absorption <i>without</i> necessarily reducing intestinal length. The resultant pattern of deficiencies — called the <b>malabsorption syndrome</b> — varies with the underlying cause."))
story.append(EXAM("FMGE/USMLE: Malabsorption = steatorrhoea + nutritional deficiencies + diarrhoea. Key cause = coeliac disease in West; tropical sprue in developing countries."))
story.append(H2("2.2 Classification"))
story.append(H3("A. By Mechanism"))
mech_data = [
[Paragraph("<b>Mechanism</b>", body_style), Paragraph("<b>Description</b>", body_style), Paragraph("<b>Examples</b>", body_style)],
["Intraluminal (pre-mucosal)", "Impaired digestion of nutrients before absorption", "Pancreatic insufficiency, cholestasis, SIBO, Zollinger-Ellison syndrome"],
["Mucosal (epithelial)", "Damage to enterocytes or reduction in absorptive surface area", "Coeliac disease, Crohn's disease, tropical sprue, radiation enteritis, short bowel syndrome"],
["Post-mucosal (lymphatic)", "Impaired transport after mucosal absorption", "Intestinal lymphangiectasia, lymphoma, Whipple's disease"],
]
story.append(make_table(mech_data, [4*cm, 5.5*cm, 7.9*cm]))
story += [SP(0.2)]
story.append(H3("B. By Nutrient Affected"))
story += [B("<b>General malabsorption:</b> fat, protein, carbohydrate — e.g., coeliac disease, short bowel"),
B("<b>Selective fat malabsorption (steatorrhoea):</b> pancreatic insufficiency, cholestasis, SIBO"),
B("<b>Selective carbohydrate malabsorption:</b> lactase deficiency, sucrase-isomaltase deficiency"),
B("<b>Selective vitamin/mineral malabsorption:</b> B12 (pernicious anaemia, ileal disease), iron (duodenal disease), folate (coeliac, tropical sprue)"),
B("<b>Protein-losing enteropathy:</b> Whipple's disease, lymphangiectasia, IBD, Menetrier's disease")]
story += [SP(0.2)]
story.append(H2("2.3 Aetiology"))
aet_data = [
[Paragraph("<b>Category</b>", body_style), Paragraph("<b>Causes</b>", body_style)],
["Pancreatic insufficiency", "Chronic pancreatitis, cystic fibrosis, pancreatic cancer, pancreatectomy"],
["Biliary / hepatic", "Cholestasis (primary biliary cholangitis, biliary obstruction), liver cirrhosis"],
["Small bowel mucosal diseases", "Coeliac disease, tropical sprue, Whipple's disease (T. whipplei), radiation enteritis, Crohn's disease, eosinophilic enteritis, autoimmune enteropathy"],
["Anatomic / surgical", "Short bowel syndrome (resection >50%), jejunoileal bypass, gastric surgery (blind loop syndrome), intestinal fistulas"],
["Bacterial overgrowth (SIBO)", "Motility disorders, anatomic loops, immunodeficiency, diabetes, proton pump inhibitor overuse"],
["Infective", "Giardia lamblia, cryptosporidiosis, strongyloidiasis, HIV enteropathy, tuberculosis"],
["Lymphatic obstruction", "Intestinal lymphangiectasia, lymphoma, Whipple's disease"],
["Endocrine", "Diabetes mellitus (motility + autonomic neuropathy), hypothyroidism, Addison's disease, Zollinger-Ellison syndrome (low pH inactivates pancreatic enzymes)"],
["Drug-induced", "Cholestyramine (binds bile salts), neomycin, metformin (B12), orlistat, laxative abuse"],
["Congenital/rare", "Abetalipoproteinaemia (failure of chylomicron synthesis), congenital lactase deficiency, Hartnup disease"],
]
story.append(make_table(aet_data, [4.5*cm, 12.9*cm], header_color=TEAL))
story += [SP(0.3)]
story.append(H2("2.4 Pathogenesis (Key Mechanisms)"))
story += [
B("<b>Fat malabsorption pathway:</b> requires intact pancreatic lipase + bile salts for emulsification → micellar solubilisation → enterocyte uptake → chylomicron formation → lymphatic transport"),
B("Any break in this pathway (low lipase, low bile, mucosal disease, lymphatic block) → fat malabsorption → steatorrhoea + fat-soluble vitamin deficiencies (A, D, E, K)"),
B("<b>Bile acid malabsorption:</b> terminal ileum resection/disease → unreabsorbed bile acids enter colon → secretory diarrhoea + steatorrhoea (chologenic diarrhoea)"),
B("<b>Carbohydrate malabsorption:</b> disaccharidase deficiency → osmotic diarrhoea (unabsorbed sugars → colonic fermentation → H₂ gas, organic acids → bloating, acidic stools)"),
B("<b>Mucosal villous atrophy</b> (coeliac, tropical sprue): ↓ absorptive surface area → pan-nutrient malabsorption"),
B("<b>SIBO:</b> bacteria deconjugate bile acids → impair micelle formation + directly damage enterocytes + consume nutrients → mixed malabsorption"),
]
story += [SP(0.2)]
story.append(NOTE("Mnemonic for fat-soluble vitamin deficiencies: ADEK — A: night blindness; D: osteomalacia/rickets; E: neuropathy, haemolytic anaemia; K: bleeding tendency (PT prolonged)"))
story.append(H2("2.5 Clinical Features"))
story.append(H3("General / Nutritional Deficiency Symptoms"))
cf_data = [
[Paragraph("<b>Deficiency</b>", body_style), Paragraph("<b>Nutrient</b>", body_style), Paragraph("<b>Clinical Manifestation</b>", body_style)],
["Fat/energy", "Calories", "Weight loss, muscle wasting, fatigue, growth failure in children"],
["Protein", "Amino acids", "Hypoalbuminaemia → oedema, ascites, muscle wasting"],
["Fat", "Triglycerides", "Steatorrhoea (pale, bulky, greasy, offensive stools, floating), flatulence"],
["Vitamin A", "Retinol", "Night blindness, xerophthalmia, follicular hyperkeratosis"],
["Vitamin D", "Cholecalciferol", "Osteomalacia (adults), rickets (children), bone pain, hypocalcaemia, tetany"],
["Vitamin E", "Tocopherol", "Peripheral neuropathy, cerebellar ataxia, haemolytic anaemia"],
["Vitamin K", "Phylloquinone", "Prolonged prothrombin time, easy bruising, bleeding"],
["Vitamin B12", "Cobalamin", "Megaloblastic anaemia, subacute combined degeneration of the spinal cord, glossitis"],
["Folate", "Folic acid", "Megaloblastic anaemia, glossitis, neural tube defects (pregnancy)"],
["Iron", "Fe²⁺", "Microcytic hypochromic anaemia, koilonychia, angular stomatitis"],
["Calcium", "Ca²⁺", "Tetany, paraesthesias, Chvostek's/Trousseau's signs, osteoporosis"],
["Zinc", "Zn²⁺", "Acrodermatitis enteropathica, poor wound healing, hypogeusia"],
["Magnesium", "Mg²⁺", "Muscle cramps, cardiac arrhythmias, hypocalcaemia (secondary)"],
]
story.append(make_table(cf_data, [3.2*cm, 2.8*cm, 11.4*cm], header_color=DARK_RED, row_colors=[colors.white, LR]))
story += [SP(0.2)]
story.append(H3("GI Symptoms"))
story += [B("Diarrhoea: typically large-volume, watery, or steatorrhoeic (pale, greasy, malodorous, difficult to flush)"),
B("Bloating, flatulence, borborygmi (carbohydrate malabsorption → colonic fermentation)"),
B("Abdominal cramps and discomfort"),
B("Nausea, vomiting (less common)"),
B("Oedema: peripheral (hypoalbuminaemia)")]
story.append(H2("2.6 Positive Diagnosis"))
story.append(H3("1st-Line Screening Tests"))
story += [B("<b>Stool fat test (qualitative/quantitative):</b> Best screening test for malabsorption. Requires 70–100 g/day fat diet. Stool >7 g fat/24h is abnormal (fat malabsorption). Sensitivity/specificity ~90% (qualitative NMR method)"),
B("<b>Faecal elastase-1:</b> Non-invasive marker of exocrine pancreatic function; <200 µg/g indicates pancreatic insufficiency"),
B("<b>72-hour stool fat collection:</b> quantitative gold standard"),
B("<b>D-xylose absorption test:</b> Tests mucosal absorptive capacity (duodenal/jejunal). Low urine D-xylose (<4.5 g/5h) suggests mucosal disease; normal in pancreatic insufficiency"),
B("<b>Hydrogen breath test:</b> Carbohydrate malabsorption (lactose H₂ breath test); SIBO (glucose/lactulose breath test)")]
story.append(H3("Specific Tests"))
diag_data = [
[Paragraph("<b>Test</b>", body_style), Paragraph("<b>Detects</b>", body_style), Paragraph("<b>Notes</b>", body_style)],
["Serum anti-tTG IgA + total IgA", "Coeliac disease", "Best first-line serological test; total IgA to exclude IgA deficiency"],
["Small bowel biopsy (OGD + duodenal biopsy)", "Coeliac, tropical sprue, Whipple's, Giardia, amyloid", "Gold standard for mucosal disease; 4–6 biopsies from duodenum D2"],
["Serum B12, folate, iron studies, TIBC", "Nutritional deficiency pattern", "Helps localise — B12 ↓ → terminal ileum/gastric; folate ↓ → proximal jejunum"],
["CT/MR enterography", "Structural lesions, lymphoma, Crohn's, lymphangiectasia", "Middle and distal small bowel; thickened folds, nodular mucosa"],
["Capsule endoscopy", "Flat mucosa, erosions, mass lesions", "For suspected coeliac or refractory malabsorption with normal OGD"],
["Jejunal aspirate culture", "SIBO (>10⁵ CFU/mL)", "Gold standard for SIBO; glucose H₂ breath test is simpler alternative"],
["PAS stain biopsy (macrophages)", "Whipple's disease (T. whipplei)", "Foamy PAS-positive macrophages in lamina propria; confirmatory PCR"],
["Stool ova & parasites / PCR", "Giardia, Cryptosporidium, ETEC", "Especially if travel history; multiplex PCR stool panel"],
["Serum albumin, prealbumin", "Protein malnutrition", "Low albumin reflects chronic nutritional depletion"],
["Prothrombin time", "Vitamin K deficiency", "Elevated PT in fat malabsorption"],
["Schilling test (historical)", "B12 malabsorption site", "Stage I/II distinguishes intrinsic factor vs. terminal ileum cause"],
]
story.append(make_table(diag_data, [5*cm, 4*cm, 8.4*cm]))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════
# SECTION 3 — DIARRHOEA
# ═══════════════════════════════════════════════════════════
story.append(H1("SECTION 3: DIARRHOEA"))
story += [SP(0.15)]
story.append(H2("3.1 Definition"))
story.append(P("<b>Diarrhoea</b> (WHO, 2009): the passage of <b>3 or more loose or liquid stools per day</b>, or more frequently than is normal for the individual. Objectively defined as stool weight >200 g/day (>10 mL/kg/day in children). Normal stool frequency: 3×/week to 3×/day."))
story += [
B("<b>Acute diarrhoea:</b> <2–3 weeks duration (most commonly infectious)"),
B("<b>Persistent diarrhoea:</b> 2–4 weeks duration"),
B("<b>Chronic diarrhoea:</b> >4 weeks duration (defined as >6–8 weeks by many sources)"),
]
story.append(EXAM("USMLE/FMGE: Diarrhoea = >3 loose stools/day OR >200 g/day stool weight. Chronic = >4 weeks. Most common cause worldwide = Rotavirus (children); Norovirus (adults in USA)."))
story.append(H2("3.2 Classification"))
story.append(H3("A. By Duration"))
story += [B("<b>Acute</b> (<2 weeks): Viral gastroenteritis (rotavirus, norovirus, adenovirus), bacterial (E. coli, Salmonella, Shigella, Campylobacter, Vibrio cholerae), protozoal (Giardia, Entamoeba), food poisoning"),
B("<b>Persistent</b> (2–4 weeks): Giardia, enteroaggregative E. coli, Cryptosporidium, especially in travellers"),
B("<b>Chronic</b> (>4 weeks): Coeliac disease, IBD, IBS, microscopic colitis, malabsorption syndromes, functional, neuroendocrine tumours")]
story += [SP(0.15)]
story.append(H3("B. By Pathophysiological Mechanism (Most Important for Exams)"))
mech_d_data = [
[Paragraph("<b>Type</b>", body_style), Paragraph("<b>Mechanism</b>", body_style), Paragraph("<b>Key Features</b>", body_style), Paragraph("<b>Examples</b>", body_style)],
["Secretory", "↑ ion secretion (Cl⁻) or ↓ absorption independent of osmolality; Na/K-ATPase pump overwhelmed", "Large-volume, watery; persists with fasting; Osmotic gap <50 mOsm/kg", "Cholera (V. cholerae CT); VIPoma; carcinoid; bile salt diarrhoea; congenital Cl⁻ diarrhoea"],
["Osmotic", "Unabsorbed osmotically active solutes draw water into lumen", "Stops with fasting; Osmotic gap >125 mOsm/kg; acidic stools", "Lactase deficiency; lactulose; sorbitol; Mg²⁺ antacids; coeliac disease (carbohydrate component)"],
["Exudative / Inflammatory", "Mucosal inflammation → protein, blood, mucus exudation; disrupted tight junctions", "Blood/mucus in stool (dysentery); fever; fecal leukocytes +ve", "Shigella, Campylobacter, EHEC, Entamoeba; IBD (Crohn's, UC); pseudomembranous colitis"],
["Motility-related", "Altered peristalsis → ↓ contact time", "Variable stool consistency; no nocturnal symptoms (functional)", "IBS-D; hyperthyroidism; diabetes (autonomic); post-vagotomy; scleroderma"],
["Malabsorptive (fat/osmotic)", "Unabsorbed nutrients (fat, carbohydrate) → osmotic load + mucosal injury", "Steatorrhoea; does NOT stop with fasting completely; osmotic gap variable", "Coeliac disease; pancreatic insufficiency; SIBO; Whipple's disease"],
]
story.append(make_table(mech_d_data, [3*cm, 4.5*cm, 4*cm, 5.9*cm], header_color=NAVY))
story += [SP(0.2)]
story.append(NOTE("Fecal osmotic gap = 290 − 2×(stool Na⁺ + stool K⁺). Gap <50 = secretory; Gap >125 = osmotic. Gap 50–125 = mixed."))
story.append(H3("C. By Morphology / Consistency"))
story += [B("<b>Watery:</b> secretory, osmotic, motility-related"),
B("<b>Bloody (dysentery):</b> inflammatory/invasive — Shigella, EHEC, Entamoeba histolytica, IBD"),
B("<b>Steatorrhoeic:</b> pale, bulky, greasy, offensive, floating — fat malabsorption"),
B("<b>Mucoid:</b> IBS, mucous colitis")]
story += [SP(0.2)]
story.append(H2("3.3 Aetiology"))
story.append(H3("Acute Diarrhoea — Key Pathogens"))
path_data = [
[Paragraph("<b>Pathogen</b>", body_style), Paragraph("<b>Mechanism</b>", body_style), Paragraph("<b>Key Feature</b>", body_style)],
["Vibrio cholerae", "Cholera toxin → ↑ cAMP → massive Cl⁻ secretion", "'Rice water' stools, no fever, severe dehydration"],
["ETEC (traveller's diarrhoea)", "Heat-labile toxin (↑ cAMP) + heat-stable toxin (↑ cGMP)", "Most common traveller's diarrhoea; watery, non-bloody"],
["EHEC O157:H7", "Shiga toxin → HUS (haemolytic uraemic syndrome)", "Bloody diarrhoea + HUS in children; no fever; hamburger disease"],
["Shigella", "Invasion + Shiga toxin; invades M cells", "Dysentery; fever; fecal leukocytes; 'rectosigmoid'"],
["Salmonella (non-typhoid)", "Invasion of Peyer's patches; cytokines", "Fever; bloody diarrhoea; poultry/eggs source"],
["Campylobacter jejuni", "Invasion + cytotoxin; triggers reactive arthritis & GBS", "Most common bacterial diarrhoea in UK; bloody; poultry"],
["C. difficile", "Toxins A (enterotoxin) + B (cytotoxin) → pseudomembranous colitis", "Post-antibiotic; risk with clindamycin, cephalosporins, fluoroquinolones"],
["Norovirus", "Partial villous blunting; decreased absorptive enzymes", "Most common adult GE in USA; vomiting prominent; 24–48h"],
["Rotavirus", "NSP4 enterotoxin + villous destruction", "Most common fatal childhood diarrhoea globally; vaccine available"],
["Giardia lamblia", "Brush border disruption; bile salt deconjugation; malabsorption", "Foul-smelling, frothy, greasy stools; no blood; camping/well water"],
["Entamoeba histolytica", "Flask-shaped ulcers; liver abscess", "Bloody mucoid stools; 'anchovy sauce' liver abscess aspirate"],
["Cryptosporidium", "Enterocyte brush border; spore-forming protozoan", "Severe in AIDS; self-limiting in immunocompetent; water-borne"],
]
story.append(make_table(path_data, [4*cm, 6*cm, 7.4*cm], header_color=DARK_RED, row_colors=[colors.white, LR]))
story += [SP(0.2)]
story.append(H3("Chronic Diarrhoea — Key Causes"))
chron_data = [
[Paragraph("<b>Category</b>", body_style), Paragraph("<b>Examples</b>", body_style)],
["Malabsorption", "Coeliac disease, pancreatic exocrine insufficiency, SIBO, tropical sprue, Whipple's disease"],
["Inflammatory bowel disease", "Crohn's disease, ulcerative colitis, microscopic colitis"],
["Functional", "IBS-D (irritable bowel syndrome with diarrhoea) — diagnosis of exclusion"],
["Neuroendocrine tumours", "Carcinoid (↑ serotonin → secretory), VIPoma (↑ VIP → 'watery diarrhoea hypokalaemia achlorhydria' = WDHA syndrome), gastrinoma (↑ gastrin → ZES), medullary thyroid cancer (↑ calcitonin)"],
["Endocrine", "Hyperthyroidism, Addison's disease, diabetes mellitus (autonomic neuropathy), hypoparathyroidism"],
["Drug-induced", "Antibiotics, laxatives, metformin, magnesium antacids, NSAIDs, SSRIs, acarbose, colchicine"],
["Post-surgical", "Post-cholecystectomy (bile salt diarrhoea), post-gastrectomy (dumping syndrome), short bowel"],
["Structural / Radiation", "Radiation enteritis, fistulas, intestinal ischaemia"],
["Immunodeficiency", "HIV enteropathy, common variable immunodeficiency"],
]
story.append(make_table(chron_data, [4.5*cm, 12.9*cm]))
story += [SP(0.3)]
story.append(H2("3.4 Pathogenesis"))
story.append(P("Normal fluid balance: 8–10 L enters duodenum daily → small intestine absorbs ~6.5 L → colon absorbs ~1.35 L → 150 mL excreted. Maximum absorptive capacity of colon ~4–5 L/day. Diarrhoea occurs when this is exceeded."))
story.append(H3("4 Core Mechanisms"))
story += [
B("<b>1. Secretory:</b> Net secretion of Na⁺ and Cl⁻ (and water) driven by intracellular messengers (cAMP, cGMP, Ca²⁺). Cholera toxin permanently activates Gs → ↑ cAMP → massive Cl⁻ secretion via CFTR channels. STa (heat-stable toxin) → ↑ cGMP → same net effect. VIP → ↑ cAMP. Result: isotonic secretion; fasting does NOT stop diarrhoea."),
B("<b>2. Osmotic:</b> Non-absorbable solutes (lactose in lactase deficiency, lactulose, Mg²⁺) remain in the lumen and obligate water retention osmotically. Stool gap >125 mOsm/kg. Diarrhoea STOPS with fasting."),
B("<b>3. Exudative/Inflammatory:</b> Mucosal damage (bacterial invasion, cytokines, immune activation) → disruption of tight junctions → exudation of protein, mucus, blood. Inflammatory cells (fecal leukocytes) present. Examples: Shigella, IBD, C. difficile."),
B("<b>4. Motility-related:</b> Reduced transit time → insufficient time for absorption. In hyperthyroidism, autonomous nervous system dysfunction (diabetes), post-vagotomy."),
]
story += [SP(0.2)]
story.append(NOTE("AIDS-associated diarrhoea: CD4 T-cell depletion from GI tract → ↑ lamina propria inflammation + barrier damage → microbial translocation. Cryptosporidium is most common protozoa; CMV most important virus in severe AIDS."))
story.append(H2("3.5 Clinical Features"))
story.append(H3("History — Key Points"))
story += [
B("<b>Duration</b>: acute (<2 wk), persistent (2–4 wk), chronic (>4 wk)"),
B("<b>Character</b>: watery vs. bloody (dysentery) vs. greasy/pale (steatorrhoea) vs. mucoid"),
B("<b>Volume</b>: small-volume frequent (colonic/distal) vs. large-volume (small bowel/secretory)"),
B("<b>Blood/mucus</b>: suggests inflammatory/invasive cause"),
B("<b>Nocturnal diarrhoea</b>: organic cause (IBD, microscopic colitis, secretory); NOT functional"),
B("<b>Associated symptoms</b>: fever (infectious/IBD), weight loss (malabsorption/malignancy), abdominal cramps"),
B("<b>Travel history, antibiotic use, food history, immunocompromise, family history, medications</b>"),
]
story.append(H3("Examination Findings"))
story += [
B("Signs of dehydration: ↓ skin turgor, dry mucous membranes, sunken eyes, tachycardia, oliguria, hypotension"),
B("Abdominal tenderness, distension, bowel sounds"),
B("Signs of malnutrition/malabsorption: peripheral oedema, muscle wasting, pallor (anaemia), angular stomatitis, glossitis, night blindness, tetany"),
B("Perianal disease: fistulae, skin tags (Crohn's)"),
B("Digital rectal examination (DRE): assess stool consistency, blood, masses"),
]
story += [SP(0.2)]
story.append(H2("3.6 Positive Diagnosis"))
story.append(H3("Acute Diarrhoea (no alarm features)"))
story.append(P("Self-limited acute diarrhoea without bleeding or constitutional symptoms rarely requires testing. Indications for investigation: blood in stool, fever, severe dehydration, symptoms >7 days, immunocompromised, hospitalised, food-borne outbreak."))
story.append(H3("Diagnostic Investigations"))
inv_d_data = [
[Paragraph("<b>Test</b>", body_style), Paragraph("<b>Method/Comments</b>", body_style), Paragraph("<b>Identifies</b>", body_style)],
["Stool microscopy (ova & parasites)", "Concentration, acid-fast stain, modified Ziehl-Neelsen", "Giardia, Entamoeba, Cryptosporidium, Cyclospora, Isospora"],
["Stool bacterial culture / PCR", "Selective media; multiplex PCR panel (most sensitive)", "Salmonella, Shigella, Campylobacter, EHEC, Yersinia, V. cholerae"],
["Stool for C. difficile toxin", "EIA for toxins A & B; PCR for CDI gene", "C. difficile in antibiotic-associated/nosocomial diarrhoea"],
["Fecal leukocytes / lactoferrin", "Wright's/methylene blue; lactoferrin EIA", "Inflammatory diarrhoea (invasive bacteria, IBD)"],
["Fecal calprotectin", "ELISA; >50 µg/g abnormal", "Distinguishes organic (IBD) from functional (IBS) cause; non-invasive"],
["Fecal osmotic gap", "290 − 2×(stool Na⁺ + K⁺)", "Osmotic (<50=secretory; >125=osmotic)"],
["Stool pH", "pH strips", "Acidic (pH<5.5) = carbohydrate malabsorption/fermentation"],
["Colonoscopy + biopsy", "With multiple biopsies", "IBD, microscopic colitis, C. difficile colitis, malignancy"],
["Upper GI endoscopy + duodenal biopsy", "4–6 biopsies from D2", "Coeliac, Whipple's, Giardia, tropical sprue"],
["CT abdomen", "Oral + IV contrast", "Colitis, abscess, fistula, lymphadenopathy, thickened bowel loops"],
["Serology: anti-tTG IgA, total IgA", "ELISA", "Coeliac disease first-line serological test"],
["Serum VIP, gastrin, serotonin, calcitonin", "RIA/immunoassay", "Neuroendocrine tumours (VIPoma, gastrinoma, carcinoid)"],
["Urine 5-HIAA", "24h urine collection", "Carcinoid syndrome (>25 mg/day abnormal)"],
["Thyroid function tests", "TSH, fT4", "Hyperthyroidism as cause of chronic diarrhoea"],
["HIV serology, CD4 count", "EIA, Western blot, flow cytometry", "AIDS-related diarrhoea; determines likely pathogens"],
]
story.append(make_table(inv_d_data, [4.5*cm, 6*cm, 6.9*cm]))
story += [SP(0.3)]
story.append(H2("3.7 Differential Diagnosis"))
dd_d_data = [
[Paragraph("<b>Feature</b>", body_style), Paragraph("<b>Small Bowel Origin</b>", body_style), Paragraph("<b>Large Bowel Origin</b>", body_style)],
["Volume", "Large volume, watery", "Small volume, frequent, urgent"],
["Blood/mucus", "No (unless severe invasion)", "Yes (blood, mucus in IBD, infection)"],
["Abdominal pain location", "Periumbilical", "Lower abdominal / left iliac fossa"],
["Steatorrhoea", "Yes (if malabsorptive)", "No"],
["Weight loss", "Common", "Less common (except malignancy)"],
["Tenesmus", "No", "Yes (rectal disease)"],
]
story.append(make_table(dd_d_data, [4*cm, 6.7*cm, 6.7*cm], header_color=NAVY))
story += [SP(0.2)]
story.append(NOTE("Key DD for bloody diarrhoea: Shigella vs. Entamoeba histolytica — both cause dysentery. Shigella: fever, fecal leukocytes, rectal ulcers; Entamoeba: milder fever, 'flask-shaped' ulcers on colonoscopy, trophozoites in stool, liver abscess risk."))
story.append(H2("3.8 Treatment"))
story.append(H3("General Principles — All Diarrhoea"))
story += [
B("<b>Rehydration (most important):</b> ORS (WHO formula: Na⁺ 75 mmol/L, Cl⁻ 65 mmol/L, K⁺ 20 mmol/L, citrate 10 mmol/L, glucose 75 mmol/L, osmolarity 245); IV fluids (Ringer's lactate/NS) if severe dehydration or unable to tolerate PO"),
B("<b>Zinc supplementation:</b> WHO recommendation for children <5 years — 20 mg/day for 10–14 days reduces severity and recurrence"),
B("<b>Continue feeding:</b> 'Rest the bowel' concept is outdated; continue appropriate diet"),
B("<b>Probiotics:</b> Lactobacillus GG and Saccharomyces boulardii reduce duration of acute diarrhoea in children (moderate evidence)"),
]
story.append(H3("Antimotility Agents"))
story += [
B("<b>Loperamide</b> (opioid agonist, µ-receptor, does not cross BBB): reduces secretion + increases intestinal transit time; 4 mg initially then 2 mg after each loose stool (max 16 mg/day); AVOID in bloody/invasive diarrhoea (risk of toxic megacolon), C. difficile"),
B("<b>Codeine phosphate</b>: antimotility; used in chronic functional diarrhoea"),
B("<b>Bismuth subsalicylate</b>: mild antisecretory + antimicrobial; effective for traveller's diarrhoea"),
]
story.append(H3("Antibiotic Therapy"))
story.append(NOTE("Antibiotics are NOT routinely indicated for acute uncomplicated diarrhoea. Indicated for: cholera, shigellosis, severe Campylobacter, typhoid, C. difficile, traveller's diarrhoea, Giardia, amoebiasis."))
ab_d_data = [
[Paragraph("<b>Organism</b>", body_style), Paragraph("<b>Drug of Choice</b>", body_style), Paragraph("<b>Alternative</b>", body_style)],
["V. cholerae", "Doxycycline 300 mg single dose", "Azithromycin 1 g single dose"],
["Shigella (dysentery)", "Ciprofloxacin 500 mg BD × 3 days", "Azithromycin, Ceftriaxone"],
["Campylobacter", "Azithromycin 500 mg OD × 3 days", "Erythromycin (if susceptible)"],
["C. difficile (1st episode)", "Fidaxomicin 200 mg BD × 10 days (preferred)", "Vancomycin 125 mg QDS × 10 days"],
["C. difficile (recurrence)", "Vancomycin tapered/pulsed OR FMT", "Bezlotoxumab (monoclonal Ab against toxin B, 10 mg/kg IV)"],
["Giardia", "Metronidazole 400 mg TDS × 5–7 days", "Tinidazole 2 g single dose"],
["Entamoeba histolytica", "Metronidazole 800 mg TDS × 5–10 days + Diloxanide furoate 500 mg TDS × 10 days", "Tinidazole"],
["Cryptosporidium", "Nitazoxanide 500 mg BD × 3 days (immunocompetent)", "ART to restore CD4 in HIV"],
["Traveller's diarrhoea (severe)", "Rifaximin 200 mg TDS × 3 days", "Ciprofloxacin 500 mg BD × 3 days"],
["SIBO", "Rifaximin 550 mg TDS × 14 days", "Metronidazole, Tetracycline"],
]
story.append(make_table(ab_d_data, [4.5*cm, 7*cm, 5.9*cm], header_color=TEAL, row_colors=[colors.white, LG]))
story += [SP(0.15)]
story.append(H3("Specific Treatments for Chronic Diarrhoea"))
story += [
B("<b>Coeliac disease:</b> strict lifelong gluten-free diet"),
B("<b>Pancreatic insufficiency:</b> pancreatic enzyme replacement therapy (PERT) with meals"),
B("<b>IBD:</b> 5-ASA, corticosteroids, immunomodulators, biologics"),
B("<b>Carcinoid syndrome:</b> octreotide (somatostatin analogue), telotristat (tryptophan hydroxylase inhibitor)"),
B("<b>VIPoma:</b> octreotide; surgical resection"),
B("<b>Bile acid diarrhoea (post-ileal resection):</b> cholestyramine 4 g QDS (bile acid sequestrant)"),
B("<b>Microscopic colitis:</b> budesonide 9 mg OD × 6–8 weeks"),
B("<b>IBS-D:</b> loperamide, low-FODMAP diet, rifaximin, eluxadoline, alosetron (severe IBS-D in women)"),
]
story.append(H2("3.9 Prevention"))
story += [
B("<b>Vaccination:</b> Rotavirus vaccine (oral; reduces fatal childhood diarrhoea globally); Cholera vaccine (rBS-WC; for travellers, relief workers in endemic areas)"),
B("<b>Water safety:</b> safe drinking water, proper sanitation — prevents cholera, typhoid, Giardia, Cryptosporidium"),
B("<b>Food safety:</b> proper food handling, cooking; avoid raw meat/seafood/tap water abroad"),
B("<b>Traveller's diarrhoea prophylaxis:</b> Bismuth subsalicylate 525 mg QDS (up to 3 weeks); Rifaximin 200 mg OD for high-risk travellers to Mexico"),
B("<b>Hand hygiene:</b> soap and water (not alcohol gel — C. difficile, norovirus)"),
B("<b>Antibiotic stewardship:</b> reduce unnecessary antibiotic use → prevents C. difficile, antibiotic-associated diarrhoea"),
B("<b>Zinc supplementation + vitamin A:</b> in malnourished children in developing countries"),
B("<b>Breastfeeding:</b> protective in infants — passive immunity + microbiome establishment"),
]
story.append(H2("3.10 Prognosis"))
story.append(P("Acute self-limited diarrhoea: resolves in 3–7 days with supportive care. Mortality in developing countries is high among children <5 years (<b>~445,000 childhood deaths/year</b> globally despite ORS). Leading causes of death: dehydration and electrolyte imbalance. Rotavirus vaccine has substantially reduced mortality in both developed and developing nations. Chronic diarrhoea prognosis depends entirely on the underlying aetiology — IBS: excellent; IBD: relapsing course; coeliac on GFD: normal life expectancy if compliant; carcinoid: depends on metastatic disease."))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════
# SECTION 4 — GLUTEN ENTEROPATHY / COELIAC DISEASE
# ═══════════════════════════════════════════════════════════
story.append(H1("SECTION 4: GLUTEN ENTEROPATHY (COELIAC DISEASE)"))
story += [SP(0.15)]
story.append(H2("4.1 Definition"))
story.append(P("<b>Coeliac disease (gluten-sensitive enteropathy, gluten-induced enteropathy, non-tropical sprue)</b> is an <b>immune-mediated, T-cell-driven inflammatory disease</b> of the small intestine precipitated by the ingestion of <b>gluten</b> (the storage protein of wheat, rye, and barley) in <b>genetically predisposed individuals</b> (HLA-DQ2 or HLA-DQ8). It is characterised by intestinal malabsorption secondary to villous atrophy of the small intestinal mucosa."))
story.append(EXAM("FMGE/USMLE Key Points: Coeliac disease = HLA-DQ2 (95%) or HLA-DQ8 (5%). Gluten in wheat/rye/barley (NOT rice or corn). Anti-tTG IgA = best screening test. Duodenal biopsy = gold standard. Treatment = strict lifelong gluten-free diet."))
story.append(H2("4.2 Classification"))
story.append(H3("Marsh Classification (Histological Grading — HIGH YIELD)"))
marsh_data = [
[Paragraph("<b>Marsh Grade</b>", body_style), Paragraph("<b>Histology</b>", body_style), Paragraph("<b>Significance</b>", body_style)],
["0 (Pre-infiltrative)", "Normal villi and crypts; normal IEL", "Normal mucosa; no disease"],
["1 (Infiltrative)", "Normal villi; ↑ intraepithelial lymphocytes (IEL) >25/100 enterocytes", "Early or potential coeliac; compatible with coeliac if serology +ve"],
["2 (Hyperplastic)", "↑ IEL + crypt hyperplasia; normal villi", "Crypt hyperplasia without atrophy"],
["3a (Partial villous atrophy)", "↑ IEL + crypt hyperplasia + partial villous atrophy", "Mild; mild malabsorption"],
["3b (Subtotal villous atrophy)", "↑ IEL + crypt hyperplasia + subtotal atrophy", "Moderate disease"],
["3c (Total villous atrophy)", "↑ IEL + crypt hyperplasia + COMPLETE villous atrophy", "Severe; 'flat mucosa'; classic coeliac disease"],
["4 (Hypoplastic/Atrophic)", "Total atrophy WITHOUT IEL increase; hypoplastic crypts", "Refractory coeliac; rare; risk of EATL"],
]
story.append(make_table(marsh_data, [3.5*cm, 6.5*cm, 7.4*cm], header_color=PURPLE, row_colors=[colors.white, LP]))
story += [SP(0.2)]
story.append(NOTE("Modified Marsh classification (Oberhuber): 3a/3b/3c. Marsh 3c = 'flat mucosa' = most severe = classic presentation. IEL count: >25 per 100 enterocytes is abnormal (normal <20)."))
story.append(H3("Clinical Variants"))
story += [
B("<b>Classical/symptomatic coeliac:</b> GI symptoms + malabsorption + positive serology + villous atrophy"),
B("<b>Non-classical/atypical:</b> extra-intestinal manifestations predominate (anaemia, bone disease, neurological) with or without GI symptoms"),
B("<b>Silent coeliac:</b> positive serology + villous atrophy + NO symptoms (found on screening of high-risk groups)"),
B("<b>Latent coeliac:</b> positive serology but normal mucosa (HLA-DQ2/DQ8 positive; may develop coeliac later)"),
B("<b>Potential coeliac:</b> positive serology + normal mucosa + HLA compatible; high risk of developing disease"),
B("<b>Refractory coeliac disease (RCD):</b> Type I (normal IEL phenotype) or Type II (aberrant IEL — monoclonal T-cell expansion) — risk of enteropathy-associated T-cell lymphoma (EATL)"),
B("<b>Dermatitis herpetiformis:</b> blistering skin rash variant of coeliac (IgA deposits at dermoepidermal junction)"),
]
story += [SP(0.2)]
story.append(H2("4.3 Aetiology"))
story.append(H3("Genetic Factors — HLA (Critical)"))
story += [
B("<b>HLA-DQ2 (DQA1*05:01/DQB1*02:01):</b> present in ~95% of coeliac patients; encoded in trans configuration in some DR11/DR7 heterozygotes"),
B("<b>HLA-DQ8 (DQA1*03:01/DQB1*03:02):</b> ~5% of coeliac patients; associated with DQ2-negative cases"),
B("HLA-DQ2/DQ8 negative → virtually excludes coeliac disease (~negative predictive value >99%)"),
B("However, 30–40% of the general population carry HLA-DQ2/DQ8 but only ~1% develop coeliac → other genetic and environmental factors required"),
B("Non-HLA genes: SH2B3, IL21, IL2/IL21 locus, TNFAIP3 — increase risk ~4-fold"),
]
story.append(H3("Environmental Factors"))
story += [
B("<b>Gluten:</b> the essential environmental trigger — specifically the gliadin fraction (alcohol-soluble)"),
B("Wheat: α, β, γ, ω-gliadins and glutenins; <b>secalin</b> (rye); <b>hordein</b> (barley) — all toxic"),
B("<b>Rice, corn, millet, sorghum, teff:</b> SAFE (no cross-reactivity)"),
B("<b>Oats:</b> avenin — majority tolerate; cross-contamination in processing is main concern; pure oats permitted in UK guidelines in moderate amounts"),
B("<b>Timing of gluten introduction:</b> optimal window for introduction in infancy may reduce risk"),
B("<b>GI infections</b> (rotavirus, adenovirus 12): may trigger onset in genetically susceptible individuals"),
B("Lack of breastfeeding, C-section delivery, altered gut microbiome — possible risk modifiers"),
]
story += [SP(0.2)]
story.append(H2("4.4 Pathogenesis"))
story.append(P("Pathogenesis involves both <b>innate</b> and <b>adaptive immune responses</b> to gliadin peptides in the intestinal lamina propria."))
path_steps_data = [
[Paragraph("<b>Step</b>", body_style), Paragraph("<b>Event</b>", body_style)],
["1", "Gliadin peptides cross the intestinal epithelium (via tight junctions or transcytosis) into the lamina propria"],
["2", "<b>Tissue transglutaminase (tTG2)</b> deamidates glutamine residues in gliadin → creates deamidated gliadin peptides with high affinity for HLA-DQ2/DQ8"],
["3", "Deamidated gliadin peptides are presented by antigen-presenting cells (dendritic cells, macrophages) expressing HLA-DQ2/DQ8 to <b>CD4⁺ T helper cells</b>"],
["4", "Activated CD4⁺ T cells produce pro-inflammatory cytokines: <b>IFN-γ</b> (most important), TNF-α, IL-15 → epithelial damage, villous atrophy, crypt hyperplasia"],
["5", "<b>IL-15</b> activates <b>intraepithelial lymphocytes (CD8⁺ T cells / NKT cells)</b> → kill enterocytes via NKG2D-MIC A/B interaction → epithelial damage"],
["6", "B cells (with T-cell help) produce <b>anti-tTG IgA antibodies</b> — the basis of serological testing"],
["7", "Net result: villous blunting/atrophy + crypt hyperplasia → ↓ absorptive surface area + ↓ brush border enzymes → malabsorption"],
]
story.append(make_table(path_steps_data, [1.5*cm, 15.9*cm], header_color=PURPLE, row_colors=[colors.white, LP]))
story += [SP(0.15)]
story.append(NOTE("Key molecule: Tissue transglutaminase 2 (tTG2) — the target of the disease antibodies AND the enzyme that deaminates gliadin, converting it from a poor antigen to a high-affinity HLA-DQ2/DQ8 ligand. This is WHY tTG IgA is used for diagnosis."))
story.append(H2("4.5 Clinical Features"))
story.append(H3("Gastrointestinal Symptoms"))
story += [
B("<b>Diarrhoea:</b> chronic, steatorrhoeic (pale, bulky, greasy, offensive, floating) — most common presenting GI symptom"),
B("<b>Abdominal bloating and distension</b>"),
B("<b>Abdominal cramping</b>"),
B("<b>Nausea, vomiting, anorexia</b>"),
B("<b>Weight loss</b> (caloric malabsorption)"),
B("Children: failure to thrive, growth retardation, irritability — often present in the first few years of life after gluten introduction"),
]
story.append(H3("Extra-intestinal / Atypical Manifestations (Increasingly Common — HIGH YIELD)"))
extra_data = [
[Paragraph("<b>System</b>", body_style), Paragraph("<b>Manifestation</b>", body_style)],
["Haematological", "Iron deficiency anaemia (most common extra-intestinal feature) — often the sole presentation in adults; megaloblastic anaemia (B12, folate deficiency); coagulopathy (vitamin K)"],
["Musculoskeletal", "Osteoporosis/osteomalacia (vitamin D + calcium malabsorption); arthralgia/oligoarthritis in up to 25% (large joints: knees, ankles); arthralgias may precede GI symptoms by months–years"],
["Neurological", "Gluten ataxia (most common neurological manifestation, ~10%); peripheral neuropathy (sensorimotor or small fibre); epilepsy + bilateral occipital calcifications (Goyer syndrome); neuromyotonia"],
["Dermatological", "Dermatitis herpetiformis (DH): intensely pruritic vesicular rash on extensor surfaces; IgA deposits at dermoepidermal junction; responds to GFD + dapsone"],
["Endocrine", "Type 1 diabetes mellitus (shared HLA-DR3/DQ2); autoimmune thyroid disease (Hashimoto's, Graves'); Addison's disease; hypogonadism"],
["Reproductive", "Infertility, recurrent miscarriage, delayed puberty, amenorrhoea"],
["Hepatic", "Cryptogenic elevated transaminases (coeliac hepatitis — normalise on GFD); primary biliary cholangitis; autoimmune hepatitis"],
["Oral", "Recurrent aphthous ulcers; dental enamel hypoplasia (childhood onset)"],
["Genetic associations", "Down syndrome (trisomy 21); Turner syndrome; Williams syndrome — all have ↑ coeliac risk"],
]
story.append(make_table(extra_data, [4*cm, 13.4*cm], header_color=ORANGE, row_colors=[colors.white, LO]))
story += [SP(0.2)]
story.append(HIGH("WARNING: In adults, coeliac disease most commonly presents WITHOUT classical GI symptoms. Unexplained iron deficiency anaemia, osteoporosis, or elevated transaminases in a young adult — always test for coeliac."))
story.append(H2("4.6 Diagnosis"))
story.append(H3("Step 1: Serology (on a gluten-containing diet)"))
sero_data = [
[Paragraph("<b>Test</b>", body_style), Paragraph("<b>Sensitivity</b>", body_style), Paragraph("<b>Specificity</b>", body_style), Paragraph("<b>Notes</b>", body_style)],
["Anti-tTG IgA", "~93–98%", "~96–99%", "BEST FIRST-LINE TEST; must check total IgA simultaneously"],
["Anti-EMA (endomysial Ab) IgA", "~90–97%", "~98–100%", "Operator-dependent IIF; highly specific; used as confirmatory test"],
["Anti-deamidated gliadin peptide (DGP) IgG", "~80–90%", "~90–95%", "BEST for IgA-deficient patients; also good in children <2 years"],
["Total serum IgA level", "—", "—", "MANDATORY alongside tTG IgA — IgA deficiency (1/500) → false negative; if low, use IgG-based tests"],
["HLA-DQ2/DQ8 typing", "~100% NPV", "~70%", "NOT for initial diagnosis; used to EXCLUDE coeliac (very high negative predictive value)"],
["Anti-gliadin IgA/IgG (AGA)", "~85%", "~80%", "OBSOLETE — replaced by DGP; no longer recommended for routine use"],
]
story.append(make_table(sero_data, [4.8*cm, 2.5*cm, 2.5*cm, 7.6*cm], header_color=TEAL))
story += [SP(0.15)]
story.append(NOTE("Patient MUST be on a GLUTEN-CONTAINING diet at time of serology and biopsy. Gluten withdrawal before testing → false negative results. If already on GFD, reintroduce gluten for 6–8 weeks (gluten challenge) before testing."))
story.append(H3("Step 2: Endoscopy and Duodenal Biopsy (GOLD STANDARD)"))
story += [
B("Upper GI endoscopy (OGD) with multiple biopsies from the <b>second part of the duodenum (D2)</b>"),
B("Seattle-protocol biopsy: ≥4–6 biopsies from D2 + ≥2 from duodenal bulb (D1)"),
B("<b>Endoscopic features:</b> scalloped folds (loss of Kerckring's folds), mosaic pattern, nodularity, loss of folds (smooth mucosa), reduced folds — 'scalloping' is most specific"),
B("<b>Histological features (on H&E):</b>"),
B("↑ Intraepithelial lymphocytes (IEL) — first change; >25 IEL/100 enterocytes", level=2),
B("Crypt hyperplasia (crypts elongated, ↑ mitotic figures)", level=2),
B("Villous atrophy (partial → subtotal → total — 'flat mucosa')", level=2),
B("Cuboid enterocytes replacing tall columnar cells (surface epithelial damage)", level=2),
]
story.append(H3("Step 3: Response to Gluten-Free Diet (GFD)"))
story += [
B("Symptomatic, serological, and histological improvement on GFD confirms diagnosis"),
B("Serological markers (tTG IgA) should normalise within 6–12 months on strict GFD"),
B("Mucosal healing takes 1–2 years (or longer in adults)"),
]
story.append(H3("Special Situations"))
story += [
B("<b>Children >2 years with strong positive serology (tTG >10× ULN) + compatible symptoms + HLA-DQ2/DQ8:</b> Diagnosis WITHOUT biopsy now accepted by ESPGHAN 2020 guidelines"),
B("<b>IgA deficiency:</b> Use IgG-based tests (tTG IgG, DGP IgG, EMA IgG)"),
B("<b>Already on GFD:</b> Gluten challenge before biopsy OR proceed with HLA typing (negative HLA-DQ2/DQ8 excludes coeliac)"),
B("<b>Capsule endoscopy:</b> for suspected seronegative coeliac or to assess extent of disease"),
]
story += [SP(0.2)]
story.append(H2("4.7 Treatment"))
story.append(H3("Strict Lifelong Gluten-Free Diet (GFD) — Cornerstone"))
story.append(P("<b>Gluten-free diet</b> is the only proven treatment for coeliac disease. Strict adherence reverses villous atrophy, normalises serology, relieves symptoms, corrects nutritional deficiencies, and reduces long-term complications (lymphoma, cancer, osteoporosis)."))
story.append(H3("Foods to AVOID"))
story += [
B("<b>Must strictly avoid:</b> wheat (bread, pasta, cakes, biscuits, pizza), rye, barley, and their derivatives"),
B("Hidden sources: sauces, gravies, malt vinegar, communion wafers, medications/supplements using wheat starch as filler, soy sauce (unless GF)"),
B("<b>Safe grains:</b> Rice, corn (maize), millet, sorghum, quinoa, buckwheat, teff, tapioca (cassava), potato starch"),
]
story.append(H3("Nutritional Supplementation (Initially)"))
story += [
B("Iron, folate, vitamin B12 (if deficient)"),
B("Calcium and vitamin D (if osteoporosis/osteomalacia present)"),
B("Fat-soluble vitamins (A, D, E, K) as water-soluble preparations in severe disease"),
B("Bone mineral density (DEXA scan) — at diagnosis; repeat after 1–2 years on GFD"),
]
story.append(H3("Monitoring"))
story += [
B("Anti-tTG IgA at 6 and 12 months → should fall; normalise within 1 year on strict GFD"),
B("Dietitian review — crucial for adherence education"),
B("Repeat duodenal biopsy after 2 years on GFD (to confirm mucosal healing, especially before stopping monitoring)"),
B("Annual blood counts, iron studies, B12, folate, vitamin D, liver function tests"),
]
story.append(H3("Treatment of Specific Complications"))
story += [
B("<b>Refractory coeliac disease Type I:</b> corticosteroids (prednisolone/budesonide), azathioprine, infliximab"),
B("<b>Refractory coeliac disease Type II (aberrant IEL):</b> cladribine, stem cell transplantation; high risk of EATL"),
B("<b>Osteoporosis:</b> bisphosphonates (alendronate) + calcium + vitamin D"),
B("<b>Dermatitis herpetiformis:</b> GFD (primary treatment) + dapsone 50–100 mg OD (symptomatic control while GFD takes effect)"),
]
story.append(H3("Emerging Pharmacological Therapies (Not yet standard)"))
story += [
B("Larazotide acetate (tight junction regulator — reduces intestinal permeability to gliadin)"),
B("ALV003 / Latiglutenase (gluten-degrading enzyme combination)"),
B("Nexvax2 (desensitisation vaccine — clinical trials)"),
B("Indulal (IL-15 antagonist — targeting IEL activation)"),
]
story += [SP(0.2)]
story.append(H2("4.8 Prevention"))
story += [
B("No proven primary prevention; all persons with HLA-DQ2/DQ8 who eat gluten are at risk"),
B("Screening of <b>first-degree relatives</b> (parent, sibling, child): 10–15% prevalence → test with anti-tTG IgA"),
B("Screen high-risk groups: Type 1 DM, Down syndrome, Turner syndrome, autoimmune thyroid disease, IgA deficiency, iron-deficiency anaemia unresponsive to iron"),
B("<b>Timing of gluten introduction:</b> earlier evidence suggested 4–6 months window; current data (PREVENTCD, EAT trials) show that timing of introduction does NOT prevent coeliac disease — only delay of diagnosis; early introduction between 4–7 months does not increase or decrease risk"),
B("Breastfeeding: previously thought protective; RCTs show no significant protective effect on coeliac disease development"),
]
story.append(H2("4.9 Prognosis"))
story += [
B("Excellent with strict lifelong GFD — symptoms resolve in weeks; serology normalises in months; mucosa heals in 1–2 years"),
B("Most patients achieve normal life expectancy with strict dietary compliance"),
B("<b>Non-compliance risks:</b>"),
B("Persistent/recurrent nutritional deficiencies (iron, B12, folate, D)", level=2),
B("Osteoporosis (2× increased fracture risk if untreated)", level=2),
B("Enteropathy-associated T-cell lymphoma (EATL) — rare (~0.5–1% lifetime risk); particularly with RCD Type II; aggressive; poor prognosis", level=2),
B("Adenocarcinoma of small intestine — 3× increased risk in untreated coeliac", level=2),
B("Oropharyngeal cancer — small increased risk", level=2),
B("<b>GFD reduces cancer risk to near normal</b> levels over time"),
B("5-year survival with EATL: <20%; hence importance of maintaining strict GFD"),
]
story.append(NOTE("FMGE/USMLE: Complications of untreated coeliac: EATL (most important malignancy), small bowel adenocarcinoma, oesophageal cancer, osteoporosis, infertility. GFD reduces all these risks."))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════
# SECTION 5 — HIGH-YIELD TABLES & MNEMONICS
# ═══════════════════════════════════════════════════════════
story.append(H1("SECTION 5: HIGH-YIELD TABLES, MNEMONICS & QUICK REVIEW"))
story += [SP(0.15)]
story.append(H2("5.1 Comparison: Malabsorption Causes — Mucosal vs. Luminal vs. Lymphatic"))
comp_data = [
[Paragraph("<b>Feature</b>", body_style), Paragraph("<b>Mucosal (e.g., Coeliac)</b>", body_style), Paragraph("<b>Luminal (e.g., Pancreatic insuff.)</b>", body_style), Paragraph("<b>Lymphatic (e.g., Whipple's)</b>", body_style)],
["D-xylose test", "Abnormal (↓) — mucosal damage", "Normal — mucosa intact", "Normal"],
["Fecal fat", "+ve", "+ve (markedly +ve)", "+ve"],
["Small bowel biopsy", "Villous atrophy, ↑ IEL", "Normal mucosa", "Foamy PAS+ macrophages (Whipple's)"],
["Serology", "Anti-tTG IgA +ve (coeliac)", "Negative", "PCR for T. whipplei +ve (Whipple's)"],
["Treatment", "Gluten-free diet", "Pancreatic enzyme replacement", "Cotrimoxazole × 1 year (Whipple's)"],
]
story.append(make_table(comp_data, [4*cm, 4.2*cm, 4.7*cm, 4.5*cm], header_color=NAVY))
story += [SP(0.2)]
story.append(H2("5.2 Secretory vs. Osmotic Diarrhoea — Key Comparison"))
sec_osm_data = [
[Paragraph("<b>Feature</b>", body_style), Paragraph("<b>Secretory</b>", body_style), Paragraph("<b>Osmotic</b>", body_style)],
["Volume", "Large (>1L/day)", "Moderate (<1L/day)"],
["Response to fasting", "Continues (does NOT stop)", "Stops with fasting"],
["Fecal osmotic gap", "<50 mOsm/kg", ">125 mOsm/kg"],
["Stool osmolality accounted by Na+K", "Yes (Na+K account for tonicity)", "No (other osmoles present)"],
["Stool pH", "Normal (>6)", "Acidic (<5.5 — carbohydrate fermentation)"],
["Examples", "Cholera; VIPoma; carcinoid; bile salt diarrhoea; congenital Cl⁻ diarrhoea", "Lactase deficiency; lactulose; osmotic laxatives (Mg²⁺); celiac (partial)"],
]
story.append(make_table(sec_osm_data, [5*cm, 5.5*cm, 6.9*cm], header_color=TEAL))
story += [SP(0.2)]
story.append(H2("5.3 FMGE/USMLE High-Yield Facts — Quick Review"))
hyl_data = [
[Paragraph("<b>Question / Topic</b>", body_style), Paragraph("<b>Answer</b>", body_style)],
["Best screening test for malabsorption", "72-hour stool fat collection (>7 g fat/24h on high-fat diet)"],
["D-xylose test: abnormal in ___; normal in ___", "Abnormal: mucosal disease (coeliac). Normal: pancreatic insufficiency, SIBO"],
["Most common cause of malabsorption in tropics", "Tropical sprue (treat with tetracycline + folic acid)"],
["Most common cause of malabsorption in West", "Coeliac disease"],
["Gold standard diagnosis of coeliac disease", "Duodenal biopsy (4–6 biopsies from D2); Marsh 3c = total villous atrophy"],
["Best first-line serological test for coeliac", "Anti-tTG IgA (+ simultaneous total serum IgA)"],
["Coeliac serology in IgA deficiency", "Use anti-DGP IgG or anti-tTG IgG"],
["HLA association with coeliac", "HLA-DQ2 (95%) and HLA-DQ8 (5%)"],
["Safe grains in coeliac", "Rice, corn, millet, sorghum, quinoa, buckwheat, teff — NOT wheat/rye/barley"],
["Diarrhoea definition (WHO)", ">3 loose/liquid stools per day or >200 g/day stool weight"],
["Cholera mechanism", "Cholera toxin → ↑ cAMP → CFTR activation → massive Cl⁻ (and water) secretion → rice-water stools"],
["EHEC O157:H7 complication", "Haemolytic Uraemic Syndrome (HUS) — Shiga toxin → microangiopathic haemolytic anaemia + thrombocytopaenia + AKI"],
["Treatment of 1st-episode C. difficile", "Fidaxomicin (preferred over vancomycin for reducing recurrence)"],
["Fecal microbiota transplant (FMT) indication", "Recurrent C. difficile infection (90% cure rate)"],
["Rotavirus vaccine impact", "Dramatically reduced fatal childhood diarrhoea globally; oral live attenuated vaccine"],
["Whipple's disease causative organism", "Tropheryma whipplei (T. whipplei)"],
["Whipple's disease histology", "PAS-positive foamy macrophages in lamina propria"],
["Whipple's disease treatment", "Cotrimoxazole (TMP-SMX) for 1 year"],
["Carcinoid causing diarrhoea — test", "Urine 5-HIAA (24h collection); also serum serotonin, chromogranin A"],
["VIPoma = WDHA syndrome", "Watery Diarrhoea + Hypokalaemia + Achlorhydria; treat with octreotide + surgery"],
["Dermatitis herpetiformis — treatment", "Gluten-free diet (primary) + Dapsone (symptomatic relief)"],
["Malignant complication of untreated coeliac", "Enteropathy-associated T-cell lymphoma (EATL); also small bowel adenocarcinoma"],
["SIBO gold standard test", "Jejunal aspirate culture >10⁵ CFU/mL; breath test (glucose H₂) is simpler"],
["Tropical sprue treatment", "Tetracycline + Folic acid; vitamin B12 if deficient"],
["Bile acid diarrhoea (post-ileal resection) treatment", "Cholestyramine (bile acid sequestrant)"],
]
story.append(make_table(hyl_data, [8*cm, 9.4*cm], header_color=DARK_RED, row_colors=[colors.white, LR]))
story += [SP(0.2)]
story.append(H2("5.4 Mnemonics"))
story += [
Paragraph("<b>MALABSORPTION SYNDROME deficiencies:</b>", body_style),
B("Fat-soluble vitamins: <b>ADEK</b> — A (night blindness), D (rickets/osteomalacia), E (neuropathy), K (bleeding)"),
B("Water-soluble: <b>B12</b> (terminal ileum disease/pernicious anaemia) and <b>Folate</b> (proximal jejunum disease/coeliac)"),
B("Minerals: <b>CAME</b> = Calcium + anaemia (iron/B12/folate) + Magnesium + E (zinc → acroder. enteropath.)"),
SP(0.1),
Paragraph("<b>CELIAC DISEASE — 'CELIAC' mnemonic:</b>", body_style),
B("C — CD4+ T cells, CDX2, crypt hyperplasia"),
B("E — EMA-IgA, endomysial antibody"),
B("L — Lymphocytic infiltration (IEL ↑), LSBE (risk in Barrett's)"),
B("I — Intestinal villous atrophy (flat mucosa), IgA-tTG"),
B("A — Autoimmune associations (DM1, thyroid), ADEK deficiencies"),
B("C — Cancer risk (EATL, adenocarcinoma), Calcium/vitamin D loss"),
SP(0.1),
Paragraph("<b>Diarrhoea types: SOME</b>", body_style),
B("S = Secretory (↑ cAMP/cGMP, persists with fasting)"),
B("O = Osmotic (stops with fasting; gap >125)"),
B("M = Motility-related (IBS, hyperthyroidism)"),
B("E = Exudative/inflammatory (bloody, leukocytes, fever)"),
]
story += [SP(0.3), HR()]
story.append(Paragraph(
"<i>References: Goldman-Cecil Medicine 26th ed.; Sleisenger & Fordtran's GI & Liver Disease 11th ed.; "
"Harrison's Principles of Internal Medicine 22nd ed. (2025); Henry's Clinical Diagnosis & Management "
"by Laboratory Methods; Ganong's Review of Medical Physiology 26th ed.; Yamada's Gastroenterology 7th ed. "
"| Compiled for FMGE / USMLE / University Exam Preparation | July 2026</i>",
footer_style
))
doc.build(story)
print(f"PDF saved: {OUTPUT_PATH}")
cd /tmp/workspace/si-notes && python generate_pdf.py 2>&1
cd /tmp/workspace/si-notes && sed -i 's/def B(text, l=1):/def B(text, l=1, level=None):/' generate_pdf.py && sed -i '/def B(text, l=1, level=None):/a\ if level is not None: l = level' generate_pdf.py && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/si-notes/SmallIntestine_Malabsorption_Diarrhea_Celiac.pdf
SmallIntestine Malabsorption Diarrhea Celiac
PDF Document · PDF
This pdf have some mistakes. Can you make another one .