I have to present this so give me a interactive professional easily understand presentation text and and things like that for each slide ,a detailed correct way of presentation
ls -la "/tmp/workspace/attachments/9101f6ee-62e5-486b-ab7d-388fedbd754c/" && file "/tmp/workspace/attachments/9101f6ee-62e5-486b-ab7d-388fedbd754c/Nithya rheumatoid arthritis"
python3 -c " from pptx import Presentation prs = Presentation('/tmp/workspace/attachments/9101f6ee-62e5-486b-ab7d-388fedbd754c/Nithya rheumatoid arthritis') for i, slide in enumerate(prs.slides, 1): print(f'=== SLIDE {i} ===') for shape in slide.shapes: if shape.has_text_frame and shape.text_frame.text.strip(): print(repr(shape.text_frame.text)) print() "
"Good morning/afternoon everyone. Today I'm going to take you through Rheumatoid Arthritis - a disease that is far more than just 'joint pain.' By the end of this session, you'll understand why it happens, how to recognize it, and how it destroys joints at the cellular level."
"Let's start with a real scenario - because medicine always begins with a patient."
"Before I reveal the diagnosis, I want you all to think - what's your differential? Take 10 seconds." (pause)
"What tells us this is NOT osteoarthritis? Three clues: symmetrical joints, morning stiffness over one hour, and the DIP joints are SPARED. Keep those in mind."
"Now, before we confirm RA, let's think about what else could mimic this picture."
| Condition | How it differs from RA |
|---|---|
| Osteoarthritis | DIP involved, no morning stiffness >1hr, no RF |
| Psoriatic Arthritis | DIP involvement, skin plaques, sausage digits |
| SLE Arthritis | Non-erosive, positive ANA/anti-dsDNA, systemic features |
| Gout | Males, monoarthritis, urate crystals, hyperuricemia |
| Viral Arthritis | Acute onset, self-limiting, often post-viral |
"But in our case - symmetrical MCP/PIP involvement, morning stiffness, positive anti-CCP, and spared DIPs - the diagnosis is clear. This is Rheumatoid Arthritis."
"So what exactly is Rheumatoid Arthritis? Let's get the definition right."
"RA is a chronic inflammatory, autoimmune disorder - and I want you to remember two words: nonsuppurative and proliferative synovitis. It primarily attacks joints, but don't be fooled - it's a systemic disease."
"Think of RA as the synovium going to war against the joint - and eventually winning, unless we intervene."
"Now let's look at who gets RA."
"Affects 0.5 to 1% of adults worldwide - that sounds small, but that's millions of people globally."
"It's 2 to 3 times more common in women - why? Likely hormonal factors, estrogen's role in immune modulation."
"Peak onset is 40 to 60 years of age - working-age adults, which means enormous socioeconomic burden."
"RA can lead to bony ankylosis - joints fuse completely. A person who was opening jars at 40 could have completely fused wrists by 60 if untreated. That's why early diagnosis matters."
"RA doesn't have one single cause - it's a perfect storm of three factors."
"The biggest genetic link is HLA-DRB1 - specifically HLA-DR4. These molecules present citrullinated peptides to T cells. Think of HLA as the 'key' that unlocks the autoimmune response." "Other genes: PTPN22 (controls T-cell signaling), STAT4 (cytokine signaling)."
"Smoking is the single biggest modifiable risk factor. How? It promotes protein citrullination in the lungs, triggering anti-CCP production." "Even your gum bacteria play a role - Porphyromonas gingivalis from periodontal disease can citrullinate proteins. Flossing may literally reduce your RA risk!"
"When immune tolerance is lost, the body produces two key autoantibodies - Rheumatoid Factor and Anti-CCP. Anti-CCP is the more specific one - it can appear years before symptoms."
"Now let's follow the disease step by step - from genetics to joint destruction. I want you to trace this pathway with me."
"Genetically susceptible person + environmental trigger (smoking, infection)"
"Proteins get citrullinated - arginine is converted to citrulline. Your immune system doesn't recognize these and mounts an attack."
"Loss of tolerance - now CD4+ T cells and antigen-presenting cells are activated."
"B cells get activated - they produce RF and Anti-CCP antibodies."
"These form immune complexes - they deposit in joints."
"Macrophages and synovial fibroblasts release TNF-Ξ±, IL-1, IL-6, IL-17 - these cytokines are the engines of inflammation."
"Chronic synovitis - the synovium thickens, new blood vessels form (angiogenesis)."
"This leads to PANNUS - the most important concept in RA pathology."
"Pannus invades cartilage via MMPs, and bone via RANKL-activated osteoclasts."
"End result: irreversible joint destruction, deformity, and disability."
"The star molecule here is TNF-Ξ± - because it's the target of the most successful RA drugs, the biologics. When we block TNF-Ξ±, we stop this whole cascade."
"Take a moment to look at this image." (pause for the audience to look) "This is what RA looks like at the tissue level. Notice [describe what's visible in the image - pannus, inflamed synovium, erosions]."
"Clinically, RA is primarily a joint disease - but the pattern of joint involvement is everything."
"Symmetrical - if the left hand is affected, so is the right. This is cardinal."
"Morning stiffness >1 hour - this is duration-dependent and directly reflects synovial inflammation. In OA, stiffness is brief, under 30 minutes."
"Joints involved: MCP, PIP, wrists, MTP joints. The DIP joints are classically SPARED - this is a high-yield exam point."
| Deformity | Description |
|---|---|
| Boutonniere | PIP flexion + DIP hyperextension |
| Swan-neck | PIP hyperextension + DIP flexion |
| Z-deformity | Thumb - MCP flexion + IP hyperextension |
| Ulnar deviation | Fingers deviate to ulnar side at MCP |
"These deformities tell you the disease has been going on for a long time, untreated."
"Here is where RA shows its true colours as a SYSTEMIC disease."
"Now let's shift to pathology - what does the surgeon or pathologist see when they open a joint?"
"The synovial membrane is thickened, opaque, gray-red - compare this to normal, which is thin and glistening."
"The surface is villous - finger-like projections, due to synovial cell hypertrophy. This dramatically increases surface area for inflammation."
"The joint fluid is turbid and yellow - inflammatory exudate. Normal synovial fluid is clear, straw-colored."
"The cartilage is dull, roughened, and eroded - it has lost its smooth, white, glistening appearance."
"PANNUS - this is the key gross finding. It is a mass of vascular granulation tissue and fibroblasts that literally grows over and into the cartilage like an invasive tumor."
"Eventually you get fibrous ankylosis - the joint is bridged by fibrous tissue - and then bony ankylosis - complete fusion. The patient loses all movement."
"At the microscopic level, five changes define RA synovitis."
"Synovial cell hyperplasia - the lining layer expands from 1-2 cells to 6-8+ cells thick."
"Dense inflammatory infiltrate - CD4+ T cells, B cells, plasma cells, macrophages. These even form lymphoid follicles - like mini lymph nodes INSIDE the joint. Called 'tertiary lymphoid structures.'"
"Angiogenesis - new blood vessels form to supply the hungry, inflamed tissue."
"Fibrinopurulent exudate - on the synovial and joint surfaces."
"Osteoclastic activity - the synovium penetrates BONE, creating periarticular erosions and subchondral cysts. This is what you see on X-ray."
"Cartilage destroyed β pannus bridges the bones β fibrous ankylosis β bony ankylosis (ossification). This is the worst outcome - complete, irreversible fusion."
"Look at this histological section." (pause) "You can identify [point out lymphoid follicles / pannus / synovial hyperplasia depending on the image]. This is the 'ground zero' of joint destruction."
"The lab picture in RA is a combination of inflammation markers, autoantibodies, and synovial fluid analysis."
"ESR and CRP are elevated - these are nonspecific but track disease activity. Anaemia of chronic disease is also expected - normocytic, normochromic due to cytokine-mediated EPO suppression."
"Two key ones - Rheumatoid Factor (IgM against Fc of IgG) is positive in ~70-80% of RA cases. But anti-CCP is the star: highly specific, can be positive years before symptoms. ANA can be positive too, but weaker than SLE."
"Yellow, turbid. WBC 5,000-50,000 - mostly neutrophils (inflammatory exudate). No crystals (rules out gout/pseudogout). Cultures sterile (rules out septic arthritis)."
"X-ray shows the classic triad: joint space narrowing, periarticular erosions, juxta-articular osteopenia. MRI detects earlier changes - bone marrow edema before erosions appear on X-ray."
"Radiology gives us objective evidence of structural damage."
"On X-ray of the hand, look at the MCP and PIP joints first - these are your targets. On wrist X-ray, look for radiocarpal joint space narrowing."
"MRI and ultrasound are now used early - ultrasound is particularly useful for detecting synovitis and power Doppler can show active blood flow into the pannus."
"How do we formally diagnose RA? We use the 2010 ACR/EULAR Classification Criteria - scoring system out of 10 points. A score of 6 or more = definite RA."
| Domain | Points |
|---|---|
| Joint involvement | |
| 1 large joint | 0 |
| 2-10 large joints | 1 |
| 1-3 small joints | 2 |
| 4-10 small joints | 3 |
| >10 joints (including small) | 5 |
| Serology | |
| Negative RF and anti-CCP | 0 |
| Low positive RF or anti-CCP | 2 |
| High positive RF or anti-CCP | 3 |
| Acute phase reactants | |
| Normal ESR and CRP | 0 |
| Abnormal ESR or CRP | 1 |
| Duration of symptoms | |
| <6 weeks | 0 |
| β₯6 weeks | 1 |
"Apply this to our case scenario: small joints bilaterally (3 pts) + high positive anti-CCP (3 pts) + raised ESR/CRP (1 pt) + 8 months duration (1 pt) = 8 points. Definite RA."
"Treatment follows a treat-to-target strategy - we aim for remission or low disease activity. The mantra is: start early, treat aggressively."
"Methotrexate is the anchor drug - first-line for almost all RA patients. It suppresses folate-dependent pathways and reduces inflammation. Supplement with folic acid to reduce side effects." "Others: Hydroxychloroquine, Sulfasalazine, Leflunomide"
"If DMARDs fail after 3-6 months, we escalate to biologics." "TNF-Ξ± inhibitors: Etanercept, Infliximab, Adalimumab - these block the cytokine we identified in the pathogenesis." "IL-6 inhibitors: Tocilizumab" "T-cell costimulation blockade: Abatacept" "B-cell depletion: Rituximab"
"Newer targeted small molecules: Tofacitinib, Baricitinib - block JAK-STAT signaling intracellularly."
"NSAIDs and corticosteroids for short-term symptom control. Corticosteroids are not long-term solutions - bone loss and metabolic effects."
"The reason anti-CCP matters so much clinically is that a patient who is positive should be started on DMARDs IMMEDIATELY, even before meeting full diagnostic criteria - because joint damage can begin before symptoms."
"Untreated or poorly controlled RA leads to serious, life-altering complications across multiple systems."
| System | Complication |
|---|---|
| Musculoskeletal | Joint deformity, bony ankylosis, functional disability, atlantoaxial subluxation (C1-C2 - can cause cord compression!) |
| Cardiovascular | Accelerated atherosclerosis, pericarditis, myocarditis - #1 cause of premature death |
| Respiratory | Interstitial lung disease, pleuritis, Caplan syndrome |
| Hematologic | Felty's syndrome (RA + splenomegaly + neutropenia), anaemia |
| Iatrogenic | Infections from immunosuppressants, GI bleed from NSAIDs, osteoporosis from steroids |
| Malignancy | Increased risk of lymphoma (especially with chronic inflammation) |
| Neurological | Carpal tunnel syndrome (median nerve), mononeuritis multiplex (vasculitis) |
"Atlantoaxial subluxation is a critical complication - any RA patient going for general anaesthesia or surgery must have a cervical spine X-ray first. Intubation without this can paralyse or kill the patient."
"Let's test our understanding with three high-yield MCQs."
"The answer is B - Pannus. Pannus is the fibrovascular granulation tissue that invades and destroys cartilage and bone. Tophus is gout. Heberden's nodes are OA. Osteophytes are also OA."
"The answer is C - Anti-CCP. RF is sensitive but not specific - it can be positive in many other conditions like Sjogren's, SLE, even chronic infections. Anti-CCP is highly specific (95%+) and can appear BEFORE symptoms."
"The answer is B - HLA-DR4 (part of the HLA-DRB1 family). Remember: HLA-B27 is ankylosing spondylitis, HLA-DR3 is primary Sjogren's/SLE, HLA-DR4 is RA."
"To summarize what we've covered today:"
"RA is a chronic autoimmune synovitis driven by genetic susceptibility, environmental triggers like smoking, and autoantibodies - especially anti-CCP. The key pathological lesion is pannus. Clinically, it presents with symmetrical small joint arthritis, morning stiffness >1 hour, with sparing of DIPs. Systemic complications are significant and cardiovascular disease is the leading cause of death. Treatment is treat-to-target with methotrexate as anchor therapy, escalating to biologics if needed."
"I'd like to thank everyone for your attention. I'm happy to take any questions."
| Tip | Details |
|---|---|
| Body language | Face the audience, not the screen. Use hand gestures when explaining pathways. |
| Voice | Slow down for complex slides (pathogenesis, microscopy). Speed up for lists. |
| Transitions | Connect slides: "Now that we know why it happens, let's see what it looks like clinically..." |
| Laser pointer | Use it on the pathogenesis flowchart to guide the audience step by step |
| Time management | Case + Definition = 3 min. Epidemiology + Etio = 4 min. Pathogenesis = 5 min. Clinical = 5 min. Pathology = 4 min. Labs/Radiology = 3 min. Treatment + Complications = 5 min. MCQs = 3 min. |
| Engagement | Ask 2-3 rhetorical or direct questions to the audience throughout |
| Never say | "I think," "Maybe," "I'm not sure" - speak with confidence |
| Backup fact | If asked a question you don't know: "That's a great question - the specific detail I'll confirm, but the principle is..." |
Create an animated PDF guide with this presentation script and slide notes
mkdir -p /tmp/workspace/ra-presentation-guide && ls /tmp/workspace/ra-presentation-guide/
~/ra-presentation-guide/build_pdf.py
#!/usr/bin/env python3
"""
Rheumatoid Arthritis - Animated Presentation Guide PDF
Uses ReportLab to create a richly formatted, visually structured PDF
with slide-by-slide speaker scripts, tips, and key points.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import Flowable
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor, white, black
import math
OUTPUT_PATH = "/tmp/workspace/ra-presentation-guide/RA_Presentation_Guide.pdf"
# βββ Colour Palette βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NAVY = HexColor("#1A237E")
BLUE = HexColor("#1565C0")
TEAL = HexColor("#00838F")
RED_DARK = HexColor("#B71C1C")
RED = HexColor("#E53935")
GREEN_DARK = HexColor("#1B5E20")
GREEN = HexColor("#2E7D32")
AMBER = HexColor("#F57F17")
AMBER_LIGHT= HexColor("#FFF8E1")
PURPLE = HexColor("#4A148C")
PURPLE_MID = HexColor("#7B1FA2")
GRAY_DARK = HexColor("#263238")
GRAY_MID = HexColor("#546E7A")
GRAY_LIGHT = HexColor("#ECEFF1")
LIGHT_BLUE_BG = HexColor("#E3F2FD")
LIGHT_GREEN_BG= HexColor("#E8F5E9")
LIGHT_RED_BG = HexColor("#FFEBEE")
LIGHT_TEAL_BG = HexColor("#E0F7FA")
CREAM = HexColor("#FAFAFA")
GOLD = HexColor("#FFD600")
W, H = A4 # 595.27 x 841.89 pt
# βββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
TITLE_STYLE = S("DocTitle",
fontSize=28, leading=34, textColor=white,
fontName="Helvetica-Bold", alignment=TA_CENTER)
SUBTITLE_STYLE = S("DocSub",
fontSize=14, leading=18, textColor=HexColor("#E3F2FD"),
fontName="Helvetica", alignment=TA_CENTER)
SLIDE_NUM_STYLE = S("SlideNum",
fontSize=9, leading=11, textColor=white,
fontName="Helvetica-Bold", alignment=TA_CENTER)
SLIDE_TITLE_STYLE = S("SlideTitle",
fontSize=16, leading=20, textColor=white,
fontName="Helvetica-Bold", alignment=TA_LEFT)
SECTION_LABEL = S("SecLabel",
fontSize=8, leading=10, textColor=white,
fontName="Helvetica-Bold", alignment=TA_LEFT)
SCRIPT_STYLE = S("Script",
fontSize=10.5, leading=16, textColor=GRAY_DARK,
fontName="Helvetica", alignment=TA_JUSTIFY,
leftIndent=4, rightIndent=4)
QUOTE_STYLE = S("Quote",
fontSize=11, leading=17, textColor=NAVY,
fontName="Helvetica-Oblique", alignment=TA_LEFT,
leftIndent=16, rightIndent=8,
borderPad=6)
BULLET_STYLE = S("Bullet",
fontSize=10, leading=15, textColor=GRAY_DARK,
fontName="Helvetica", leftIndent=18, bulletIndent=6,
alignment=TA_LEFT)
KEY_STYLE = S("Key",
fontSize=10, leading=15, textColor=GREEN_DARK,
fontName="Helvetica-Bold", leftIndent=18, bulletIndent=6)
TIP_STYLE = S("Tip",
fontSize=10, leading=15, textColor=AMBER,
fontName="Helvetica-Bold", leftIndent=4)
TABLE_HEADER = S("TblHdr",
fontSize=9, leading=12, textColor=white,
fontName="Helvetica-Bold", alignment=TA_CENTER)
TABLE_CELL = S("TblCell",
fontSize=9, leading=13, textColor=GRAY_DARK,
fontName="Helvetica", alignment=TA_LEFT)
MNEMONIC_STYLE = S("Mnemonic",
fontSize=11, leading=16, textColor=PURPLE,
fontName="Helvetica-Bold", alignment=TA_CENTER)
FOOTER_STYLE = S("Footer",
fontSize=7.5, leading=10, textColor=GRAY_MID,
fontName="Helvetica", alignment=TA_CENTER)
HEADING2 = S("H2",
fontSize=11, leading=14, textColor=BLUE,
fontName="Helvetica-Bold", alignment=TA_LEFT, spaceAfter=2)
# βββ Custom Flowables βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
class RoundedBox(Flowable):
"""A coloured rounded-rectangle background box."""
def __init__(self, width, height, bg_color, radius=6):
super().__init__()
self.box_width = width
self.box_height = height
self.bg_color = bg_color
self.radius = radius
def wrap(self, availWidth, availHeight):
return self.box_width, self.box_height
def draw(self):
c = self.canv
c.setFillColor(self.bg_color)
c.roundRect(0, 0, self.box_width, self.box_height, self.radius, fill=1, stroke=0)
class SlideHeader(Flowable):
"""Decorative slide header with number badge + title bar."""
def __init__(self, slide_num, title, accent_color, total=20):
super().__init__()
self.slide_num = slide_num
self.title = title
self.accent = accent_color
self.total = total
self._height = 52
def wrap(self, availWidth, availHeight):
self._width = availWidth
return availWidth, self._height
def draw(self):
c = self.canv
w = self._width
h = self._height
# Full-width background bar
c.setFillColor(self.accent)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=0)
# Slide number badge (circle on left)
badge_r = 18
cx = badge_r + 8
cy = h / 2
c.setFillColor(white)
c.circle(cx, cy, badge_r, fill=1, stroke=0)
c.setFillColor(self.accent)
c.setFont("Helvetica-Bold", 13)
txt = str(self.slide_num)
c.drawCentredString(cx, cy - 5, txt)
c.setFont("Helvetica", 6)
c.setFillColor(GRAY_MID)
c.drawCentredString(cx, cy - 13, f"of {self.total}")
# Title text
c.setFillColor(white)
c.setFont("Helvetica-Bold", 14)
max_w = w - cx*2 - badge_r - 20
title = self.title.upper()
c.drawString(cx + badge_r + 14, cy - 6, title)
# Progress bar at bottom
bar_y = 3
bar_h = 4
c.setFillColor(HexColor("#FFFFFF44"))
c.roundRect(cx + badge_r + 10, bar_y, w - cx - badge_r - 20, bar_h, 2, fill=1, stroke=0)
progress = (self.slide_num / self.total) * (w - cx - badge_r - 20)
c.setFillColor(GOLD)
c.roundRect(cx + badge_r + 10, bar_y, progress, bar_h, 2, fill=1, stroke=0)
class SpeakerBubble(Flowable):
"""A speech-bubble style box for script text."""
def __init__(self, text, width, color=LIGHT_BLUE_BG, border=BLUE):
super().__init__()
self._text = text
self._w = width
self._color = color
self._border = border
def wrap(self, availWidth, availHeight):
self._width = min(self._w, availWidth)
# measure text height
from reportlab.platypus import Paragraph
p = Paragraph(self._text, SCRIPT_STYLE)
_, h = p.wrap(self._width - 24, 9999)
self._inner_h = h
self._height = h + 20
return self._width, self._height
def draw(self):
c = self.canv
# Shadow
c.setFillColor(HexColor("#00000018"))
c.roundRect(3, -3, self._width - 4, self._height, 8, fill=1, stroke=0)
# Box
c.setFillColor(self._color)
c.setStrokeColor(self._border)
c.setLineWidth(1.2)
c.roundRect(0, 0, self._width - 4, self._height, 8, fill=1, stroke=1)
# Left accent bar
c.setFillColor(self._border)
c.roundRect(0, 0, 4, self._height, 4, fill=1, stroke=0)
# Mic icon area
c.setFillColor(self._border)
c.circle(16, self._height - 12, 6, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(16, self._height - 14.5, "SAY")
# Render text
from reportlab.platypus import Paragraph
p = Paragraph(self._text, SCRIPT_STYLE)
p.wrap(self._width - 32, self._inner_h + 4)
p.drawOn(c, 28, 8)
class TipBox(Flowable):
"""A styled tip/note box."""
def __init__(self, label, text, width, bg=AMBER_LIGHT, accent=AMBER):
super().__init__()
self._label = label
self._text = text
self._w = width
self._bg = bg
self._accent = accent
def wrap(self, availWidth, availHeight):
self._width = min(self._w, availWidth)
from reportlab.platypus import Paragraph
p = Paragraph(self._text, SCRIPT_STYLE)
_, h = p.wrap(self._width - 28, 9999)
self._inner_h = h
self._height = h + 24
return self._width, self._height
def draw(self):
c = self.canv
c.setFillColor(self._bg)
c.setStrokeColor(self._accent)
c.setLineWidth(1.5)
c.roundRect(0, 0, self._width - 4, self._height, 6, fill=1, stroke=1)
# Top label strip
c.setFillColor(self._accent)
c.roundRect(0, self._height - 18, self._width - 4, 18, 6, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 8)
c.drawString(10, self._height - 13, self._label)
from reportlab.platypus import Paragraph
p = Paragraph(self._text, SCRIPT_STYLE)
p.wrap(self._width - 28, self._inner_h + 4)
p.drawOn(c, 12, 8)
class KeyPointsBox(Flowable):
"""Numbered key points in a styled container."""
def __init__(self, points, width, bg=LIGHT_GREEN_BG, accent=GREEN):
super().__init__()
self._points = points
self._w = width
self._bg = bg
self._accent = accent
def wrap(self, availWidth, availHeight):
self._width = min(self._w, availWidth)
from reportlab.platypus import Paragraph
total_h = 22 # header
for pt in self._points:
p = Paragraph(pt, SCRIPT_STYLE)
_, h = p.wrap(self._width - 52, 9999)
total_h += h + 12
self._height = total_h + 10
return self._width, self._height
def draw(self):
c = self.canv
c.setFillColor(self._bg)
c.setStrokeColor(self._accent)
c.setLineWidth(1.2)
c.roundRect(0, 0, self._width - 4, self._height, 6, fill=1, stroke=1)
# Header
c.setFillColor(self._accent)
c.roundRect(0, self._height - 20, self._width - 4, 20, 6, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 8)
c.drawString(10, self._height - 14, "KEY POINTS")
from reportlab.platypus import Paragraph
y = self._height - 32
for i, pt in enumerate(self._points, 1):
# Circle number
c.setFillColor(self._accent)
c.circle(20, y - 2, 8, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 8)
c.drawCentredString(20, y - 4.5, str(i))
# Text
p = Paragraph(pt, SCRIPT_STYLE)
_, h = p.wrap(self._width - 52, 9999)
p.drawOn(c, 36, y - h + 2)
y -= h + 12
class MCQBox(Flowable):
"""MCQ question box with answer reveal."""
def __init__(self, qnum, question, options, answer_idx, answer_text, width):
super().__init__()
self.qnum = qnum
self.question = question
self.options = options
self.answer_idx = answer_idx
self.answer_text = answer_text
self._w = width
def wrap(self, availWidth, availHeight):
self._width = min(self._w, availWidth)
from reportlab.platypus import Paragraph
q_p = Paragraph(self.question, SCRIPT_STYLE)
_, qh = q_p.wrap(self._width - 30, 9999)
opt_h = 0
for o in self.options:
op = Paragraph(o, SCRIPT_STYLE)
_, oh = op.wrap(self._width - 50, 9999)
opt_h += oh + 8
ans_p = Paragraph(self.answer_text, SCRIPT_STYLE)
_, ah = ans_p.wrap(self._width - 50, 9999)
self._height = qh + opt_h + ah + 70
return self._width, self._height
def draw(self):
c = self.canv
w = self._width - 4
h = self._height
# Outer box
c.setFillColor(HexColor("#F3E5F5"))
c.setStrokeColor(PURPLE_MID)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=1)
# Q badge
c.setFillColor(PURPLE_MID)
c.roundRect(0, h - 28, w, 28, 8, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 11)
c.drawString(12, h - 20, f"Q{self.qnum}")
from reportlab.platypus import Paragraph
q_p = Paragraph(self.question, SCRIPT_STYLE)
_, qh = q_p.wrap(w - 30, 9999)
q_p.drawOn(c, 12, h - 36 - qh)
y = h - 42 - qh
labels = ["A", "B", "C", "D"]
for i, opt in enumerate(self.options):
is_ans = (i == self.answer_idx)
c.setFillColor(GREEN if is_ans else HexColor("#EEEEEE"))
c.roundRect(12, y - 18, w - 24, 18, 4, fill=1, stroke=0)
if is_ans:
c.setFillColor(white)
c.setFont("Helvetica-Bold", 9)
else:
c.setFillColor(GRAY_MID)
c.setFont("Helvetica", 9)
c.drawString(20, y - 13, f"{labels[i]}. {opt}")
if is_ans:
c.setFillColor(GOLD)
c.setFont("Helvetica-Bold", 8)
c.drawRightString(w - 14, y - 13, "CORRECT β")
y -= 24
# Answer explanation
c.setFillColor(LIGHT_GREEN_BG)
c.setStrokeColor(GREEN)
c.setLineWidth(1)
ans_p = Paragraph(self.answer_text, SCRIPT_STYLE)
_, ah = ans_p.wrap(w - 36, 9999)
c.roundRect(10, y - ah - 14, w - 20, ah + 14, 4, fill=1, stroke=1)
c.setFillColor(GREEN_DARK)
c.setFont("Helvetica-Bold", 8)
c.drawString(18, y - 4, "EXPLANATION:")
ans_p.drawOn(c, 18, y - ah - 10)
# βββ Page Template ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def on_page(canv, doc):
"""Background gradient + footer on every page."""
canv.saveState()
# Subtle gradient background (top strip)
canv.setFillColor(HexColor("#F8FAFF"))
canv.rect(0, 0, W, H, fill=1, stroke=0)
# Top accent line
canv.setFillColor(NAVY)
canv.rect(0, H - 6, W, 6, fill=1, stroke=0)
# Bottom accent line
canv.setFillColor(TEAL)
canv.rect(0, 0, W, 4, fill=1, stroke=0)
# Footer
canv.setFillColor(GRAY_MID)
canv.setFont("Helvetica", 7)
canv.drawCentredString(W/2, 12, "Rheumatoid Arthritis β Presenter's Guide | Prepared by Nithya | Page %d" % doc.page)
canv.restoreState()
# βββ Cover Page βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def cover_page():
story = []
story.append(Spacer(1, 30*mm))
# Big title block
class CoverBlock(Flowable):
def wrap(self, aw, ah):
self._w = aw
return aw, 160
def draw(self):
c = self.canv
w = self._w
# Deep navy rectangle
c.setFillColor(NAVY)
c.roundRect(0, 0, w, 160, 12, fill=1, stroke=0)
# Red accent stripe
c.setFillColor(RED)
c.roundRect(0, 0, w, 6, 3, fill=1, stroke=0)
# Teal top stripe
c.setFillColor(TEAL)
c.roundRect(0, 154, w, 6, 3, fill=1, stroke=0)
# RA icon circles (decorative)
for i, (cx, cy, r, col) in enumerate([
(w-50, 130, 28, HexColor("#FFFFFF15")),
(w-30, 100, 40, HexColor("#FFFFFF10")),
(w-70, 90, 18, HexColor("#FFFFFF20")),
]):
c.setFillColor(col)
c.circle(cx, cy, r, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 30)
c.drawCentredString(w/2, 105, "RHEUMATOID ARTHRITIS")
c.setFont("Helvetica", 14)
c.setFillColor(HexColor("#90CAF9"))
c.drawCentredString(w/2, 82, "Complete Presenter's Script & Slide Guide")
c.setFont("Helvetica", 10)
c.setFillColor(HexColor("#B0BEC5"))
c.drawCentredString(w/2, 58, "20 Slides β’ Detailed Speaker Notes β’ Key Points β’ MCQ Answers")
c.setFont("Helvetica-Bold", 9)
c.setFillColor(GOLD)
c.drawCentredString(w/2, 36, "Prepared by Nithya | July 2026")
story.append(CoverBlock())
story.append(Spacer(1, 10*mm))
# Info cards row
cards = [
(TEAL, "20", "Slides"),
(RED, "~30", "Minutes"),
(GREEN, "3", "MCQs"),
(PURPLE_MID, "6", "Systems"),
]
card_w = (W - 2*cm - 3*8) / 4
card_data = []
for bg, num, label in cards:
class Card(Flowable):
def __init__(self, bg, num, label, w):
super().__init__()
self._bg = bg; self._num = num; self._label = label; self._w = w
def wrap(self, aw, ah): return self._w, 50
def draw(self):
c = self.canv
c.setFillColor(self._bg)
c.roundRect(0, 0, self._w, 50, 6, fill=1, stroke=0)
c.setFillColor(white)
c.setFont("Helvetica-Bold", 20)
c.drawCentredString(self._w/2, 28, self._num)
c.setFont("Helvetica", 8)
c.drawCentredString(self._w/2, 14, self._label.upper())
card_data.append(Card(bg, num, label, card_w))
tbl = Table([[card_data[0], card_data[1], card_data[2], card_data[3]]],
colWidths=[card_w]*4, rowHeights=[50])
tbl.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
]))
story.append(tbl)
story.append(Spacer(1, 8*mm))
# How to use this guide
story.append(Paragraph("HOW TO USE THIS GUIDE", S("h",
fontSize=10, fontName="Helvetica-Bold", textColor=NAVY,
spaceBefore=4, spaceAfter=4)))
story.append(HRFlowable(width="100%", thickness=1.5, color=TEAL, spaceAfter=6))
instructions = [
"<b>SAY boxes (blue)</b> β your exact spoken script for each slide. Read naturally; don't memorise word-for-word.",
"<b>KEY POINTS boxes (green)</b> β the 3-5 things the audience must take away from each slide.",
"<b>PRESENTER TIPS boxes (amber)</b> β body language, pacing, audience engagement suggestions.",
"<b>Tables</b> β use these to cross-reference differentials, lab values, or treatment options.",
"<b>MCQ section</b> β correct answer is highlighted green with an explanation. Pause 15 seconds before revealing.",
]
for ins in instructions:
story.append(Paragraph(f"β’ {ins}", BULLET_STYLE))
story.append(Spacer(1, 2))
story.append(Spacer(1, 6*mm))
story.append(Paragraph(
"References: Robbins & Cotran Pathological Basis of Disease (South Asian Ed.) β’ "
"Harsh Mohan Textbook of Pathology 9th Ed. β’ American College of Rheumatology (ACR) 2010 Criteria",
FOOTER_STYLE))
story.append(PageBreak())
return story
# βββ Helper builders ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
PW = W - 2*cm # usable page width
def slide_section(slide_num, title, accent, script_lines, key_points=None,
tips=None, tables=None, extra_paras=None):
"""Build all flowables for one slide section."""
story = []
story.append(SlideHeader(slide_num, title, accent))
story.append(Spacer(1, 4))
# Script
for line in script_lines:
if line.startswith("##"):
story.append(Spacer(1, 4))
story.append(Paragraph(line[2:].strip(), HEADING2))
elif line.startswith('"') or line.startswith('>'):
txt = line.lstrip('>"').rstrip('"')
story.append(Spacer(1, 3))
story.append(SpeakerBubble(txt, PW))
story.append(Spacer(1, 3))
elif line.startswith("MNEMONIC:"):
story.append(Spacer(1, 3))
story.append(Paragraph(line[9:].strip(), MNEMONIC_STYLE))
story.append(Spacer(1, 3))
else:
story.append(Paragraph(line, SCRIPT_STYLE))
# Tables
if tables:
for tbl_data in tables:
story.append(Spacer(1, 5))
story.append(build_table(tbl_data))
story.append(Spacer(1, 3))
# Key points
if key_points:
story.append(Spacer(1, 5))
story.append(KeyPointsBox(key_points, PW, LIGHT_GREEN_BG, GREEN))
story.append(Spacer(1, 4))
# Tips
if tips:
for label, tip in tips:
story.append(Spacer(1, 4))
story.append(TipBox(label, tip, PW))
story.append(Spacer(1, 3))
if extra_paras:
for p in extra_paras:
story.append(p)
story.append(Spacer(1, 6))
story.append(HRFlowable(width="100%", thickness=0.5, color=GRAY_LIGHT, spaceAfter=4))
return story
def build_table(tbl_data):
"""tbl_data = {"headers": [...], "rows": [[...], ...], "col_widths": [...]}"""
headers = tbl_data["headers"]
rows = tbl_data["rows"]
col_widths = tbl_data.get("col_widths", None)
accent = tbl_data.get("accent", BLUE)
header_row = [Paragraph(h, TABLE_HEADER) for h in headers]
data = [header_row]
for row in rows:
data.append([Paragraph(str(cell), TABLE_CELL) for cell in row])
tbl = Table(data, colWidths=col_widths, repeatRows=1)
tbl.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, 0), accent),
("TEXTCOLOR", (0, 0), (-1, 0), white),
("ROWBACKGROUNDS", (0, 1), (-1, -1), [CREAM, GRAY_LIGHT]),
("GRID", (0, 0), (-1, -1), 0.4, HexColor("#BDBDBD")),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("FONTSIZE", (0, 0), (-1, -1), 9),
("TOPPADDING", (0, 0), (-1, -1), 4),
("BOTTOMPADDING", (0, 0), (-1, -1), 4),
("LEFTPADDING", (0, 0), (-1, -1), 6),
("RIGHTPADDING", (0, 0), (-1, -1), 6),
("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, GRAY_LIGHT]),
]))
return tbl
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# SLIDE CONTENT
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def all_slides():
story = []
# ββ SLIDE 1 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(1, "Title Slide", NAVY,
script_lines=[
'"Good morning / afternoon everyone. Today I\'m going to take you through Rheumatoid Arthritis β a disease that is far more than \'just joint pain.\' By the end of this session, you\'ll understand WHY it happens, HOW to recognise it, and HOW it destroys joints at the cellular level."',
"Stand confidently before speaking. Pause 3 seconds after saying your name. Introduce yourself:",
'"My name is Nithya, and this is my presentation on Rheumatoid Arthritis β a systemic autoimmune disease that I\'d like to take you through step by step."',
],
key_points=[
"State your name clearly and confidently.",
"Set expectations: 'By the end you will understand the mechanism, diagnosis, and management.'",
"DO NOT read from the screen β speak to the audience.",
],
tips=[
("BODY LANGUAGE TIP", "Face the audience. Stand to the left of the screen so you don't block the slides. Make eye contact with 3β4 different people in the room."),
("OPENER TIP", "Starting with confidence on Slide 1 sets the tone. Don't rush β a 3-second pause after introduction commands attention."),
]
)
# ββ SLIDE 2 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(2, "Case Scenario", TEAL,
script_lines=[
'"Let\'s begin with a real patient. Because in medicine, everything starts with the patient in front of you."',
"Read the case aloud, then PAUSE and ask the audience:",
'"Before I tell you the diagnosis β I want you to think. You have 15 seconds. What is the most likely diagnosis and what three clinical clues are pointing you there?"',
"After the pause:",
'"Three things should catch your eye: symmetrical joint involvement, morning stiffness lasting MORE than one hour, and β critically β the DIP joints are SPARED. Keep those in mind."',
],
key_points=[
"Female, 45 years old β classic RA demographic (2β3x more common in women).",
"Morning stiffness >1 hour = inflammatory arthritis (OA stiffness is <30 mins).",
"DIP sparing distinguishes RA from osteoarthritis and psoriatic arthritis.",
"Positive RF + strongly positive anti-CCP = near-diagnostic for RA.",
"Difficulty with fine motor tasks (buttons, jars) = grip strength loss from MCP/PIP involvement.",
],
tips=[
("ENGAGEMENT TIP", "Ask for a show of hands: 'Who thinks this is Rheumatoid Arthritis? Who thinks Psoriatic? Who thinks OA?' Getting hands up immediately activates the room."),
("PAUSE TIP", "Silence after a question feels long to the speaker but is normal for the audience. Count to 10 silently before moving on."),
]
)
# ββ SLIDE 3 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(3, "Differential Diagnosis", RED,
script_lines=[
'"Now, before we confirm the diagnosis, let\'s think critically β what else could look like this?"',
],
tables=[{
"headers": ["Condition", "Key Distinguishing Feature from RA"],
"accent": RED,
"col_widths": [120, 340],
"rows": [
["Osteoarthritis", "DIP joints INVOLVED; no morning stiffness >1hr; no RF; Heberden's/Bouchard's nodes; osteophytes on X-ray"],
["Psoriatic Arthritis", "DIP involvement; sausage digits (dactylitis); skin plaques; nail pitting; seronegative"],
["SLE Arthritis", "Non-erosive (Jaccoud arthropathy); positive ANA/anti-dsDNA; malar rash; renal involvement"],
["Gout", "Males >40; acute monoarthritis; urate crystals in synovial fluid; hyperuricemia; tophi"],
["Pseudogout", "Elderly; calcium pyrophosphate crystals; knee/wrist; chondrocalcinosis on X-ray"],
["Viral Arthritis", "Acute onset; self-limiting; post-viral (parvovirus B19, rubella, hep B); no erosions"],
["Reactive Arthritis", "Post-infection (GI/STI); asymmetrical; 'can't see, can't pee, can't climb a tree'"],
]
}],
key_points=[
"Always exclude septic arthritis first β it is a medical emergency (fever + monoarthritis + WBC >50,000 in fluid).",
"The symmetry + DIP sparing + autoantibodies + chronicity = RA until proven otherwise.",
],
tips=[
("EXAM TIP", "Differential diagnosis slides are gold in viva exams. Mention at least 3 alternatives and state clearly why RA fits best. Examiners love this clinical reasoning approach."),
]
)
# ββ SLIDE 4 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(4, "Definition", BLUE,
script_lines=[
'"Rheumatoid Arthritis is a chronic inflammatory disorder of autoimmune origin. And I want you to memorise five key words from this definition."',
"Break the definition down word by word:",
'"CHRONIC β this lasts months to years. Not days. INFLAMMATORY β heat, redness, swelling, pain. AUTOIMMUNE β the body attacks itself. NONSUPPURATIVE β there is NO pus, unlike septic arthritis. SYNOVITIS β the synovial membrane is the primary battleground."',
'"Think of RA as the immune system declaring war on the synovium β and unless we intervene, the synovium eventually wins, destroying the joint completely."',
],
key_points=[
"Chronic + Inflammatory + Autoimmune + Nonsuppurative + Synovitis = the 5-word RA definition.",
"RA is primarily a joint disease but is SYSTEMIC β skin, lungs, heart, vessels are all involved.",
"The synovium is the lining of joints β thickening and inflaming it drives all downstream damage.",
],
tips=[
("DEFINITION TIP", "When defining a disease, break it into components. This shows depth of understanding and gives you 5 mini-talking-points from a single sentence."),
]
)
# ββ SLIDE 5 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(5, "Epidemiology", GREEN,
script_lines=[
'"Who gets Rheumatoid Arthritis? Let\'s look at the numbers."',
'"RA affects 0.5 to 1 percent of adults worldwide. That sounds small β but that is millions of people globally. It is 2 to 3 times more common in women β likely due to estrogen\'s role in immune modulation."',
'"Peak onset is 40 to 60 years of age β working-age adults. This creates an enormous socioeconomic burden: lost productivity, disability benefits, and lifelong treatment costs."',
'"Without treatment, RA can progress to complete bony ankylosis β joint fusion. A person opening jars at 40 could have completely fused, immobile wrists by 60."',
],
key_points=[
"Prevalence: 0.5β1% worldwide. More common in developed countries and certain Indigenous populations.",
"Female:Male ratio = 2β3:1 (hormonal influence β estrogen promotes immune activation).",
"Onset: 40β60 years, but juvenile RA (JIA) also exists.",
"Extra-articular lesions can involve skin, heart, blood vessels, and lungs.",
"Untreated RA reduces life expectancy by up to 10 years β primarily from cardiovascular disease.",
],
tips=[
("ENGAGEMENT TIP", "Ask the audience: 'Why do you think women are more affected? What hormone connects to immune overactivation?' This creates a 30-second discussion."),
("MEMORABLE FACT TIP", "Giving a 'before and after' story (opening jars at 40 β fused wrists at 60) makes the severity of untreated RA stick in memory."),
]
)
# ββ SLIDE 6 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(6, "Etiopathogenesis", PURPLE_MID,
script_lines=[
'"RA doesn\'t have a single cause. It is a perfect storm of three converging factors."',
"##1. Genetic Factors",
'"The strongest genetic link is HLA-DRB1 β specifically HLA-DR4. These molecules present citrullinated peptides to T cells, triggering the autoimmune cascade. Think of HLA as the key that unlocks the autoimmune response. Other risk genes include PTPN22, which controls T-cell signalling, and STAT4, which drives cytokine production."',
"##2. Environmental Factors",
'"Cigarette smoking is the single most important modifiable risk factor. Smoking promotes protein citrullination in the lung, which drives anti-CCP production. Here\'s something memorable: even your GUM BACTERIA play a role. Porphyromonas gingivalis from periodontal disease can citrullinate self-proteins. Flossing may literally reduce your RA risk!"',
"##3. Autoimmune Mechanisms",
'"When immune tolerance breaks down, the body produces two key autoantibodies β Rheumatoid Factor, which is an IgM against the Fc portion of IgG, and Anti-CCP β the more specific of the two. Anti-CCP can appear YEARS before joint symptoms."',
],
key_points=[
"HLA-DRB1 (DR4) = strongest genetic risk factor for RA.",
"Smoking = strongest modifiable environmental trigger; acts via protein citrullination in lungs.",
"Anti-CCP is more specific than RF β detectable years before symptoms.",
"Periodontal disease (P. gingivalis) is an emerging environmental trigger.",
],
tips=[
("MNEMONIC TIP", "Share this with the audience: 'Genes load the gun, Environment pulls the trigger, Autoimmunity fires the bullet.' This will stay with them for exams."),
]
)
# ββ SLIDE 7 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(7, "Pathogenesis Flowchart", RED_DARK,
script_lines=[
'"This is the most important slide mechanistically. I want you to trace this pathway with me β step by step β from genetics to joint destruction."',
'"STEP 1 β Genetically susceptible person meets an environmental trigger: smoking, an infection, or citrullinated proteins from P. gingivalis."',
'"STEP 2 β Proteins get CITRULLINATED. Arginine residues are enzymatically converted to citrulline. Your immune system doesn\'t recognise these altered proteins and mounts an attack."',
'"STEP 3 β Loss of tolerance. CD4+ T cells and antigen-presenting cells are activated."',
'"STEP 4 β B cells activate and produce RF and Anti-CCP antibodies."',
'"STEP 5 β These form immune complexes that deposit inside joints."',
'"STEP 6 β Macrophages and synovial fibroblasts release the cytokine storm: TNF-alpha, IL-1, IL-6, IL-17. These are the ENGINES of inflammation."',
'"STEP 7 β Chronic synovitis develops. The synovium thickens. New blood vessels form β this is angiogenesis β feeding the inflamed tissue."',
'"STEP 8 β This creates PANNUS β the most important concept in RA pathology. A vascular fibrous tissue that invades cartilage and bone."',
'"STEP 9 β Pannus destroys cartilage via matrix metalloproteinases β MMPs. It destroys bone via RANKL-activated osteoclasts."',
'"STEP 10 β End result: irreversible joint destruction, deformity, and disability."',
'"Why does TNF-alpha matter so much? Because it is the target of the most effective RA drugs β the biologic agents. Block TNF-alpha, and you interrupt this entire cascade."',
],
key_points=[
"Citrullination is the pivotal event: modified self-proteins trigger the autoimmune response.",
"TNF-Ξ±, IL-1, IL-6 = the three key pro-inflammatory cytokines driving synovitis.",
"Pannus = fibrovascular granulation tissue; the direct destroyer of cartilage and bone.",
"MMPs degrade cartilage matrix; RANKL activates osteoclasts to erode bone.",
"Biologic drugs (anti-TNF, anti-IL-6) interrupt the cascade at the cytokine level.",
],
tips=[
("LASER POINTER TIP", "Use your laser pointer on this flowchart β trace each arrow as you speak. This keeps the audience visually anchored to your words."),
("SPEED TIP", "This slide deserves 4β5 minutes. Don't rush it. It is the intellectual heart of the presentation."),
]
)
# ββ SLIDE 8 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(8, "Pathology Image (Gross/Diagram)", GRAY_MID,
script_lines=[
'"Take a moment to look at this image."',
"(Pause 5 seconds β let the audience absorb the visual.)",
'"What you\'re seeing here is the synovium at the gross level β the thickening, the villous projections, the invasion of pannus over the articular cartilage. This is what the pathologist or surgeon sees when they open a RA joint."',
"Point to specific areas on the image if possible:",
'"Notice the dull, roughened cartilage β compare that to normal cartilage which should be smooth, white, and glistening. That roughness tells you pannus has been at work."',
],
key_points=[
"Image slides are anchor points β let the audience look before you speak.",
"Connect gross appearance to mechanism: thickening = hyperplasia; roughness = pannus erosion.",
],
tips=[
("IMAGE SLIDE TIP", "Never just stand silently next to an image. Narrate what you see β use anatomical language. This shows clinical maturity."),
]
)
# ββ SLIDE 9 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(9, "Clinical Manifestations β Articular", TEAL,
script_lines=[
'"Now we move to the patient at the bedside. Clinically, RA is primarily a joint disease β but the pattern of joint involvement is everything."',
'"SYMMETRICAL β if the left MCP joints are inflamed, so are the right. This is cardinal and distinguishes RA from most other arthritides."',
'"MORNING STIFFNESS for more than one hour. This is duration-dependent and reflects the degree of synovial inflammation. The stiffness improves with movement. In osteoarthritis, stiffness is brief β under 30 minutes β and worsens with use."',
'"Joints involved: MCPs, PIPs, wrists, MTP joints, knees, ankles, shoulders. The DIP JOINTS ARE SPARED β this is a HIGH YIELD EXAM POINT."',
],
tables=[{
"headers": ["Deformity", "Description", "Joints Involved"],
"accent": TEAL,
"col_widths": [100, 250, 110],
"rows": [
["Boutonniere", "PIP flexion + DIP hyperextension", "PIP + DIP"],
["Swan-neck", "PIP hyperextension + DIP flexion", "PIP + DIP"],
["Z-deformity", "Thumb: MCP flexion + IP hyperextension", "Thumb MCP + IP"],
["Ulnar deviation", "Fingers deviate ulnarward at MCPs", "MCP joints"],
["Piano key sign", "Ulnar styloid bounces up/down", "Distal radio-ulnar joint"],
]
}],
key_points=[
"Symmetrical small joint polyarthritis is the hallmark of RA.",
"Morning stiffness >1 hour = inflammatory (RA/SLE); <30 min = degenerative (OA).",
"DIP sparing is a key differentiator from OA and psoriatic arthritis.",
"Deformities (swan-neck, boutonniere) indicate longstanding, destructive disease.",
"Test grip strength β inability to open jars/buttons = MCP/PIP involvement.",
],
tips=[
("CLINICAL PEARL", "Always examine grip strength at the bedside. Ask the patient to squeeze two of your fingers. Weak grip = active synovitis at MCPs."),
]
)
# ββ SLIDE 10 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(10, "Extra-Synovial Manifestations", RED,
script_lines=[
'"This slide is where RA reveals itself as a SYSTEMIC disease, not just a joint disease."',
],
tables=[{
"headers": ["System", "Manifestation", "Key Point"],
"accent": RED,
"col_widths": [90, 190, 178],
"rows": [
["Skin", "Rheumatoid nodules", "Firm, nontender, subcutaneous; central fibrinoid necrosis + palisading macrophages; near bony prominences"],
["Eyes", "Keratoconjunctivitis sicca, scleritis, episcleritis", "Red painful eye = emergency; Sjogren's overlap common"],
["Lungs", "Pleuritis, interstitial fibrosis, Caplan syndrome", "ILD = common cause of death in RA"],
["Heart", "Pericarditis, myocarditis, accelerated atherosclerosis", "#1 cause of premature death in RA"],
["Vasculitis", "Skin ulcers, mononeuritis multiplex", "Digital infarcts, livedo reticularis"],
["Blood", "Anaemia of chronic disease, Felty's syndrome", "Normocytic normochromic; Felty = RA + splenomegaly + neutropenia"],
["Constitutional", "Fatigue, low-grade fever, weight loss", "Often precede joint symptoms by months"],
]
}],
key_points=[
"Rheumatoid nodules = central fibrinoid necrosis + palisading macrophages = pathognomonic histology.",
"Cardiovascular disease = #1 cause of premature death in RA patients.",
"ILD (interstitial lung disease) = second leading cause of RA-related death.",
"Felty syndrome = RA + splenomegaly + neutropenia β risk of serious infection.",
],
tips=[
("IMPACT STATEMENT TIP", "Say this aloud: 'Untreated RA can shorten life expectancy by up to 10 years, primarily through cardiovascular disease. This is why we treat aggressively.' This lands powerfully with the audience."),
]
)
# ββ SLIDE 11 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(11, "Gross Pathological Features", GRAY_DARK,
script_lines=[
'"Let\'s shift to pathology β what does the surgeon or pathologist actually see when they open this joint?"',
'"The synovial membrane is THICKENED and OPAQUE, with a dull grey-red appearance. Normal synovium is thin and glistening. This thickening is due to synovial cell hyperplasia."',
'"The surface is VILLOUS β covered in finger-like projections, dramatically increasing the surface area for inflammation."',
'"The joint contains excess TURBID, YELLOWISH fluid. Normal synovial fluid is clear and straw-coloured. Turbidity = inflammatory exudate."',
'"The articular cartilage is DULL, ROUGHENED, and ERODED β it has lost the smooth, white, hyaline appearance of healthy cartilage."',
'"And then there is PANNUS β a mass of oedematous synovium, inflammatory cells, granulation tissue, and fibroblasts that physically grows OVER the articular cartilage like an invasive tissue. This is the gross hallmark of RA."',
'"In the end stage, pannus bridges the opposing bones. First as FIBROUS ANKYLOSIS, then as BONY ANKYLOSIS β complete fusion. The joint is literally locked in place."',
],
key_points=[
"Pannus = thickened vascular synovium that physically invades and covers articular cartilage.",
"Turbid yellow joint fluid = inflammatory (vs. clear normal; vs. hemorrhagic in trauma).",
"Fibrous β bony ankylosis = end-stage RA with complete loss of joint movement.",
],
tips=[
("ANALOGY TIP", "Use this analogy: 'Pannus is like biological rust β it spreads across the joint surface, destroying everything it contacts, and once it has set, it cannot be reversed without treatment.'"),
]
)
# ββ SLIDE 12 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(12, "Microscopic Features", NAVY,
script_lines=[
'"At the microscopic level, five hallmark changes define RA synovitis. Number them as I call them out."',
'"ONE β Synovial cell HYPERPLASIA. The lining layer expands from the normal 1β2 cell layers to 6β8 or more layers thick."',
'"TWO β Dense INFLAMMATORY INFILTRATE. CD4+ T cells, B cells, plasma cells, macrophages β they even form LYMPHOID FOLLICLES inside the joint. These are called tertiary lymphoid structures β essentially mini lymph nodes forming in your synovium."',
'"THREE β ANGIOGENESIS. New blood vessels form to supply the ravenous, inflamed tissue."',
'"FOUR β FIBRINOPURULENT EXUDATE on the synovial and joint surfaces."',
'"FIVE β OSTEOCLASTIC ACTIVITY. The synovium penetrates INTO the bone, creating periarticular erosions and subchondral cysts β exactly what you see on X-ray."',
'"The combination of all five produces PANNUS β a fibrovascular invasive tissue. Cartilage is destroyed. Pannus bridges the opposing bones. Fibrous ankylosis. Then ossification. BONY ANKYLOSIS."',
],
key_points=[
"Five microscopic changes: hyperplasia, inflammatory infiltrate, angiogenesis, exudate, osteoclastic erosion.",
"Lymphoid follicles inside the joint = tertiary lymphoid structures = advanced synovitis.",
"Periarticular erosions on X-ray correspond to osteoclastic activity seen microscopically.",
"Pannus = the culmination of all five microscopic changes combined.",
],
tips=[
("EXAM TIP", "In pathology exams, if asked 'what is pathognomonic of RA histology?' the answer is: pannus formation + rheumatoid nodule (central fibrinoid necrosis + palisading macrophages). Know both."),
]
)
# ββ SLIDE 13 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(13, "Histology Image", GRAY_MID,
script_lines=[
'"Look carefully at this histological section."',
"(Pause 5β8 seconds.)",
'"Identify the lymphoid follicle formation in the synovium β those dense clusters of lymphocytes. See the multilayered synovial lining? That is the hyperplasia we discussed. And notice the vascular proliferation β the angiogenesis feeding this inflamed tissue."',
'"This is what pannus looks like under the microscope. This is the cellular machinery destroying the joint."',
],
key_points=[
"Always narrate histology images β don't stand silently.",
"Point out: synovial lining thickness, lymphoid follicles, vascular channels, osteoclasts at bone margin.",
],
tips=[
("HISTOLOGY TIP", "If you're unsure about a detail in the image, say: 'I'll focus on the key features here.' Never guess. Stick to what you know."),
]
)
# ββ SLIDE 14 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(14, "Laboratory Findings", GREEN_DARK,
script_lines=[
'"The lab picture in RA combines inflammation markers, autoantibodies, and synovial fluid analysis. Let me take you through each category."',
],
tables=[
{
"headers": ["Test", "Finding in RA", "Clinical Significance"],
"accent": GREEN_DARK,
"col_widths": [110, 110, 240],
"rows": [
["ESR", "Elevated (>30 mm/hr)", "Tracks disease activity; normalises with treatment"],
["CRP", "Elevated", "More sensitive acute-phase reactant than ESR"],
["FBC / CBC", "Normocytic normochromic anaemia", "Anaemia of chronic disease; cytokine-mediated EPO suppression"],
["Rheumatoid Factor (RF)", "Positive (~70β80% of RA)", "IgM against Fc of IgG; not specific β positive in SLE, Sjogren's, infections"],
["Anti-CCP", "Positive; high specificity (>95%)", "Can be positive YEARS before symptoms; best early marker"],
["ANA", "Low-positive", "Weaker than SLE; helps with overlap syndromes"],
["C3/C4 Complement", "Low in active disease", "Immune complex consumption"],
]
},
{
"headers": ["Synovial Fluid Finding", "Value in RA"],
"accent": TEAL,
"col_widths": [180, 280],
"rows": [
["Colour/clarity", "Yellow, turbid (inflammatory)"],
["WBC count", "5,000β50,000/mmΒ³ (predominantly neutrophils)"],
["Crystals", "ABSENT β rules out gout (urate) and pseudogout (CPPD)"],
["Culture", "Sterile β rules out septic arthritis"],
["Viscosity", "Decreased (inflammatory protease degradation of hyaluronate)"],
]
}
],
key_points=[
"Anti-CCP is the most specific RA autoantibody (>95% specificity) and can precede symptoms by years.",
"RF is sensitive (~75%) but not specific β it appears in many other conditions.",
"Synovial fluid: No crystals + sterile culture = rules out gout and septic arthritis.",
"Quick memory rule: RF + Anti-CCP + ESRβ + no crystals + sterile = Rheumatoid Arthritis.",
],
tips=[
("LAB TIP", "In exams and clinical settings, if anti-CCP is strongly positive and the patient has any joint symptoms β even early β treat as RA until proven otherwise."),
]
)
# ββ SLIDE 15 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(15, "Radiological Findings", AMBER,
script_lines=[
'"Radiology gives us objective, permanent evidence of structural damage. The X-ray tells us how long this disease has been active."',
],
tables=[{
"headers": ["Stage", "X-Ray Finding", "What It Means"],
"accent": AMBER,
"col_widths": [80, 200, 180],
"rows": [
["Early", "Soft tissue swelling; periarticular osteopenia", "Hyperaemia increases osteoclast activity near joints; earliest radiological sign"],
["Intermediate", "Joint space narrowing", "Articular cartilage is being eroded by pannus"],
["Late", "Periarticular erosions (bare area); subluxation; deformity", "Bone is being invaded; ligaments and tendons failing"],
["End-stage", "Bony ankylosis; fusion", "Joint completely destroyed and fused; irreversible"],
]
}],
script_lines2=[
'"On a hand X-ray, focus on the MCP and PIP joints first. Look for the classic triad: joint space narrowing, periarticular erosions at the bare area, and juxta-articular osteopenia."',
'"MRI detects EARLIER changes than X-ray β bone marrow oedema appears before erosions are visible on plain films. Ultrasound with power Doppler shows active blood flow into the pannus in real time."',
],
key_points=[
"Periarticular osteopenia = earliest X-ray sign of RA (hyperaemia drives local bone loss).",
"Erosions appear at the 'bare area' of the joint β where pannus first contacts bone.",
"MRI > X-ray for early detection; ultrasound + Doppler shows active synovitis.",
"Atlantoaxial subluxation on cervical X-ray = CRITICAL finding β must screen before GA/intubation.",
],
tips=[
("SAFETY TIP", "Highlight this for the audience: ANY RA patient going for surgery under general anaesthesia MUST have a cervical spine X-ray. Atlantoaxial subluxation can cause spinal cord injury during intubation."),
]
)
# ββ SLIDE 16 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(16, "Diagnostic Criteria β 2010 ACR/EULAR", BLUE,
script_lines=[
'"How do we formally diagnose RA? We use the 2010 ACR/EULAR Classification Criteria. Score out of 10 points β 6 or more = definite Rheumatoid Arthritis."',
],
tables=[{
"headers": ["Domain", "Finding", "Points"],
"accent": BLUE,
"col_widths": [120, 260, 80],
"rows": [
["Joint involvement", "1 large joint", "0"],
["", "2β10 large joints", "1"],
["", "1β3 small joints", "2"],
["", "4β10 small joints", "3"],
["", ">10 joints (including small)", "5"],
["Serology", "Negative RF and anti-CCP", "0"],
["", "Low positive RF or anti-CCP", "2"],
["", "High positive RF or anti-CCP", "3"],
["Acute phase reactants", "Normal ESR and CRP", "0"],
["", "Abnormal ESR or CRP", "1"],
["Symptom duration", "<6 weeks", "0"],
["", "β₯6 weeks", "1"],
["", "TOTAL NEEDED FOR DIAGNOSIS β", "β₯ 6 / 10"],
]
}],
script_lines2=[
'"Now apply this to our case: multiple small joints bilaterally (5 pts) + high positive anti-CCP (3 pts) + elevated ESR and CRP (1 pt) + 8 months duration (1 pt) = 10 out of 10 points. DEFINITE RHEUMATOID ARTHRITIS."',
],
key_points=[
"Score β₯6/10 = definite RA by 2010 ACR/EULAR criteria.",
"The case scenario scores 10/10 β a textbook-perfect presentation.",
"'Small joints' = MCPs, PIPs, MTPs, IP thumb, wrist.",
"High positive = >3x upper limit of normal for RF or anti-CCP.",
],
tips=[
("STRUCTURE TIP", "Applying the criteria to your case scenario closes the diagnostic loop beautifully. The audience will see how clinical presentation connects to formal diagnosis."),
]
)
# ββ SLIDE 17 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(17, "Treatment", GREEN,
script_lines=[
'"Treatment of RA follows a TREAT-TO-TARGET strategy. The goal is remission or low disease activity. The mantra is: start EARLY, treat AGGRESSIVELY."',
],
tables=[
{
"headers": ["Drug Class", "Examples", "Mechanism", "Notes"],
"accent": GREEN,
"col_widths": [95, 115, 130, 118],
"rows": [
["Conventional DMARDs", "Methotrexate (MTX)", "Folate antagonist β reduces cytokine production", "ANCHOR drug; always supplement folic acid; monitor LFTs"],
["", "Hydroxychloroquine", "Inhibits TLR signalling; anti-inflammatory", "Mildest; eye checks needed (retinal toxicity)"],
["", "Sulfasalazine", "Inhibits NF-ΞΊB; anti-inflammatory", "Used in combination (triple therapy)"],
["", "Leflunomide", "Pyrimidine synthesis inhibitor", "Alternative to MTX; teratogenic"],
["Biologics β TNF-Ξ± inhibitors", "Etanercept, Infliximab, Adalimumab", "Block TNF-Ξ± (soluble or receptor-mediated)", "Screen for TB and HBV before starting; risk of infections"],
["Biologics β IL-6 inhibitors", "Tocilizumab, Sarilumab", "Block IL-6 receptor", "Used when TNF-inhibitors fail"],
["Biologics β B cell depletion", "Rituximab", "Anti-CD20 β depletes B cells", "Used in RF/anti-CCP+ patients"],
["Biologics β T cell costimulation", "Abatacept", "Blocks CD28-CD80/86 costimulation", "Preferred in patients with lung disease"],
["JAK Inhibitors (targeted synthetic DMARDs)", "Tofacitinib, Baricitinib, Upadacitinib", "Block JAK1/2/3 β inhibit STAT signalling", "Oral; check for VTE risk, cardiovascular risk before use"],
["Corticosteroids", "Prednisolone", "Broad anti-inflammatory", "Short-term bridging only; not long-term due to bone loss, DM, HTN"],
["NSAIDs", "Naproxen, Diclofenac", "COX inhibition β prostaglandin reduction", "Symptom control only; no disease modification; GI risk"],
]
}
],
script_lines2=[
'"The reason anti-CCP matters clinically: a patient who is strongly positive should be started on Methotrexate IMMEDIATELY β even before meeting full diagnostic criteria. Joint damage can begin BEFORE symptoms appear."',
'"Physical therapy and occupational therapy are equally important. Hand exercises, splinting, and joint protection are part of every RA treatment plan."',
],
key_points=[
"Methotrexate is the anchor drug β first-line for almost all RA patients.",
"Treat-to-target: aim for DAS28 remission (<2.6) or low disease activity (<3.2).",
"If DMARDs fail at 3β6 months, escalate to biologic or JAK inhibitor.",
"Screen for TB, Hepatitis B, and infections BEFORE starting biologics.",
"JAK inhibitors are oral β easier than injectable biologics, but cardiovascular screening needed.",
],
tips=[
("CLINICAL INSIGHT TIP", "The biologic revolution transformed RA. Before biologics (pre-1998), many patients ended up in wheelchairs. Today, with early MTX + biologic, many achieve remission and lead normal lives."),
]
)
# ββ SLIDE 18 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story += slide_section(18, "Complications", RED_DARK,
script_lines=[
'"Untreated or poorly controlled RA leads to serious, multi-system complications."',
],
tables=[{
"headers": ["System", "Complication", "Key Point"],
"accent": RED_DARK,
"col_widths": [100, 180, 178],
"rows": [
["Musculoskeletal", "Joint deformity, bony ankylosis, functional disability", "Irreversible if untreated; major quality-of-life impact"],
["Cervical spine", "Atlantoaxial subluxation (C1-C2)", "CRITICAL β can compress spinal cord; mandatory pre-operative X-ray"],
["Cardiovascular", "Accelerated atherosclerosis, pericarditis, myocarditis", "#1 cause of premature death; inflammation = endothelial damage"],
["Respiratory", "ILD, pleuritis, Caplan syndrome (RA + pneumoconiosis)", "Common cause of death; monitor with PFTs"],
["Haematological", "Felty syndrome (RA + splenomegaly + neutropenia)", "Risk of life-threatening infections; lymphoma risk elevated"],
["Neurological", "Carpal tunnel syndrome (median nerve); mononeuritis multiplex", "From synovial compression or vasculitis"],
["Iatrogenic", "Infections (biologics), GI bleed (NSAIDs), osteoporosis (steroids)", "Drug-related complications equal the disease burden"],
["Malignancy", "Lymphoma (especially DLBCL)", "Chronic immune activation drives B-cell proliferation"],
]
}],
key_points=[
"Atlantoaxial subluxation is life-threatening β must screen with X-ray before any GA/intubation.",
"CV disease (not joint disease) is the #1 killer in RA.",
"Felty syndrome = RA + splenomegaly + neutropenia β triad to memorise.",
"Biologics dramatically reduce joint complications but increase infection risk.",
],
tips=[
("HIGH-YIELD TIP", "For exams: Felty's triad, atlantoaxial subluxation, and ILD are three 'must-know' RA complications that frequently appear in short-answer and OSCE stations."),
]
)
# ββ SLIDE 19 β MCQs βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SlideHeader(19, "MCQ Assessment", PURPLE_MID, total=20))
story.append(Spacer(1, 6))
story.append(Paragraph(
"Read each question aloud. Allow 15β20 seconds for the audience to think. Then reveal the answer and explain. "
"Correct answers are highlighted in <b>green</b>.",
SCRIPT_STYLE))
story.append(Spacer(1, 8))
story.append(MCQBox(
qnum=1,
question="The most characteristic pathological lesion responsible for joint destruction in Rheumatoid Arthritis is:",
options=["Tophus", "Pannus", "Heberden's nodes", "Osteophyte"],
answer_idx=1,
answer_text="PANNUS is the fibrovascular granulation tissue that physically invades and destroys articular cartilage and subchondral bone in RA. A Tophus is the urate crystal deposit in gout. Heberden's nodes and Osteophytes are features of osteoarthritis.",
width=PW
))
story.append(Spacer(1, 10))
story.append(MCQBox(
qnum=2,
question="Which autoantibody is the most specific marker for Rheumatoid Arthritis?",
options=["Antinuclear antibody (ANA)", "Rheumatoid factor (RF)", "Anti-cyclic citrullinated peptide (Anti-CCP) antibody", "Anti-dsDNA antibody"],
answer_idx=2,
answer_text="Anti-CCP has >95% specificity for RA and can be detected years before symptoms. RF is sensitive (~75%) but not specific β it appears in SLE, Sjogren's, chronic infections. ANA is a broad marker. Anti-dsDNA is specific to SLE.",
width=PW
))
story.append(Spacer(1, 10))
story.append(MCQBox(
qnum=3,
question="The genetic marker most strongly associated with Rheumatoid Arthritis is:",
options=["HLA-B27", "HLA-DR4 (HLA-DRB1)", "HLA-A3", "HLA-B8"],
answer_idx=1,
answer_text="HLA-DR4 (part of the HLA-DRB1 allele group) is the strongest genetic association with RA β it presents citrullinated peptides to CD4+ T cells. HLA-B27 = Ankylosing Spondylitis. HLA-DR3 = Primary Sjogren's / SLE. HLA-B8 = Myasthenia Gravis.",
width=PW
))
story.append(Spacer(1, 8))
story.append(HRFlowable(width="100%", thickness=0.5, color=GRAY_LIGHT, spaceAfter=4))
# ββ SLIDE 20 β Thank You ββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(Spacer(1, 4))
story += slide_section(20, "Thank You & Summary", NAVY,
script_lines=[
'"Before I close, let me give you the one-minute summary of everything we covered today."',
'"Rheumatoid Arthritis is a chronic autoimmune synovitis driven by genetic susceptibility β especially HLA-DR4 β combined with environmental triggers like cigarette smoking. The key autoantibodies are RF and Anti-CCP, with Anti-CCP being the more specific. The defining pathological lesion is PANNUS β a fibrovascular tissue that destroys cartilage via MMPs and bone via RANKL-activated osteoclasts."',
'"Clinically: symmetrical small joint polyarthritis with morning stiffness over one hour, sparing of DIP joints, and extra-articular features including rheumatoid nodules, ILD, and cardiovascular disease."',
'"The 2010 ACR/EULAR criteria gives us a formal score. Treatment is treat-to-target with Methotrexate as the anchor, escalating to biologics β especially anti-TNF agents β if needed."',
'"Thank you all for your attention. I\'m happy to take any questions."',
],
key_points=[
"RA = chronic autoimmune synovitis β pannus β cartilage and bone destruction.",
"Key autoantibody: Anti-CCP (most specific, detectable years before symptoms).",
"Key gene: HLA-DR4. Key trigger: Cigarette smoking.",
"DIP sparing + morning stiffness >1hr + symmetry = clinical hallmarks.",
"Treatment: MTX first, then biologics (anti-TNF). Treat-to-target strategy.",
],
tips=[
("CLOSING TIP", "End with an open invitation: 'Does anyone want to attempt one more clinical scenario or has a question about anything we covered?' This signals confidence and invites engagement."),
("REFERENCES", "Robbins & Cotran Pathological Basis of Disease (South Asian Ed.) | Harsh Mohan Textbook of Pathology, 9th Ed. | ACR/EULAR 2010 Classification Criteria for RA."),
]
)
return story
# Patch for slide 15 which has two script_lines args
def slide_section(slide_num, title, accent, script_lines, key_points=None,
tips=None, tables=None, extra_paras=None, script_lines2=None):
story = []
story.append(SlideHeader(slide_num, title, accent))
story.append(Spacer(1, 4))
def render_lines(lines):
for line in lines:
if line.startswith("##"):
story.append(Spacer(1, 4))
story.append(Paragraph(line[2:].strip(), HEADING2))
elif line.startswith('"') or line.startswith('>'):
txt = line.lstrip('>"').rstrip('"')
story.append(Spacer(1, 3))
story.append(SpeakerBubble(txt, PW))
story.append(Spacer(1, 3))
elif line.startswith("MNEMONIC:"):
story.append(Spacer(1, 3))
story.append(Paragraph(line[9:].strip(), MNEMONIC_STYLE))
story.append(Spacer(1, 3))
else:
story.append(Paragraph(line, SCRIPT_STYLE))
render_lines(script_lines)
if tables:
for tbl_data in tables:
story.append(Spacer(1, 5))
story.append(build_table(tbl_data))
story.append(Spacer(1, 3))
if script_lines2:
render_lines(script_lines2)
if key_points:
story.append(Spacer(1, 5))
story.append(KeyPointsBox(key_points, PW, LIGHT_GREEN_BG, GREEN))
story.append(Spacer(1, 4))
if tips:
for label, tip in tips:
story.append(Spacer(1, 4))
story.append(TipBox(label, tip, PW))
story.append(Spacer(1, 3))
if extra_paras:
for p in extra_paras:
story.append(p)
story.append(Spacer(1, 6))
story.append(HRFlowable(width="100%", thickness=0.5, color=GRAY_LIGHT, spaceAfter=4))
return story
# βββ Build PDF ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def build():
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=1*cm, rightMargin=1*cm,
topMargin=1.2*cm, bottomMargin=1.5*cm,
title="Rheumatoid Arthritis β Presenter's Guide",
author="Nithya",
subject="Rheumatoid Arthritis Presentation Script",
creator="Orris AI"
)
story = cover_page() + all_slides()
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF saved: {OUTPUT_PATH}")
if __name__ == "__main__":
build()
cd /tmp/workspace/ra-presentation-guide && python3 build_pdf.py 2>&1
ls -lh /tmp/workspace/ra-presentation-guide/RA_Presentation_Guide.pdf
RA Presentation Guide
PDF Document Β· PDF
| Element | What it does |
|---|---|
| Slide Header with progress bar | Shows slide number, title, and how far through the deck you are |
| SAY boxes (blue speech bubbles) | Your exact spoken script β word-for-word what to say |
| KEY POINTS boxes (green, numbered) | 3β5 take-away facts the audience must remember |
| PRESENTER TIPS boxes (amber) | Body language, pacing, engagement, and safety tips |
| Tables | Differentials, lab values, treatment ladder, deformities, staging |
| MCQ boxes | Correct answer highlighted green with a full explanation |