I am giving you subtitles related to my ppt presentation for pathology topic : Inflammatory bowel disease Subtopics : 1 - Introduction, classification Definition 2- Pathogenesis 3- Ulcerative collitis Which includes Clinical features and morphology 5- crohns disease which includes clinical feature and Morphology 6- comparison table
mkdir -p /tmp/workspace/IBD-ppt && ls /tmp/workspace/IBD-ppt/
~/IBD-ppt/build_ibd.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
from io import BytesIO
# ── Colour palette ──────────────────────────────────────────────────────────
BG_DARK = RGBColor(0x0D, 0x1B, 0x2A) # deep navy
ACCENT = RGBColor(0xE8, 0x4C, 0x60) # vibrant red
ACCENT2 = RGBColor(0x1A, 0x73, 0xE8) # blue
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_TXT = RGBColor(0xCF, 0xD8, 0xDC)
GOLD = RGBColor(0xFF, 0xCA, 0x28)
DARK_CARD = RGBColor(0x18, 0x2B, 0x3E)
UC_COLOR = RGBColor(0xE8, 0x4C, 0x60)
CD_COLOR = RGBColor(0x1A, 0x73, 0xE8)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ── Helper: fill slide background ───────────────────────────────────────────
def fill_bg(slide, color=BG_DARK):
from pptx.oxml.ns import qn
from lxml import etree
bg = slide.background
fill = bg.fill
fill.solid()
fill.fore_color.rgb = color
def add_box(slide, text, x, y, w, h,
font_size=18, bold=False, color=WHITE,
align=PP_ALIGN.LEFT, italic=False,
anchor=MSO_ANCHOR.TOP, word_wrap=True):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = word_wrap
tf.vertical_anchor = anchor
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom= Pt(2)
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(font_size)
run.font.bold = bold
run.font.color.rgb = color
run.font.italic = italic
return tf
def add_rect(slide, x, y, w, h, fill_color, line_color=None):
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
Inches(x), Inches(y), Inches(w), Inches(h)
)
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
if line_color:
shape.line.color.rgb = line_color
else:
shape.line.fill.background()
return shape
def add_bullet_tf(slide, items, x, y, w, h,
font_size=16, color=LIGHT_TXT, bold_first=False):
"""Add a textbox with bullet items (list of strings)."""
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = True
tf.vertical_anchor = MSO_ANCHOR.TOP
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
for i, item in enumerate(items):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.space_before = Pt(3)
run = p.add_run()
run.text = item
run.font.size = Pt(font_size)
run.font.color.rgb = color
if bold_first and i == 0:
run.font.bold = True
return tf
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 1 — TITLE
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
# Top accent bar
add_rect(slide, 0, 0, 13.333, 0.12, ACCENT)
# Red vertical accent line
add_rect(slide, 0.55, 1.8, 0.1, 2.5, ACCENT)
# Main title
add_box(slide, "Inflammatory Bowel Disease",
0.8, 1.7, 12, 1.3, font_size=52, bold=True, color=WHITE,
align=PP_ALIGN.LEFT)
# Subtitle line
add_box(slide, "Pathology | Classification | Pathogenesis | Morphology",
0.8, 3.15, 12, 0.6, font_size=20, color=LIGHT_TXT, italic=True)
# Horizontal rule
add_rect(slide, 0.8, 3.85, 7, 0.04, ACCENT)
# IBD label
add_box(slide, "IBD",
0.8, 4.05, 2, 0.55, font_size=28, bold=True, color=ACCENT)
add_box(slide, "Crohn Disease • Ulcerative Colitis",
2.5, 4.1, 8, 0.55, font_size=20, color=GOLD)
# Bottom accent bar
add_rect(slide, 0, 7.38, 13.333, 0.12, ACCENT2)
add_box(slide, "Source: Robbins & Kumar Basic Pathology",
0.5, 7.1, 12, 0.3, font_size=10, color=LIGHT_TXT,
align=PP_ALIGN.RIGHT, italic=True)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 2 — Introduction & Classification
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, ACCENT)
add_rect(slide, 0, 0.12, 13.333, 0.9, DARK_CARD)
add_box(slide, "1. Introduction & Classification",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Definition box
add_rect(slide, 0.3, 1.2, 12.7, 1.3, RGBColor(0x14, 0x2A, 0x3E))
add_box(slide, "Definition",
0.55, 1.25, 5, 0.4, font_size=16, bold=True, color=ACCENT)
add_box(slide,
"IBD is a chronic inflammatory condition triggered by the host immune response "
"to intestinal microbes in genetically predisposed individuals.",
0.55, 1.6, 12.3, 0.8, font_size=16, color=LIGHT_TXT)
# Two classification cards
# Ulcerative Colitis card
add_rect(slide, 0.3, 2.7, 5.9, 4.35, RGBColor(0x1C, 0x10, 0x1A))
add_rect(slide, 0.3, 2.7, 5.9, 0.45, UC_COLOR)
add_box(slide, "Ulcerative Colitis (UC)",
0.45, 2.72, 5.7, 0.42, font_size=18, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
uc_points = [
"• Limited to colon and rectum",
"• Involves only mucosa & submucosa",
"• Diffuse, continuous involvement",
"• Always involves rectum",
"• Superficial, broad-based ulcers",
"• No granulomas",
"• No fistulas/sinuses",
"• No skip lesions",
"• Thin bowel wall",
"• Mild to no fibrosis",
]
add_bullet_tf(slide, uc_points, 0.45, 3.25, 5.6, 3.7, font_size=15, color=LIGHT_TXT)
# Crohn Disease card
add_rect(slide, 6.5, 2.7, 6.55, 4.35, RGBColor(0x10, 0x18, 0x2A))
add_rect(slide, 6.5, 2.7, 6.55, 0.45, CD_COLOR)
add_box(slide, "Crohn Disease (CD)",
6.65, 2.72, 6.3, 0.42, font_size=18, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
cd_points = [
"• May involve any GI tract segment",
"• Also called Regional Enteritis",
"• Transmural inflammation",
"• Skip lesions (segmental)",
"• Deep, knife-like ulcers",
"• Granulomas (~35%)",
"• Fistulas & sinuses common",
"• Thick bowel wall",
"• Marked fibrosis & strictures",
"• Most common: terminal ileum",
]
add_bullet_tf(slide, cd_points, 6.65, 3.25, 6.3, 3.7, font_size=15, color=LIGHT_TXT)
add_rect(slide, 0, 7.38, 13.333, 0.12, ACCENT2)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 3 — Pathogenesis
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, ACCENT)
add_rect(slide, 0, 0.12, 13.333, 0.9, DARK_CARD)
add_box(slide, "2. Pathogenesis of IBD",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Three pillar boxes
pillars = [
("Genetic Susceptibility", ACCENT,
[
"• HLA associations (especially HLA-DR2 in UC)",
"• NOD2 gene mutations (CD): impaired bacterial recognition",
"• Barrier dysfunction cosegregates with NOD2 polymorphisms",
"• Genetic variants affecting innate and adaptive immunity",
"• Family history is a major risk factor",
]),
("Epithelial Defects", GOLD,
[
"• Defective intestinal tight junction barrier function",
"• Abnormal Paneth cell granules (antimicrobial peptides)",
"• Defective 'crosstalk' between epithelium & microbiota",
"• Defective mucosal barrier activates immune responses",
"• Paneth cell metaplasia occurs in Crohn disease",
]),
("Aberrant Immune Response", CD_COLOR,
[
"• Dysregulation of mucosal T-helper cells (Th1, Th17)",
"• UC: Th2-mediated → IL-4, IL-5, IL-13 excess",
"• CD: Th1-mediated → IFN-γ, TNF excess",
"• Loss of regulatory T-cell (Treg) tolerance",
"• Defective bacterial clearance → sustained inflammation",
]),
]
for i, (title, color, bullets) in enumerate(pillars):
x = 0.3 + i * 4.35
add_rect(slide, x, 1.2, 4.05, 5.9, RGBColor(0x14, 0x22, 0x35))
add_rect(slide, x, 1.2, 4.05, 0.5, color)
add_box(slide, title, x + 0.1, 1.22, 3.85, 0.47,
font_size=16, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_bullet_tf(slide, bullets, x + 0.12, 1.8, 3.82, 5.0,
font_size=14, color=LIGHT_TXT)
# Microbiota note
add_rect(slide, 0.3, 7.05, 12.7, 0.28, RGBColor(0x0A, 0x22, 0x38))
add_box(slide, "Microbiome: Up to 10¹² organisms/mL in fecal material. "
"Changes in microbiota composition play a key role — fecal transplants & probiotics show clinical benefit.",
0.45, 7.05, 12.5, 0.28, font_size=11, color=GOLD, italic=True)
add_rect(slide, 0, 7.38, 13.333, 0.12, ACCENT2)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 4 — Ulcerative Colitis: Clinical Features
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, UC_COLOR)
add_rect(slide, 0, 0.12, 13.333, 0.9, RGBColor(0x2A, 0x10, 0x15))
add_box(slide, "3. Ulcerative Colitis — Clinical Features",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Left column
add_rect(slide, 0.3, 1.2, 5.9, 5.9, RGBColor(0x1C, 0x0F, 0x15))
add_rect(slide, 0.3, 1.2, 5.9, 0.45, UC_COLOR)
add_box(slide, "Signs & Symptoms",
0.45, 1.22, 5.7, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
uc_sx = [
"• Onset: adolescents / young adults (can be any age)",
"• Relapsing episodes of bloody diarrhea",
"• Passage of mucus and pus in stools",
"• Lower abdominal cramping",
"• Urgency / tenesmus",
"• Fever, malaise, weight loss in severe disease",
"• Toxic megacolon (life-threatening complication)",
"• Profuse watery diarrhea (fulminant colitis)",
"• Onset may follow cessation of smoking",
]
add_bullet_tf(slide, uc_sx, 0.45, 1.75, 5.7, 5.0, font_size=14.5, color=LIGHT_TXT)
# Right column - extraintestinal + complications
add_rect(slide, 6.5, 1.2, 6.55, 2.8, RGBColor(0x1C, 0x0F, 0x15))
add_rect(slide, 6.5, 1.2, 6.55, 0.45, UC_COLOR)
add_box(slide, "Extraintestinal Manifestations",
6.65, 1.22, 6.3, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
uc_extra = [
"• Uveitis / episcleritis",
"• Migratory polyarthritis",
"• Sacroiliitis",
"• Ankylosing spondylitis",
"• Erythema nodosum / pyoderma gangrenosum",
"• Primary sclerosing cholangitis (PSC)",
"• Autoimmune hemolytic anemia",
]
add_bullet_tf(slide, uc_extra, 6.65, 1.75, 6.3, 2.0, font_size=14, color=LIGHT_TXT)
add_rect(slide, 6.5, 4.15, 6.55, 2.95, RGBColor(0x1C, 0x0F, 0x15))
add_rect(slide, 6.5, 4.15, 6.55, 0.45, RGBColor(0xC0, 0x39, 0x50))
add_box(slide, "Complications & Risk",
6.65, 4.17, 6.3, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
uc_comp = [
"• Colorectal cancer: risk rises after 8-10 yrs",
"• Risk: 34% at 30 years in extensive colitis",
"• Hemorrhage, perforation",
"• Toxic megacolon (severe complication)",
"• Dysplasia → carcinoma sequence",
"• p-ANCA positive (~70%)",
]
add_bullet_tf(slide, uc_comp, 6.65, 4.7, 6.3, 2.35, font_size=14, color=LIGHT_TXT)
add_rect(slide, 0, 7.38, 13.333, 0.12, ACCENT2)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 5 — Ulcerative Colitis: Morphology
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, UC_COLOR)
add_rect(slide, 0, 0.12, 13.333, 0.9, RGBColor(0x2A, 0x10, 0x15))
add_box(slide, "3. Ulcerative Colitis — Morphology",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Gross morphology
add_rect(slide, 0.3, 1.2, 6.05, 5.9, RGBColor(0x18, 0x0C, 0x14))
add_rect(slide, 0.3, 1.2, 6.05, 0.45, UC_COLOR)
add_box(slide, "Gross / Macroscopic",
0.45, 1.22, 5.85, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
gross_uc = [
"• Disease always begins in rectum",
"• Extends proximally in a continuous, diffuse pattern",
"• Pancolitis (universal colitis): entire colon involved",
"• Mucosal hyperemia, edema, granularity",
"• Superficial, broad-based ulcers (mucosal only)",
"• Ulcers may undermine adjacent mucosa",
"• Pseudopolyps: islands of regenerating mucosa",
"• Bowel wall thin (no transmural involvement)",
"• No skip lesions",
"• In chronic disease: shortened, pipe-stem colon",
"• Sharp demarcation between involved & normal mucosa",
]
add_bullet_tf(slide, gross_uc, 0.45, 1.75, 5.85, 5.0, font_size=13.5, color=LIGHT_TXT)
# Microscopic morphology
add_rect(slide, 6.6, 1.2, 6.4, 5.9, RGBColor(0x18, 0x0C, 0x14))
add_rect(slide, 6.6, 1.2, 6.4, 0.45, RGBColor(0xB0, 0x30, 0x45))
add_box(slide, "Histology / Microscopic",
6.75, 1.22, 6.1, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
micro_uc = [
"• Inflammatory infiltrate limited to mucosa & submucosa",
"• Neutrophilic infiltration of crypt epithelium",
"• Crypt abscesses: neutrophil clusters within crypts",
"• Crypt destruction → irregular, distorted crypts",
"• Branching, shortened crypts (architectural distortion)",
"• Reduced mucin (goblet cell depletion)",
"• Paneth cell metaplasia (distal colon)",
"• Lamina propria: plasma cells, eosinophils, mast cells",
"• Dysplasia in long-standing disease",
"• NO granulomas",
"• NO transmural inflammation",
"• NO fissure ulcers",
]
add_bullet_tf(slide, micro_uc, 6.75, 1.75, 6.15, 5.0, font_size=13.5, color=LIGHT_TXT)
add_rect(slide, 0, 7.38, 13.333, 0.12, ACCENT2)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 6 — Crohn Disease: Clinical Features
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, CD_COLOR)
add_rect(slide, 0, 0.12, 13.333, 0.9, RGBColor(0x10, 0x18, 0x2A))
add_box(slide, "4. Crohn Disease — Clinical Features",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Left
add_rect(slide, 0.3, 1.2, 5.9, 5.9, RGBColor(0x0F, 0x17, 0x28))
add_rect(slide, 0.3, 1.2, 5.9, 0.45, CD_COLOR)
add_box(slide, "Signs & Symptoms",
0.45, 1.22, 5.7, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
cd_sx = [
"• Onset: usually young adults (bimodal: 20s & 60s)",
"• Abdominal pain (especially RLQ — mimics appendicitis)",
"• Non-bloody diarrhea (usually)",
"• Fever, malaise, weight loss",
"• Palpable RLQ mass (inflamed ileum/mesentery)",
"• Obstructive symptoms (strictures)",
"• Perianal disease: fistulas, fissures, abscesses",
"• Malabsorption: B12, fat-soluble vitamins",
"• Growth retardation in children",
"• CDAI (Crohn Disease Activity Index) used for scoring",
"• Remission: CDAI < 150",
]
add_bullet_tf(slide, cd_sx, 0.45, 1.75, 5.7, 5.0, font_size=14, color=LIGHT_TXT)
# Right top & bottom
add_rect(slide, 6.5, 1.2, 6.55, 2.8, RGBColor(0x0F, 0x17, 0x28))
add_rect(slide, 6.5, 1.2, 6.55, 0.45, CD_COLOR)
add_box(slide, "Extraintestinal Manifestations",
6.65, 1.22, 6.3, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
cd_extra = [
"• Uveitis / episcleritis",
"• Migratory polyarthritis",
"• Sacroiliitis / ankylosing spondylitis",
"• Erythema nodosum / pyoderma gangrenosum",
"• Primary sclerosing cholangitis",
"• Gallstones (ileal disease → bile salt malabsorption)",
"• Oxalate kidney stones",
]
add_bullet_tf(slide, cd_extra, 6.65, 1.75, 6.3, 2.0, font_size=14, color=LIGHT_TXT)
add_rect(slide, 6.5, 4.15, 6.55, 2.95, RGBColor(0x0F, 0x17, 0x28))
add_rect(slide, 6.5, 4.15, 6.55, 0.45, RGBColor(0x0E, 0x55, 0xC0))
add_box(slide, "Complications & Investigations",
6.65, 4.17, 6.3, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
cd_comp = [
"• Intestinal obstruction (fibrotic strictures)",
"• Fistulas: entero-enteric, enterovesical, entero-cutaneous",
"• Abscess formation",
"• Colorectal + small bowel adenocarcinoma risk",
"• ASCA positive (~60%)",
"• CRP, ESR elevated in active disease",
"• Fecal calprotectin: marker of intestinal inflammation",
]
add_bullet_tf(slide, cd_comp, 6.65, 4.7, 6.3, 2.35, font_size=14, color=LIGHT_TXT)
add_rect(slide, 0, 7.38, 13.333, 0.12, UC_COLOR)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 7 — Crohn Disease: Morphology
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, CD_COLOR)
add_rect(slide, 0, 0.12, 13.333, 0.9, RGBColor(0x10, 0x18, 0x2A))
add_box(slide, "4. Crohn Disease — Morphology",
0.35, 0.18, 12, 0.7, font_size=28, bold=True, color=WHITE)
# Gross
add_rect(slide, 0.3, 1.2, 6.05, 5.9, RGBColor(0x0C, 0x16, 0x26))
add_rect(slide, 0.3, 1.2, 6.05, 0.45, CD_COLOR)
add_box(slide, "Gross / Macroscopic",
0.45, 1.22, 5.85, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
gross_cd = [
"• Most common: terminal ileum + ileocecal valve + cecum",
"• Small intestine only: ~40% of cases",
"• Small intestine + colon: ~30% of cases",
"• SKIP LESIONS: segmental, sharply demarcated areas",
"• Earliest lesion: aphthous ulcer",
"• Ulcers progress → elongated serpentine/linear ulcers",
"• Cobblestone mucosa: edema + sparing between ulcers",
"• Bowel wall thickened (transmural edema + fibrosis)",
"• Strictures & obstruction common",
"• Creeping fat: mesenteric fat adheres to serosa",
"• Fistulas, sinuses, perianal abscesses",
"• Fissures → perforation tracts",
]
add_bullet_tf(slide, gross_cd, 0.45, 1.75, 5.85, 5.0, font_size=13, color=LIGHT_TXT)
# Micro
add_rect(slide, 6.6, 1.2, 6.4, 5.9, RGBColor(0x0C, 0x16, 0x26))
add_rect(slide, 6.6, 1.2, 6.4, 0.45, RGBColor(0x0E, 0x55, 0xC0))
add_box(slide, "Histology / Microscopic",
6.75, 1.22, 6.1, 0.42, font_size=17, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
micro_cd = [
"• TRANSMURAL inflammation (all layers)",
"• Neutrophilic infiltration → crypt abscesses",
"• Crypt distortion & architectural irregularity",
"• Epithelial metaplasia: pyloric (pseudopyloric) type",
"• Paneth cell metaplasia in left colon",
"• NON-CASEATING GRANULOMAS (~35%) — hallmark",
"• Granulomas: compact histiocytes, ± giant cells",
"• Submucosal fibrosis → stricture formation",
"• Lymphoid aggregates in all layers",
"• Marked lymphoid reaction in submucosa & serosa",
"• Hypertrophy of muscularis propria",
"• Deep fissure ulcers extending to muscularis/serosa",
]
add_bullet_tf(slide, micro_cd, 6.75, 1.75, 6.15, 5.0, font_size=13, color=LIGHT_TXT)
add_rect(slide, 0, 7.38, 13.333, 0.12, UC_COLOR)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 8 — Comparison Table
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
fill_bg(slide)
add_rect(slide, 0, 0, 13.333, 0.12, GOLD)
add_rect(slide, 0, 0.12, 13.333, 0.9, RGBColor(0x18, 0x18, 0x14))
add_box(slide, "5. Crohn Disease vs. Ulcerative Colitis — Comparison",
0.35, 0.18, 12.7, 0.7, font_size=26, bold=True, color=WHITE)
from pptx.util import Inches, Pt
from pptx.oxml.ns import qn
from lxml import etree
# Build table manually using add_table
ROWS = [
("Feature", "Crohn Disease", "Ulcerative Colitis"),
("GI location", "Any (mouth to anus)", "Colon & rectum only"),
("Rectum involvement", "Sometimes", "Always"),
("Distribution", "Skip lesions", "Continuous / diffuse"),
("Depth of inflammation", "Transmural", "Mucosa & submucosa only"),
("Bowel wall", "Thick (fibrosis)", "Thin"),
("Ulcers", "Deep, knife-like", "Superficial, broad-based"),
("Cobblestone mucosa", "Yes", "No"),
("Strictures", "Common", "Rare"),
("Fistulas/sinuses", "Common", "Absent"),
("Granulomas", "Yes (~35%)", "No"),
("Pseudopolyps", "Moderate", "Marked"),
("Serositis", "Yes", "No"),
("Fibrosis", "Marked", "Mild to none"),
("Cancer risk", "Small intestine + colon","Colon only"),
("Serology", "ASCA positive", "p-ANCA positive"),
("Smoking", "Worsened by cessation", "Symptom relief with smoking"),
]
n_rows = len(ROWS)
n_cols = 3
tbl_x, tbl_y = Inches(0.3), Inches(1.2)
tbl_w, tbl_h = Inches(12.73), Inches(6.1)
tbl = slide.shapes.add_table(n_rows, n_cols, tbl_x, tbl_y, tbl_w, tbl_h).table
# Column widths
tbl.columns[0].width = Inches(3.5)
tbl.columns[1].width = Inches(4.6)
tbl.columns[2].width = Inches(4.6)
col_colors = [RGBColor(0x22, 0x22, 0x30), RGBColor(0x12, 0x1C, 0x30), RGBColor(0x28, 0x10, 0x18)]
hdr_colors = [RGBColor(0x44, 0x44, 0x55), CD_COLOR, UC_COLOR]
for r_idx, row_data in enumerate(ROWS):
for c_idx, cell_text in enumerate(row_data):
cell = tbl.cell(r_idx, c_idx)
# Background
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
solidFill = etree.SubElement(tcPr, qn('a:solidFill'))
srgbClr = etree.SubElement(solidFill, qn('a:srgbClr'))
if r_idx == 0:
srgbClr.set('val', '%06X' % int(hdr_colors[c_idx].rgb))
else:
base = col_colors[c_idx]
# alternate row shade
if r_idx % 2 == 0:
shade_r = min(base.red + 10, 255)
shade_g = min(base.green + 10, 255)
shade_b = min(base.blue + 10, 255)
srgbClr.set('val', '%02X%02X%02X' % (shade_r, shade_g, shade_b))
else:
srgbClr.set('val', '%06X' % int(base.rgb))
tf = cell.text_frame
tf.word_wrap = True
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER if c_idx == 0 and r_idx == 0 else PP_ALIGN.LEFT
run = p.add_run()
run.text = cell_text
run.font.size = Pt(13) if r_idx > 0 else Pt(14)
run.font.bold = (r_idx == 0)
run.font.color.rgb = WHITE if r_idx == 0 else LIGHT_TXT
if c_idx == 0 and r_idx > 0:
run.font.bold = True
run.font.color.rgb = GOLD
add_rect(slide, 0, 7.38, 13.333, 0.12, GOLD)
# ─────────────────────────────────────────────────────────────────────────────
# SAVE
# ─────────────────────────────────────────────────────────────────────────────
out = "/tmp/workspace/IBD-ppt/Inflammatory_Bowel_Disease.pptx"
buf = BytesIO()
prs.save(buf)
with open(out, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out}")
print(f"Slides: {len(prs.slides)}")
cd /tmp/workspace/IBD-ppt && python build_ibd.py 2>&1
~/IBD-ppt/build_ibd.py
Error: String not found in file: ' if r_idx == 0:
srgbClr.set('val', '%06X' % int(hdr_colors[c_idx].rgb))
else:
base = col_colors[c_idx]
# alternate row shade
if r_idx % 2 == 0:
shade_r = min(base.red + 10, 255)
shade_g = min(base.green + 10, 255)
shade_b = min(base.blue + 10, 255)
srgbClr.set('val', '%02X%02X%02X' % (shade_r, shade_g, shade_b))
else:
srgbClr.set('val', '%06X' % int(base.rgb))'cd /tmp/workspace/IBD-ppt && sed -i "s/srgbClr.set('val', '%06X' % int(hdr_colors\[c_idx\].rgb))/def rgb_hex(c): return '%02X%02X%02X' % (c.red, c.green, c.blue)\n srgbClr.set('val', rgb_hex(hdr_colors[c_idx]))/" build_ibd.py && sed -i "s/srgbClr.set('val', '%06X' % int(base.rgb))/srgbClr.set('val', '%02X%02X%02X' % (base.red, base.green, base.blue))/" build_ibd.py && python build_ibd.py 2>&1
cd /tmp/workspace/IBD-ppt && python3 - <<'PYEOF' with open("build_ibd.py","r") as f: code = f.read() old = """srgbClr.set('val', '%06X' % int(hdr_colors[c_idx].rgb))""" new_block = """def _rgb_hex(c): return '%02X%02X%02X' % (c.red, c.green, c.blue) srgbClr.set('val', _rgb_hex(hdr_colors[c_idx]))""" code2 = code.replace(old, new_block, 1) old2 = """srgbClr.set('val', '%06X' % int(base.rgb))""" new2 = """srgbClr.set('val', '%02X%02X%02X' % (base.red, base.green, base.blue))""" code3 = code2.replace(old2, new2, 1) with open("build_ibd.py","w") as f: f.write(code3) print("patched") print(code3[code3.find("srgbClr.set"):code3.find("srgbClr.set")+200]) PYEOF
python build_ibd.py run could execute. The script is fully written and patched - it just needs one more execution to generate the file./tmp/workspace/IBD-ppt/build_ibd.py and is fully ready - it just needs one final python build_ibd.py run to produce the .pptx file.Continue
cd /tmp/workspace/IBD-ppt && python build_ibd.py 2>&1
sed -n '568,582p' /tmp/workspace/IBD-ppt/build_ibd.py | cat -A
python3 - <<'PYEOF' with open("/tmp/workspace/IBD-ppt/build_ibd.py", "r") as f: code = f.read() # Fix the malformed block bad = """ if r_idx == 0: def rgb_hex(c): return '%02X%02X%02X' % (c.red, c.green, c.blue) srgbClr.set('val', rgb_hex(hdr_colors[c_idx]))""" good = """ def rgb_hex(c): return '%02X%02X%02X' % (c.red, c.green, c.blue) if r_idx == 0: srgbClr.set('val', rgb_hex(hdr_colors[c_idx]))""" code2 = code.replace(bad, good, 1) if bad not in code: print("BAD STRING NOT FOUND - showing lines 570-576:") for i, line in enumerate(code.splitlines()[568:578], 569): print(f"{i}: {repr(line)}") else: with open("/tmp/workspace/IBD-ppt/build_ibd.py", "w") as f: f.write(code2) print("Fixed successfully") PYEOF
cd /tmp/workspace/IBD-ppt && python build_ibd.py 2>&1
python3 -c "from pptx.dml.color import RGBColor; c = RGBColor(0xE8,0x4C,0x60); print(dir(c)); print(type(c)); print(int(c))"
python3 -c "from pptx.dml.color import RGBColor; c = RGBColor(0xE8,0x4C,0x60); print(str(c)); print(repr(c)); print(c[0],c[1],c[2])"
python3 - <<'PYEOF' with open("/tmp/workspace/IBD-ppt/build_ibd.py", "r") as f: code = f.read() # Fix rgb_hex - RGBColor supports str() which gives hex directly old = " def rgb_hex(c): return '%02X%02X%02X' % (c.red, c.green, c.blue)" new = " def rgb_hex(c): return '%02X%02X%02X' % (c[0], c[1], c[2])" code2 = code.replace(old, new, 1) # Also fix base color using index old2 = " srgbClr.set('val', '%02X%02X%02X' % (base.red, base.green, base.blue))" new2 = " srgbClr.set('val', '%02X%02X%02X' % (base[0], base[1], base[2]))" code3 = code2.replace(old2, new2, 1) with open("/tmp/workspace/IBD-ppt/build_ibd.py", "w") as f: f.write(code3) print("done, changed:", old in code, old2 in code) PYEOF
sed -n '578,592p' /tmp/workspace/IBD-ppt/build_ibd.py
python3 - <<'PYEOF' with open("/tmp/workspace/IBD-ppt/build_ibd.py", "r") as f: code = f.read() # Fix all .red .green .blue -> [0] [1] [2] import re code2 = code.replace("base.red", "base[0]").replace("base.green", "base[1]").replace("base.blue", "base[2]") with open("/tmp/workspace/IBD-ppt/build_ibd.py", "w") as f: f.write(code2) print("done") PYEOF cd /tmp/workspace/IBD-ppt && python build_ibd.py 2>&1
Inflammatory Bowel Disease
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide - dark navy with red/blue accents |
| 2 | Introduction & Classification - definition + UC vs CD side-by-side cards |
| 3 | Pathogenesis - 3-pillar layout (Genetics / Epithelial Defects / Immune Response) |
| 4 | Ulcerative Colitis - Clinical Features (symptoms, extraintestinal, complications) |
| 5 | Ulcerative Colitis - Morphology (gross + microscopic, two-column) |
| 6 | Crohn Disease - Clinical Features (symptoms, extraintestinal, CDAI scoring) |
| 7 | Crohn Disease - Morphology (gross + microscopic, cobblestone, granulomas) |
| 8 | Comparison Table - 17-row side-by-side (UC red column, CD blue column) |