~/surgery-summary/create_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, HRFlowable, PageBreak, KeepTogether)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
from reportlab.pdfgen import canvas
OUTPUT = "/tmp/workspace/surgery-summary/Surgery_Mnemonics_HY_Facts.pdf"
# ββ Color palette ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DARK_BLUE = colors.HexColor("#1A237E")
MID_BLUE = colors.HexColor("#283593")
LIGHT_BLUE = colors.HexColor("#E8EAF6")
ACCENT = colors.HexColor("#FF6F00") # amber
GREEN = colors.HexColor("#1B5E20")
GREEN_LIGHT = colors.HexColor("#E8F5E9")
RED = colors.HexColor("#B71C1C")
RED_LIGHT = colors.HexColor("#FFEBEE")
GOLD = colors.HexColor("#F9A825")
GOLD_LIGHT = colors.HexColor("#FFFDE7")
PURPLE = colors.HexColor("#4A148C")
PURPLE_LIGHT= colors.HexColor("#F3E5F5")
TEAL = colors.HexColor("#004D40")
TEAL_LIGHT = colors.HexColor("#E0F2F1")
GREY_LIGHT = colors.HexColor("#F5F5F5")
GREY_MED = colors.HexColor("#BDBDBD")
WHITE = colors.white
BLACK = colors.black
# ββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle",
fontName="Helvetica-Bold", fontSize=28, textColor=WHITE,
alignment=TA_CENTER, leading=34, spaceAfter=8)
cover_sub = S("CoverSub",
fontName="Helvetica-Bold", fontSize=14, textColor=GOLD,
alignment=TA_CENTER, leading=20, spaceAfter=4)
cover_info = S("CoverInfo",
fontName="Helvetica", fontSize=11, textColor=WHITE,
alignment=TA_CENTER, leading=16)
chapter_title = S("ChapterTitle",
fontName="Helvetica-Bold", fontSize=15, textColor=WHITE,
alignment=TA_LEFT, leading=18, leftIndent=6)
section_title = S("SectionTitle",
fontName="Helvetica-Bold", fontSize=12, textColor=DARK_BLUE,
alignment=TA_LEFT, leading=14, spaceBefore=10, spaceAfter=4,
leftIndent=4, borderPad=2)
hy_title = S("HYTitle",
fontName="Helvetica-Bold", fontSize=10, textColor=RED,
alignment=TA_LEFT, leading=12, spaceBefore=4, spaceAfter=2)
mnemonic_title = S("MnemonicTitle",
fontName="Helvetica-Bold", fontSize=10, textColor=PURPLE,
alignment=TA_LEFT, leading=12, spaceBefore=4, spaceAfter=2)
body = S("Body",
fontName="Helvetica", fontSize=9, textColor=BLACK,
alignment=TA_LEFT, leading=13, spaceAfter=2, leftIndent=4)
body_bold = S("BodyBold",
fontName="Helvetica-Bold", fontSize=9, textColor=BLACK,
alignment=TA_LEFT, leading=13, spaceAfter=2, leftIndent=4)
bullet_style = S("Bullet",
fontName="Helvetica", fontSize=9, textColor=BLACK,
alignment=TA_LEFT, leading=12, leftIndent=12, firstLineIndent=-8,
spaceAfter=2)
bullet_bold = S("BulletBold",
fontName="Helvetica-Bold", fontSize=9, textColor=DARK_BLUE,
alignment=TA_LEFT, leading=12, leftIndent=12, firstLineIndent=-8,
spaceAfter=2)
small = S("Small",
fontName="Helvetica", fontSize=8, textColor=colors.HexColor("#444444"),
alignment=TA_LEFT, leading=11, leftIndent=4)
footer_style = S("Footer",
fontName="Helvetica-Oblique", fontSize=7, textColor=colors.HexColor("#888888"),
alignment=TA_CENTER)
# ββ Helper builders ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def chapter_header(title, color=DARK_BLUE):
"""Colored full-width chapter banner."""
data = [[Paragraph(title, chapter_title)]]
t = Table(data, colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("ROWBACKGROUNDS", (0,0), (-1,-1), [color]),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return t
def section_box(title, bg=LIGHT_BLUE, fg=DARK_BLUE):
"""Section heading in colored box."""
st = S("_sec", fontName="Helvetica-Bold", fontSize=11, textColor=fg,
alignment=TA_LEFT, leading=13)
data = [[Paragraph(f"βΆ {title}", st)]]
t = Table(data, colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
]))
return t
def hy_box(lines, color=RED_LIGHT, border=RED):
"""HIGH YIELD orange/red box."""
label_style = S("_hyl", fontName="Helvetica-Bold", fontSize=9,
textColor=border, leading=12, alignment=TA_LEFT)
content = [Paragraph("β
HIGH YIELD", label_style)]
for l in lines:
content.append(Paragraph(f"β’ {l}", bullet_style))
data = [[content]]
t = Table([[content]], colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("BOX", (0,0), (-1,-1), 1, border),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def mnemonic_box(mnemonic_name, lines, color=PURPLE_LIGHT, border=PURPLE):
"""Mnemonic box in purple."""
label_style = S("_mnl", fontName="Helvetica-Bold", fontSize=9,
textColor=border, leading=12, alignment=TA_LEFT)
content = [Paragraph(f"π§ MNEMONIC: {mnemonic_name}", label_style)]
for l in lines:
content.append(Paragraph(f" {l}", bullet_style))
t = Table([[content]], colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("BOX", (0,0), (-1,-1), 1, border),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def gold_box(title, lines):
"""Gold PYT box."""
label_style = S("_gl", fontName="Helvetica-Bold", fontSize=9,
textColor=colors.HexColor("#7B5E00"), leading=12, alignment=TA_LEFT)
content = [Paragraph(f"π PYT GOLD: {title}", label_style)]
for l in lines:
content.append(Paragraph(f"β’ {l}", bullet_style))
t = Table([[content]], colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GOLD_LIGHT),
("BOX", (0,0), (-1,-1), 1.5, GOLD),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def green_box(lines):
"""Tip/Note green box."""
label_style = S("_gnl", fontName="Helvetica-Bold", fontSize=9,
textColor=GREEN, leading=12, alignment=TA_LEFT)
content = [Paragraph("β
KEY RULE / NOTE", label_style)]
for l in lines:
content.append(Paragraph(f"β’ {l}", bullet_style))
t = Table([[content]], colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GREEN_LIGHT),
("BOX", (0,0), (-1,-1), 1, GREEN),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def teal_box(lines):
"""Comparison / differentiation box."""
label_style = S("_tl", fontName="Helvetica-Bold", fontSize=9,
textColor=TEAL, leading=12, alignment=TA_LEFT)
content = [Paragraph("β‘ DIFFERENTIATOR", label_style)]
for l in lines:
content.append(Paragraph(f"β’ {l}", bullet_style))
t = Table([[content]], colWidths=[170*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL_LIGHT),
("BOX", (0,0), (-1,-1), 1, TEAL),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def make_table(headers, rows, col_widths=None, header_bg=DARK_BLUE):
"""Generic styled table."""
if col_widths is None:
w = 170*mm / max(len(headers),1)
col_widths = [w]*len(headers)
header_style = S("_th", fontName="Helvetica-Bold", fontSize=8.5,
textColor=WHITE, leading=11, alignment=TA_CENTER)
cell_style = S("_td", fontName="Helvetica", fontSize=8.5,
textColor=BLACK, leading=11, alignment=TA_LEFT)
bold_cell = S("_tdb", fontName="Helvetica-Bold", fontSize=8.5,
textColor=DARK_BLUE, leading=11, alignment=TA_LEFT)
data = [[Paragraph(h, header_style) for h in headers]]
for r in rows:
row = []
for i, cell in enumerate(r):
if isinstance(cell, str) and cell.startswith("**") and cell.endswith("**"):
row.append(Paragraph(cell[2:-2], bold_cell))
else:
row.append(Paragraph(str(cell), cell_style))
data.append(row)
t = Table(data, colWidths=col_widths, repeatRows=1)
row_colors = []
for i in range(1, len(data)):
bg = GREY_LIGHT if i % 2 == 0 else WHITE
row_colors.append(("BACKGROUND", (0,i), (-1,i), bg))
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), header_bg),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
] + row_colors))
return t
def sp(n=4): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.5, color=GREY_MED, spaceAfter=4, spaceBefore=4)
# ββ Page numbering βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def add_page_number(canvas_obj, doc):
canvas_obj.saveState()
canvas_obj.setFont("Helvetica", 7)
canvas_obj.setFillColor(colors.HexColor("#888888"))
canvas_obj.drawCentredString(A4[0]/2, 10*mm,
f"Surgery Part 1 β Mnemonics & High-Yield Facts | Page {doc.page}")
# top banner stripe
canvas_obj.setFillColor(DARK_BLUE)
canvas_obj.rect(0, A4[1]-8*mm, A4[0], 8*mm, fill=1, stroke=0)
canvas_obj.setFont("Helvetica-Bold", 7)
canvas_obj.setFillColor(WHITE)
canvas_obj.drawString(15*mm, A4[1]-5.5*mm, "SURGERY PART 1 β HYPERREVISION")
canvas_obj.drawRightString(A4[0]-15*mm, A4[1]-5.5*mm, "Cerebellum 20th Course @AnandxBotss")
canvas_obj.restoreState()
# ββ COVER PAGE βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def cover_page(canvas_obj, doc):
w, h = A4
# gradient-like background
canvas_obj.setFillColor(DARK_BLUE)
canvas_obj.rect(0, 0, w, h, fill=1, stroke=0)
canvas_obj.setFillColor(MID_BLUE)
canvas_obj.rect(0, 0, w, h*0.45, fill=1, stroke=0)
# accent stripe
canvas_obj.setFillColor(ACCENT)
canvas_obj.rect(0, h*0.45, w, 4, fill=1, stroke=0)
# bottom watermark text
canvas_obj.setFont("Helvetica-Bold", 80)
canvas_obj.setFillColor(colors.HexColor("#FFFFFF10"))
canvas_obj.drawCentredString(w/2, h*0.15, "SURGERY")
# page number off for cover
pass
# ββ BUILD DOCUMENT βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story = []
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# PAGE 1 β COVER
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
cover_bg_style = S("covbg",
fontName="Helvetica-Bold", fontSize=32, textColor=WHITE,
alignment=TA_CENTER, leading=38, spaceBefore=60, spaceAfter=6)
story.append(Spacer(1, 55*mm))
story.append(Paragraph("SURGERY PART 1", cover_bg_style))
story.append(Paragraph("Mnemonics & High-Yield Facts", S("_cs2",
fontName="Helvetica-Bold", fontSize=18, textColor=GOLD,
alignment=TA_CENTER, leading=22, spaceAfter=8)))
story.append(Spacer(1, 6))
story.append(Paragraph("GIT Β· Esophagus Β· Stomach Β· Intestines Β· Anal Disorders Β· Hernia Β· Hepatobiliary",
S("_cs3", fontName="Helvetica", fontSize=10, textColor=WHITE,
alignment=TA_CENTER, leading=14)))
story.append(Spacer(1, 14*mm))
cover_table_data = [
[Paragraph("π SOURCE", S("_ct", fontName="Helvetica-Bold", fontSize=9, textColor=GOLD, alignment=TA_CENTER)),
Paragraph("Cerebellum's Hyperrevision β 20th Course", S("_cv", fontName="Helvetica", fontSize=9, textColor=WHITE, alignment=TA_LEFT))],
[Paragraph("π
DATE", S("_ct", fontName="Helvetica-Bold", fontSize=9, textColor=GOLD, alignment=TA_CENTER)),
Paragraph("July 2026", S("_cv", fontName="Helvetica", fontSize=9, textColor=WHITE, alignment=TA_LEFT))],
[Paragraph("π― PURPOSE", S("_ct", fontName="Helvetica-Bold", fontSize=9, textColor=GOLD, alignment=TA_CENTER)),
Paragraph("Quick revision β mnemonics, differentiators, exam-ready facts", S("_cv", fontName="Helvetica", fontSize=9, textColor=WHITE, alignment=TA_LEFT))],
]
ct = Table(cover_table_data, colWidths=[38*mm, 120*mm])
ct.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#283593")),
("BOX", (0,0), (-1,-1), 1, GOLD),
("INNERGRID", (0,0), (-1,-1), 0.3, colors.HexColor("#3F51B5")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(ct)
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 1 β ESOPHAGUS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 1: ESOPHAGEAL DISORDERS", DARK_BLUE))
story.append(sp(6))
# --- ACHALASIA ---
story.append(section_box("ACHALASIA CARDIA", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(KeepTogether([
mnemonic_box("THREE CITIES OF ESOPHAGUS", [
"ποΈ CHICAGO β Manometry classification of Achalasia",
"ποΈ MONTREAL β Definition of GERD",
"ποΈ LA (Los Angeles) β Grading of GERD severity (AβD)",
]),
sp(5),
hy_box([
"MC motility disorder of esophagus",
"Dysphagia: LIQUIDS > SOLIDS (key differentiator from malignancy where SOLIDS > LIQUIDS)",
"Triad: Dysphagia + Regurgitation + Weight loss",
"IOC: High-Resolution Manometry (HRM) β Absent peristalsis + Elevated LES pressure",
"Type 3 Achalasia (Spastic) β TOC = POEM | Type 1 & 2 β TOC = Heller's Cardiomyotomy",
]),
sp(5),
]))
story.append(make_table(
["Type", "Manometry Findings", "Key Point"],
[
["Type 1 (MC)", "Absent peristalsis + High resting LES pressure", "BOTH must be present"],
["Type 2", "Type 1 + Pan-esophageal pressurization β₯20% swallows", "Best response to treatment"],
["Type 3 (Spastic)", "Type 1 + Premature spasms in esophagus", "TOC = POEM"],
],
col_widths=[30*mm, 90*mm, 50*mm]
))
story.append(sp(5))
story.append(mnemonic_box("Allgrove Syndrome = AAA", [
"A β Adrenal insufficiency",
"A β Alacrymia (no tears)",
"A β Achalasia",
]))
story.append(sp(8))
# --- BOERHAAVE ---
story.append(section_box("BOERHAAVE SYNDROME (Spontaneous Perforation)", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(mnemonic_box("Mackler's TRIAD", [
"1. Chest pain (retrosternal)",
"2. Retching / vomiting",
"3. Subcutaneous emphysema",
]))
story.append(sp(4))
story.append(hy_box([
"Cause: Alcohol binge β forceful vomiting β esophagus bursts",
"Site: Left lower esophagus (weak area)",
"IOC: CT with WATER-SOLUBLE contrast (NOT barium β barium is toxic when it leaks!)",
"Sites of narrowing: 15 cm (Cricopharynx β MC perforation) | 25 cm (L bronchus/Aorta) | 40 cm (Diaphragm)",
]))
story.append(sp(8))
# --- GERD & BARRETT'S ---
story.append(section_box("GERD / BARRETT'S ESOPHAGUS", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(hy_box([
"GERD gold standard: 24-hr pH Study β DeMeester score >14.7 = POSITIVE",
"LA grading on endoscopy: AβD (severity of esophageal erosions)",
"TOC: PPI + Lifestyle modifications (4β8 weeks)",
"Barrett's = Squamous β Columnar metaplasia (chronic GERD)",
"Endoscopy: Salmon-pink tongue-like projections at GE junction (NOT erosions!)",
"Seattle biopsy: 4-quadrant biopsies at 2 cm intervals",
"High-grade dysplasia β 7%/year cancer risk β Excision + Surveillance",
]))
story.append(sp(5))
story.append(make_table(
["Dysplasia Grade", "Cancer Risk/Year", "Treatment"],
[
["No dysplasia", "0.2β0.5%", "Treat GERD (PPI + LSM)"],
["Low grade", "0.7%", "EMR / Radiofrequency Ablation (RFA)"],
["High grade", "7%", "Excision (endoscopic/surgical) + Surveillance"],
],
col_widths=[50*mm, 40*mm, 80*mm]
))
story.append(sp(5))
story.append(teal_box([
"Achalasia: Dysphagia liquids > solids | Malignancy: Dysphagia solids > liquids",
"Barrett's endoscopy: Salmon-pink projections (NOT erosions β those are GERD)",
"Corrosive injury: Alkali = liquefaction (worse, deeper) | Acid = coagulation (shallower)",
"Pilonidal sinus vs Fistula in Ano: Pilonidal = upper natal cleft | Fistula = near anal verge",
]))
story.append(sp(8))
# --- HIATUS HERNIA ---
story.append(section_box("HIATUS HERNIA + FUNDOPLICATIONS", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(make_table(
["Type", "Mechanism", "Association", "Treatment"],
[
["Type 1: Sliding (MC)", "GE junction slides into chest; muscle weakness", "GERD", "Nissen/Toupet"],
["Type 2: Rolling (Paraesophageal)", "Fundus herniates beside esophagus; GE junction normal", "NOT GERD", "Surgery + fix defect"],
["Type 3: Mixed", "Both GE junction + fundus herniate", "GERD + weakness", "Combine both"],
],
col_widths=[40*mm, 58*mm, 32*mm, 40*mm]
))
story.append(sp(5))
story.append(make_table(
["Procedure", "Wrap", "Key Points"],
[
["Nissen (Floppy)", "360Β° complete", "MC complication: Short-term dysphagia (<3 months); also gas bloat, vagus nerve injury"],
["Toupet", "270Β° posterior", "Less dysphagia than Nissen; commonly done now"],
["Dor", "180Β° anterior", "Partial wrap"],
],
col_widths=[38*mm, 32*mm, 100*mm]
))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 2 β STOMACH & DUODENUM
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 2: STOMACH & DUODENUM", MID_BLUE))
story.append(sp(6))
# --- CA STOMACH ---
story.append(section_box("CA STOMACH", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(mnemonic_box("Risk Factors β 4S + 1D", [
"S β Smoking",
"S β Spirits (alcohol)",
"S β Sepsis (H. pylori β lives in antrum, Type B gastritis)",
"S β Smoked foods / Soya sauce",
"D β Diet (nitrates, smoked foods)",
]))
story.append(sp(5))
story.append(hy_box([
"H. pylori causes: Chronic Gastritis + Peptic Ulcers + Gastric Cancer (Adenocarcinoma + MALT lymphoma)",
"Golden Rule ALL GI Cancers: ELDERLY MALE SMOKER β Think Malignancy",
"MC site of CA Stomach: Antrum",
"Diagnosis: UGI Endoscopy + Biopsy (1st step & IOC) | Local staging: EUS | Distant: PET Scan",
"Surgery: Radical Gastrectomy + D2 Lymphadenectomy | Chemo: FLOT regimen (Platinum-based)",
]))
story.append(sp(5))
story.append(make_table(
["Sign", "Location", "Origin"],
[
["Virchow's node", "Left supraclavicular lymph node", "GI cancer metastasis (MC from stomach)"],
["Sister Mary Joseph nodule", "Para-umbilical nodule", "Peritoneal metastasis"],
["Krukenberg tumour", "Bilateral ovaries", "Haematogenous spread from stomach"],
["Irish node", "Left axillary lymph node", "GI cancer metastasis"],
],
col_widths=[50*mm, 60*mm, 60*mm]
))
story.append(sp(8))
# --- IHPS ---
story.append(section_box("IHPS (Infantile Hypertrophic Pyloric Stenosis)", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(hy_box([
"NOT congenital β presents at 4β8 WEEKS after birth, NOT at birth",
"Projectile, NON-BILIOUS vomiting after feeds",
"Olive-shaped mass in RUQ (best felt when baby is relaxed/during feeding)",
"Visible peristalsis: LEFT to RIGHT direction",
"IOC: USG abdomen β pylorus thickness β₯4 mm is diagnostic",
"X-ray: Single bubble (dilated stomach) | Barium: Mushroom appearance",
"DDx from Neonatal GERD: GERD is non-projectile; improves with growth",
]))
story.append(sp(5))
story.append(mnemonic_box("IHPS Classic Metabolic Triad", [
"Hypo KALEMIA",
"Hypo CHLOREMIA",
"Metabolic ALKALOSIS with Paradoxical ACIDURIA",
"(Acid is lost in vomit β body tries to conserve H+ β paradoxically excretes H+ in urine)",
]))
story.append(sp(5))
story.append(green_box([
"Step 1: Correct DEHYDRATION FIRST (Fluid: DNS with KCl)",
"Step 2: Ramstedt's Pyloromyotomy β cut adventitia β cut muscularis β DO NOT cut mucosa",
]))
story.append(sp(8))
# --- PUD ---
story.append(section_box("PEPTIC ULCER DISEASE (PUD)", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(make_table(
["Johnson Type", "Location", "Acid Level", "Surgery"],
[
["I", "Distal lesser curvature", "Normal", "Ulcer resection only"],
["II", "Lesser curve + Duodenal (double)", "HIGH", "Acid-lowering surgery"],
["III", "Pyloric / Pre-pyloric", "HIGH", "Acid-lowering surgery"],
["IV", "Proximal lesser curvature", "Normal", "Similar to Type I"],
["V", "Anywhere (NSAID-induced)", "NSAID-related", "Stop NSAIDs"],
],
col_widths=[28*mm, 55*mm, 32*mm, 55*mm]
))
story.append(sp(5))
story.append(mnemonic_box("Vagotomy Procedures β Bailey's Golden Rule", [
"HSV (Highly Selective Vagotomy) = BEST TOLERATED",
" β Mortality <0.2% | Side effects <5% | Recurrence 2β10% (acceptable)",
" β Spares pyloric Crow's Foot / Nerves of Latarjet | NO drainage needed",
"TV + Antrectomy = 'With great power come great complications'",
" β Lowest recurrence (1%) BUT highest side effects (10β20%) + mortality (1%)",
]))
story.append(sp(5))
story.append(hy_box([
"D1 Ulcer memory aid: ANTERIOR wall = Perforate | POSTERIOR wall = Bleed (erodes GDA)",
"Posterior D1 bleeds from: Gastroduodenal Artery (GDA)",
"MC cause of UGI Bleed: Bleeding Peptic Ulcer (NOT varices!)",
"Graham's Omental Patch = DU Perforation | Simple suture = Ileal/Gastric Perforation",
"Gastric perforation β ALWAYS take biopsy (rule out malignancy)",
]))
story.append(sp(8))
story.append(PageBreak())
# --- DUMPING + UGI BLEED ---
story.append(chapter_header("SECTION 2 (cont.): DUMPING + UGI BLEED", MID_BLUE))
story.append(sp(6))
story.append(section_box("DUMPING SYNDROME", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(make_table(
["Feature", "Early Dumping", "Late Dumping"],
[
["Timing", "Within minutes of meal", "1β3 hours after meal"],
["Mechanism", "Osmotic fluid shift (hyperosmolar food β jejunum)", "Rebound hypoglycemia"],
["BP", "LOW", "Normal"],
["Blood Sugar", "Normal", "LOW"],
["Symptoms", "Sweating, tachycardia, diarrhea, lightheadedness", "Tremors, fainting, sense of impending doom"],
["Relieves with", "Lying down", "Food intake"],
],
col_widths=[38*mm, 66*mm, 66*mm]
))
story.append(sp(4))
story.append(green_box([
"Trigger: High sugar foods (milkshakes, fruit juices, refined flour, bananas)",
"Medical: Acarbose | Severe: Octreotide",
]))
story.append(sp(8))
story.append(section_box("UPPER GI BLEED β FORREST CLASSIFICATION", LIGHT_BLUE, DARK_BLUE))
story.append(sp(4))
story.append(make_table(
["Grade", "Finding", "Rebleed Risk", "Management"],
[
["Ia", "Active arterial jet (spurting)", "HIGH", "Dual Endotherapy"],
["Ib", "Active oozing (diffuse)", "HIGH", "Dual Endotherapy"],
["IIa", "Visible vessel (stopped)", "HIGH", "Dual Endotherapy"],
["IIb", "Adherent clot (stopped)", "INTERMEDIATE", "Endotherapy"],
["IIc", "Black spot/flat (stopped)", "LOW", "Medical management"],
["III", "Clean base, no bleeding", "LOW", "Medical management"],
],
col_widths=[18*mm, 55*mm, 35*mm, 62*mm]
))
story.append(sp(5))
story.append(mnemonic_box("Dual Endotherapy = Any 2 of 3", [
"1. CLIP the vessel",
"2. INJECT Adrenaline",
"3. APC β Argon Plasma Coagulation",
"Can attempt endotherapy TWICE. If still bleeds β Angioembolization of GDA OR Surgery",
]))
story.append(sp(5))
story.append(mnemonic_box("Scoring Systems", [
"ROCKALL Score = Rebleed risk + MORTALITY (ABCDE: Age, BP, Comorbidities, Diagnosis, Endoscopic appearance)",
"GLASGOW-BLATCHFORD = Does NOT look at endoscopic findings",
"FORREST = ONLY specific for PU bleeding",
]))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 3 β INTESTINAL DISORDERS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 3: INTESTINAL DISORDERS", colors.HexColor("#1B5E20")))
story.append(sp(6))
story.append(section_box("INTESTINAL TB vs CROHN'S DISEASE", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(make_table(
["Feature", "Intestinal TB", "Crohn's Disease"],
[
["Cause", "Mycobacterium tuberculosis (swallowed sputum)", "Autoimmune; NOD2 mutation"],
["MC Site", "Terminal ileum / IC junction", "Terminal ileum (mouth to anus)"],
["Ulcer type", "TRANSVERSE / circumferential β STRICTURE", "Longitudinal/serpiginous"],
["Histology", "CASEATING granulomas; transmural", "NON-CASEATING granulomas; transmural"],
["Gross Appearance", "Strictures, tubercles on peritoneum", "Creeping fat, cobblestone mucosa"],
["Serology", "CBNAAT, TB culture", "ASCA positive"],
["Treatment", "ATT (2 HRZE + 4β6 HRE); surgery ONLY for complications", "Immunosuppression (steroids, biologics); surgery for complications"],
],
col_widths=[36*mm, 67*mm, 67*mm]
))
story.append(sp(5))
story.append(teal_box([
"TB ulcers: TRANSVERSE β heal by fibrosis β STRICTURE",
"Typhoid ulcers: LONGITUDINAL β do NOT cause stricture (key differentiator!)",
"Investigation Dictum: UGI symptoms β UGI Endoscopy | Acute abdomen β X-ray/USG β CECT | Lower GI β Stool exam β Colonoscopy",
]))
story.append(sp(8))
# --- ACUTE APPENDICITIS ---
story.append(section_box("ACUTE APPENDICITIS", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(mnemonic_box("Alvarado Score β MANTRELS", [
"M β Migration of pain (1)",
"A β Anorexia (1)",
"N β Nausea / Vomiting (1)",
"T β Tenderness in RIF (2) β double points",
"R β Rebound tenderness (1)",
"E β Elevated temperature (1)",
"L β Leucocytosis (2) β double points",
"S β Shift to left of WBCs (1)",
"Score β₯7/10 = Appendicitis LIKELY",
]))
story.append(sp(5))
story.append(make_table(
["Sign", "Description"],
[
["McBurney's tenderness", "Point of max tenderness β 2/3 from umbilicus to ASIS on right side"],
["Blumberg sign", "Rebound tenderness β pain on releasing pressure in RIF"],
["Rovsing sign", "Press in LIF β pain in RIF"],
["Psoas sign", "Pain on hip extension β retrocaecal appendix (70% MC position)"],
["Obturator sign", "Pain on hip flexion β pelvic appendix (20β25%)"],
],
col_widths=[50*mm, 120*mm]
))
story.append(sp(5))
story.append(hy_box([
"IOC: Children = USG (diameter β₯6 mm) | Adults = CECT abdomen | Pregnancy = MRI (USG first)",
"TOC: Laparoscopic appendectomy",
"Appendicular lump β Oschner-Sherren regimen (conservative)",
"Tumor at tip <1 cm β Appendectomy alone | At base or >2 cm β Right hemicolectomy",
"MC early complication: Wound infection | MC late complication: Adhesive intestinal obstruction",
"MC nerve injured: Iliohypogastric nerve β right-sided inguinal hernia risk",
"Amyand's hernia = Inguinal hernia containing appendix",
]))
story.append(sp(8))
story.append(PageBreak())
# --- POLYPOSIS ---
story.append(chapter_header("SECTION 3 (cont.): POLYPOSIS + CA COLON/RECTUM", colors.HexColor("#1B5E20")))
story.append(sp(6))
story.append(section_box("COLONIC POLYPOSIS SYNDROMES β All Autosomal Dominant!", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(make_table(
["Feature", "Peutz-Jeghers", "FAP", "HNPCC / Lynch"],
[
["Mutation", "STK11", "APC gene", "Mismatch repair (MSH, MLH)"],
["Polyp type", "Hamartomas (non-neoplastic)", "Adenomatous (>100)", "Few adenomas"],
["Location", "Small bowel + Colon + Rectum", "Colon + Rectum", "RIGHT colon (MC)"],
["CRC Risk", "Slightly β", "100% by 20s", "~80%"],
["Management", "Surveillance", "Prophylactic proctocolectomy before age 20", "Surveillance colonoscopy"],
["Other cancers", "Pancreatic adenoCA", "Gardner: osteomas, brain tumors (Turcot)", "Pancreatic, endometrial, ovarian"],
],
col_widths=[32*mm, 46*mm, 46*mm, 46*mm]
))
story.append(sp(5))
story.append(hy_box([
"Peutz-Jeghers: Lip/mucosal MELANOSIS β pathognomonic; hamartomas on small bowel",
"FAP: >100 adenomas = practically diagnostic; 100% cancer risk β prophylactic proctocolectomy BEFORE age 20",
"HNPCC: Non-polyposis (FEW adenomas) but HIGH cancer risk; RIGHT colon predominance",
]))
story.append(sp(8))
story.append(section_box("CA COLON & RECTUM", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(mnemonic_box("Blood in Stools by AGE", [
"Elderly Male Smoker β COLORECTAL CANCER",
"Young patient (20s) β ULCERATIVE COLITIS",
"Child β POLYP or MECKEL'S DIVERTICULUM",
]))
story.append(sp(5))
story.append(hy_box([
"MC site: Rectosigmoid (Rectum 38% + Sigmoid 21% = ~60%)",
"IOC: Colonoscopy + Biopsy (Adenocarcinoma β MC histology)",
"Local staging RECTUM: MRI rectum (preferred over EUS)",
"Local staging COLON: CECT abdomen | Distant mets: PET scan",
"Tumor marker: CEA (Carcinoembryonic Antigen)",
"Hematogenous spread: MC site = LIVER (50% of liver mets come from CRC)",
"GI cancers β LIVER mets | Urinary cancers β LUNG/BONE mets",
"Metformin + Aspirin are protective but NOT for prophylactic use",
]))
story.append(sp(5))
story.append(mnemonic_box("CA RECTUM β Special Rule", [
"CA RECTUM = ONLY GI cancer where NEOADJUVANT CHEMORADIATION is given",
"All other GI cancers β Neoadjuvant CHEMO ONLY",
"Chemo regimens: FOLFOX | FOLFIRI | FOLFOXIRI (5-FU based)",
]))
story.append(sp(5))
story.append(mnemonic_box("Nerve Injury in Rectal Surgery (NEET PG 2023)", [
"P for POINTING (erection) = PARASYMPATHETIC injury (Nervi erigentes S2βS4) β IMPOTENCE",
"S for SHOOTING (ejaculation) = SYMPATHETIC injury (Lumbar sympathetics L3βL4) β RETROGRADE EJACULATION",
"Injury during: High IMA ligation β Sympathetic | Lateral/AP dissection β Parasympathetic",
]))
story.append(sp(8))
story.append(PageBreak())
# --- INTUSSUSCEPTION / VOLVULUS / ILEUS ---
story.append(chapter_header("SECTION 3 (cont.): OBSTRUCTION + VOLVULUS", colors.HexColor("#1B5E20")))
story.append(sp(6))
story.append(section_box("INTUSSUSCEPTION", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(hy_box([
"MC type in CHILDREN: Ileocolic | Lead point: Hypertrophied Peyer's patches",
"MC type in ADULTS: Colocolic | Lead point: Tumors",
"Age: Weaning period (6 months β 1 year)",
"Classic: RED CURRANT JELLY STOOLS (mucosal ischemia)",
"Mass: Para-umbilical sausage-shaped | Sign of Dance: RIF feels empty",
"USG: Donut/Target appearance | Barium enema: CLAW sign",
"Treatment: STABLE β High-pressure enema (hydro-reduction) | UNSTABLE β Surgery",
]))
story.append(sp(8))
story.append(section_box("SIGMOID VOLVULUS", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(hy_box([
"Anti-clockwise twist of sigmoid β CLOSED LOOP OBSTRUCTION β TRUE SURGICAL EMERGENCY",
"Elderly patient, chronic constipation, sudden massive distension + obstipation",
"X-ray: COFFEE BEAN SIGN (also called: Bent inner tube sign)",
"Management: X-ray β CECT (assess ischemia)",
"No ischemia: Colonoscopic decompression β Elective sigmoidectomy after 2β3 days",
"Ischemia / failed: Emergency sigmoidectomy",
]))
story.append(sp(8))
story.append(section_box("PARALYTIC ILEUS vs MECHANICAL OBSTRUCTION", GREEN_LIGHT, GREEN))
story.append(sp(4))
story.append(make_table(
["Feature", "Paralytic Ileus", "Mechanical Obstruction"],
[
["Pain", "NO colicky pain", "Colicky pain PRESENT"],
["Bowel sounds", "ABSENT", "Present (exaggerated/high-pitched)"],
["Air-fluid levels", "Absent / diffuse dilated bowel", "Step-ladder pattern"],
["Air in rectum", "Present", "Absent (distal collapse)"],
["MC cause", "Post-laparotomy", "Adhesions (MC in adults)"],
["MC electrolyte abnormality", "Hypokalemia", "Variable"],
["Management", "NPO + IV fluids + correct K+ (2β3 days)", "CECT abdomen β Surgery"],
],
col_widths=[50*mm, 60*mm, 60*mm]
))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 4 β ANAL DISORDERS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 4: ANAL DISORDERS", colors.HexColor("#4A148C")))
story.append(sp(6))
story.append(section_box("FISTULA IN ANO β Park's Classification", PURPLE_LIGHT, PURPLE))
story.append(sp(4))
story.append(make_table(
["Type", "Name", "Course", "Frequency", "Classification"],
[
["1", "Intersphincteric", "Between internal & external sphincter", "MC", "LOW"],
["2", "Transsphincteric", "Crosses through external sphincter", "2nd MC", "LOW"],
["3", "Suprasphincteric", "Above ext sphincter, crosses levator ani", "Rare", "HIGH"],
["4", "Extrasphincteric", "From rectum to perianal skin", "Least common", "HIGH"],
],
col_widths=[14*mm, 38*mm, 56*mm, 28*mm, 34*mm]
))
story.append(sp(5))
story.append(hy_box([
"IOC: MRI Perineum (Goodsall's Rule predicts course of fistula tract)",
"LOW fistula (Types 1 & 2): Fistulectomy or Fistulotomy",
"HIGH/Complex fistula (Types 3 & 4): Seton insertion (Kshar Sutra)",
"Seton = sphincter-saving; causes fibrosis to close tract over weeks",
"Cause: Usually secondary to perianal abscess β then discharge",
]))
story.append(sp(8))
story.append(section_box("HEMORRHOIDS", PURPLE_LIGHT, PURPLE))
story.append(sp(4))
story.append(hy_box([
"Origin: ABOVE dentate line (dilated superior hemorrhoidal veins)",
"Presentation: PAINLESS bleeding = 'Splash in the pan'",
"IOC: Proctoscopy β seen at 3, 7, 11 o'clock positions",
"ALWAYS do DRE first! If anal spasm β Proctoscopy CONTRAINDICATED (vasovagal risk)",
]))
story.append(sp(4))
story.append(make_table(
["Grade", "Description", "Treatment"],
[
["Grade 1", "Inside anus, asymptomatic (or bleeding)", "Conservative / Barron's band ligation / Sclerotherapy"],
["Grade 2", "Exit but return spontaneously", "Barron's band ligation or Sclerotherapy"],
["Grade 3", "Exit anus, manually reducible", "Stapled hemorrhoidopexy or Milligan-Morgan"],
["Grade 4", "Permanently outside, irreducible", "Stapled hemorrhoidopexy or Milligan-Morgan open"],
],
col_widths=[22*mm, 58*mm, 90*mm]
))
story.append(sp(8))
story.append(section_box("FISSURE IN ANO", PURPLE_LIGHT, PURPLE))
story.append(sp(4))
story.append(teal_box([
"Fissure: BELOW dentate line | Hemorrhoids: ABOVE dentate line",
"Fissure: PAINFUL (MC painful condition) | Hemorrhoids: PAINLESS",
"Fissure bleeding: STREAKING pattern | Hemorrhoids: SPLASH in the pan",
"Proctoscopy CONTRAINDICATED in fissure (anal spasm present)",
"Sentinel pile = skin tag covering the ulcer (misnomer β NOT a true pile mass)",
]))
story.append(sp(4))
story.append(green_box([
"Conservative: Laxatives + Lignocaine gel + Sitz bath",
"Surgery: Lateral Internal Sphincterotomy (of Notaras) β cut internal sphincter to relieve spasm",
]))
story.append(sp(8))
story.append(section_box("PILONIDAL SINUS", PURPLE_LIGHT, PURPLE))
story.append(sp(4))
story.append(hy_box([
"Site: UPPER END of natal cleft (overlying coccyx) β NOT near anal verge",
"Contains hair (hair falls INTO the sinus, not grows from it)",
"Seen in men with hairy back; clinical diagnosis",
"Karydakis: Elliptical PARAMEDIAN excision (suture line avoids midline)",
"Limberg flap: Rhomboid excision with local flap reconstruction",
"Bascom: Linear paramedian incision β excise tracts from the side",
]))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 5 β HERNIA
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 5: HERNIA", colors.HexColor("#BF360C")))
story.append(sp(6))
story.append(section_box("INGUINAL HERNIA", RED_LIGHT, RED))
story.append(sp(4))
story.append(make_table(
["Type", "Defect", "Key Feature"],
[
["Indirect (MC overall)", "Deep ring (fascia transversalis)", "Enters scrotum; any age; accompanies spermatic cord"],
["Direct", "Hesselbach's triangle (weakness)", "Purely inguinal (doesn't enter scrotum); elderly men"],
["Femoral", "Femoral ring", "More common in females vs males β but NOT MC hernia in females!"],
],
col_widths=[40*mm, 55*mm, 75*mm]
))
story.append(sp(5))
story.append(mnemonic_box("Hesselbach's Triangle β 'RIL'", [
"R β Rectus abdominis (medial border)",
"I β Inferior epigastric artery (lateral border)",
"L β Inguinal ligament (inferior border)",
"Direct hernia = MEDIAL to inferior epigastric artery (inside triangle)",
"Indirect hernia = LATERAL to inferior epigastric artery (outside triangle)",
]))
story.append(sp(5))
story.append(mnemonic_box("EHS Classification β 'Don't use D and I, use M and L'", [
"M = Medial (Direct) | L = Lateral (Indirect) | F = Femoral",
"1 = <1.5 cm | 2 = <3 cm | 3 = >3 cm",
"P = Primary | R = Recurrent",
"Example: Primary + Direct + 3cm defect = PM2 (NOT PD2!)",
]))
story.append(sp(5))
story.append(make_table(
["Named Hernia", "Content", "Key Feature"],
[
["Richter's", "Part/knuckle of bowel WALL only", "HIGH strangulation risk with NO obstruction (no lumen involved)"],
["Maydl's (W hernia)", "TWO loops of bowel (W-shape)", "Middle loop most vulnerable"],
["Amyand's", "Appendix inside hernia", "Inguinal hernia containing appendix β PYQ"],
["Littre's", "Meckel's diverticulum", "Very rare"],
],
col_widths=[35*mm, 50*mm, 85*mm]
))
story.append(sp(5))
story.append(hy_box([
"TOC Repair: Lichtenstein's tension-free hernioplasty β Mesh = Polypropylene (Prolene) β ONLAY",
"Open repair MC nerve injured: ILIOINGUINAL nerve β sensory loss at root of penis/inner thigh",
"Laparoscopic (TAPP/TEP) MC nerve injured: LATERAL CUTANEOUS NERVE OF THIGH β Meralgia paraesthetica",
"Laparoscopic: Can repair Direct + Indirect + Femoral + Obturator ALL AT ONCE",
]))
story.append(sp(5))
story.append(mnemonic_box("Triangles in Laparoscopic Inguinal Repair", [
"TRIANGLE OF DOOM: Vas deferens (medial) + Testicular vessels (lateral)",
" β Contains: External iliac vessels + Genital branch of Genitofemoral nerve",
" β Risk: Vascular injury (avoid dissecting here!)",
"TRIANGLE OF PAIN: Testicular vessels (medial) + Ilio-pubic tract (lateral)",
" β Contains: Lateral cutaneous nerve of thigh, Femoral nerve, Femoral branch of GFN",
" β Risk: Nerve injury β chronic pain / meralgia paraesthetica",
]))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SECTION 6 β HEPATOBILIARY
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("SECTION 6: HEPATOBILIARY DISORDERS", colors.HexColor("#006064")))
story.append(sp(6))
story.append(section_box("HYDATID CYST OF LIVER", TEAL_LIGHT, TEAL))
story.append(sp(4))
story.append(mnemonic_box("Echinococcus Host Chain", [
"Definitive host: DOG (adult worm lives here)",
"Intermediate host: SHEEP (cysts form here)",
"Man = ACCIDENTAL / DEAD-END host",
"MC site: LIVER | 2nd MC: LUNGS (via portal vein)",
]))
story.append(sp(5))
story.append(hy_box([
"FNAC / Biopsy: ABSOLUTELY CONTRAINDICATED (anaphylaxis + spillage risk)",
"USG: Water lily sign (floating membrane) | CT: Honeycombing (multiseptated)",
"Active/Symptomatic: Albendazole Γ3 weeks β PAIR procedure (TOC)",
"Inactive/Calcified/Asymptomatic: Surveillance only",
]))
story.append(sp(5))
story.append(mnemonic_box("PAIR Procedure", [
"P β Puncture (under image guidance)",
"A β Aspirate contents",
"I β Inject scolicidal agent (10% hypertonic saline OR 10% Povidone iodine)",
"R β Re-aspirate",
"PAIR CONTRAINDICATED: Deep/inaccessible | Multiseptated | Cysto-biliary communication",
]))
story.append(sp(8))
story.append(section_box("LIVER ABSCESS β Pyogenic vs Amebic", TEAL_LIGHT, TEAL))
story.append(sp(4))
story.append(green_box([
"PYOGENIC = Real abscess β DRAINAGE IS MANDATORY",
"AMEBIC = Not a real abscess (liquefied liver) β MEDICAL MANAGEMENT IS TOC",
]))
story.append(sp(5))
story.append(make_table(
["Feature", "Pyogenic", "Amebic"],
[
["Organism", "E. coli / Klebsiella", "Entamoeba histolytica"],
["Pathway", "Ascending cholangitis (MC)", "Feco-oral β Cyst β Gut β Portal vein β Liver"],
["Number", "Usually MULTIPLE", "Usually SOLITARY"],
["Pus character", "True pus", "ANCHOVY SAUCE (dark brown; dead liver + few RBCs/WBCs)"],
["Presentation", "Acute, HIGH fever", "Subacute, mild symptoms"],
["Treatment", "Antibiotics + DRAINAGE (always)", "High-dose Metronidazole + Diloxanide furoate (10β14 days)"],
["Drainage", "ALWAYS needed", "ONLY if non-responsive, size >5 cm, subcapsular, left lobe"],
],
col_widths=[38*mm, 66*mm, 66*mm]
))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# MASTER QUICK-REFERENCE PAGE
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("MASTER QUICK-REFERENCE: ALL MNEMONICS & DIFFERENTIATORS", colors.HexColor("#37474F")))
story.append(sp(6))
story.append(section_box("MNEMONICS AT A GLANCE", GREY_LIGHT, colors.HexColor("#37474F")))
story.append(sp(5))
mnemonics_data = [
["THREE CITIES", "Chicago = Achalasia Manometry | Montreal = GERD Definition | LA = GERD Grading"],
["AAA Syndrome", "Adrenal insufficiency + Alacrymia + Achalasia (Allgrove Syndrome)"],
["Mackler's Triad", "Chest pain + Retching + Subcutaneous emphysema (Boerhaave Syndrome)"],
["4S + 1D (CA Stomach)", "Smoking + Spirits + Sepsis (H.pylori) + Smoked foods + Diet"],
["Virchow/Krukenberg", "Virchow = Left supraclavicular | Krukenberg = Bilateral ovaries | Irish = Left axilla"],
["IHPS Metabolic Triad", "Hypokalemia + Hypochloremia + Metabolic Alkalosis + Paradoxical Aciduria"],
["MANTRELS (Appendix)", "Migration + Anorexia + Nausea + Tenderness(2) + Rebound + Elevated T + Leucocytosis(2) + Shift"],
["Blood in Stools Age", "Elderly male smoker = CRC | Young (20s) = UC | Child = Polyp/Meckel's"],
["P for Pointing", "Parasympathetic injury β Impotence (erection lost) β rectal surgery"],
["S for Shooting", "Sympathetic injury β Retrograde ejaculation β rectal surgery"],
["TAD (Rectal Prolapse)", "Thiersch + Altemeier + Delorme = Perineal procedures (elderly/unfit)"],
["PAIR Procedure", "Puncture + Aspirate + Inject scolicidal + Re-aspirate (Hydatid cyst)"],
["Dual Endotherapy", "Any 2 of: Clip + Adrenaline injection + APC (UGI bleed Forrest I)"],
["Rockall ABCDE", "Age + BP + Comorbidities + Diagnosis + Endoscopic appearance"],
["Hesselbach's RIL", "Rectus (medial) + Inferior epigastric (lateral) + Inguinal ligament (inferior)"],
["Triangle of DOOM", "Vas deferens + Testicular vessels = External iliac vessels = Vascular injury risk"],
["Triangle of PAIN", "Testicular vessels + Ilio-pubic tract = Nerve-dense area = Chronic pain risk"],
]
mnemonics_table = make_table(
["Mnemonic / Rule", "What It Means"],
mnemonics_data,
col_widths=[52*mm, 118*mm],
header_bg=PURPLE
)
story.append(mnemonics_table)
story.append(sp(8))
story.append(section_box("KEY DIFFERENTIATORS EXAM TABLE", GREY_LIGHT, colors.HexColor("#37474F")))
story.append(sp(5))
diff_data = [
["Achalasia dysphagia", "LIQUIDS > SOLIDS", "Malignancy dysphagia", "SOLIDS > LIQUIDS"],
["Fissure bleeding", "STREAKING (painful)", "Hemorrhoid bleeding", "SPLASH (painless)"],
["TB ulcers", "TRANSVERSE β Stricture", "Typhoid ulcers", "LONGITUDINAL β No stricture"],
["Pilonidal sinus site", "Upper natal cleft (coccyx)", "Fistula in ano site", "Near anal verge"],
["Ripstein procedure", "ABDOMINAL (rectopexy)", "Altemeier/Delorme", "PERINEAL"],
["Pyogenic abscess", "Multiple, true pus, DRAIN always", "Amebic abscess", "Solitary, anchovy sauce, MEDICAL TOC"],
["Corrosive alkali", "Liquefaction (deep, worse)", "Corrosive acid", "Coagulation (shallow, eschar limits)"],
["Early dumping", "Low BP + Normal sugar", "Late dumping", "Normal BP + Low sugar"],
["Rockall score", "Rebleed + Mortality", "Glasgow-Blatchford", "Endoscopy NOT included"],
["Direct hernia", "Medial (M) β Hesselbach's", "Indirect hernia", "Lateral (L) β Deep ring"],
],
diff_table_data = [["Condition A", "Finding A", "Condition B", "Finding B"]]
for row in diff_data:
diff_table_data.append(row)
diff_st_h = S("_dh", fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE,
alignment=TA_CENTER, leading=11)
diff_st_a = S("_da", fontName="Helvetica-Bold", fontSize=8.5, textColor=TEAL,
alignment=TA_LEFT, leading=11)
diff_st_b = S("_db", fontName="Helvetica-Bold", fontSize=8.5, textColor=RED,
alignment=TA_LEFT, leading=11)
diff_st_n = S("_dn", fontName="Helvetica", fontSize=8.5, textColor=BLACK,
alignment=TA_LEFT, leading=11)
formatted_diff = [[Paragraph(h, diff_st_h) for h in ["Condition A", "Finding A", "Condition B", "Finding B"]]]
for row in diff_data:
formatted_diff.append([
Paragraph(row[0], diff_st_a),
Paragraph(row[1], diff_st_n),
Paragraph(row[2], diff_st_b),
Paragraph(row[3], diff_st_n),
])
dt = Table(formatted_diff, colWidths=[38*mm, 47*mm, 38*mm, 47*mm], repeatRows=1)
dt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, TEAL_LIGHT]),
("GRID", (0,0), (-1,-1), 0.4, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LINEAFTER", (1,1), (1,-1), 1.5, GREY_MED),
]))
story.append(dt)
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# INVESTIGATIONS QUICK-REF
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("IOC / STAGING QUICK-REFERENCE", colors.HexColor("#1A237E")))
story.append(sp(6))
story.append(make_table(
["Condition", "1st Step", "IOC / Diagnosis", "Local Staging", "Distant Staging"],
[
["Achalasia", "UGI Endoscopy (rule out malignancy)", "High-Resolution Manometry (HRM)", "β", "β"],
["GERD", "UGI Endoscopy (LA grading)", "24-hr pH Study (DeMeester >14.7)", "β", "β"],
["Esophageal Perforation", "X-ray chest", "CT with water-soluble contrast", "β", "β"],
["CA Esophagus", "UGI Endoscopy + Biopsy", "UGI Endoscopy + Biopsy", "EUS (T-stage)", "PET Scan"],
["CA Stomach", "UGI Endoscopy + Biopsy", "UGI Endoscopy + Biopsy", "EUS (T-stage)", "PET Scan"],
["IHPS", "USG abdomen", "USG (pylorus β₯4 mm)", "β", "β"],
["PU Perforation", "X-ray chest (pneumoperitoneum)", "CECT abdomen", "β", "β"],
["Intestinal TB (stable)", "Stool exam", "Colonoscopy + Biopsy (CBNAAT)", "β", "β"],
["Intestinal TB (acute)", "X-ray abdomen", "CECT abdomen", "β", "β"],
["Appendicitis (Adults)", "USG abdomen", "CECT abdomen", "β", "β"],
["Appendicitis (Children)", "USG abdomen", "USG (diameter β₯6 mm)", "β", "β"],
["Appendicitis (Pregnancy)", "USG abdomen", "MRI appendix", "β", "β"],
["CA Colon", "Stool exam", "Colonoscopy + Biopsy", "CECT abdomen", "PET Scan"],
["CA Rectum", "Stool exam", "Colonoscopy + Biopsy", "MRI rectum", "PET Scan"],
["Intussusception", "USG abdomen", "USG (donut sign)", "β", "β"],
["Sigmoid Volvulus", "X-ray abdomen (coffee bean)", "CECT abdomen (ischemia)", "β", "β"],
["Fistula in Ano", "DRE + Proctoscopy", "MRI perineum", "β", "β"],
["Hydatid Cyst", "USG abdomen", "CT abdomen (honeycombing)", "β", "β"],
["Liver Abscess (Pyogenic)", "USG abdomen", "Image-guided aspiration", "β", "β"],
["Zenker's Diverticulum", "β", "Barium Swallow (lateral view)", "β", "β"],
["Hiatus Hernia", "β", "CT with oral contrast / Barium meal", "β", "β"],
],
col_widths=[35*mm, 37*mm, 42*mm, 30*mm, 26*mm]
))
story.append(sp(8))
story.append(PageBreak())
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# FINAL REVISION FLASH FACTS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(chapter_header("FINAL RAPID FIRE β EXAM FLASH FACTS", colors.HexColor("#B71C1C")))
story.append(sp(6))
flash_facts = [
("Achalasia", [
"MC motility disorder of esophagus",
"HRM shows: Absent peristalsis + Elevated LES pressure (BOTH cardinal findings)",
"Type 2 has best response to treatment",
"Type 3 (Spastic) TOC = POEM",
"Eckhardt score: Triad + Heartburn = 4 components",
]),
("Barrett's Esophagus", [
"Squamous β Columnar metaplasia (intestinal metaplasia)",
"Seattle protocol: 4-quadrant biopsy at 2 cm intervals",
"High-grade dysplasia = 7%/year adenocarcinoma risk",
"NBI (Narrow Band Imaging) = Blue light endoscopy for better visualization",
]),
("CA Stomach", [
"Adenocarcinoma | MC site: Antrum",
"H. pylori β Type B gastritis (antral)",
"Bormann's classification: Advanced CA stomach (gross appearance)",
"D2 lymphadenectomy = standard of care",
"FLOT regimen = chemotherapy of choice",
]),
("Ramstedt's Pyloromyotomy", [
"Order: Adventitia β Muscularis β STOP (do NOT cut mucosa)",
"Fluid before surgery: DNS with KCl",
"DDx: Neonatal GERD (non-projectile; improves with growth)",
]),
("PUD Surgery", [
"Best tolerated: HSV (mortality <0.2%, side effects <5%)",
"Lowest recurrence: TV + Antrectomy (1%) but highest complications",
"Billroth II > Billroth I (more commonly done; more complications)",
"Dumping = complication of gastrectomy/GJ anastomosis",
]),
("Appendicitis", [
"Appendix: Arises at convergence of taenia coli on cecum",
"Has mesoappendix (Meckel's is antimesenteric)",
"Retrocaecal = MC position (70%) = Psoas sign",
"Phlegmon = Oschner-Sherren (conservative, NO surgery acutely)",
"Amyand's = appendix inside inguinal hernia (PYQ)",
]),
("Rectal Prolapse", [
"Perineal (TAD): Thiersch + Altemeier (strangulated) + Delorme",
"TOC: Laparoscopic ventral mesh rectopexy (abdominal; young/fit)",
"Ripstein = ABDOMINAL procedure (asked: which is NOT perineal?)",
]),
("Hernia Repair", [
"Herniotomy: Only for congenital hernia/hydrocele (sac excision only)",
"Lichtenstein: Tension-free, Prolene mesh, ONLAY placement",
"IPOM: DUAL/COMPOSITE mesh (Prolene + collagen/PTFE); non-adhering side faces bowel",
"Mesh must be 3β5 cm LARGER than defect on ALL sides (IPOM rule)",
]),
("Hydatid/Liver Abscess", [
"Hydatid: FNAC CONTRAINDICATED; Water lily sign on USG",
"Anchovy sauce = Amebic abscess (sterile; organism at border only)",
"Amebic: Metronidazole + Diloxanide; drain ONLY if >5 cm/non-responsive",
"Pyogenic: ALWAYS drain (true pus; ascending cholangitis MC cause)",
]),
]
for topic, facts in flash_facts:
story.append(KeepTogether([
Paragraph(f"βΈ {topic}", S("_ft", fontName="Helvetica-Bold", fontSize=10,
textColor=DARK_BLUE, leading=13, spaceBefore=6, spaceAfter=3)),
*[Paragraph(f" β¦ {f}", S("_ff", fontName="Helvetica", fontSize=8.5, textColor=BLACK,
leading=12, leftIndent=8, spaceAfter=1)) for f in facts],
HRFlowable(width="100%", thickness=0.4, color=GREY_MED, spaceBefore=4, spaceAfter=2),
]))
story.append(sp(10))
# back cover note
back = S("_bk", fontName="Helvetica-Oblique", fontSize=9, textColor=colors.HexColor("#555555"),
alignment=TA_CENTER, leading=14)
story.append(Paragraph("All content sourced from: Cerebellum's Hyperrevision β 20th Course (Surgery Part 1)", back))
story.append(Paragraph("@AnandxBotss | Compiled for rapid exam revision", back))
# ββ BUILD ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=18*mm, bottomMargin=15*mm,
title="Surgery Part 1 β Mnemonics & High-Yield Facts",
author="Cerebellum Hyperrevision 20th Course",
)
# Cover page uses different template
def cover_canvas(canvas_obj, doc):
cover_page(canvas_obj, doc)
def normal_canvas(canvas_obj, doc):
add_page_number(canvas_obj, doc)
# Build with page number from page 2 onwards
doc.build(story,
onFirstPage=cover_canvas,
onLaterPages=normal_canvas)
print(f"PDF created: {OUTPUT}")
import os
size = os.path.getsize(OUTPUT)
print(f"File size: {size/1024:.1f} KB")