Make ppt of splenic anatomy using BD chourasya in white background
mkdir -p /tmp/workspace/splenic-anatomy-ppt && ls /tmp/workspace/splenic-anatomy-ppt/
~/splenic-anatomy-ppt/build_ppt.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import json, subprocess, base64
from io import BytesIO
# ─── Color Palette ───────────────────────────────────────────────────────────
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
BLACK = RGBColor(0x1A, 0x1A, 0x2E) # near-black for text
ACCENT = RGBColor(0x8B, 0x00, 0x00) # dark red / maroon (anatomical feel)
ACCENT2 = RGBColor(0xC0, 0x39, 0x2B) # lighter red
LIGHT_GRAY = RGBColor(0xF2, 0xF2, 0xF2) # very light gray for alt slides
MID_GRAY = RGBColor(0xCC, 0xCC, 0xCC)
STEEL_BLUE = RGBColor(0x2E, 0x86, 0xAB) # highlight color
W = Inches(13.333)
H = Inches(7.5)
prs = Presentation()
prs.slide_width = W
prs.slide_height = H
blank = prs.slide_layouts[6]
# ─── Helper functions ─────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_color=None, line_color=None, line_width=Pt(0)):
shape = slide.shapes.add_shape(1, x, y, w, h) # MSO_SHAPE_TYPE.RECTANGLE = 1
if fill_color:
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
else:
shape.fill.background()
if line_color:
shape.line.color.rgb = line_color
shape.line.width = line_width
else:
shape.line.fill.background()
return shape
def add_textbox(slide, x, y, w, h, text, font_name="Calibri", font_size=Pt(18),
bold=False, italic=False, color=BLACK, align=PP_ALIGN.LEFT,
word_wrap=True, v_anchor=MSO_ANCHOR.TOP):
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = word_wrap
tf.vertical_anchor = v_anchor
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = font_size
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tb
def add_multiline_textbox(slide, x, y, w, h, lines, font_name="Calibri",
font_size=Pt(16), bold=False, color=BLACK,
align=PP_ALIGN.LEFT, line_spacing=None):
"""lines: list of (text, bold, size, color) tuples OR plain strings."""
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
first = True
for item in lines:
if isinstance(item, str):
txt, b, sz, col = item, bold, font_size, color
else:
txt, b, sz, col = item
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
p.alignment = align
if line_spacing:
from pptx.oxml.ns import qn
from lxml import etree
pPr = p._p.get_or_add_pPr()
lnSpc = etree.SubElement(pPr, qn('a:lnSpc'))
spcPct = etree.SubElement(lnSpc, qn('a:spcPct'))
spcPct.set('val', str(int(line_spacing * 1000)))
run = p.add_run()
run.text = txt
run.font.name = font_name
run.font.size = sz
run.font.bold = b
run.font.color.rgb = col
return tb
def heading_bar(slide, title_text):
"""Dark red top bar with white title."""
add_rect(slide, 0, 0, W, Inches(0.85), fill_color=ACCENT)
add_textbox(slide, Inches(0.4), Inches(0.08), Inches(12.5), Inches(0.7),
title_text, font_name="Calibri", font_size=Pt(30),
bold=True, color=WHITE, align=PP_ALIGN.LEFT,
v_anchor=MSO_ANCHOR.MIDDLE)
def footer(slide, text="BD Chaurasia's Human Anatomy – Splenic Anatomy"):
add_rect(slide, 0, H - Inches(0.35), W, Inches(0.35), fill_color=LIGHT_GRAY)
add_textbox(slide, Inches(0.3), H - Inches(0.32), Inches(12.5), Inches(0.3),
text, font_size=Pt(10), color=MID_GRAY,
align=PP_ALIGN.LEFT)
add_textbox(slide, Inches(12.0), H - Inches(0.32), Inches(1.1), Inches(0.3),
"", font_size=Pt(10), color=MID_GRAY, align=PP_ALIGN.RIGHT)
def left_accent_bar(slide):
add_rect(slide, 0, Inches(0.85), Inches(0.08), H - Inches(1.2), fill_color=ACCENT)
def bullet_list(slide, x, y, w, h, items, title=None, title_color=ACCENT,
font_size=Pt(16), title_size=Pt(19)):
"""Renders a boxed bullet list block."""
# Optional sub-title
ty = y
if title:
add_textbox(slide, x, ty, w, Inches(0.38), title,
font_size=title_size, bold=True, color=title_color)
ty += Inches(0.38)
tb = slide.shapes.add_textbox(x, ty, w, h - (ty - y))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = Inches(0.1); tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
first = True
for item in items:
if isinstance(item, str):
txt, b, col = item, False, BLACK
else:
txt, b, col = item
if first:
p = tf.paragraphs[0]; first = False
else:
p = tf.add_paragraph()
p.alignment = PP_ALIGN.LEFT
run = p.add_run()
run.text = "• " + txt
run.font.name = "Calibri"
run.font.size = font_size
run.font.bold = b
run.font.color.rgb = col
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 1 – Title Slide
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
# Full white background
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
# Top bar
add_rect(slide, 0, 0, W, Inches(0.7), fill_color=ACCENT)
# Decorative side strip
add_rect(slide, 0, Inches(0.7), Inches(0.25), H - Inches(0.7), fill_color=ACCENT2)
# Bottom bar
add_rect(slide, 0, H - Inches(0.5), W, Inches(0.5), fill_color=ACCENT)
# Main title
add_textbox(slide, Inches(0.6), Inches(1.2), Inches(12), Inches(1.4),
"ANATOMY OF THE SPLEEN",
font_name="Calibri", font_size=Pt(52), bold=True,
color=ACCENT, align=PP_ALIGN.CENTER)
add_textbox(slide, Inches(0.6), Inches(2.7), Inches(12), Inches(0.6),
"Based on BD Chaurasia's Human Anatomy",
font_name="Calibri", font_size=Pt(22), bold=False,
color=BLACK, align=PP_ALIGN.CENTER)
add_rect(slide, Inches(3.5), Inches(3.4), Inches(6.3), Inches(0.06),
fill_color=ACCENT2)
add_textbox(slide, Inches(0.6), Inches(3.6), Inches(12), Inches(0.5),
"Abdomen & Lower Limb | Volume 2",
font_name="Calibri", font_size=Pt(18), italic=True,
color=RGBColor(0x55, 0x55, 0x55), align=PP_ALIGN.CENTER)
add_textbox(slide, Inches(0.6), Inches(4.3), Inches(12), Inches(0.5),
"Topics: Position • Surface Projections • Ligaments • Blood Supply • Nerve Supply • Lymphatics • Histology • Applied Anatomy",
font_name="Calibri", font_size=Pt(14), italic=False,
color=RGBColor(0x44, 0x44, 0x44), align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 2 – Introduction & General Features
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Introduction & General Features")
left_accent_bar(slide)
footer(slide)
# Left column
bullet_list(slide, Inches(0.3), Inches(1.05), Inches(5.8), Inches(5.5),
title="General Features",
items=[
("Largest lymphoid organ in the body", True, ACCENT),
("Located in left hypochondrium (upper left quadrant)", False, BLACK),
("Lies against the diaphragm in the area of ribs 9–11", False, BLACK),
("Intraperitoneal organ", False, BLACK),
("Weight: 100–250 g in healthy adults", False, BLACK),
("Dimensions: ~12 × 7 × 3 cm (length × breadth × thickness)", False, BLACK),
("Not palpable below costal margin in healthy adults", False, BLACK),
("Color: dark purplish-red (due to rich blood content)", False, BLACK),
("Consistency: soft and friable (easily ruptures on trauma)", False, BLACK),
], font_size=Pt(15))
# Right column
bullet_list(slide, Inches(6.4), Inches(1.05), Inches(6.6), Inches(5.5),
title="Embryology",
items=[
("Develops from mesenchymal cells in dorsal mesogastrium", False, BLACK),
("First appears as discernible organ in week 5 of embryogenesis", False, BLACK),
("Initially adherent to dorsal pancreatic bud", False, BLACK),
("Ultimately separates and settles in left upper abdomen", False, BLACK),
("Part of vascular system development", False, BLACK),
], font_size=Pt(15), title_color=STEEL_BLUE)
# Divider
add_rect(slide, Inches(6.25), Inches(1.05), Inches(0.04), Inches(5.6),
fill_color=LIGHT_GRAY)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 3 – Position, Relations & Surfaces
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Position, Relations & Surfaces")
left_accent_bar(slide)
footer(slide)
# Surfaces box
bullet_list(slide, Inches(0.3), Inches(1.05), Inches(4.1), Inches(5.7),
title="Two Surfaces",
items=[
("DIAPHRAGMATIC SURFACE", True, ACCENT),
("Convex surface", False, BLACK),
("Related to diaphragm (which separates it from the 9th, 10th, 11th ribs and pleura)", False, BLACK),
("VISCERAL (MEDIAL) SURFACE", True, ACCENT),
("Concave surface with hilum", False, BLACK),
("Gastric impression: related to stomach", False, BLACK),
("Renal impression: related to left kidney", False, BLACK),
("Colic impression: related to splenic flexure of colon", False, BLACK),
("Pancreatic impression: tail of pancreas reaches hilum in ~30% and within 1 cm in ~70%", False, BLACK),
], font_size=Pt(14))
# Middle box - poles and borders
bullet_list(slide, Inches(4.5), Inches(1.05), Inches(4.0), Inches(5.7),
title="Poles & Borders",
items=[
("POLES:", True, STEEL_BLUE),
("Superior (posterior) pole – blunt", False, BLACK),
("Inferior (anterior) pole – pointed", False, BLACK),
("BORDERS:", True, STEEL_BLUE),
("Superior border – notched (characteristic feature)", False, BLACK),
(" - 1–3 notches in anterior part", False, BLACK),
(" - Notches represent embryological lobulation", False, BLACK),
("Inferior border – rounded", False, BLACK),
], font_size=Pt(14))
# Right box - surface projections
bullet_list(slide, Inches(8.8), Inches(1.05), Inches(4.2), Inches(5.7),
title="Surface Projections",
items=[
("Projected onto posterior chest wall:", True, ACCENT),
("Long axis along the 10th rib", False, BLACK),
("Extends from 9th to 11th rib", False, BLACK),
("Does NOT extend anterior to midaxillary line", False, BLACK),
("Protected by 9th, 10th & 11th ribs", False, BLACK),
("Note: Enlarged spleen extends antero-inferiorly toward the right iliac fossa", False, BLACK),
], font_size=Pt(14))
# Vertical dividers
add_rect(slide, Inches(4.35), Inches(1.05), Inches(0.04), Inches(5.6), fill_color=LIGHT_GRAY)
add_rect(slide, Inches(8.65), Inches(1.05), Inches(0.04), Inches(5.6), fill_color=LIGHT_GRAY)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 4 – Peritoneal Ligaments
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Peritoneal Ligaments of the Spleen")
left_accent_bar(slide)
footer(slide)
add_textbox(slide, Inches(0.3), Inches(0.92), Inches(12.5), Inches(0.3),
"The spleen is surrounded by visceral peritoneum except at the hilum. Peritoneal folds form 4 major ligaments:",
font_size=Pt(14), color=BLACK, italic=True)
lig_data = [
("Gastrosplenic\nLigament",
"• Connects spleen to greater curvature of stomach\n• ANTERIOR part of splenic hilum\n• Contains: Short gastric arteries & veins (superior part), Left gastroepiploic artery & vein (inferior part)\n• Part of greater omentum",
ACCENT),
("Splenorenal\n(Lienorenal)\nLigament",
"• Connects spleen to left kidney\n• POSTERIOR part of splenic hilum\n• Contains: Splenic artery & vein (tail of pancreas)\n• Part of greater omentum",
STEEL_BLUE),
("Phrenicosplenic\nLigament",
"• Connects spleen to diaphragm\n• Superior attachment\n• Relatively avascular (in absence of portal hypertension)\n• Continuous with splenorenal ligament",
ACCENT2),
("Splenocolic\nLigament",
"• Connects spleen to splenic flexure of colon\n• Inferior attachment\n• Avascular structure – safely divided during surgery\n• Part of phrenocolic ligament",
RGBColor(0x27, 0x6E, 0x45)),
]
col_w = Inches(3.0)
for i, (lig, desc, col) in enumerate(lig_data):
cx = Inches(0.25) + i * (col_w + Inches(0.17))
# colored header box
add_rect(slide, cx, Inches(1.3), col_w, Inches(0.9), fill_color=col)
add_textbox(slide, cx + Inches(0.08), Inches(1.35), col_w - Inches(0.1), Inches(0.85),
lig, font_size=Pt(15), bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# content box
add_rect(slide, cx, Inches(2.2), col_w, Inches(4.7),
fill_color=LIGHT_GRAY, line_color=MID_GRAY, line_width=Pt(0.5))
tb = slide.shapes.add_textbox(cx + Inches(0.1), Inches(2.3),
col_w - Inches(0.2), Inches(4.5))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
for j, line in enumerate(desc.split('\n')):
if j == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.alignment = PP_ALIGN.LEFT
run = p.add_run()
run.text = line
run.font.name = "Calibri"
run.font.size = Pt(13.5)
run.font.color.rgb = BLACK
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 5 – Arterial Supply
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Arterial Supply of the Spleen")
left_accent_bar(slide)
footer(slide)
# Left column - splenic artery
bullet_list(slide, Inches(0.3), Inches(1.05), Inches(6.0), Inches(6.0),
title="Splenic Artery",
items=[
("ORIGIN: Largest branch of celiac trunk", True, ACCENT),
("(Rarely from aorta, SMA, left gastric, or middle colic artery)", False, RGBColor(0x66, 0x66, 0x66)),
("COURSE:", True, STEEL_BLUE),
("Tortuous vessel along superior border of pancreas body", False, BLACK),
("Enters splenorenal ligament at hilum", False, BLACK),
("Gives 16–18 branches to pancreas en route", False, BLACK),
("BRANCHING PATTERN (2 types):", True, STEEL_BLUE),
("1. Distributed type (70%): arborizes proximally from hilum", False, BLACK),
("2. Magistral type (30%): long trunk divides near hilum into 3–4 large branches (compact bundle)", False, BLACK),
("BRANCHES:", True, STEEL_BLUE),
("4–6 polar arteries → lobes → terminal arteries (within organ)", False, BLACK),
("Left gastroepiploic artery → along greater curvature", False, BLACK),
("Short gastric arteries (5–7) → fundus of stomach", False, BLACK),
("Inferior polar arteries from left gastroepiploic artery", False, BLACK),
], font_size=Pt(13.5))
# Divider
add_rect(slide, Inches(6.35), Inches(1.05), Inches(0.04), Inches(5.6), fill_color=LIGHT_GRAY)
# Right column - additional
bullet_list(slide, Inches(6.55), Inches(1.05), Inches(6.5), Inches(6.0),
title="Splenic Segments (Zones)",
items=[
("Spleen is divided into 2–3 vascular segments/lobes", False, BLACK),
("Segments are separated by avascular planes", False, BLACK),
("Superior segment (supplied by superior polar artery)", False, BLACK),
("Inferior segment (supplied by inferior polar artery)", False, BLACK),
("Segmental anatomy allows partial splenectomy", False, BLACK),
], font_size=Pt(13.5), title_color=STEEL_BLUE)
bullet_list(slide, Inches(6.55), Inches(3.3), Inches(6.5), Inches(3.5),
title="Accessory Spleen",
items=[
("Present in 10–30% of individuals", False, BLACK),
("Usually located at splenic hilum or gastrosplenic ligament", False, BLACK),
("Also found in splenorenal ligament, greater omentum, mesentery", False, BLACK),
("Clinical importance: must be removed during splenectomy for hematologic disease (e.g., ITP)", False, BLACK),
("Failure to remove → recurrence of symptoms", False, BLACK),
], font_size=Pt(13.5), title_color=ACCENT2)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 6 – Venous Drainage, Lymphatics & Nerve Supply
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Venous Drainage, Lymphatics & Nerve Supply")
left_accent_bar(slide)
footer(slide)
# Venous box
bullet_list(slide, Inches(0.3), Inches(1.05), Inches(4.0), Inches(5.7),
title="Venous Drainage",
items=[
("SPLENIC VEIN:", True, ACCENT),
("Formed at hilum by union of 5–6 tributaries", False, BLACK),
("Travels posterior to pancreas (along inferior border)", False, BLACK),
("Joins inferior mesenteric vein (IMV) first", False, BLACK),
("Then unites with superior mesenteric vein (SMV) to form PORTAL VEIN", True, ACCENT),
("Portal Vein formed: behind neck of pancreas", False, BLACK),
("Tributaries:", True, STEEL_BLUE),
("Short gastric veins", False, BLACK),
("Left gastroepiploic vein", False, BLACK),
("Inferior mesenteric vein (usually)", False, BLACK),
("Several pancreatic veins", False, BLACK),
], font_size=Pt(13.5))
# Lymphatics box
bullet_list(slide, Inches(4.55), Inches(1.05), Inches(4.2), Inches(5.7),
title="Lymphatics",
items=[
("EFFERENT LYMPHATICS:", True, STEEL_BLUE),
("Leave at the hilum with splenic vessels", False, BLACK),
("Drain into pancreaticosplenic (splenic) lymph nodes at hilum", False, BLACK),
("Then to celiac lymph nodes", False, BLACK),
("Then to cisterna chyli", False, BLACK),
("NOTE: No afferent lymphatics — spleen filters BLOOD not lymph", True, ACCENT2),
("Largest single accumulation of lymphoid tissue in body", False, BLACK),
("Spleen = secondary lymphoid organ (filters blood-borne antigens)", False, BLACK),
], font_size=Pt(13.5))
# Nerve supply box
bullet_list(slide, Inches(9.0), Inches(1.05), Inches(4.1), Inches(5.7),
title="Nerve Supply",
items=[
("Via splenic plexus (autonomic)", True, STEEL_BLUE),
("SYMPATHETIC (vasomotor):", True, ACCENT),
("From celiac plexus → splenic plexus → along splenic artery", False, BLACK),
("Pre-ganglionic: T6–T10 via greater splanchnic nerve", False, BLACK),
("Post-ganglionic: from celiac ganglion", False, BLACK),
("Function: vasoconstriction (reduces blood pooling)", False, BLACK),
("PARASYMPATHETIC:", True, STEEL_BLUE),
("Minor role; from vagal fibers via celiac plexus", False, BLACK),
("Pain from spleen → referred to left shoulder (phrenic nerve C3,4,5)", False, BLACK),
], font_size=Pt(13.5))
# Dividers
add_rect(slide, Inches(4.4), Inches(1.05), Inches(0.04), Inches(5.6), fill_color=LIGHT_GRAY)
add_rect(slide, Inches(8.85), Inches(1.05), Inches(0.04), Inches(5.6), fill_color=LIGHT_GRAY)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 7 – Internal Structure / Histology
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Internal Structure & Histology of the Spleen")
left_accent_bar(slide)
footer(slide)
add_textbox(slide, Inches(0.3), Inches(0.9), Inches(12.5), Inches(0.3),
"The spleen is covered by a fibrous capsule, from which trabeculae extend inward dividing the parenchyma (splenic pulp) into compartments.",
font_size=Pt(13.5), color=BLACK, italic=True)
hist_data = [
("CAPSULE &\nTRABECULAE",
["Dense connective tissue capsule", "Trabeculae project inward from capsule and hilum",
"Carry splenic artery, vein, lymphatics & nerves into pulp",
"Smooth muscle in capsule → contracts and expels blood (especially in animals)"],
ACCENT),
("WHITE PULP\n(~20%)",
["Lymphoid tissue around central arterioles", "PALS: Periarteriolar Lymphoid Sheaths (mainly T cells)",
"Lymphoid nodules (B cells) → form germinal centers when activated",
"Marginal zone: surrounds each nodule; developing B cells + APCs",
"Central arteriole is displaced eccentrically in active nodule"],
STEEL_BLUE),
("RED PULP\n(~80%)",
["Fills most of spleen parenchyma", "Two components:",
"• Splenic sinusoids: large irregular blood channels lined by elongated endothelial cells",
"• Splenic cords (of Billroth): reticular meshwork between sinusoids",
"• Cords contain: macrophages, reticular cells, RBCs, WBCs, platelets",
"Site of old/damaged RBC destruction by macrophages"],
ACCENT2),
("MARGINAL\nZONE",
["Between white & red pulp", "Rich in B cells, macrophages, DCs",
"First site of contact between blood-borne antigens and immune cells",
"Important for T-independent antibody responses",
"Unique macrophages: marginal zone macrophages (filter particulates)"],
RGBColor(0x27, 0x6E, 0x45)),
]
col_w = Inches(2.95)
for i, (title, items, col) in enumerate(hist_data):
cx = Inches(0.25) + i * (col_w + Inches(0.18))
add_rect(slide, cx, Inches(1.28), col_w, Inches(0.9), fill_color=col)
add_textbox(slide, cx + Inches(0.06), Inches(1.32), col_w - Inches(0.1), Inches(0.85),
title, font_size=Pt(15), bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, cx, Inches(2.18), col_w, Inches(4.9),
fill_color=LIGHT_GRAY, line_color=MID_GRAY, line_width=Pt(0.5))
tb = slide.shapes.add_textbox(cx + Inches(0.1), Inches(2.3),
col_w - Inches(0.2), Inches(4.7))
tf = tb.text_frame; tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
for j, txt in enumerate(items):
p = tf.paragraphs[0] if j == 0 else tf.add_paragraph()
p.alignment = PP_ALIGN.LEFT
run = p.add_run()
run.text = "• " + txt
run.font.name = "Calibri"
run.font.size = Pt(13)
run.font.color.rgb = BLACK
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 8 – Functions of the Spleen
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Functions of the Spleen")
left_accent_bar(slide)
footer(slide)
func_data = [
("FILTRATION", ACCENT,
["Filters blood (only lymphoid organ to do so)",
"Removes aged, damaged or abnormal RBCs",
"Destroys old erythrocytes via splenic cord macrophages",
"Removes blood-borne pathogens, cellular debris",
"Culling: removal of whole defective cells",
"Pitting: removal of inclusions from RBCs (e.g., Howell-Jolly bodies, Heinz bodies)",
"Sequesters platelets: stores ~30% of total platelets"]),
("IMMUNITY", STEEL_BLUE,
["Largest secondary lymphoid organ",
"Production of antibodies (IgM especially in early response)",
"Activated lymphocytes delivered directly into blood",
"Site for B and T cell activation against blood-borne antigens",
"Produces opsonins: tuftsin and properdin",
"Critical defense against encapsulated bacteria (S. pneumoniae, H. influenzae, N. meningitidis)"]),
("HAEMATOPOIESIS\n& RESERVOIR", ACCENT2,
["Extramedullary haematopoiesis (fetal life; reactivated in diseases like myelofibrosis)",
"Acts as blood reservoir: holds ~200–500 mL blood",
"Contracts to release blood during exercise/stress (in animals > humans)",
"Contains large pool of monocytes (~50% of total)",
"Reservoir of platelets (~30% of total platelet mass)"]),
]
col_w = Inches(3.9)
for i, (title, col, items) in enumerate(func_data):
cx = Inches(0.3) + i * (col_w + Inches(0.2))
# Header
add_rect(slide, cx, Inches(1.05), col_w, Inches(0.7), fill_color=col)
add_textbox(slide, cx + Inches(0.05), Inches(1.08), col_w - Inches(0.1), Inches(0.65),
title, font_size=Pt(18), bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# Content
add_rect(slide, cx, Inches(1.75), col_w, Inches(5.4),
fill_color=LIGHT_GRAY, line_color=MID_GRAY, line_width=Pt(0.5))
tb = slide.shapes.add_textbox(cx + Inches(0.1), Inches(1.9),
col_w - Inches(0.2), Inches(5.2))
tf = tb.text_frame; tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
for j, txt in enumerate(items):
p = tf.paragraphs[0] if j == 0 else tf.add_paragraph()
run = p.add_run()
run.text = "• " + txt
run.font.name = "Calibri"
run.font.size = Pt(14)
run.font.color.rgb = BLACK
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 9 – Applied Anatomy / Clinical Correlations
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Applied Anatomy of the Spleen")
left_accent_bar(slide)
footer(slide)
applied_data = [
("Splenic Rupture", ACCENT,
["Most common abdominal organ to rupture in blunt trauma",
"Left lower chest/flank trauma → most common cause",
"Soft, fragile capsule → easily ruptures",
"Presents: left upper quadrant pain, hypovolaemic shock",
"Kehr's sign: referred pain to left shoulder (diaphragm irritation, C3-5)",
"Two-stage rupture: initial subcapsular hematoma → delayed rupture",
"Management: splenorrhaphy (repair) or splenectomy"]),
("Splenomegaly", STEEL_BLUE,
["Clinically detectable when spleen is 2-3× normal size",
"Enlarges toward right iliac fossa (along long axis = left costal margin)",
"Causes: malaria, portal hypertension, lymphoma, kala-azar, storage diseases",
"Cannot get above the swelling (vs. renal swelling)",
"Moves with respiration",
"Notch palpable on superior border",
"Dull on percussion (vs. colon = resonant)"]),
("Post-Splenectomy", ACCENT2,
["OPSI: Overwhelming Post-Splenectomy Infection",
"Most feared complication",
"Causative organisms: S. pneumoniae (>50%), H. influenzae b, N. meningitidis",
"Risk highest in first 2 years; lifelong risk persists",
"Prevention: vaccinate 2 weeks before elective surgery",
"Prophylactic penicillin (especially in children)",
"Annual influenza vaccination",
"Blood film shows Howell-Jolly bodies after splenectomy"]),
]
col_w = Inches(3.9)
for i, (title, col, items) in enumerate(applied_data):
cx = Inches(0.3) + i * (col_w + Inches(0.2))
add_rect(slide, cx, Inches(1.05), col_w, Inches(0.65), fill_color=col)
add_textbox(slide, cx + Inches(0.05), Inches(1.08), col_w - Inches(0.1), Inches(0.6),
title, font_size=Pt(17), bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, cx, Inches(1.7), col_w, Inches(5.45),
fill_color=LIGHT_GRAY, line_color=MID_GRAY, line_width=Pt(0.5))
tb = slide.shapes.add_textbox(cx + Inches(0.1), Inches(1.82),
col_w - Inches(0.2), Inches(5.25))
tf = tb.text_frame; tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
for j, txt in enumerate(items):
p = tf.paragraphs[0] if j == 0 else tf.add_paragraph()
run = p.add_run()
run.text = "• " + txt
run.font.name = "Calibri"
run.font.size = Pt(13.5)
run.font.color.rgb = BLACK
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 10 – Summary / Mnemonics
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, W, H, fill_color=WHITE)
heading_bar(slide, "Summary & Mnemonics")
left_accent_bar(slide)
footer(slide)
# Left summary table
add_textbox(slide, Inches(0.3), Inches(0.97), Inches(6.5), Inches(0.35),
"Quick Summary", font_size=Pt(17), bold=True, color=ACCENT)
rows = [
("Feature", "Detail"),
("Location", "Left hypochondrium, Ribs 9–11"),
("Weight", "100–250 g"),
("Dimensions", "12 × 7 × 3 cm"),
("Surfaces", "Diaphragmatic (convex) + Visceral (concave)"),
("Long axis", "Along 10th rib"),
("Arterial supply", "Splenic artery (celiac trunk branch)"),
("Venous drainage", "Splenic vein → Portal vein"),
("Lymphatics", "→ Pancreaticosplenic nodes → Celiac nodes"),
("Nerve supply", "Splenic plexus (celiac plexus)"),
("Peritoneum", "Intraperitoneal (visceral peritoneum)"),
]
row_h = Inches(0.38)
for r, (feat, det) in enumerate(rows):
ry = Inches(1.35) + r * row_h
bg = ACCENT if r == 0 else (LIGHT_GRAY if r % 2 == 0 else WHITE)
fg = WHITE if r == 0 else BLACK
add_rect(slide, Inches(0.3), ry, Inches(2.2), row_h, fill_color=bg,
line_color=MID_GRAY, line_width=Pt(0.5))
add_rect(slide, Inches(2.5), ry, Inches(4.1), row_h, fill_color=bg,
line_color=MID_GRAY, line_width=Pt(0.5))
add_textbox(slide, Inches(0.35), ry + Inches(0.04), Inches(2.1), row_h - Inches(0.04),
feat, font_size=Pt(12.5), bold=(r==0), color=fg)
add_textbox(slide, Inches(2.55), ry + Inches(0.04), Inches(4.0), row_h - Inches(0.04),
det, font_size=Pt(12.5), bold=(r==0), color=fg)
# Right - Mnemonics
add_textbox(slide, Inches(6.9), Inches(0.97), Inches(6.0), Inches(0.35),
"Mnemonics & Key Points", font_size=Pt(17), bold=True, color=STEEL_BLUE)
mnemonic_blocks = [
("1×3×5×7×9×11 Rule (BD Chaurasia Classic):",
["Weight = 1 × 3 × 5 = 150 g (approx)",
"Dimensions = 1 × 3 × 5 inches (~2.5 × 7.5 × 12.5 cm)",
"Lies along 9, 10, 11th ribs",
"Long axis along 10th rib"],
ACCENT),
("Ligaments Mnemonic – G S P S C:",
["Gastrosplenic → short gastric + gastroepiploic vessels",
"Splenorenal → splenic vessels + tail of pancreas",
"Phrenicosplenic → connects to diaphragm (avascular)",
"Splenocolic → connects to colon (avascular)"],
STEEL_BLUE),
("Post-Splenectomy Blood Film Changes:",
["Howell-Jolly bodies (nuclear remnants)",
"Pappenheimer bodies (iron granules)",
"Heinz bodies (denatured Hb)",
"Target cells, acanthocytes, thrombocytosis"],
ACCENT2),
]
my = Inches(1.35)
for title, items, col in mnemonic_blocks:
add_rect(slide, Inches(6.9), my, Inches(6.1), Inches(0.4), fill_color=col)
add_textbox(slide, Inches(7.0), my + Inches(0.03), Inches(5.9), Inches(0.37),
title, font_size=Pt(13), bold=True, color=WHITE)
my += Inches(0.4)
for item in items:
add_rect(slide, Inches(6.9), my, Inches(6.1), Inches(0.36),
fill_color=LIGHT_GRAY, line_color=MID_GRAY, line_width=Pt(0.3))
add_textbox(slide, Inches(7.0), my + Inches(0.02), Inches(5.9), Inches(0.33),
"• " + item, font_size=Pt(12.5), color=BLACK)
my += Inches(0.36)
my += Inches(0.12)
# ─────────────────────────────────────────────────────────────────────────────
# SAVE
# ─────────────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/splenic-anatomy-ppt/Splenic_Anatomy_BD_Chaurasia.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out_path}")
cd /tmp/workspace/splenic-anatomy-ppt && python build_ppt.py 2>&1
python3 -c " from pptx import Presentation prs = Presentation('/tmp/workspace/splenic-anatomy-ppt/Splenic_Anatomy_BD_Chaurasia.pptx') print(f'Slides: {len(prs.slides)}') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text[:60] for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f'Slide {i}: {texts[0] if texts else \"(empty)\"}') "
Splenic Anatomy BD Chaurasia
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide |
| 2 | Introduction & General Features (size, weight, embryology) |
| 3 | Position, Relations & Surfaces (diaphragmatic vs. visceral, poles, borders, surface projections) |
| 4 | Peritoneal Ligaments (Gastrosplenic, Splenorenal, Phrenicosplenic, Splenocolic) |
| 5 | Arterial Supply (splenic artery, magistral vs. distributed type, accessory spleen) |
| 6 | Venous Drainage, Lymphatics & Nerve Supply (portal vein formation, splenic plexus) |
| 7 | Internal Structure & Histology (capsule, white pulp/PALS, red pulp, marginal zone) |
| 8 | Functions (filtration, immunity, haematopoiesis, reservoir) |
| 9 | Applied Anatomy (splenic rupture, splenomegaly, post-splenectomy OPSI) |
| 10 | Summary table + BD Chaurasia mnemonics (1×3×5×7×9×11 rule, ligaments, blood film changes) |
Along with diagrams easily
cd /tmp/workspace/splenic-anatomy-ppt && python /tmp/skills/shared/scripts/fetch_images.py \ "https://cdn.orris.care/cdss_images/8758db0ed2f5e43d7da13347afb33a48260837562052e809d4e0877030d8f874.png" \ "https://cdn.orris.care/cdss_images/34b1ae30d13d211eb8ac76f3ec3960446d2b0cd0ebb539818a682f7d50495fb5.png" \ "https://cdn.orris.care/cdss_images/fd5d239124c63084cac1f11075a77f095f012327a8002e83093c0333dc20cd77.png" \ "https://cdn.orris.care/cdss_images/532563ca75cf4bdc94b4827d35052d5f26f64ba1616a05a7c5f1eb4c9b6b8912.png" \ "https://cdn.orris.care/cdss_images/5e5184de1de901cb91fcfb22523b0ce3116f21767b67bae0bd163bc88f7a9fb2.png" \ "https://cdn.orris.care/cdss_images/0884e5396beb4083b384a8ca792d49d8249ac569e9675c37eac116b51af5f40c.png" \ "https://cdn.orris.care/cdss_images/da3f3fe016841b7f38847a5f63803cc96e1dda44b688041d5f0b9a5937299f6d.png" \ "https://cdn.orris.care/cdss_images/fe935a6ec69041430eea77fb148716d05c2369155a344b85b2ea534925c28194.png" \ "https://cdn.orris.care/cdss_images/2b306cf73eada4e3c27b1d7f792a88a9025860469c4d7f8236495eb2a1f12598.png" \ "https://cdn.orris.care/cdss_images/6c610f1faca1fa86b9447b4885b003566f6f87a8ec43ac2f5231242bf12ffd6d.png" \ 2>&1 | head -5
An error occurred (ValidationException) when calling the ConverseStream operation: The model returned the following errors: prompt is too long: 213683 tokens > 200000 maximum
We encountered an error while processing your request. Please try again or reach out to us for help.