~/abdomen-study-guide/generate_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 cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
OUTPUT = "/home/daytona/workspace/abdomen-study-guide/Abdomen_Pelvis_Gold_Medal_Study_Guide.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MID_BLUE = colors.HexColor("#2e6da4")
LIGHT_BLUE = colors.HexColor("#d6e8f7")
GOLD = colors.HexColor("#c8960c")
GOLD_LIGHT = colors.HexColor("#fff5d6")
RED = colors.HexColor("#b30000")
RED_LIGHT = colors.HexColor("#fde8e8")
GREEN = colors.HexColor("#1a6b2a")
GREEN_LIGHT = colors.HexColor("#e6f4ea")
PURPLE = colors.HexColor("#5b1a8c")
PURPLE_LIGHT= colors.HexColor("#f0e8f8")
ORANGE = colors.HexColor("#c45000")
ORANGE_LIGHT= colors.HexColor("#fff0e6")
GREY_LIGHT = colors.HexColor("#f5f5f5")
GREY_MID = colors.HexColor("#cccccc")
WHITE = colors.white
BLACK = colors.black
# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle", fontSize=28, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica-Bold", spaceAfter=8, leading=34)
cover_sub = S("CoverSub", fontSize=14, textColor=GOLD, alignment=TA_CENTER,
fontName="Helvetica-Bold", spaceAfter=6, leading=18)
cover_body = S("CoverBody", fontSize=11, textColor=WHITE, alignment=TA_CENTER,
fontName="Helvetica", spaceAfter=4, leading=16)
h1 = S("H1", fontSize=16, textColor=WHITE, fontName="Helvetica-Bold",
spaceAfter=4, spaceBefore=6, leading=20)
h2 = S("H2", fontSize=13, textColor=DARK_BLUE, fontName="Helvetica-Bold",
spaceAfter=3, spaceBefore=8, leading=16)
h3 = S("H3", fontSize=11, textColor=MID_BLUE, fontName="Helvetica-Bold",
spaceAfter=2, spaceBefore=5, leading=14)
body= S("Body", fontSize=9, textColor=BLACK, fontName="Helvetica",
spaceAfter=3, leading=13, alignment=TA_JUSTIFY)
bullet=S("Bullet",fontSize=9, textColor=BLACK, fontName="Helvetica",
spaceAfter=2, leading=13, leftIndent=12, bulletIndent=2)
small=S("Small",fontSize=8, textColor=colors.HexColor("#444444"),
fontName="Helvetica", spaceAfter=2, leading=11)
tip = S("Tip", fontSize=9, textColor=GREEN, fontName="Helvetica-Bold",
spaceAfter=2, leading=13, leftIndent=6)
warn = S("Warn",fontSize=9, textColor=RED, fontName="Helvetica-Bold",
spaceAfter=2, leading=13, leftIndent=6)
gold_rule=S("GoldRule",fontSize=10,textColor=GOLD,fontName="Helvetica-Bold",
spaceAfter=3,leading=14,leftIndent=4)
toc_item=S("TocItem",fontSize=10,textColor=DARK_BLUE,fontName="Helvetica",
spaceAfter=2,leading=14,leftIndent=12)
# ── Helper builders ───────────────────────────────────────────────────────────
def section_header(text, bg=DARK_BLUE, fg=WHITE):
data = [[Paragraph(text, h1)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS",[4]),
]))
return t
def subsection_header(text, bg=LIGHT_BLUE):
data = [[Paragraph(text, h2)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), bg),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),8),
("LINEBELOW",(0,0),(-1,-1),1.5,MID_BLUE),
]))
return t
def colored_box(content_rows, bg=GOLD_LIGHT, border=GOLD):
"""content_rows: list of Paragraph objects wrapped in single-cell rows"""
data = [[p] for p in content_rows]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),bg),
("BOX",(0,0),(-1,-1),1.2,border),
("LEFTPADDING",(0,0),(-1,-1),8),
("RIGHTPADDING",(0,0),(-1,-1),8),
("TOPPADDING",(0,0),(0,0),6),
("BOTTOMPADDING",(0,-1),(-1,-1),6),
("TOPPADDING",(0,1),(-1,-1),2),
("BOTTOMPADDING",(0,0),(-1,-2),2),
]))
return t
def two_col_table(headers, rows, col1=8.5*cm, col2=8.5*cm,
hdr_bg=DARK_BLUE, hdr_fg=WHITE, alt_bg=GREY_LIGHT):
all_rows = [[Paragraph(h, S("th",fontSize=9,textColor=hdr_fg,
fontName="Helvetica-Bold",leading=12))
for h in headers]] + \
[[Paragraph(str(c), small) for c in r] for r in rows]
t = Table(all_rows, colWidths=[col1, col2])
ts = [
("BACKGROUND",(0,0),(-1,0),hdr_bg),
("TEXTCOLOR",(0,0),(-1,0),hdr_fg),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,0),9),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),6),
("GRID",(0,0),(-1,-1),0.5,GREY_MID),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, alt_bg]),
]
t.setStyle(TableStyle(ts))
return t
def three_col_table(headers, rows, widths=None, hdr_bg=DARK_BLUE):
widths = widths or [5*cm, 6*cm, 6*cm]
hdr_fg = WHITE
all_rows = [[Paragraph(h, S("th3",fontSize=9,textColor=hdr_fg,
fontName="Helvetica-Bold",leading=12))
for h in headers]] + \
[[Paragraph(str(c), small) for c in r] for r in rows]
t = Table(all_rows, colWidths=widths)
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),hdr_bg),
("GRID",(0,0),(-1,-1),0.5,GREY_MID),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE,GREY_LIGHT]),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),5),
]))
return t
def four_col_table(headers, rows, widths=None, hdr_bg=DARK_BLUE):
widths = widths or [4*cm,4.5*cm,4.5*cm,4*cm]
hdr_fg = WHITE
all_rows = [[Paragraph(h, S("th4",fontSize=9,textColor=hdr_fg,
fontName="Helvetica-Bold",leading=12))
for h in headers]] + \
[[Paragraph(str(c), small) for c in r] for r in rows]
t = Table(all_rows, colWidths=widths)
t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),hdr_bg),
("GRID",(0,0),(-1,-1),0.5,GREY_MID),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE,GREY_LIGHT]),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),4),
]))
return t
def sp(n=4): return Spacer(1, n)
def hr(c=GREY_MID): return HRFlowable(width="100%", thickness=0.8, color=c, spaceAfter=4, spaceBefore=4)
# ════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════════════════
story = []
# ── PAGE 1: COVER ────────────────────────────────────────────────────────────
cover_bg_data = [
[Paragraph("", cover_title)], # spacer row
]
# Build cover as a big coloured table
cover_rows = [
[Paragraph("ABDOMEN & PELVIS", cover_title)],
[Paragraph("GOLD MEDAL ANATOMY STUDY GUIDE", cover_sub)],
[Paragraph("", cover_body)],
[Paragraph("TM's Anatomy QBank — LAQ Format | 15-Mark Questions", cover_body)],
[Paragraph("", cover_body)],
[Paragraph("11 Key Organs • Story-Linked Learning • Exam-Ready Answers", cover_body)],
[Paragraph("", cover_body)],
[Paragraph("Vascular Hierarchy • Lymphatic Drainage • Applied Anatomy", cover_body)],
[Paragraph("", cover_body)],
[Paragraph("", cover_body)],
[Paragraph("Structured for Vishram Singh Pattern", S("cs2",fontSize=10,textColor=GOLD,
fontName="Helvetica-BoldOblique",alignment=TA_CENTER,leading=14))],
]
cover_table = Table(cover_rows, colWidths=[17*cm])
cover_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),DARK_BLUE),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),20),
("RIGHTPADDING",(0,0),(-1,-1),20),
("TOPPADDING",(0,0),(0,0),60),
("BOTTOMPADDING",(0,-1),(-1,-1),60),
]))
story.append(cover_table)
story.append(PageBreak())
# ── PAGE 2: TABLE OF CONTENTS ─────────────────────────────────────────────
story.append(section_header("📋 TABLE OF CONTENTS"))
story.append(sp(6))
toc_data = [
("1.", "The Master Story — How All Organs Connect", "Pg 3"),
("2.", "The Universal 15-Mark Format (LEIR VNLA)", "Pg 3"),
("3.", "Topic 1 — Inguinal Canal", "Pg 4"),
("4.", "Topic 2 — Stomach", "Pg 5"),
("5.", "Topic 3 — Liver", "Pg 6"),
("6.", "Topic 4 — Portal Vein & Portosystemic Anastomoses", "Pg 7"),
("7.", "Topic 5 — Pancreas", "Pg 8"),
("8.", "Topic 6 — Kidney", "Pg 9"),
("9.", "Topic 7 — Urinary Bladder", "Pg 10"),
("10.","Topic 8 — Uterus", "Pg 11"),
("11.","Topic 9 — Testis", "Pg 12"),
("12.","Topic 10 — Rectum", "Pg 13"),
("13.","Topic 11 — Anal Canal", "Pg 14"),
("14.","Master Vascular Hierarchy Table", "Pg 15"),
("15.","Master Lymphatic Drainage Table", "Pg 15"),
("16.","Top 30 Exam Facts — Quick Revision", "Pg 16"),
("17.","3 Exam Traps — Never Lose Marks", "Pg 16"),
]
for num, title, pg in toc_data:
row_data = [[
Paragraph(num, S("tn",fontSize=10,textColor=GOLD,fontName="Helvetica-Bold",leading=14)),
Paragraph(title, toc_item),
Paragraph(pg, S("tp",fontSize=10,textColor=MID_BLUE,fontName="Helvetica",
leading=14,alignment=TA_CENTER)),
]]
t = Table(row_data, colWidths=[1*cm, 13.5*cm, 2.5*cm])
t.setStyle(TableStyle([
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),4),
("LINEBELOW",(0,0),(-1,-1),0.3,GREY_MID),
]))
story.append(t)
story.append(PageBreak())
# ── PAGE 3: MASTER STORY + FORMAT ────────────────────────────────────────────
story.append(section_header("🔗 THE MASTER STORY — How All Organs Connect"))
story.append(sp(6))
story.append(colored_box([
Paragraph("THE FOOD JOURNEY STORY", S("FS",fontSize=11,textColor=GOLD,
fontName="Helvetica-Bold",leading=16)),
Paragraph(
"Food enters <b>Stomach</b> (T2) → digested using <b>Bile from Liver</b> (T3) and "
"<b>Enzymes from Pancreas</b> (T5) → nutrients absorbed → carried to Liver via "
"<b>Portal Vein</b> (T4) → <b>Kidneys</b> (T6) filter blood → urine stored in "
"<b>Bladder</b> (T7) → the <b>Uterus</b> (T8) sits between bladder and rectum in "
"females → the <b>Testis</b> (T9) descended from near kidney (L2) through the "
"<b>Inguinal Canal</b> (T1) → waste exits via <b>Rectum</b> (T10) and "
"<b>Anal Canal</b> (T11).",
body),
], bg=GOLD_LIGHT, border=GOLD))
story.append(sp(8))
story.append(subsection_header("📝 THE UNIVERSAL 15-MARK FORMAT — LEIR VNLA"))
story.append(sp(4))
leir_rows = [
("L", "Location", "Region, vertebral level, peritoneal status (retro/intra)"),
("E", "External Features", "Shape, size, weight, parts, surfaces, borders, curvatures"),
("I", "Internal Features", "Mucosal lining, sphincters, ducts, internal architecture"),
("R", "Relations", "Anterior, posterior, superior, inferior, lateral — all sides"),
("V", "Vascular Supply", "Artery (named source) + Vein (portal or systemic)"),
("N", "Nervous Supply", "Sympathetic (level) + Parasympathetic (nerve name) + somatic"),
("L", "Lymphatic Drainage", "Primary nodes → Secondary nodes → Final destination"),
("A", "Applied Anatomy", "3–5 clinical points: surgery, pathology, investigations"),
]
leir_table = four_col_table(
["Letter","Heading","What to Write",""],
[(r[0],r[1],r[2],"") for r in leir_rows],
widths=[1.2*cm, 3.8*cm, 10*cm, 2*cm],
hdr_bg=MID_BLUE
)
story.append(leir_table)
story.append(sp(6))
story.append(colored_box([
Paragraph("⭐ GOLDEN RULE FOR EVERY ORGAN:",
S("GR",fontSize=10,textColor=RED,fontName="Helvetica-Bold",leading=14)),
Paragraph(
"Lymphatics always follow the artery <b>BACKWARDS</b> to its origin. "
"If the artery comes from the aorta at L2 (kidney, testis) → lymph goes to "
"<b>para-aortic nodes at L2</b>. If artery from coeliac → lymph to <b>coeliac nodes</b>. "
"If artery from internal iliac → lymph to <b>internal iliac nodes</b>.", body),
], bg=RED_LIGHT, border=RED))
story.append(PageBreak())
# ════════════════════════════════════════════════════════════════════════════
# ORGAN PAGES (compact but complete)
# ════════════════════════════════════════════════════════════════════════════
# Helper to build a compact organ page
def organ_page(title, star, color_bg, color_border,
location, ext_feat, int_feat, relations_rows,
artery, vein, nerve, lymph, applied_points, memory=""):
items = []
# Title banner
banner_data = [[
Paragraph(f"{title} {star}",
S("OT",fontSize=15,textColor=WHITE,fontName="Helvetica-Bold",leading=20)),
]]
bt = Table(banner_data, colWidths=[17*cm])
bt.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),color_border),
("TOPPADDING",(0,0),(-1,-1),7),("BOTTOMPADDING",(0,0),(-1,-1),7),
("LEFTPADDING",(0,0),(-1,-1),12),
]))
items.append(bt)
items.append(sp(5))
# Two-column top row: Location + External Features
loc_data = [[Paragraph("📍 LOCATION", h3)],[Paragraph(location, body)]]
ext_data = [[Paragraph("🔷 EXTERNAL FEATURES", h3)],[Paragraph(ext_feat, body)]]
top_t = Table([[
Table(loc_data, colWidths=[8*cm]),
Table(ext_data, colWidths=[8.5*cm]),
]], colWidths=[8.2*cm, 8.8*cm])
top_t.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),0),
]))
items.append(top_t)
items.append(sp(4))
# Internal Features
items.append(subsection_header("🔬 INTERNAL FEATURES", bg=color_bg))
items.append(Paragraph(int_feat, body))
items.append(sp(4))
# Relations table
items.append(subsection_header("🗺 RELATIONS", bg=color_bg))
rel_table = Table(
[[Paragraph("<b>Direction</b>",small), Paragraph("<b>Structure</b>",small)]] +
[[Paragraph(r[0],small), Paragraph(r[1],body)] for r in relations_rows],
colWidths=[4*cm, 13*cm]
)
rel_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),color_border),
("TEXTCOLOR",(0,0),(-1,0),WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("GRID",(0,0),(-1,-1),0.4,GREY_MID),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE,color_bg]),
("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),5),
]))
items.append(rel_table)
items.append(sp(4))
# Vascular + Nerve + Lymph in 3 columns
vasc = [[Paragraph("🩸 VASCULAR SUPPLY",h3)],[Paragraph(artery,body)],
[Paragraph(vein, S("vb",fontSize=9,textColor=MID_BLUE,fontName="Helvetica",
leading=12,spaceAfter=2))]]
nerv = [[Paragraph("⚡ NERVE SUPPLY", h3)],[Paragraph(nerve, body)]]
lymp = [[Paragraph("🟢 LYMPHATICS", h3)],[Paragraph(lymph, body)]]
vnl_t = Table([[
Table(vasc, colWidths=[6*cm]),
Table(nerv, colWidths=[5.2*cm]),
Table(lymp, colWidths=[5.5*cm]),
]], colWidths=[6.2*cm, 5.4*cm, 5.7*cm])
vnl_t.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),2),
]))
items.append(vnl_t)
items.append(sp(4))
# Applied Anatomy
items.append(subsection_header("🏥 APPLIED ANATOMY (Clinical Points)", bg=RED_LIGHT))
for i, pt in enumerate(applied_points, 1):
items.append(Paragraph(f"<b>{i}.</b> {pt}", bullet))
items.append(sp(3))
# Memory trick
if memory:
items.append(colored_box([
Paragraph(f"💡 MEMORY TRICK: {memory}",
S("MT",fontSize=9,textColor=PURPLE,fontName="Helvetica-Bold",leading=13))
], bg=PURPLE_LIGHT, border=PURPLE))
items.append(PageBreak())
return items
# ── TOPIC 1: INGUINAL CANAL ─────────────────────────────────────────────────
story += organ_page(
"TOPIC 1 — INGUINAL CANAL", "⭐⭐⭐⭐⭐",
LIGHT_BLUE, DARK_BLUE,
location="Lower anterior abdominal wall, just above medial half of inguinal ligament. "
"4 cm oblique passage from deep inguinal ring (lateral) to superficial inguinal "
"ring (medial).",
ext_feat="Deep ring: opening in transversalis fascia, midpoint of inguinal ligament, "
"lateral to inferior epigastric vessels. Superficial ring: triangular gap in "
"external oblique aponeurosis, above pubic tubercle.",
int_feat="<b>WALLS (MALT):</b> Anterior = External oblique aponeurosis (whole) + Internal "
"oblique (lateral 1/3). Posterior = Transversalis fascia (whole) + Conjoint "
"tendon (medial 1/3). Roof = Arched fibres of internal oblique + Transversus. "
"Floor = Inguinal ligament + Lacunar ligament (medially).",
relations_rows=[
("Anterior", "External oblique aponeurosis throughout"),
("Posterior", "Transversalis fascia + Conjoint tendon medially"),
("Floor", "Inguinal ligament; lacunar ligament medially"),
("Roof", "Arched fibres of internal oblique + transversus abdominis"),
],
artery="Testicular artery (from aorta at L2) within spermatic cord. "
"Cremasteric artery (from inferior epigastric). "
"Artery to vas deferens (from inferior vesical).",
vein="Pampiniform plexus → Testicular vein → Right: IVC directly. "
"Left: Left renal vein → IVC.",
nerve="Ilioinguinal nerve (L1) — travels inside canal, exits at superficial ring. "
"Genital branch of genitofemoral nerve (L1/L2) — within spermatic cord.",
lymph="From testis: Para-aortic nodes (L2) — NOT inguinal nodes! "
"From scrotal skin: Superficial inguinal nodes.",
applied_points=[
"Indirect inguinal hernia: through deep ring → along canal → superficial ring. "
"Controlled by pressure over deep ring (midinguinal point).",
"Direct inguinal hernia: through Hesselbach's triangle (posterior wall weakness). "
"NOT controlled by pressure over deep ring.",
"Males 8× more hernias than females — longer canal, larger rings.",
"Orchidopexy: Undescended testis brought down through canal to scrotum.",
"Laparoscopic repair (TEP/TAPP): Must know all 3 fascial layers.",
],
memory="'MALT': Medial=conjoint, Anterior=ext.oblique, Lateral=int.oblique, "
"Top=int.oblique arch. Deep ring is LATERAL to inferior epigastric vessels."
)
# ── TOPIC 2: STOMACH ─────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 2 — STOMACH", "⭐⭐⭐⭐⭐",
GREEN_LIGHT, GREEN,
location="Epigastric, umbilical, left hypochondriac regions. Extends from cardiac "
"orifice (T11) to pylorus (L1). J-shaped distensible organ.",
ext_feat="Parts: Cardia, Fundus (above cardiac orifice), Body, Pyloric antrum → "
"Pyloric canal → Pylorus (sphincter). Two curvatures: Lesser (right, shorter, "
"lesser omentum attaches) and Greater (left, longer, greater omentum attaches).",
int_feat="Rugae: longitudinal folds allowing distension. Gastric pits (foveolae): "
"openings of gastric glands. Pyloric sphincter: thickened circular muscle. "
"Magenstrasse: canal along lesser curvature for liquids. "
"Mucosa: simple columnar with gastric glands (fundic, cardiac, pyloric types).",
relations_rows=[
("Anterior surface", "Left lobe of liver (upper), Diaphragm (left), Anterior abdominal wall (lower)"),
("Posterior surface (Gastric Bed)", "'Please Let Lady Spiders Stop To Dance': Pancreas, Left Kidney, Left Adrenal, Spleen, Splenic artery, Transverse mesocolon, Diaphragm"),
("Superior", "Diaphragm; oesophagus enters at cardiac orifice"),
("Inferior", "Transverse colon and mesocolon"),
],
artery="Lesser curvature: Left gastric (direct from coeliac) + Right gastric (from "
"hepatic artery). Greater curvature: Right gastro-omental (from gastroduodenal) "
"+ Left gastro-omental (from splenic). Fundus: Short gastric arteries (from splenic).",
vein="All drain into PORTAL SYSTEM. Left/right gastric → portal vein directly. "
"Left gastro-omental + short gastric → splenic vein. "
"Right gastro-omental → superior mesenteric vein.",
nerve="Parasympathetic: Anterior vagal trunk (L vagus) + Posterior vagal trunk "
"(R vagus) through oesophageal hiatus. "
"Sympathetic: T6–T10 via greater splanchnic nerve → coeliac plexus. "
"Pain from stomach referred to epigastrium (T6-T9).",
lymph="4 groups all drain to coeliac nodes ultimately. "
"Lesser curvature → left gastric nodes. Pyloric region → pyloric nodes. "
"Greater curvature → gastro-omental nodes. Fundus → pancreaticosplenic nodes.",
applied_points=[
"Peptic ulcer: Anterior duodenal ulcer perforates → peritonitis. "
"Posterior DU erodes gastroduodenal artery → haematemesis.",
"Gastric cancer: Spreads via lymphatics. Virchow's node (left supraclavicular) = "
"advanced disease via thoracic duct.",
"Vagotomy for PUD: Highly selective vagotomy spares hepatic and coeliac branches.",
"Gastrostomy: Lower anterior surface of stomach directly contacts anterior "
"abdominal wall — accessible without displacing bowel.",
"Referred pain: Gastric pain felt in epigastrium (T6–T9 dermatome).",
],
memory="Gastric bed: 'Please Let Lady Spiders Stop To Dance' = Pancreas, Left Kidney, "
"Left Adrenal, Spleen, Splenic artery, Transverse mesocolon, Diaphragm."
)
# ── TOPIC 3: LIVER ───────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 3 — LIVER", "⭐⭐⭐⭐⭐",
ORANGE_LIGHT, ORANGE,
location="Right hypochondriac + epigastric + small part of left hypochondriac. "
"Largest abdominal organ (~1500g). Under right dome of diaphragm.",
ext_feat="Diaphragmatic surface: convex, smooth, covered by peritoneum except bare area. "
"Visceral surface: H-shaped arrangement — left limb (falciform/ligamentum venosum), "
"right limb (gallbladder fossa/IVC groove), crossbar = PORTA HEPATIS. "
"Lobes: Right (largest), Left, Caudate (posterior), Quadrate (anterior).",
int_feat="Portal triad: portal vein + hepatic artery branch + bile ductule in each "
"portal tract. Hepatic lobule: hexagonal functional unit. Central vein: "
"drains each lobule to hepatic veins. Sinusoids: between hepatocyte plates. "
"Kupffer cells: macrophages in sinusoids. Spaces of Disse: between hepatocytes "
"and sinusoids — site of fibrosis in cirrhosis.",
relations_rows=[
("Superior/Anterior", "Diaphragm (separates from right lung, pericardium, heart)"),
("Right lobe visceral", "Right kidney + adrenal, hepatic flexure, 2nd part duodenum"),
("Left lobe visceral", "Stomach, oesophagus"),
("Quadrate lobe", "Pylorus of stomach"),
("Caudate lobe", "IVC (grooved posteriorly), lesser omentum anteriorly"),
("Porta hepatis", "Portal vein (posterior), Hepatic artery (left), Bile duct (right)"),
],
artery="DUAL SUPPLY: (1) Hepatic artery proper (25% volume, oxygenated) — from coeliac "
"axis → common hepatic → hepatic artery proper. (2) Portal vein (75% volume, "
"nutrient-rich) — from SMV + splenic vein. Both enter at porta hepatis.",
vein="Right, middle, left hepatic veins → IVC just below diaphragm. "
"No portal hypertension builds here (drains directly to IVC).",
nerve="Sympathetic: T7–T10 via coeliac plexus (hepatic plexus around hepatic artery). "
"Parasympathetic: Vagus (anterior vagal trunk → hepatic branch of lesser omentum). "
"Liver parenchyma insensitive to pain; Glisson's capsule is sensitive.",
lymph="Superficial: subdiaphragmatic nodes → mediastinal nodes. "
"Deep: hepatic nodes (porta hepatis) → coeliac nodes → para-aortic → cisterna chyli.",
applied_points=[
"Pringle's manoeuvre: Compress hepatoduodenal ligament (porta hepatis) between "
"finger and thumb to control haemorrhage during liver surgery.",
"Liver biopsy: Right 9th–10th ICS midaxillary line in full expiration.",
"Porta hepatis = 'Portal Bill': Portal vein (posterior), Bile duct (right), "
"artery (left). Mnemonic: 'Portal Bill Art'.",
"Couinaud's 8 segments: Functional surgical anatomy. Rex-Cantlie line (IVC to "
"gallbladder fossa) divides right and left functional lobes — no surface marking.",
"Cirrhosis: Fibrosis → portal hypertension → varices + splenomegaly + ascites.",
],
memory="At porta hepatis front to back: Bile duct (right) + Artery (left) + Portal vein "
"(behind). 'BAP' — Bile, Artery, Portal (right to left, front to back)."
)
# ── TOPIC 4: PORTAL VEIN ─────────────────────────────────────────────────────
story += organ_page(
"TOPIC 4 — PORTAL VEIN", "⭐⭐⭐",
LIGHT_BLUE, MID_BLUE,
location="Formed behind neck of pancreas at L2. Ascends in free edge of lesser "
"omentum to porta hepatis. Length ~8 cm. No valves.",
ext_feat="Formed by union of Superior Mesenteric Vein (SMV) + Splenic Vein behind "
"neck of pancreas at L2. Passes behind 1st part of duodenum. Enters lesser "
"omentum — in right free edge (epiploic foramen boundary).",
int_feat="In lesser omentum (front to back): Bile duct (right) → Hepatic artery "
"(left) → Portal vein (behind). The portal vein is the most posterior of the "
"three. Divides into right and left branches at porta hepatis.",
relations_rows=[
("Formation (L2)", "Behind neck of pancreas: SMV + Splenic vein unite"),
("Behind", "1st part of duodenum; head of pancreas"),
("In lesser omentum", "Posterior to bile duct (right) and hepatic artery (left)"),
("Anterior", "Omental foramen (Winslow) — can compress here with finger"),
("At porta hepatis", "Divides into right and left hepatic branches"),
],
artery="Receives: Right + left gastric veins (lesser curvature + oesophagus). "
"Para-umbilical veins (round ligament — dilate in portal HTN = caput medusae). "
"Cystic vein (gallbladder). Plus SMV (gut) and splenic vein (spleen + pancreas).",
vein="Delivers blood to liver sinusoids → central veins → hepatic veins → IVC. "
"Normal portal pressure: 5–10 mmHg. Hypertension when >12 mmHg.",
nerve="Autonomic fibres from coeliac plexus follow the portal vein. No direct "
"innervation of portal vein wall (it is thin-walled, no smooth muscle).",
lymph="Hepatic (portal) lymph nodes at porta hepatis → coeliac nodes → para-aortic → "
"cisterna chyli → thoracic duct.",
applied_points=[
"PORTOSYSTEMIC ANASTOMOSES (OEURA): Oesophagus (left gastric ↔ azygos = "
"oesophageal varices), Umbilicus (para-umbilical ↔ epigastric = caput medusae), "
"Rectum (superior ↔ middle/inferior rectal = anorectal varices), "
"Retroperitoneum, Bare Area of liver.",
"Oesophageal varices rupture = massive haematemesis, 30% mortality per bleed.",
"TIPS procedure: Radiological stent between portal vein and hepatic vein — "
"decompress portal system without surgery.",
"Splenomegaly in portal hypertension → hypersplenism → pancytopenia.",
"Pringle's manoeuvre stops portal AND hepatic arterial flow simultaneously.",
],
memory="PORTOSYSTEMIC SITES — 'OEURA': Oesophagus, Umbilicus, Rectum, "
"Retroperitoneum, Area (bare area). All dilate in portal hypertension."
)
# ── TOPIC 5: PANCREAS ────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 5 — PANCREAS", "⭐⭐⭐",
GREEN_LIGHT, GREEN,
location="Secondarily retroperitoneal, at L1–L2. Head in C-loop of duodenum, "
"tail touches hilum of spleen. Dual function: exocrine (acini → digestive "
"enzymes) + endocrine (islets of Langerhans → insulin/glucagon).",
ext_feat="Parts: Head (in duodenal C-loop) + Uncinate process (hooks behind SMV) + "
"Neck (over portal vein formation) + Body (crosses L1) + Tail (splenorenal "
"ligament, contacts spleen). Length ~15 cm.",
int_feat="Main pancreatic duct (Wirsung): runs full length → joins common bile duct → "
"ampulla of Vater → major duodenal papilla (2nd part duodenum). "
"Accessory duct (Santorini): upper head → minor papilla (2 cm above major). "
"Islets of Langerhans: Alpha (glucagon), Beta (insulin), Delta (somatostatin).",
relations_rows=[
("Head anterior", "Transverse colon, gastroduodenal artery, stomach"),
("Head posterior", "IVC, right renal vessels, bile duct (grooves head), portal vein formation"),
("Neck anterior", "Pylorus of stomach"),
("Neck posterior", "Portal vein formed here (SMV + splenic vein)"),
("Body anterior", "Lesser sac, stomach beyond"),
("Body posterior", "Aorta, SMA origin, left kidney + adrenal, splenic vein (in groove)"),
("Body superior", "Splenic artery (tortuous, along upper border)"),
("Tail", "Spleen (in splenorenal ligament with splenic vessels)"),
],
artery="Head: Superior pancreaticoduodenal artery (from gastroduodenal/hepatic) + "
"Inferior pancreaticoduodenal artery (from SMA) — important anastomosis. "
"Body + Tail: Multiple branches from splenic artery.",
vein="Pancreatic veins → splenic vein (body/tail) and SMV (head). "
"All ultimately drain into the PORTAL SYSTEM.",
nerve="Sympathetic: T6–T10 via coeliac plexus → pain fibres (epigastric pain). "
"Parasympathetic: Vagus → stimulates enzyme and insulin secretion.",
lymph="Pancreaticoduodenal nodes → coeliac nodes + superior mesenteric nodes → "
"para-aortic nodes → cisterna chyli.",
applied_points=[
"Acute pancreatitis: Gallstones (block ampulla) + Alcohol. Cullen's sign "
"(periumbilical bruising) + Grey-Turner (flank bruising) = retroperitoneal bleed.",
"Carcinoma of head: Obstructs bile duct → painless progressive jaundice. "
"Courvoisier's law: palpable non-tender gallbladder = carcinoma (not stones).",
"Whipple's operation (pancreaticoduodenectomy): For head carcinoma — removes "
"head + duodenum + gallbladder + distal stomach.",
"Splenic vein runs in groove on posterior body → thrombosis in pancreatitis "
"→ left-sided (sinistral) portal hypertension → gastric varices.",
"Neck of pancreas lies directly over portal vein formation — key surgical danger zone.",
],
memory="'FISH': Head (in duodenal C-loop), body (crosses aorta/SMA), tail (touches Spleen). "
"Neck covers portal vein formation (SMV + splenic vein meet here at L2)."
)
# ── TOPIC 6: KIDNEY ──────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 6 — KIDNEY", "⭐⭐⭐⭐⭐",
LIGHT_BLUE, MID_BLUE,
location="Retroperitoneal, posterior abdominal wall. Right: T12–L3 (lower, pushed by "
"liver). Left: T11–L2 (higher). Each ~11×6×3 cm, ~150g.",
ext_feat="Hilum on medial border — structures (front to back): Renal vein, Renal artery, "
"Ureter (VAU). Coverings: Fibrous capsule → Perinephric fat → Gerota's fascia "
"→ Paranephric fat → Peritoneum (anterior only).",
int_feat="Cortex (outer): glomeruli + convoluted tubules. Medulla: 8–18 renal pyramids "
"with papillae draining → minor calices → major calices → renal pelvis → ureter. "
"Columns of Bertin between pyramids. Sinus: fat + collecting system + vessels.",
relations_rows=[
("Right kidney — Anterior", "Suprarenal gland, Liver (upper 2/3), 2nd part duodenum (directly applied, no peritoneum), Hepatic flexure, Jejunum"),
("Left kidney — Anterior", "Suprarenal gland, Spleen, Stomach, Tail of pancreas + splenic vessels, Splenic flexure, Jejunum"),
("Both — Posterior", "Diaphragm (upper), Psoas major (medial), Quadratus lumborum (lateral), Transversus abdominis"),
("Posterior nerves", "Subcostal nerve T12, Iliohypogastric L1, Ilioinguinal L1"),
],
artery="Renal arteries from aorta at L1 (just below SMA). Right renal artery longer — "
"crosses behind IVC, right renal vein, head of pancreas. "
"5 segmental arteries (end arteries — no anastomosis = infarction if blocked).",
vein="Right renal vein → IVC directly (short). Left renal vein longer — "
"crosses anterior to aorta, receives left gonadal vein + left suprarenal vein → IVC.",
nerve="Sympathetic: T10–L1 via renal plexus (from coeliac + aorticorenal ganglia). "
"Pain from kidney referred to T10 dermatome (loin to groin = ureteric colic). "
"No parasympathetic to kidneys.",
lymph="Para-aortic (lateral aortic) nodes at L1–L2 — follows renal artery back to aorta. "
"→ cisterna chyli → thoracic duct.",
applied_points=[
"Renal colic: Stone in ureter → pain radiates loin to groin (T10-L1 + ilioinguinal "
"nerve distribution). 3 narrowings: PUJ, pelvic brim (crosses iliac vessels), VUJ.",
"Nephrectomy: Posterior approach — 12th rib removal. Beware subcostal nerve (T12) "
"→ skin anaesthesia of anterolateral abdominal wall.",
"Renal transplant: In iliac fossa (extraperitoneal). Renal artery → internal/external "
"iliac artery. Renal vein → external iliac vein. Ureter → bladder.",
"Horseshoe kidney: Lower poles fused across midline, held by IMA → 'tethered'. "
"Cannot ascend normally during development.",
"Left renal vein longer → left testicular/ovarian vein drains into it at 90° "
"→ left varicocele more common than right.",
],
memory="Hilum structures front to back: 'VAU' — Vein, Artery, Ureter. "
"Right kidney anterior: 'Suprarenal-Liver-Duodenum-Colon'. "
"Left kidney anterior: 'Suprarenal-Spleen-Stomach-Pancreas-Colon'."
)
# ── TOPIC 7: URINARY BLADDER ─────────────────────────────────────────────────
story += organ_page(
"TOPIC 7 — URINARY BLADDER", "⭐⭐⭐",
ORANGE_LIGHT, ORANGE,
location="Anterior pelvis, behind pubic symphysis. Empty: entirely pelvic. "
"Full: rises into abdomen above pubic symphysis.",
ext_feat="Apex (→ median umbilical ligament = obliterated urachus), Base/Fundus "
"(posterior, triangular), Body, Neck (most fixed, connects to urethra). "
"Capacity: 500 mL functionally, 1000+ mL before rupture.",
int_feat="Trigone: Smooth triangular area on internal base. 3 angles = 2 ureteric "
"orifices (posterolateral) + 1 internal urethral orifice (antero-inferior). "
"Interureteric bar: ridge connecting ureteric openings. Detrusor muscle: "
"3 layers of smooth muscle; inner + outer longitudinal, middle circular. "
"Rugae: folds in body (absent over trigone).",
relations_rows=[
("Male — Superior", "Loops of small intestine, sigmoid colon"),
("Male — Posterior", "Rectovesical pouch → Seminal vesicles + vas ampullae → Rectum"),
("Male — Inferior", "Prostate gland (directly below neck)"),
("Female — Superior", "Uterus (lies on top when anteflexed)"),
("Female — Posterior", "Vesicouterine pouch → Cervix → Upper vagina"),
("Both — Anterior", "Retropubic space (Cave of Retzius, fatty) → Pubic symphysis"),
],
artery="Superior vesical artery (from patent umbilical artery branch of internal iliac): "
"supplies dome. Inferior vesical artery (males, from internal iliac): base, "
"fundus, seminal vesicles, prostate. Vaginal artery (females) = equivalent.",
vein="Vesical venous plexus → internal iliac veins → common iliac → IVC.",
nerve="Parasympathetic S2–S4 (pelvic splanchnic = nervi erigentes): Motor to detrusor "
"(contraction = voiding). Sympathetic L1–L2 (hypogastric plexus): Inhibits detrusor "
"+ contracts internal sphincter (storage). Pudendal nerve S2–S4: somatic motor "
"to external sphincter (voluntary).",
lymph="Internal iliac + external iliac nodes → common iliac → para-aortic nodes.",
applied_points=[
"Suprapubic cystostomy: Insert above pubic symphysis when full — safe because "
"bladder rises above pubis and no peritoneum anteriorly (Cave of Retzius).",
"Bladder carcinoma (TCC): Painless haematuria until proven otherwise. "
"Transitional cell carcinoma = most common. Staging: T1 (lamina propria), "
"T2 (muscle), T3 (perivesical fat), T4 (adjacent organs).",
"VUJ obstruction: Ureter enters bladder obliquely (anti-reflux flap valve mechanism). "
"Stone commonly stuck here (3rd narrowing of ureter).",
"Cystocele: Bladder bulges into anterior vaginal wall due to pelvic floor weakness.",
"Parasympathetic = 'PEE' (S2-S4 detrusor contracts). Sympathetic = 'STOP' (L1-L2).",
],
memory="Parasympathetic = PEE (S2-S4). Sympathetic = STOP (L1-L2). "
"Suprapubic tap is SAFE because bladder rises above pubis when full."
)
# ── TOPIC 8: UTERUS ──────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 8 — UTERUS", "⭐⭐⭐⭐⭐",
PURPLE_LIGHT, PURPLE,
location="Pelvic cavity between bladder (anterior) and rectum (posterior). "
"Normal position: Anteverted (~90° angle to vagina) + Anteflexed (~125° bend "
"at internal os). Retroversion in 20% of women (normal variant).",
ext_feat="Parts: Fundus (above fallopian tube openings), Body, Isthmus (1 cm), Cervix "
"(supravaginal + vaginal parts). Covered by peritoneum except anteriorly below "
"isthmus (extraperitoneal cervix). Weight ~60g non-pregnant.",
int_feat="Endometrium: columnar epithelium, undergoes cyclical changes. "
"Myometrium: 3 smooth muscle layers (outer longitudinal, middle oblique/spiral, "
"inner longitudinal). External os: circular (nulliparous), transverse slit "
"(multiparous). Internal os: site of incompetent cervix (cervical stitch here).",
relations_rows=[
("Anterior", "Vesicouterine pouch → Bladder (body rests on bladder)"),
("Posterior", "Recto-uterine pouch (Pouch of Douglas, deepest part of peritoneal cavity) → Rectum"),
("Lateral", "Broad ligament; UTERINE ARTERY (crosses ABOVE ureter 2cm lateral to cervix)"),
("Superior (fundus)", "Loops of small intestine"),
("Inferior (cervix)", "Vaginal fornices surround cervix; vagina below"),
],
artery="Uterine artery (main) from internal iliac — runs in base of broad ligament, "
"CROSSES ABOVE URETER 2 cm lateral to cervix ('water under the bridge'). "
"Ovarian artery (from aorta at L2): supplies fundus + fallopian tubes. "
"Extensive anastomosis between both.",
vein="Uterine venous plexus → uterine veins → internal iliac veins → IVC.",
nerve="Sympathetic T10–L1 via hypogastric plexus: pain from uterine body referred "
"to T10 (umbilical level) — labour pains felt at umbilicus. "
"Parasympathetic S2–S4: pelvic splanchnic nerves. "
"Cervix: pelvic plexus (less sensitive — IUD insertion tolerable).",
lymph="Fundus → para-aortic nodes (L2) [follows ovarian/round ligament artery]. "
"Body → internal + external iliac nodes. "
"Cervix → internal iliac + external iliac + obturator nodes.",
applied_points=[
"CRITICAL: Ureter passes 2 cm lateral to cervix UNDER the uterine artery "
"('water under the bridge'). At risk in hysterectomy when uterine artery ligated.",
"Uterine prolapse: Failure of transverse (cardinal/Mackenrodt's) ligament + pelvic "
"floor. Grades: 1st (descent), 2nd (cervix at introitus), 3rd (procidentia).",
"Ectopic pregnancy: Usually in fallopian tube → rupture → blood in Pouch of "
"Douglas → posterior fornix tenderness on examination.",
"Cervical cancer: Parametrial spread makes it inoperable (Stage IIB+). Pap smear "
"detects pre-cancerous CIN changes.",
"Endometriosis: Ectopic endometrium; most common sites = Pouch of Douglas + ovaries.",
],
memory="'Water under the bridge': Uterine artery (bridge) crosses ABOVE ureter (water). "
"Cervix lymphatics → obturator/internal iliac nodes. "
"Fundus lymphatics → para-aortic (like ovary — both drain to aorta level)."
)
# ── TOPIC 9: TESTIS ──────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 9 — TESTIS", "⭐⭐⭐⭐⭐",
GREEN_LIGHT, GREEN,
location="Scrotum, suspended by spermatic cord. Left usually lower. Temperature "
"2–3°C below body temp (required for spermatogenesis). Descended from "
"near L2 (why blood supply and lymphatics go to L2 level).",
ext_feat="Tunica vaginalis (double serous coat, derived from peritoneum). "
"Tunica albuginea (fibrous capsule). Epididymis on posterolateral surface "
"(head, body, tail → vas deferens). Mediastinum testis: posterior thickening "
"where vessels + ducts enter.",
int_feat="Seminiferous tubules (~900): sperm production. Sertoli cells: blood-testis "
"barrier, support sperm, secrete inhibin (inhibits FSH). "
"Leydig cells (interstitial): testosterone (under LH stimulation). "
"Rete testis → efferent ductules (×15) → head of epididymis → vas deferens.",
relations_rows=[
("Anteriorly", "Tunica vaginalis (visceral layer directly, parietal layer separated by potential space = hydrocele site)"),
("Posterolaterally", "Epididymis (head above, body, tail below)"),
("Medially", "Scrotal septum"),
("Above", "Spermatic cord with all its contents"),
],
artery="Testicular artery: from AORTA at L2 (directly — not from iliac!). "
"This reflects testicular origin near kidney at L2. "
"Cremasteric artery (from inferior epigastric). "
"Artery to vas (from inferior vesical artery).",
vein="Pampiniform plexus (venous net around testicular artery in spermatic cord) → "
"Testicular vein. Right: → IVC directly. Left: → LEFT RENAL VEIN → IVC. "
"(Left is longer, drains at 90° angle = higher pressure = left varicocele more common).",
nerve="Sympathetic T10 via testicular plexus (follows testicular artery from aorta). "
"Pain referred to T10 dermatome = umbilicus. Cremasteric reflex: L1-L2 "
"(femoral branch of genitofemoral nerve afferent, genitofemoral efferent).",
lymph="Para-aortic nodes (lateral aortic nodes at L2) — NOT inguinal nodes! "
"If scrotal SKIN invaded by tumour → THEN inguinal nodes involved. "
"→ para-aortic → cisterna chyli → thoracic duct.",
applied_points=[
"EXAM TRAP: Testicular lymph drains to PARA-AORTIC nodes (L2), NOT inguinal nodes. "
"Only scrotal skin drainage goes to inguinal nodes.",
"Varicocele: Dilated pampiniform plexus ('bag of worms'). 90% left-sided — "
"left testicular vein drains into left renal vein at 90° angle (higher resistance).",
"Testicular torsion: 'Bell-clapper' deformity (high tunica vaginalis insertion). "
"Emergency surgery within 6 hours. Cremasteric reflex ABSENT (unlike epididymitis).",
"Testicular tumours: Germ cell (seminoma, teratoma) = peak 20–35 years. "
"Painless lump. Spread to para-aortic nodes first.",
"Cryptorchidism: 20× increased cancer risk. Treat with orchidopexy by age 1–2 years.",
],
memory="Testicular artery from AORTA at L2 → lymph to PARA-AORTIC at L2. "
"Left varicocele (90%) because left testicular vein drains into left renal vein "
"at 90° = higher resistance = backpressure = pampiniform plexus dilates."
)
# ── TOPIC 10: RECTUM ─────────────────────────────────────────────────────────
story += organ_page(
"TOPIC 10 — RECTUM", "⭐⭐⭐⭐⭐",
RED_LIGHT, RED,
location="Rectosigmoid junction at S3 to anorectal junction (perineal flexure). "
"12–15 cm long. Follows sacral curvature. No mesentery.",
ext_feat="No taeniae coli, haustrations, or appendices epiploicae. 3 lateral flexures "
"(R-L-R when viewed anteriorly). Peritoneal coverage: Upper 1/3 = front + sides; "
"Middle 1/3 = front only (peritoneal reflection here = Pouch of Douglas in "
"females / rectovesical pouch in males); Lower 1/3 = no peritoneum (extraperitoneal).",
int_feat="3 Houston's valves (transverse rectal folds): upper (left), middle (right, most "
"prominent = at peritoneal reflection level), lower (left). "
"Ampulla: dilated lower rectum for faecal storage. "
"Mucosa: columnar epithelium (like colon) above anorectal junction.",
relations_rows=[
("Male — Anterior", "Rectovesical pouch → Seminal vesicles + vas ampullae → Prostate → Membranous urethra (top to bottom)"),
("Female — Anterior", "Recto-uterine pouch (Pouch of Douglas) → Cervix → Posterior vaginal wall"),
("Both — Posterior", "Sacrum, Coccyx → Piriformis, Coccygeus → Median sacral artery → Sympathetic trunks"),
("Lateral", "Upper: peritoneum (pararectal fossae). Lower: Levator ani, pelvic fascia, pelvic lymph nodes"),
],
artery="Superior rectal artery (main): from IMA — portal system territory. "
"Middle rectal artery: from internal iliac — systemic territory. "
"Inferior rectal artery: from pudendal artery (internal iliac). "
"→ Portosystemic anastomosis between superior and middle/inferior rectal vessels.",
vein="Superior rectal vein → IMV → portal system. "
"Middle + inferior rectal veins → internal iliac → systemic. "
"Anastomosis here = anorectal portosystemic site.",
nerve="Sympathetic L1–L2 via hypogastric plexus: inhibits motility, controls internal "
"anal sphincter. Parasympathetic S2–S4 (pelvic splanchnic): stimulates peristalsis, "
"inhibits sphincter (defecation). Somatic: pudendal nerve for external sphincter.",
lymph="Upper rectum → superior rectal nodes → IMA nodes → para-aortic. "
"Lower rectum (below peritoneal reflection) → internal iliac nodes. "
"Lymphatics do NOT cross the peritoneal reflection.",
applied_points=[
"PR (per rectal) examination: Feel prostate (male) / cervix (female) anteriorly, "
"sacrum posteriorly, ischiorectal fossa laterally.",
"Rectal carcinoma below peritoneal reflection: Spread laterally to pelvic wall "
"→ circumferential resection margin (CRM) determines prognosis.",
"APR (abdominoperineal resection) vs anterior resection: Low tumour (<5 cm from "
"anal verge) = APR + permanent colostomy.",
"Middle Houston's valve corresponds to peritoneal reflection level — key in "
"rigid sigmoidoscopy (15 cm from anal verge = peritoneal cavity).",
"Lateral lymph node dissection: For tumours below peritoneal reflection to clear "
"internal iliac nodes — reduces local recurrence.",
],
memory="Anterior to rectum in males (top-bottom): 'Seminal vessels Visit Prostate's "
"Membrane' = Seminal vesicles, Vas, Prostate, Membranous urethra."
)
# ── TOPIC 11: ANAL CANAL ─────────────────────────────────────────────────────
story += organ_page(
"TOPIC 11 — ANAL CANAL", "⭐⭐⭐⭐⭐",
ORANGE_LIGHT, ORANGE,
location="From anorectal junction (perineal flexure) to anal verge. 4 cm long. "
"Passes through pelvic floor (levator ani) and perineum.",
ext_feat="Two sphincters: Internal anal sphincter (IAS — smooth muscle, involuntary, "
"provides 85% resting tone) and External anal sphincter (EAS — skeletal "
"muscle, voluntary, 3 parts). Puborectalis creates anorectal angle (~90°) "
"= most important continence mechanism.",
int_feat="Pectinate (dentate) line: MOST IMPORTANT LANDMARK — divides upper (endoderm, "
"columnar, insensitive) from lower (ectoderm, squamous, sensitive). "
"Anal columns of Morgagni (8–10): contain terminal superior rectal artery + vein "
"(= internal haemorrhoidal cushions at 3, 7, 11 o'clock). "
"Anal valves at bases of columns. Anal sinuses: pockets behind valves "
"(anal glands open here → source of fistulae and abscesses).",
relations_rows=[
("Above pectinate line", "Columnar epithelium, portal venous drainage (superior rectal → IMV), autonomic nerve supply (insensitive to pain), lymph → internal iliac"),
("Below pectinate line", "Stratified squamous, systemic venous drainage (middle/inferior rectal), somatic nerve supply (inferior rectal branch of pudendal = PAINFUL), lymph → inguinal"),
("Lateral", "Ischiorectal (ischioanal) fossa — fat-filled space allowing distension"),
("Posterior", "Anococcygeal body (ligament)"),
],
artery="Above pectinate: Superior rectal artery (from IMA, portal). "
"Below pectinate: Inferior rectal artery (from pudendal, from internal iliac, systemic). "
"Middle rectal: supplies sphincters.",
vein="Above pectinate: Superior rectal vein → IMV → PORTAL SYSTEM. "
"Below pectinate: Inferior rectal vein → pudendal vein → internal iliac → SYSTEMIC. "
"→ Portosystemic anastomosis at this level.",
nerve="Above pectinate: Autonomic (visceral) — insensitive to pain, only sensitive to "
"stretch/distension. Below pectinate: Inferior rectal nerve (branch of pudendal, "
"S2–S3) — sensitive to pain, temperature, touch.",
lymph="Above pectinate line → internal iliac nodes. "
"Below pectinate line → superficial inguinal nodes. "
"(Ectodermal origin = skin drainage = inguinal nodes.)",
applied_points=[
"Haemorrhoids: Internal = above pectinate = painless bleeding (autonomic nerve). "
"External = below pectinate = painful (somatic pudendal nerve). "
"Primary positions: 3, 7, 11 o'clock (patient in lithotomy).",
"Anal carcinoma: Squamous cell carcinoma (below pectinate) → inguinal node spread. "
"Adenocarcinoma (above pectinate) → internal iliac nodes.",
"Fistula-in-ano: Goodsall's rule: anterior external opening → straight tract to "
"pectinate line; posterior opening → curved tract to posterior midline.",
"Hirschsprung's disease: Absent Auerbach's plexus → no RAIR → IAS cannot relax "
"→ neonatal bowel obstruction. Segment always includes internal sphincter.",
"ANORECTAL ANGLE (90°): Maintained by puborectalis — most important continence "
"factor. Division of puborectalis = faecal incontinence.",
],
memory="PECTINATE LINE RULE: 'Above = Inside (portal, autonomic, internal iliac lymph, "
"columnar). Below = Outside (systemic, somatic, inguinal lymph, squamous)'. "
"Everything flips at this one line!"
)
# ── MASTER TABLES PAGE ────────────────────────────────────────────────────────
story.append(section_header("📊 MASTER VASCULAR & LYMPHATIC HIERARCHY TABLES"))
story.append(sp(6))
story.append(subsection_header("🩸 ARTERIAL SUPPLY — ALL 11 ORGANS", bg=RED_LIGHT))
story.append(sp(3))
art_rows = [
("Stomach","Coeliac → L.gastric, R.gastric, gastro-omental, short gastric","T12"),
("Liver","Coeliac → Hepatic artery proper (25%) + Portal vein (75%)","T12"),
("Pancreas","Coeliac + SMA → pancreaticoduodenal arteries; Splenic (body/tail)","T12/L1"),
("Portal vein","Formed by SMV + Splenic vein (NO arterial supply)","L2"),
("Kidney","Direct from Aorta → Renal artery (5 segmental = end arteries)","L1"),
("Bladder","Internal iliac → Superior vesical + Inferior vesical","Pelvis"),
("Uterus","Internal iliac → Uterine artery (crosses ABOVE ureter 2cm lat to cervix)","Pelvis"),
("Testis","DIRECT from Aorta → Testicular artery","L2"),
("Rectum","IMA → Superior rectal; Internal iliac → Middle + Inferior rectal","L3/Pelvis"),
("Anal canal","IMA → Superior rectal (above PC); Pudendal → Inferior rectal (below PC)","L3/Pelvis"),
("Inguinal canal","Inf. epigastric (Cremasteric); Aorta (Testicular); Inf. vesical (Artery to vas)","L2"),
]
story.append(four_col_table(
["Organ","Arterial Supply","Level",""],
[(r[0],r[1],r[2],"") for r in art_rows],
widths=[3.5*cm, 9.5*cm, 2.5*cm, 1.5*cm],
hdr_bg=RED
))
story.append(sp(8))
story.append(subsection_header("🟢 LYMPHATIC DRAINAGE — ALL 11 ORGANS", bg=GREEN_LIGHT))
story.append(sp(3))
lymp_rows = [
("Stomach","Coeliac nodes","Para-aortic","Thoracic duct"),
("Liver","Hepatic (portal) nodes → Coeliac","Para-aortic","Thoracic duct"),
("Pancreas","Pancreaticoduodenal nodes","Coeliac + SMA nodes","Para-aortic"),
("Portal vein","Hepatic nodes at porta","Coeliac","Para-aortic"),
("Kidney","Para-aortic (L1–L2)","—","Cisterna chyli"),
("Bladder","Internal + External iliac","Common iliac","Para-aortic"),
("Uterus — Fundus","Para-aortic (L2)","—","Thoracic duct"),
("Uterus — Body","Int + Ext iliac","Common iliac","Para-aortic"),
("Uterus — Cervix","Int iliac + Obturator","Common iliac","Para-aortic"),
("Testis ⚠️","PARA-AORTIC (L2) — NOT inguinal!","—","Thoracic duct"),
("Rectum — upper","Superior rectal → IMA nodes","Para-aortic","Cisterna chyli"),
("Rectum — lower","Internal iliac nodes","Common iliac","Para-aortic"),
("Anal — above PC","Internal iliac","Common iliac","Para-aortic"),
("Anal — below PC ⚠️","Superficial INGUINAL","External iliac","Para-aortic"),
]
story.append(four_col_table(
["Organ/Part","Primary Nodes","Secondary Nodes","Final"],
lymp_rows,
widths=[4.5*cm, 5*cm, 4*cm, 3.5*cm],
hdr_bg=GREEN
))
story.append(PageBreak())
# ── QUICK REVISION PAGE ────────────────────────────────────────────────────────
story.append(section_header("⚡ TOP 30 EXAM FACTS — Quick Revision"))
story.append(sp(5))
facts = [
("1","Portal vein","Formed behind NECK OF PANCREAS at L2 by SMV + Splenic vein"),
("2","Hilum of kidney","Front-to-back: VEIN → ARTERY → URETER (VAU)"),
("3","Testis lymph","Para-aortic nodes (L2) — NEVER inguinal (unless scrotal skin involved)"),
("4","Left varicocele","Left testicular vein → Left renal vein at 90° = high resistance = 90% left"),
("5","Uterine artery","Crosses ABOVE ureter 2 cm lateral to cervix — injured in hysterectomy"),
("6","Anal canal above PC","Autonomic nerves = PAINLESS; portal venous drainage; internal iliac lymph"),
("7","Anal canal below PC","Pudendal nerve = PAINFUL; systemic venous drainage; INGUINAL lymph"),
("8","Portosystemic sites","OEURA: Oesophagus, Umbilicus, Rectum, Retroperitoneum, Area (bare)"),
("9","Liver blood supply","Portal vein = 75% volume; Hepatic artery = 25% volume"),
("10","Porta hepatis","Portal vein (behind), Bile duct (right), Artery (left) — 'BAP'"),
("11","Pancreatic neck","Portal vein formed directly behind it — danger in surgery"),
("12","Gastric bed","PLEASE LET LADY SPIDERS STOP TO DANCE (7 structures)"),
("13","Inguinal canal","Deep ring = lateral to inf. epigastric vessels (in transversalis fascia)"),
("14","Bladder nerve","Parasympathetic = PEE (S2-S4). Sympathetic = STOP (L1-L2)"),
("15","Suprapubic cystostomy","Safe because full bladder rises above pubic symphysis"),
("16","Courvoisier's law","Palpable non-tender gallbladder = carcinoma of pancreatic head"),
("17","Haemorrhoid positions","3, 7, 11 o'clock in lithotomy (correspond to end branches of superior rectal artery)"),
("18","Rectal peritoneum","Upper 1/3 = front+sides; Middle 1/3 = front only; Lower 1/3 = none"),
("19","Renal transplant","Placed in iliac fossa; renal artery → iliac artery; NOT in retroperitoneal position"),
("20","Right kidney lower","Because liver pushes it down (right kidney at T12-L3, left at T11-L2)"),
("21","Goodsall's rule","Anterior fistula-in-ano: straight; Posterior: curved to posterior midline"),
("22","Anorectal angle","90°, maintained by puborectalis — most important continence factor"),
("23","Uterus fundus lymph","Para-aortic (not iliac) — fundus drains with ovarian vessels to L2"),
("24","SMA origin","L1 — supplies small intestine + right colon (jejunum to 2/3 transverse colon)"),
("25","IMA origin","L3 — supplies left colon + sigmoid + upper rectum"),
("26","Renal colic levels","3 narrow sites: PUJ, crossing iliac vessels at pelvic brim, VUJ"),
("27","Pancreatic cancer","Head → painless jaundice. Body/tail → diabetes mellitus"),
("28","Ectopic pregnancy","Blood collects in Pouch of Douglas → posterior fornix tenderness"),
("29","Pectinate line","Everything changes here — embryological boundary of endoderm/ectoderm"),
("30","Lymph rule","Lymphatics FOLLOW THE ARTERY back to its origin — derive all drainage from this"),
]
facts_table = Table(
[[Paragraph("<b>#</b>",small),
Paragraph("<b>Topic</b>",small),
Paragraph("<b>Key Fact</b>",small)]] +
[[Paragraph(f[0], S("fn",fontSize=9,textColor=GOLD,fontName="Helvetica-Bold",leading=12)),
Paragraph(f[1], S("ft",fontSize=9,textColor=DARK_BLUE,fontName="Helvetica-Bold",leading=12)),
Paragraph(f[2], small)] for f in facts],
colWidths=[0.8*cm, 3.8*cm, 12.4*cm]
)
facts_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),DARK_BLUE),
("TEXTCOLOR",(0,0),(-1,0),WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("GRID",(0,0),(-1,-1),0.4,GREY_MID),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE,GREY_LIGHT]),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),4),
("FONTSIZE",(0,1),(-1,-1),8.5),
]))
story.append(facts_table)
story.append(sp(8))
story.append(section_header("⚠️ THE 3 EXAM TRAPS — Never Lose Marks", bg=RED))
story.append(sp(5))
traps = [
("TRAP 1", "TESTIS LYMPH → PARA-AORTIC, NOT INGUINAL",
"The testis originated near the kidney (L2). As it descended through the inguinal canal, "
"it TOOK ITS BLOOD SUPPLY AND LYMPHATICS with it from the aorta at L2. Therefore: testicular "
"lymphatics = para-aortic nodes at L2. Inguinal nodes are only involved if the SCROTAL SKIN "
"(not the testis itself) is invaded by tumour."),
("TRAP 2", "BELOW PECTINATE LINE → INGUINAL NODES (not internal iliac)",
"The lower anal canal (below pectinate line) is derived from ectoderm = skin = perineal skin. "
"All skin of the perineum drains to SUPERFICIAL INGUINAL nodes. Above the pectinate line = "
"endoderm = gut = drains to internal iliac nodes (like all pelvic viscera). Anal carcinoma "
"BELOW the line = inguinal node involvement; ABOVE the line = internal iliac nodes."),
("TRAP 3", "UTERINE ARTERY CROSSES ABOVE URETER (not below)",
"The uterine artery is the 'bridge'. The ureter is 'water'. WATER PASSES UNDER THE BRIDGE. "
"The ureter runs 2 cm lateral to the cervix UNDER the uterine artery. During hysterectomy, "
"when the surgeon clamps and cuts the uterine artery, the ureter is at risk of being cut or "
"kinked. This is the #1 complication of hysterectomy. Always remember: artery above, ureter below."),
]
for trap in traps:
trap_data = [
[Paragraph(trap[0], S("TL",fontSize=11,textColor=WHITE,fontName="Helvetica-Bold",leading=14)),
Paragraph(trap[1], S("TT",fontSize=11,textColor=GOLD, fontName="Helvetica-Bold",leading=14))],
[Paragraph("", small), Paragraph(trap[2], body)],
]
tt = Table(trap_data, colWidths=[2.5*cm, 14.5*cm])
tt.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,-1), RED),
("BACKGROUND",(1,0),(1,0), RED),
("BACKGROUND",(1,1),(1,1), RED_LIGHT),
("TOPPADDING",(0,0),(-1,-1),5),
("BOTTOMPADDING",(0,0),(-1,-1),5),
("LEFTPADDING",(0,0),(-1,-1),8),
("BOX",(0,0),(-1,-1),1.5,RED),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
story.append(tt)
story.append(sp(6))
# ── BUILD PDF ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=1.8*cm, bottomMargin=1.8*cm,
title="Abdomen & Pelvis Gold Medal Study Guide",
author="Orris Medical Education",
subject="Anatomy LAQ 15-Mark Answers",
)
doc.build(story)
print(f"PDF created: {OUTPUT}")