Explain same in organise and easy way covering all
| Category | Examples |
|---|---|
| Psychological stress | Anxiety, critical illness |
| Shock | Hypovolemic, septic |
| Severe trauma | β |
| Septicemia | β |
| Burns | Curling's ulcers (posterior duodenum) |
| Brain trauma/tumors | Cushing's ulcers (intracranial lesions β hyperacidity from vagal stimulation) |
| Drugs | Aspirin, steroids, butyazolidine, indomethacin |
| Local irritants | Alcohol, smoking, coffee |
| Feature | Duodenal Ulcer | Gastric Ulcer |
|---|---|---|
| Incidence | 4Γ more common | Less common |
| Age | 25β50 yrs (5th decade) | Usually >60 yrs (6th decade) |
| Sex | Male > Female (4:1) | Male > Female (3.5:1) |
| Etiology | Mainly H. pylori; also acid hypersecretion, blood group O, genetic factors | H. pylori asymptomatic colonisation; higher risk of duodenal ulcer coexistence; gastritis, bile reflux, drugs, alcohol, tobacco |
| Pathogenesis | Mucosal digestion from hyperacidity (most significant) | Usually normal-to-low acid; hyperacidity only if high serum gastrin |
| Protective gastric mucus barrier may be damaged | Damage to mucus barrier is most significant factor | |
| Pathologic changes | Most common in 1st part of duodenum | Most common along lesser curvature and pyloric antrum |
| Often solitary, 1β2.5 cm, round-to-oval, "punched out" | Grossly similar to duodenal ulcer | |
| Histologically: 4 layers β necrotic β superficial exudative β granulation tissue β cicatrisation | Histologically indistinguishable from duodenal ulcer | |
| Complications | Haemorrhage, perforation, sometimes stenosis | Perforation, haemorrhage, and at times obstruction |
| Malignant risk | Very rare | β οΈ Can be malignant β always biopsy to exclude gastric carcinoma |
Trigger (H. pylori / NSAIDs / stress)
β
Disruption of mucosal "barrier"
β
Acid-pepsin attacks mucosa
β
Erosion β Ulceration
β
Acute: superficial, heals without scar
Chronic: deeper, 4-layer histology, complications
| Complication | Notes |
|---|---|
| Haemorrhage | Most common; may be occult or massive (hematemesis/melena) |
| Perforation | Gastric > duodenal risk; surgical emergency |
| Obstruction/Stenosis | Duodenal ulcer healing β pyloric stenosis |
| Malignant transformation | Gastric ulcer only (not duodenal) |
| Penetration | Ulcer burrows into adjacent organ (pancreas, liver) |
Sources: Harsh Mohan Textbook of Pathology, pp. 533β534 | Robbins & Kumar Basic Pathology | Bailey & Love's Short Practice of Surgery, 28th Ed.
Explain same ebut using points and flowcharts diagrams
Medical pathology flowchart diagram titled "Peptic Ulcer - Pathogenesis" showing: A clean white background flowchart with colored boxes. Top box in dark blue: "Trigger Factors: H. pylori / NSAIDs / Stress / Drugs". Arrow down to orange box: "Disruption of Mucosal Barrier (mucus, bicarbonate, blood flow)". Arrow down to red box: "Acid-Pepsin Attacks Mucosa". Then splits into two branches - left branch in yellow: "ACUTE (Stress Ulcer): Superficial, Multiple, Heals without scar, Complications: Bleed/Perforate". Right branch in purple: "CHRONIC Peptic Ulcer: Deeper, 4-layer histology, Gastric or Duodenal, Complications: Bleed/Perforate/Obstruct/Malignancy". Clean medical textbook style, clear arrows, bold labels, readable fonts.
Medical comparison table diagram titled "Gastric Ulcer vs Duodenal Ulcer" with two columns side by side. Left column header in green: "DUODENAL ULCER". Right column header in orange: "GASTRIC ULCER". Rows showing: Incidence: 4x more common vs Less common | Age: 25-50 yrs (5th decade) vs Over 60 yrs (6th decade) | Sex: Male:Female 4:1 vs 3.5:1 | Site: 1st part of duodenum vs Lesser curvature and antrum | Main cause: H. pylori + Hyperacidity vs Mucosal barrier damage | Acid level: HIGH vs NORMAL or LOW | Malignant risk: VERY RARE vs YES - must biopsy | Shape: Solitary, punched out, 1-2.5cm vs Similar to duodenal. Clean white background, medical textbook style, clear grid lines, bold text, color coded columns.
1st part of Duodenum β MOST COMMON
β
Lesser Curvature of Stomach
β
Lower Oesophagus (GERD-related)
β
Meckel's Diverticulum (ectopic gastric mucosa)
PEPTIC ULCERS
β
ββββββββββββββββ΄βββββββββββββββ
βΌ βΌ
ACUTE (Stress) CHRONIC PEPTIC
Ulcers Ulcers
β β
Multiple, small, ββββββββββ΄βββββββββ
superficial βΌ βΌ
GASTRIC DUODENAL
ULCER ULCER
P β Psychological stress
S β Shock
S β Severe trauma
I β Intracranial lesions β Cushing's ulcers
B β Burns (Curling's ulcers β posterior duodenum)
C β Corticosteroids / Drugs (Aspirin, Indomethacin)
D β Drug intake
L β Local irritants (alcohol, smoking, coffee)
Severe stress / Drugs / Burns / Shock
β
βΌ
Two mechanisms operate:
ββββββββββββββββββββββββββββ
β 1. Ischaemic hypoxia ββββ Mucosal cells die
β of mucosal cells β
ββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββ
β 2. Depletion of ββββ Mucus barrier gone
β gastric mucus barrier β
ββββββββββββββββββββββββββββ
β
βΌ
Acid-pepsin attacks unprotected mucosa
β
βΌ
ACUTE SUPERFICIAL EROSION
Haemorrhage βββββ Acute Stress Ulcer βββββ Perforation
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4 FACTORS IN PEPTIC ULCER PATHOGENESIS β
βββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ€
β FACTOR 1 β H. pylori Gastritis β
β FACTOR 2 β NSAIDs-Induced Mucosal Injury β
β FACTOR 3 β Acid-Pepsin Secretions β
β FACTOR 4 β Gastritis (background) β
βββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ
H. pylori infection
Parietal cell hyperplasia
Excessive secretory response
Loss of inhibitory signals
Zollinger-Ellison syndrome (gastrinoma β massive acid β ulcers in stomach + duodenum + jejunum)
H. pylori / NSAIDs / Hyperacidity / Gastritis
β
βΌ
βββββββββββββββββββββββββββββββββ
β MUCOSAL BARRIER DISRUPTED β
β (mucus β, bicarbonate β, β
β blood flow β) β
βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββ
β ACID-PEPSIN ATTACKS MUCOSA β
βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββ
β MUCOSAL EROSION β
βββββββββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
βΌ βΌ
GASTRIC ULCER DUODENAL ULCER
(normal/low acid; (high acid; H. pylori
barrier damage + hyperacidity main
is key factor) factor)
βββββββββββββββββββββ¬ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β FEATURE β DUODENAL ULCER β GASTRIC ULCER β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Incidence β 4Γ MORE COMMON β LESS common β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Age β 25β50 yrs (5th decade) β >60 yrs (6th decade) β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Sex β Male : Female = 4:1 β Male : Female = 3.5:1 β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Main cause β H. pylori + Hyperacidity β Mucosal barrier damage β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Acid level β HIGH β β NORMAL or LOW β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Site β 1st part of duodenum β Lesser curvature + antrumβ
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Appearance β Solitary, punched-out, β Grossly similar β
β β 1β2.5 cm, round/oval β β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Histology β 4 layers: β Indistinguishable from β
β β Necrotic β Exudative β duodenal ulcer β
β β β Granulation β Scar β β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Malignant risk β VERY RARE β β οΈ YES β always biopsy! β
βββββββββββββββββββββΌββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ€
β Complications β Haemorrhage, Perforation,β Perforation, Haemorrhage,β
β β Stenosis β Obstruction β
βββββββββββββββββββββ΄ββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββ
CHRONIC PEPTIC ULCER
β
ββββββββββ¬ββββββββΌβββββββββ¬βββββββββββ
βΌ βΌ βΌ βΌ βΌ
Haemorrhage Perf- Obst- Penetra- Malignant
(most common) oration ruction tion change
(pyloric (gastric
β stenosis) ulcer only)
Surgical
emergency
Step 1 β PPI (Omeprazole/Pantoprazole) β Suppress acid β Heals ulcer
Step 2 β H. pylori eradication β Triple therapy:
PPI + Clarithromycin + Amoxicillin (x 14 days)
β Prevents recurrence
Step 3 β Stop NSAIDs / Smoking / Alcohol
Step 4 (if complications) β Endoscopy β Surgery
| Point | Key Fact |
|---|---|
| No acid = no ulcer | PPIs cure by making patient achlorhydric |
| Most common cause | H. pylori (70β80%) |
| Duodenal : Gastric ratio | 4 : 1 |
| Curling's ulcer | Burns β posterior duodenum |
| Cushing's ulcer | Brain injury β vagal stimulation β hyperacidity |
| Pernicious anaemia | NEVER get peptic ulcers (no acid/pepsin) |
| Zollinger-Ellison | Gastrinoma β massive acid β multiple ulcers stomach + duodenum + jejunum |
| Always biopsy | Gastric ulcer (rule out malignancy) |
| Duodenal histology | 4 layers: Necrotic β Exudative β Granulation β Scar |
Generate a PDF quick reference guide for peptic ulcer diagnosis & treatment
ls -la /home/daytona/workspace/ 2>/dev/null || mkdir -p /home/daytona/workspace
mkdir -p /home/daytona/workspace/peptic-ulcer-pdf && python3 -c "from reportlab.β¦
~/peptic-ulcer-pdf/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, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus.flowables import Flowable
OUTPUT = "/home/daytona/workspace/peptic-ulcer-pdf/Peptic_Ulcer_Quick_Reference.pdf"
# ββ Colours ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NAVY = colors.HexColor("#1B3A6B")
STEEL = colors.HexColor("#2E6DA4")
TEAL = colors.HexColor("#1A7A6E")
ORANGE = colors.HexColor("#E07B2A")
RED = colors.HexColor("#C0392B")
GREEN = colors.HexColor("#1E7F45")
PURPLE = colors.HexColor("#6C3483")
YELLOW_BG = colors.HexColor("#FFF8E1")
BLUE_BG = colors.HexColor("#E8F4FD")
GREEN_BG = colors.HexColor("#E8F8F0")
RED_BG = colors.HexColor("#FDEDEC")
GRAY_BG = colors.HexColor("#F5F5F5")
LIGHT_GRAY= colors.HexColor("#ECEFF1")
WHITE = colors.white
BLACK = colors.HexColor("#212121")
# ββ Styles ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
COVER_TITLE = S("CoverTitle", fontSize=28, textColor=WHITE,
leading=34, alignment=TA_CENTER, fontName="Helvetica-Bold")
COVER_SUB = S("CoverSub", fontSize=13, textColor=colors.HexColor("#CFE2FF"),
leading=18, alignment=TA_CENTER, fontName="Helvetica")
COVER_META = S("CoverMeta", fontSize=10, textColor=colors.HexColor("#AED6F1"),
leading=14, alignment=TA_CENTER, fontName="Helvetica-Oblique")
SEC_HEAD = S("SecHead", fontSize=13, textColor=WHITE,
leading=17, fontName="Helvetica-Bold", alignment=TA_LEFT)
SUBSEC = S("SubSec", fontSize=11, textColor=NAVY,
leading=15, fontName="Helvetica-Bold", spaceBefore=6)
BODY = S("Body", fontSize=9, textColor=BLACK,
leading=14, fontName="Helvetica", alignment=TA_JUSTIFY)
BULLET = S("Bullet", fontSize=9, textColor=BLACK,
leading=13, fontName="Helvetica", leftIndent=12,
firstLineIndent=-10)
SMALL = S("Small", fontSize=8, textColor=colors.HexColor("#555555"),
leading=11, fontName="Helvetica-Oblique", alignment=TA_CENTER)
TBL_HEAD = S("TblHead", fontSize=9, textColor=WHITE,
leading=12, fontName="Helvetica-Bold", alignment=TA_CENTER)
TBL_CELL = S("TblCell", fontSize=8.5, textColor=BLACK,
leading=12, fontName="Helvetica", alignment=TA_LEFT)
TBL_CELL_C = S("TblCellC", fontSize=8.5, textColor=BLACK,
leading=12, fontName="Helvetica", alignment=TA_CENTER)
BADGE = S("Badge", fontSize=8, textColor=WHITE,
leading=11, fontName="Helvetica-Bold", alignment=TA_CENTER)
FLOW_TEXT= S("FlowText", fontSize=8.5, textColor=BLACK,
leading=12, fontName="Helvetica", alignment=TA_CENTER)
WARN = S("Warn", fontSize=9, textColor=RED,
leading=13, fontName="Helvetica-Bold")
FOOTER = S("Footer", fontSize=7.5, textColor=colors.HexColor("#888888"),
leading=10, fontName="Helvetica-Oblique", alignment=TA_CENTER)
# ββ Helper Flowables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
class SectionHeader(Flowable):
def __init__(self, text, bg=NAVY, width=None):
super().__init__()
self.text = text
self.bg = bg
self._width = width or (A4[0] - 3*cm)
self.height = 24
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 0, self._width, self.height, 5, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 11)
c.drawString(10, 7, self.text)
def wrap(self, *args):
return self._width, self.height
class ColorBox(Flowable):
"""A coloured banner box with centred text."""
def __init__(self, text, bg, fg=WHITE, width=None, height=18, radius=4,
font="Helvetica-Bold", fontsize=9):
super().__init__()
self.text = text
self.bg = bg
self.fg = fg
self._width = width or (A4[0] - 3*cm)
self._height = height
self.radius = radius
self.font = font
self.fontsize = fontsize
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 0, self._width, self._height, self.radius, fill=1, stroke=0)
c.setFillColor(self.fg)
c.setFont(self.font, self.fontsize)
c.drawCentredString(self._width / 2, (self._height - self.fontsize) / 2 + 1, self.text)
def wrap(self, *args):
return self._width, self._height
def bullet(text, color=STEEL):
marker = f'<font color="#{hex(int(color.red*255))[2:].zfill(2)}{hex(int(color.green*255))[2:].zfill(2)}{hex(int(color.blue*255))[2:].zfill(2)}">β</font>'
return Paragraph(f"{marker} {text}", BULLET)
def sp(h=4):
return Spacer(1, h)
def hr(color=LIGHT_GRAY, thickness=0.5):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4, spaceBefore=4)
# ββ Cover Page ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
class CoverPage(Flowable):
def __init__(self, w, h):
super().__init__()
self._w = w
self._h = h
def draw(self):
c = self.canv
# Gradient-style background: navy top, steel bottom
c.setFillColor(NAVY)
c.rect(0, 0, self._w, self._h, fill=1, stroke=0)
# Accent strip
c.setFillColor(STEEL)
c.rect(0, self._h * 0.38, self._w, self._h * 0.62, fill=1, stroke=0)
c.setFillColor(NAVY)
c.rect(0, self._h * 0.42, self._w, self._h * 0.58, fill=1, stroke=0)
# Bottom accent
c.setFillColor(TEAL)
c.rect(0, 0, self._w, 8, fill=1, stroke=0)
c.setFillColor(ORANGE)
c.rect(0, 8, self._w, 4, fill=1, stroke=0)
def wrap(self, *args):
return self._w, self._h
# ββ Build PDF βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
W, H = A4
MARGIN = 1.5 * cm
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=MARGIN, bottomMargin=MARGIN,
title="Peptic Ulcer Quick Reference Guide",
author="Medical Quick Reference",
subject="Peptic Ulcer Diagnosis & Treatment"
)
story = []
CONTENT_W = W - 2 * MARGIN
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# PAGE 1 β COVER
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(CoverPage(CONTENT_W, H - 2*MARGIN))
# Overlay text via table on cover
cover_data = [
[Paragraph("QUICK REFERENCE GUIDE", S("cr1", fontSize=11, textColor=colors.HexColor("#AED6F1"),
fontName="Helvetica", alignment=TA_CENTER, leading=14))],
[Spacer(1, 10)],
[Paragraph("PEPTIC ULCER", S("cr2", fontSize=36, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=42))],
[Paragraph("DISEASE", S("cr3", fontSize=36, textColor=colors.HexColor("#FFD700"),
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=42))],
[Spacer(1, 12)],
[Paragraph("Diagnosis Β· Pathogenesis Β· Treatment Β· Complications", S("cr4",
fontSize=12, textColor=colors.HexColor("#CFE2FF"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, leading=16))],
[Spacer(1, 30)],
[Paragraph("βββββββββββββββββββββββββββββ", S("cr5", fontSize=10,
textColor=TEAL, alignment=TA_CENTER, leading=14))],
[Spacer(1, 12)],
[Paragraph("Based on: Harsh Mohan Textbook of Pathology Β· Robbins & Kumar Basic Pathology<br/>"
"Bailey & Love's Short Practice of Surgery Β· Sleisenger & Fordtran's GI Disease",
S("cr6", fontSize=9, textColor=colors.HexColor("#AED6F1"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, leading=13))],
[Spacer(1, 20)],
[Paragraph("For Educational Use Only | May 2026",
S("cr7", fontSize=9, textColor=colors.HexColor("#7FB3D3"),
fontName="Helvetica", alignment=TA_CENTER, leading=12))],
]
cover_table = Table(cover_data, colWidths=[CONTENT_W])
cover_table.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
]))
# Place the cover text over the cover background using a frame trick
# We wrap cover bg + text as a composite table
final_cover = Table(
[[cover_table]],
colWidths=[CONTENT_W],
rowHeights=[H - 2*MARGIN]
)
final_cover.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("ROUNDEDCORNERS", [8]),
("TOPPADDING", (0,0), (-1,-1), 60),
("BOTTOMPADDING", (0,0), (-1,-1), 40),
]))
story.append(final_cover)
story.append(Spacer(1, 10))
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# PAGE 2 β OVERVIEW + CLASSIFICATION + ACUTE ULCERS
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# ββ Section 1: Overview ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("1 OVERVIEW β PEPTIC ULCERS", bg=NAVY))
story.append(sp(6))
overview_cols = [
# Left column
[
Paragraph("<b>Definition</b>", SUBSEC),
bullet("Areas of degeneration & necrosis of GI mucosa"),
bullet("Exposed to acid-pepsin secretions"),
bullet("<b>Acid is essential</b> β no acid = no ulcer"),
bullet("PPIs render patient achlorhydric β heal ulcers"),
sp(6),
Paragraph("<b>Common Sites</b>", SUBSEC),
bullet("1st part of duodenum <b>(most common)</b>"),
bullet("Stomach β lesser curvature & antrum"),
bullet("Lower oesophagus (GERD-related)"),
bullet("Meckel's diverticulum (ectopic gastric mucosa)"),
sp(6),
Paragraph("<b>Duodenum : Stomach Ratio = 4 : 1</b>",
S("ratio", fontSize=10, textColor=STEEL, fontName="Helvetica-Bold",
leading=14, leftIndent=8)),
],
# Right column β classification box
[
Paragraph("<b>Classification</b>", SUBSEC),
sp(4),
Table([
[Paragraph("PEPTIC ULCERS", S("ct", fontSize=10, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))],
], colWidths=[7.5*cm], style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("ROUNDEDCORNERS", [6]),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
])),
sp(4),
Table([
[
Table([[Paragraph("TYPE 1\nACUTE\n(Stress) Ulcers", S("bt1",
fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=13))]],
colWidths=[3.4*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), ORANGE),
("ROUNDEDCORNERS",[6]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
])),
Table([[Paragraph("TYPE 2\nCHRONIC\nPeptic Ulcers", S("bt2",
fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=13))]],
colWidths=[3.4*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), STEEL),
("ROUNDEDCORNERS",[6]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
])),
]
], colWidths=[3.6*cm, 3.6*cm], style=TableStyle([
("ALIGN",(0,0),(-1,-1),"CENTER"),
("LEFTPADDING",(0,0),(-1,-1),3),
("RIGHTPADDING",(0,0),(-1,-1),3),
])),
sp(6),
Table([
[
Table([[Paragraph("GASTRIC\nULCER", S("bt3", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]],
colWidths=[3.4*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), TEAL),
("ROUNDEDCORNERS",[6]),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
])),
Table([[Paragraph("DUODENAL\nULCER", S("bt4", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]],
colWidths=[3.4*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), PURPLE),
("ROUNDEDCORNERS",[6]),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
])),
]
], colWidths=[3.6*cm, 3.6*cm], style=TableStyle([
("ALIGN",(0,0),(-1,-1),"CENTER"),
("LEFTPADDING",(0,0),(-1,-1),3),
("RIGHTPADDING",(0,0),(-1,-1),3),
])),
]
]
overview_table = Table(
[[overview_cols[0], overview_cols[1]]],
colWidths=[CONTENT_W*0.50, CONTENT_W*0.50],
style=TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
])
)
story.append(overview_table)
story.append(sp(10))
# ββ Section 2: Acute Stress Ulcers βββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("2 ACUTE (STRESS) ULCERS", bg=ORANGE))
story.append(sp(6))
acute_left = [
Paragraph("<b>Etiology</b>", SUBSEC),
bullet("Psychological stress"),
bullet("Shock (hypovolemic / septic)"),
bullet("Severe trauma"),
bullet("Septicaemia"),
bullet("<b>Burns</b> β <b>Curling's ulcers</b> (posterior duodenum)"),
bullet("<b>Brain injury / tumours</b> β <b>Cushing's ulcers</b><br/>"
"<i>(intracranial β β vagal stimulation β hyperacidity)</i>"),
bullet("Drugs: Aspirin, steroids, indomethacin"),
bullet("Local irritants: alcohol, smoking, coffee"),
sp(6),
Paragraph("<b>Pathogenesis</b>", SUBSEC),
bullet("Ischaemic hypoxic injury to mucosal cells"),
bullet("Depletion of gastric mucus barrier"),
bullet("β Acid-pepsin attacks unprotected mucosa"),
]
acute_right = [
Paragraph("<b>Morphology</b>", SUBSEC),
Paragraph("<b>Gross:</b>", S("gh", fontSize=9, textColor=STEEL, fontName="Helvetica-Bold", leading=13)),
bullet("Multiple (>3 ulcers in 75% of cases)"),
bullet("Distribution: Stomach > Duodenum (1st part)"),
bullet("Oval/circular, <b>< 1 cm</b> diameter"),
sp(4),
Paragraph("<b>Microscopic:</b>", S("mh", fontSize=9, textColor=STEEL, fontName="Helvetica-Bold", leading=13)),
bullet("Shallow β do NOT invade muscularis"),
bullet("Base shows mild inflammatory reaction"),
bullet("Heal by <b>complete re-epithelialisation</b>"),
bullet("<b>No scar formation</b>"),
sp(6),
Paragraph("<b>Complications</b>", SUBSEC),
Table([
[Paragraph("β Haemorrhage", S("comp1", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13)),
Paragraph("β Perforation", S("comp2", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]
], colWidths=[CONTENT_W*0.22, CONTENT_W*0.22],
style=TableStyle([
("BACKGROUND", (0,0), (0,0), RED),
("BACKGROUND", (1,0), (1,0), ORANGE),
("ROUNDEDCORNERS", [5]),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
]))
]
acute_table = Table(
[[acute_left, acute_right]],
colWidths=[CONTENT_W*0.50, CONTENT_W*0.50],
style=TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("BACKGROUND", (0,0), (0,0), YELLOW_BG),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#FFF3E0")),
("ROUNDEDCORNERS", [6]),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
])
)
story.append(acute_table)
story.append(sp(10))
# ββ Section 3: Pathogenesis of Chronic PUD βββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("3 CHRONIC PEPTIC ULCER β PATHOGENESIS", bg=STEEL))
story.append(sp(8))
# Flowchart as a table
fc_style = lambda bg, fg=WHITE: TableStyle([
("BACKGROUND",(0,0),(-1,-1), bg),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),7),
("BOTTOMPADDING",(0,0),(-1,-1),7),
("LEFTPADDING",(0,0),(-1,-1),8),
("RIGHTPADDING",(0,0),(-1,-1),8),
("ALIGN",(0,0),(-1,-1),"CENTER"),
])
arrow_p = Paragraph("βΌ", S("arr", fontSize=14, textColor=STEEL,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=16))
def fc_box(text, bg, fg=WHITE, width=CONTENT_W*0.6):
return Table([[Paragraph(text, S("fc"+text[:5], fontSize=9, textColor=fg,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]],
colWidths=[width], style=fc_style(bg))
def fc_row(box):
return [Spacer(CONTENT_W*0.2, 1), box]
flow_data = [
[Spacer(1,2), fc_box("H. pylori Β· NSAIDs Β· Stress Β· Hyperacidity Β· Gastritis",
NAVY, width=CONTENT_W*0.85)],
[Spacer(1,2), arrow_p],
[Spacer(1,2), fc_box("DISRUPTION OF MUCOSAL BARRIER\n(β mucus Β· β bicarbonate Β· β mucosal blood flow)",
STEEL, width=CONTENT_W*0.85)],
[Spacer(1,2), arrow_p],
[Spacer(1,2), fc_box("ACID-PEPSIN ATTACKS UNPROTECTED MUCOSA",
ORANGE, width=CONTENT_W*0.85)],
[Spacer(1,2), arrow_p],
[Spacer(1,2), fc_box("MUCOSAL EROSION β ULCERATION",
RED, width=CONTENT_W*0.85)],
[Spacer(1,2), arrow_p],
]
center_fc = Table(flow_data, colWidths=[CONTENT_W*0.07, CONTENT_W*0.93],
style=TableStyle([
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("ALIGN",(0,0),(-1,-1),"CENTER"),
("TOPPADDING",(0,0),(-1,-1),1),
("BOTTOMPADDING",(0,0),(-1,-1),1),
]))
story.append(center_fc)
# Branch boxes
branch_data = [[
Table([[Paragraph("GASTRIC ULCER\n\nβ’ Normal / Low acid\nβ’ Mucosal barrier\n damage is KEY",
S("gb", fontSize=9, textColor=WHITE, fontName="Helvetica",
alignment=TA_CENTER, leading=13))]],
colWidths=[CONTENT_W*0.38],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), TEAL),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
])),
Spacer(CONTENT_W*0.08, 1),
Table([[Paragraph("DUODENAL ULCER\n\nβ’ HIGH acid levels\nβ’ H. pylori is\n primary driver",
S("db", fontSize=9, textColor=WHITE, fontName="Helvetica",
alignment=TA_CENTER, leading=13))]],
colWidths=[CONTENT_W*0.38],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), PURPLE),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
])),
]]
branch_table = Table(branch_data, colWidths=[CONTENT_W*0.44, CONTENT_W*0.08, CONTENT_W*0.44],
style=TableStyle([
("ALIGN",(0,0),(-1,-1),"CENTER"),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
]))
story.append(branch_table)
story.append(sp(10))
# 4 factors in 2x2 grid
story.append(Paragraph("<b>4 Key Pathogenic Factors</b>", SUBSEC))
story.append(sp(6))
factor_data = [
[
Table([[
Paragraph("<b>1. H. pylori Infection π¦ </b>", S("f1h", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=13)),
Spacer(1,4),
Paragraph("β’ 70β80% of PUD associated with H. pylori\n"
"β’ H. pylori in antrum β duodenal ulcer\n"
"β’ Gastric colonisation = asymptomatic\n"
"β’ Only 5β10% of infected β ulcers\n"
"β’ Identified by histology/culture/serology",
S("f1b", fontSize=8.5, textColor=WHITE, fontName="Helvetica", leading=13)),
]], colWidths=[CONTENT_W*0.46],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), STEEL),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
])),
Table([[
Paragraph("<b>2. NSAIDs-Induced Injury π</b>", S("f2h", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=13)),
Spacer(1,4),
Paragraph("β’ Most common drug class causing PUD\n"
"β’ Inhibit COX β β prostaglandins\n"
"β’ β Mucus & bicarbonate secretion\n"
"β’ Damage endothelial cells + epithelium\n"
"β’ Risk β with low-dose aspirin in elderly",
S("f2b", fontSize=8.5, textColor=WHITE, fontName="Helvetica", leading=13)),
]], colWidths=[CONTENT_W*0.46],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), ORANGE),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
])),
],
[Spacer(1,8), Spacer(1,8)],
[
Table([[
Paragraph("<b>3. Acid-Pepsin Secretions π§ͺ</b>", S("f3h", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=13)),
Spacer(1,4),
Paragraph("β’ Essential for ulcer formation\n"
"β’ PU never occurs in pernicious anaemia\n"
" (no acid / pepsin-secreting cells)\n"
"β’ Zollinger-Ellison: gastrinoma β massive\n"
" acid β ulcers in stomach + duodenum +\n"
" jejunum",
S("f3b", fontSize=8.5, textColor=WHITE, fontName="Helvetica", leading=13)),
]], colWidths=[CONTENT_W*0.46],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), TEAL),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
])),
Table([[
Paragraph("<b>4. Gastritis (Background) π₯</b>", S("f4h", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=13)),
Spacer(1,4),
Paragraph("β’ Gastritis ALWAYS present near gastric\n"
" ulcer region\n"
"β’ Gastric ulcer distribution mirrors\n"
" chronic gastritis distribution\n"
"β’ Other cofactors: smoking, alcohol,\n"
" cirrhosis, renal failure, hyperPTH",
S("f4b", fontSize=8.5, textColor=WHITE, fontName="Helvetica", leading=13)),
]], colWidths=[CONTENT_W*0.46],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), PURPLE),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
("LEFTPADDING",(0,0),(-1,-1),10),
("RIGHTPADDING",(0,0),(-1,-1),10),
])),
],
]
factor_table = Table(factor_data,
colWidths=[CONTENT_W*0.49, CONTENT_W*0.49],
style=TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),3),
("RIGHTPADDING",(0,0),(-1,-1),3),
]))
story.append(factor_table)
story.append(sp(10))
# ββ Section 4: Comparison Table βββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("4 GASTRIC vs DUODENAL ULCER β COMPARISON", bg=TEAL))
story.append(sp(8))
hdr = lambda t: Paragraph(t, TBL_HEAD)
cel = lambda t: Paragraph(t, TBL_CELL)
celc= lambda t: Paragraph(t, TBL_CELL_C)
comp_data = [
[hdr("Feature"), hdr("Duodenal Ulcer"), hdr("Gastric Ulcer")],
[cel("Incidence"), cel("4Γ MORE COMMON"), cel("Less common")],
[cel("Age"), cel("25β50 yrs (5th decade)"), cel("> 60 yrs (6th decade)")],
[cel("Sex (M:F)"), cel("4 : 1"), cel("3.5 : 1")],
[cel("Main Cause"), cel("H. pylori + Hyperacidity"), cel("Mucosal barrier damage")],
[cel("Acid Level"), cel("HIGH β"), cel("Normal or LOW β")],
[cel("Site"), cel("1st part of duodenum"), cel("Lesser curvature + antrum")],
[cel("Appearance"), cel("Solitary, punched-out,\n1β2.5 cm, round/oval"), cel("Grossly similar")],
[cel("Histology"), cel("4 layers:\nNecrotic β Exudative\nβ Granulation β Scar"),
cel("Indistinguishable from\nduodenal ulcer")],
[cel("Malignant risk"), cel("Very RARE"), cel("β YES β always biopsy!")],
[cel("Complications"), cel("Haemorrhage, Perforation,\nStenosis"), cel("Perforation, Haemorrhage,\nObstruction")],
]
comp_table = Table(comp_data,
colWidths=[CONTENT_W*0.26, CONTENT_W*0.37, CONTENT_W*0.37],
repeatRows=1)
comp_table.setStyle(TableStyle([
# Header row
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("ALIGN", (0,0), (-1,0), "CENTER"),
# Feature column
("BACKGROUND", (0,1), (0,-1), colors.HexColor("#E0F2F1")),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("FONTSIZE", (0,1), (0,-1), 8.5),
# Alternating rows
("BACKGROUND", (1,1), (-1,1), WHITE),
("BACKGROUND", (1,2), (-1,2), LIGHT_GRAY),
("BACKGROUND", (1,3), (-1,3), WHITE),
("BACKGROUND", (1,4), (-1,4), LIGHT_GRAY),
("BACKGROUND", (1,5), (-1,5), WHITE),
("BACKGROUND", (1,6), (-1,6), LIGHT_GRAY),
("BACKGROUND", (1,7), (-1,7), WHITE),
("BACKGROUND", (1,8), (-1,8), LIGHT_GRAY),
("BACKGROUND", (1,9), (-1,9), RED_BG),
("BACKGROUND", (0,9), (0,9), RED_BG),
("BACKGROUND", (1,10), (-1,10), WHITE),
# Grid
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS", (0,0), (-1,-1), [None]),
]))
story.append(comp_table)
story.append(sp(10))
# ββ Section 5: Incidence + Diagnosis βββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("5 CLINICAL FEATURES & DIAGNOSIS", bg=PURPLE))
story.append(sp(6))
diag_left = [
Paragraph("<b>Symptoms</b>", SUBSEC),
bullet("Epigastric pain / burning (most common)"),
bullet("Duodenal ulcer: pain <b>relieved</b> by food/antacids"),
bullet("Gastric ulcer: pain <b>worsened</b> by food"),
bullet("Nausea, vomiting, bloating"),
bullet("Weight loss (esp. gastric ulcer)"),
bullet("Haematemesis or melaena (bleeding)"),
sp(6),
Paragraph("<b>Signs</b>", SUBSEC),
bullet("Epigastric tenderness"),
bullet("Succussion splash (pyloric stenosis)"),
bullet("Peritonism (perforation)"),
bullet("Anaemia (chronic blood loss)"),
]
diag_right = [
Paragraph("<b>Investigations</b>", SUBSEC),
Table([
[Paragraph("TEST", TBL_HEAD), Paragraph("PURPOSE", TBL_HEAD)],
[cel("OGD (endoscopy)"), cel("Gold standard β visualise + biopsy")],
[cel("Biopsy (CLO test)"), cel("H. pylori detection + exclude malignancy")],
[cel("Urea breath test"), cel("Non-invasive H. pylori test")],
[cel("Stool antigen test"), cel("H. pylori β test of cure")],
[cel("Serology (IgG)"), cel("H. pylori (less specific)")],
[cel("Barium meal"), cel("If endoscopy unavailable")],
[cel("FBC / Iron studies"), cel("Assess anaemia from blood loss")],
[cel("AXR / CXR erect"), cel("Free air under diaphragm (perforation)")],
], colWidths=[CONTENT_W*0.25, CONTENT_W*0.23],
style=TableStyle([
("BACKGROUND",(0,0),(-1,0), PURPLE),
("TEXTCOLOR",(0,0),(-1,0), WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),8),
("GRID",(0,0),(-1,-1),0.4, colors.HexColor("#C0C0C0")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GRAY]),
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),5),
("RIGHTPADDING",(0,0),(-1,-1),5),
])),
]
diag_table = Table(
[[diag_left, diag_right]],
colWidths=[CONTENT_W*0.40, CONTENT_W*0.60],
style=TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),4),
("RIGHTPADDING",(0,0),(-1,-1),4),
])
)
story.append(diag_table)
story.append(sp(10))
# ββ Section 6: Treatment ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("6 TREATMENT", bg=GREEN))
story.append(sp(6))
# Step-by-step treatment flowchart
steps = [
("STEP 1", "Acid Suppression", "PPI (Omeprazole 20β40 mg BD or Pantoprazole 40 mg OD)\nβ Renders patient achlorhydric β heals mucosa", GREEN),
("STEP 2", "H. pylori Eradication", "Triple Therapy Γ 14 days:\nPPI + Clarithromycin 500 mg + Amoxicillin 1 g (all BD)\nIf penicillin allergy: replace amoxicillin with Metronidazole 400 mg", STEEL),
("STEP 3", "Lifestyle Modification", "Stop NSAIDs Β· Stop smoking Β· Avoid alcohol\nReduce stress Β· Small frequent meals", TEAL),
("STEP 4", "Test for Eradication", "Urea breath test or stool antigen test\nβ₯ 4 weeks after completing therapy (off PPIs Γ 2 weeks)", ORANGE),
("STEP 5", "Surgery (Complications)", "Perforation β Laparotomy + repair\nBleeding β Endoscopic haemostasis β surgery if refractory\nObstruction β Balloon dilatation / gastrojejunostomy", RED),
]
for step, title, detail, col in steps:
step_data = [[
Table([[Paragraph(step, S("st_badge", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]],
colWidths=[1.5*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), col),
("ROUNDEDCORNERS",[5]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),10),
])),
Table([[
Paragraph(f"<b>{title}</b>", S("st_t", fontSize=9.5, textColor=col,
fontName="Helvetica-Bold", leading=13)),
Paragraph(detail, S("st_d", fontSize=8.5, textColor=BLACK,
fontName="Helvetica", leading=13)),
]], colWidths=[CONTENT_W - 2.2*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), GRAY_BG),
("TOPPADDING",(0,0),(-1,-1),6),
("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),8),
("RIGHTPADDING",(0,0),(-1,-1),8),
])),
]]
story.append(Table(step_data, colWidths=[1.8*cm, CONTENT_W - 1.8*cm],
style=TableStyle([
("VALIGN",(0,0),(-1,-1),"MIDDLE"),
("LEFTPADDING",(0,0),(-1,-1),2),
("RIGHTPADDING",(0,0),(-1,-1),2),
])))
story.append(sp(4))
story.append(sp(6))
# ββ Section 7: Complications ββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("7 COMPLICATIONS", bg=RED))
story.append(sp(6))
comp_boxes = [
("Haemorrhage\n(Most Common)", "Haematemesis / melaena\nEndoscopic haemostasis\nSurgery if refractory", RED),
("Perforation", "Gastric > Duodenal\nPeritonitis\nSurgical emergency\nFree air on CXR", ORANGE),
("Obstruction /\nStenosis", "Duodenal ulcer β pyloric stenosis\nVomiting + weight loss\nBalloon dilatation", TEAL),
("Penetration", "Ulcer into pancreas,\nliver, biliary tree\nPain radiates to back", STEEL),
("Malignancy", "GASTRIC ULCER ONLY\n(Duodenal = very rare)\nMUST biopsy all\ngastric ulcers", PURPLE),
]
comp_row = []
for title, detail, col in comp_boxes:
comp_row.append(
Table([[
Paragraph(title, S("cbt", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=13)),
Spacer(1,4),
Paragraph(detail, S("cbd", fontSize=7.5, textColor=WHITE, fontName="Helvetica",
alignment=TA_CENTER, leading=12)),
]], colWidths=[CONTENT_W/5 - 4],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), col),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),5),
("RIGHTPADDING",(0,0),(-1,-1),5),
]))
)
complications_table = Table(
[comp_row],
colWidths=[CONTENT_W/5]*5,
style=TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),3),
("RIGHTPADDING",(0,0),(-1,-1),3),
])
)
story.append(complications_table)
story.append(sp(10))
# ββ Section 8: High-Yield Summary βββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionHeader("8 HIGH-YIELD EXAM POINTS", bg=colors.HexColor("#37474F")))
story.append(sp(6))
hye_data = [
["No acid = No ulcer", "PPIs cure by rendering patient achlorhydric"],
["Most common cause", "H. pylori (70β80% of PUD)"],
["D : G ulcer ratio", "Duodenal : Gastric = 4 : 1"],
["Curling's ulcer", "Burns β posterior duodenum"],
["Cushing's ulcer", "Brain injury β vagal stim β hyperacidity"],
["Pernicious anaemia", "NEVER get peptic ulcers (no acid/pepsin)"],
["Zollinger-Ellison", "Gastrinoma β massive acid β ulcers in stomach + duodenum + jejunum"],
["Always biopsy", "Gastric ulcer (rule out malignancy β never skip!)"],
["Duodenal histology", "4 layers: Necrotic β Exudative β Granulation β Scar"],
["Duodenal pain", "RELIEVED by food/antacids (food buffers acid)"],
["Gastric pain", "WORSENED by food (food stimulates acid)"],
["Test of cure", "Urea breath test β₯ 4 weeks after triple therapy"],
]
hye_table = Table(
[[Paragraph(f"<b>{row[0]}</b>", S("hyek", fontSize=8.5, textColor=NAVY,
fontName="Helvetica-Bold", leading=13)),
Paragraph(f"β {row[1]}", S("hyev", fontSize=8.5, textColor=BLACK,
fontName="Helvetica", leading=13))]
for row in hye_data],
colWidths=[CONTENT_W*0.34, CONTENT_W*0.66],
style=TableStyle([
("ROWBACKGROUNDS", (0,0), (-1,-1), [WHITE, LIGHT_GRAY]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CFD8DC")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("BACKGROUND", (0,0), (0,-1), colors.HexColor("#E3F2FD")),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
])
)
story.append(hye_table)
story.append(sp(10))
# ββ Footer βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(hr(LIGHT_GRAY, 1))
story.append(Paragraph(
"Sources: Harsh Mohan Textbook of Pathology pp.533β534 Β· Robbins & Kumar Basic Pathology Β· "
"Bailey & Love's Short Practice of Surgery 28th Ed. Β· Sleisenger & Fordtran's GI Disease | "
"For Educational Use Only | May 2026",
FOOTER
))
# ββ Build ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
doc.build(story)
print(f"PDF created: {OUTPUT}")
Perfect way to present in exam
Anti arrythmic drugs