Heyy so.. im 3rd yr mbbs student and I have am presently studying psm ... Soo I'm studying the lesson communicable diseases epidemiology.. we actually have to answer questions for exam in a order like for each disease we have to write epidemiology, clinical features, treatment, prevention, complications.. so can u like give me a proforma that I can use for all the questions
| What examiners love | What to always include |
|---|---|
| Case definition (WHO) | Always mention incubation period |
| Vaccine details (type, schedule, efficacy) | Notifiable status |
| Gold standard of diagnosis | Period of communicability |
| National Program name | Herd immunity threshold (if vaccine-preventable) |
| 5 levels of prevention | Epidemic investigation steps for outbreak Q |
Create a quick reference PDF of this proforma for offline access
ls /home/daytona/workspace/ 2>/dev/null && mkdir -p /home/daytona/workspace/psm-…
~/psm-proforma/create_proforma.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
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
# ── Output path ──────────────────────────────────────────────────────────────
OUTPUT = "/home/daytona/workspace/psm-proforma/PSM_Communicable_Disease_Proforma.pdf"
# ── Colour palette ────────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1A3A5C")
MED_BLUE = colors.HexColor("#2E6DA4")
LIGHT_BLUE = colors.HexColor("#D6E8F7")
ACCENT = colors.HexColor("#E8A020")
LIGHT_GREY = colors.HexColor("#F4F6F9")
MID_GREY = colors.HexColor("#7F8C9A")
WHITE = colors.white
GREEN_DARK = colors.HexColor("#1B6B3A")
GREEN_LIGHT = colors.HexColor("#D4EDDA")
RED_DARK = colors.HexColor("#8B1A1A")
RED_LIGHT = colors.HexColor("#FAE0E0")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=1.5*cm, bottomMargin=1.5*cm,
title="PSM Communicable Disease Proforma",
author="Orris Medical Assistant"
)
W, H = A4
CONTENT_W = W - 3.6*cm
styles = getSampleStyleSheet()
# ── Custom styles ─────────────────────────────────────────────────────────────
def S(name, **kw):
return ParagraphStyle(name, **kw)
sTitle = S("sTitle",
fontName="Helvetica-Bold", fontSize=20,
textColor=WHITE, alignment=TA_CENTER, leading=26, spaceAfter=4)
sSubtitle = S("sSubtitle",
fontName="Helvetica", fontSize=11,
textColor=LIGHT_BLUE, alignment=TA_CENTER, leading=14)
sSectionNum = S("sSectionNum",
fontName="Helvetica-Bold", fontSize=13,
textColor=WHITE, alignment=TA_LEFT, leading=17)
sSubHead = S("sSubHead",
fontName="Helvetica-Bold", fontSize=10.5,
textColor=DARK_BLUE, alignment=TA_LEFT, leading=14, spaceAfter=2)
sBullet = S("sBullet",
fontName="Helvetica", fontSize=9.5,
textColor=colors.HexColor("#222222"),
leftIndent=10, leading=13,
alignment=TA_LEFT)
sBold = S("sBold",
fontName="Helvetica-Bold", fontSize=9.5,
textColor=colors.HexColor("#222222"),
leftIndent=10, leading=13)
sNote = S("sNote",
fontName="Helvetica-Oblique", fontSize=8.5,
textColor=MID_GREY, alignment=TA_LEFT, leading=12)
sTipHead = S("sTipHead",
fontName="Helvetica-Bold", fontSize=10,
textColor=GREEN_DARK, leading=14)
sTipBody = S("sTipBody",
fontName="Helvetica", fontSize=9,
textColor=colors.HexColor("#1B3A27"), leading=13)
story = []
# ═══════════════════════════════════════════════════════════════════════════════
# HEADER BANNER
# ═══════════════════════════════════════════════════════════════════════════════
header_data = [[
Paragraph("COMMUNICABLE DISEASE EPIDEMIOLOGY", sTitle),
]]
header_table = Table(header_data, colWidths=[CONTENT_W])
header_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
("ROUNDEDCORNERS", (0,0), (-1,-1), [6,6,0,0]),
]))
story.append(header_table)
sub_data = [[Paragraph("Quick Reference Proforma | 3rd Year MBBS | PSM / Community Medicine", sSubtitle)]]
sub_table = Table(sub_data, colWidths=[CONTENT_W])
sub_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MED_BLUE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
("ROUNDEDCORNERS", (0,0), (-1,-1), [0,0,6,6]),
]))
story.append(sub_table)
story.append(Spacer(1, 0.35*cm))
# ── Helper: section header ─────────────────────────────────────────────────────
def section_header(num, title):
data = [[
Paragraph(f"{num}.", S(f"sn{num}", fontName="Helvetica-Bold", fontSize=15,
textColor=ACCENT, alignment=TA_CENTER, leading=18)),
Paragraph(title, S(f"sh{num}", fontName="Helvetica-Bold", fontSize=13,
textColor=WHITE, alignment=TA_LEFT, leading=18)),
]]
t = Table(data, colWidths=[1.1*cm, CONTENT_W - 1.1*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (0,0), 8),
("LEFTPADDING", (1,0), (1,0), 4),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS",(0,0), (-1,-1), [5,5,5,5]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
return t
# ── Helper: sub-section block ──────────────────────────────────────────────────
def sub_section(title, items, bg=LIGHT_GREY):
"""items = list of (label, text) or plain strings"""
rows = [[Paragraph(title, sSubHead)]]
for item in items:
if isinstance(item, tuple):
label, text = item
rows.append([Paragraph(f"<b>{label}:</b> {text}", sBullet)])
else:
rows.append([Paragraph(f"• {item}", sBullet)])
t = Table(rows, colWidths=[CONTENT_W - 0.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BACKGROUND", (0,0), (0,0), LIGHT_BLUE),
("TOPPADDING", (0,0), (0,0), 5),
("BOTTOMPADDING", (0,0), (0,0), 5),
("TOPPADDING", (0,1), (-1,-1), 3),
("BOTTOMPADDING", (0,1), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 0.5, colors.HexColor("#C5D8EE")),
("LINEBELOW", (0,0), (0,0), 0.5, MED_BLUE),
("ROUNDEDCORNERS",(0,0), (-1,-1), [4,4,4,4]),
]))
return t
# ── Helper: two-column row layout ─────────────────────────────────────────────
def two_col(left_widget, right_widget, gap=0.3*cm):
col = (CONTENT_W - gap) / 2
t = Table([[left_widget, right_widget]], colWidths=[col, col])
t.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING",(0,0), (-1,-1), 0),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 1 – EPIDEMIOLOGY
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("1", "EPIDEMIOLOGY"))
story.append(Spacer(1, 0.2*cm))
agent = sub_section("Agent Factors (Epidemiological Triad)", [
("Causative agent", "Name, type (bacteria / virus / parasite / fungus / prion)"),
("Source of infection", "Human case / carrier / animal reservoir / soil / water"),
("Reservoir", "Human (anthroponosis) / Animal (zoonosis)"),
("Infective material", "Stool, blood, respiratory secretions, urine, skin lesions"),
("Infectivity / Virulence / Pathogenicity / Antigenicity", "Describe as relevant"),
])
host = sub_section("Host Factors", [
("Age group affected", "Neonates / children / adults / elderly"),
("Sex predilection", "If any"),
("Immunity", "Natural / acquired; herd immunity threshold (%)"),
("Other", "Nutrition, occupation, genetic susceptibility, comorbidities"),
])
env = sub_section("Environmental Factors", [
("Season / Climate", "e.g., monsoon, winter, tropical"),
("Geography", "Endemic zones, global distribution"),
("Socioeconomic", "Overcrowding, poor sanitation, unsafe water, poverty"),
])
story.append(two_col(agent, host))
story.append(Spacer(1, 0.2*cm))
story.append(env)
story.append(Spacer(1, 0.2*cm))
transmission = sub_section("Transmission", [
("Mode", "Faecal-oral / droplet / contact / vector-borne / airborne / vertical / sexual"),
("Vehicle / Vector", "Name vector, its scientific name, role (biological / mechanical)"),
("Portal of entry", "GI tract / respiratory / skin / mucous membrane"),
("Incubation period", "Range and average"),
("Period of communicability", "When the case is infectious to others"),
])
desc_epi = sub_section("Descriptive Epidemiology", [
("Global burden", "WHO incidence / prevalence / mortality data"),
("Indian scenario", "IDSP / NVBDCP / NTEP figures; notifiable disease? (State / Central)"),
("Epidemic pattern", "Endemic / epidemic / pandemic / sporadic / seasonal"),
])
story.append(two_col(transmission, desc_epi))
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 2 – CLINICAL FEATURES
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2", "CLINICAL FEATURES"))
story.append(Spacer(1, 0.2*cm))
stages = sub_section("Stages of Disease", [
("Incubation period", "Repeat for clinical context"),
("Prodromal stage", "Early, non-specific symptoms"),
("Fastigium (Stage of invasion)", "Peak / characteristic symptoms"),
("Defervescence", "Symptoms subsiding"),
("Convalescence", "Recovery phase"),
])
cardinal = sub_section("Cardinal / Pathognomonic Features", [
"List hallmark signs & symptoms specific to this disease",
"Include classic clinical signs (e.g., Koplik's spots, rose spots, etc.)",
"Note any diagnostic clinical triad or syndrome name",
])
story.append(two_col(stages, cardinal))
story.append(Spacer(1, 0.2*cm))
types = sub_section("Clinical Types / Grades / Severity Classification", [
"Mild / Moderate / Severe",
"Disease-specific WHO classification if applicable (e.g., dengue grades, cholera grades)",
"Carrier states: incubatory / convalescent / healthy / chronic carrier",
])
story.append(types)
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 3 – DIAGNOSIS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("3", "DIAGNOSIS"))
story.append(Spacer(1, 0.2*cm))
diag_left = sub_section("Lab Investigations", [
("Clinical diagnosis", "Basis of suspicion"),
("Routine labs", "CBC, ESR, LFT, RFT as relevant"),
("Specific tests", "Culture, smear microscopy, serology, PCR, antigen/antibody"),
("Gold standard", "State the confirmatory test"),
])
diag_right = sub_section("Case Definition (WHO / IDSP)", [
("Suspected case", "Clinical criteria only"),
("Probable case", "Clinical + epidemiological link"),
("Confirmed case", "Laboratory confirmation"),
("Notifiable?", "Under which Act / Program"),
])
story.append(two_col(diag_left, diag_right))
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 4 – TREATMENT
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4", "TREATMENT"))
story.append(Spacer(1, 0.2*cm))
tx_left = sub_section("General / Supportive Care", [
"Hydration: ORS / IV fluids (specify Ringer's lactate / NS / DNS)",
"Nutritional support; bed rest",
"Antipyretics, antiemetics, analgesics as needed",
"Monitor vitals and fluid balance",
])
tx_right = sub_section("Specific Treatment", [
("Drug of choice", "Name, dose, route, duration"),
("Alternatives", "Second-line / if resistance / if contraindicated"),
("Special populations", "Pregnancy, paediatrics, immunocompromised"),
("Resistance patterns", "Mention if relevant (e.g., MDR-TB, CQ-resistant malaria)"),
])
story.append(two_col(tx_left, tx_right))
story.append(Spacer(1, 0.2*cm))
iso = sub_section("Isolation & Notification", [
("Isolation type", "Enteric / Respiratory / Strict / Reverse / None"),
("Duration of isolation", "Until non-infectious"),
("Notification", "Compulsory notification to: CMO / State / Centre / IHR 2005"),
])
story.append(iso)
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 5 – COMPLICATIONS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5", "COMPLICATIONS"))
story.append(Spacer(1, 0.2*cm))
comp = sub_section("System-wise Complications", [
("Immediate / Acute", "Life-threatening complications to list first"),
("Organ-specific", "CNS, CVS, respiratory, GI, renal, hepatic complications"),
("Long-term sequelae", "Chronic disability, carrier state, post-infectious syndromes"),
("Complications of treatment", "Drug side effects, paradoxical reactions"),
"Always highlight the MOST dangerous complication with * or underline in exam",
])
story.append(comp)
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# SECTION 6 – PREVENTION AND CONTROL (most scoring)
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("6", "PREVENTION AND CONTROL [Most Scoring Section]"))
story.append(Spacer(1, 0.2*cm))
primary_a = sub_section("Primary Prevention — Health Promotion", [
"Health education of community",
"Nutritional improvement",
"Improvement in living standards and sanitation",
"Safe water supply; food hygiene",
], bg=colors.HexColor("#F0F7FF"))
primary_b = sub_section("Primary Prevention — Specific Protection", [
("Immunization", "Vaccine name, type (live/killed/toxoid/subunit/conjugate), schedule, cold chain, efficacy %"),
("Chemoprophylaxis", "Drug, dose, indication (e.g., malaria prophylaxis)"),
("Vector control", "Chemical / biological / environmental methods"),
("Personal protection", "LLIN, condoms, PPE, repellents, gloves"),
], bg=colors.HexColor("#F0F7FF"))
story.append(two_col(primary_a, primary_b))
story.append(Spacer(1, 0.2*cm))
secondary = sub_section("Secondary Prevention — Early Diagnosis + Prompt Treatment", [
"Active case finding and passive surveillance",
"Mass screening programs (e.g., DOTS for TB)",
"Contact tracing and treatment",
"Sentinel surveillance systems (IDSP, IHIP)",
])
tertiary = sub_section("Tertiary Prevention — Rehabilitation", [
"Prevention of disability and deformity",
"Physical / occupational / social rehabilitation",
"Long-term follow-up of complicated cases",
])
story.append(two_col(secondary, tertiary))
story.append(Spacer(1, 0.2*cm))
outbreak = sub_section("Control Measures During an Outbreak", [
("Case isolation", "Isolate & treat all confirmed / suspected cases"),
("Contact tracing", "Identify, trace, quarantine contacts; give prophylaxis if available"),
("Disinfection", "Concurrent (ongoing) + Terminal (after case removal)"),
("Epidemiological investigation", "Attack rate, spot map, epidemic curve, identify source"),
("Notification", "Inform CMO, State Health Dept, IDSP war room"),
("Health education", "Community awareness to prevent spread"),
])
story.append(outbreak)
story.append(Spacer(1, 0.2*cm))
national = sub_section("National Programs & WHO Goals", [
("Relevant NHP", "e.g., NVBDCP, NTEP/RNTCP, NVHCP, RCH, NLEP, NACP"),
("WHO targets", "Elimination / eradication goals, SDG health targets"),
("Surveillance systems", "IDSP, IHIP, HMIS, NVBDCP dashboards"),
])
story.append(national)
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# EXAM TIPS TABLE
# ═══════════════════════════════════════════════════════════════════════════════
tip_header_style = ParagraphStyle("th", fontName="Helvetica-Bold", fontSize=10,
textColor=WHITE, alignment=TA_CENTER, leading=14)
tip_cell_style = ParagraphStyle("tc", fontName="Helvetica", fontSize=9,
textColor=colors.HexColor("#1B3A27"),
alignment=TA_LEFT, leading=13)
tip_cell_bold = ParagraphStyle("tcb", fontName="Helvetica-Bold", fontSize=9,
textColor=GREEN_DARK, alignment=TA_LEFT, leading=13)
tip_data = [
[Paragraph("EXAM TIPS", tip_header_style),
Paragraph("ALWAYS MENTION", tip_header_style),
Paragraph("MARKS GUIDE", tip_header_style)],
[Paragraph("WHO case definition\n(suspected / probable / confirmed)", tip_cell_style),
Paragraph("Incubation period", tip_cell_bold),
Paragraph("10 marks: All 6 sections", tip_cell_style)],
[Paragraph("Vaccine details: type, schedule, cold chain, efficacy", tip_cell_style),
Paragraph("Period of communicability", tip_cell_bold),
Paragraph("5 marks: Asked section + brief epi context", tip_cell_style)],
[Paragraph("Gold standard diagnostic test", tip_cell_style),
Paragraph("Notifiable disease status", tip_cell_bold),
Paragraph("Short note: Unique features + vaccine/vector + key complication", tip_cell_style)],
[Paragraph("National Program name + year started", tip_cell_style),
Paragraph("Herd immunity threshold %", tip_cell_bold),
Paragraph("Always end Prevention section with National Program", tip_cell_style)],
[Paragraph("Epidemic investigation steps for outbreak question", tip_cell_style),
Paragraph("Drug of choice (name + dose)", tip_cell_bold),
Paragraph("Draw epidemic curve if outbreak question asked", tip_cell_style)],
]
col_w = CONTENT_W / 3
tips_table = Table(tip_data, colWidths=[col_w, col_w, col_w])
tips_table.setStyle(TableStyle([
# Header row
("BACKGROUND", (0,0), (-1,0), GREEN_DARK),
("TOPPADDING", (0,0), (-1,0), 8),
("BOTTOMPADDING", (0,0), (-1,0), 8),
# Data rows
("BACKGROUND", (0,1), (-1,-1), GREEN_LIGHT),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREEN_LIGHT, colors.HexColor("#E2F4EA")]),
("TOPPADDING", (0,1), (-1,-1), 5),
("BOTTOMPADDING", (0,1), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
# Grid
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#A8D5B5")),
("BOX", (0,0), (-1,-1), 1, GREEN_DARK),
("VALIGN", (0,0), (-1,-1), "TOP"),
("ROUNDEDCORNERS",(0,0), (-1,-1), [5,5,5,5]),
]))
story.append(tips_table)
story.append(Spacer(1, 0.25*cm))
# ── Footer note ────────────────────────────────────────────────────────────────
footer_data = [[
Paragraph(
"Use this proforma as a skeleton for EVERY communicable disease. "
"Fill in disease-specific details for each heading. "
"Section 6 (Prevention) is the highest-scoring section in PSM exams — never skip it.",
S("fnote", fontName="Helvetica-Oblique", fontSize=8.5,
textColor=WHITE, alignment=TA_CENTER, leading=12)
)
]]
footer_table = Table(footer_data, colWidths=[CONTENT_W])
footer_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING",(0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("ROUNDEDCORNERS",(0,0), (-1,-1), [5,5,5,5]),
]))
story.append(footer_table)
# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
python3 /home/daytona/workspace/psm-proforma/create_proforma.py 2>&1
ls -lh /home/daytona/workspace/psm-proforma/PSM_Communicable_Disease_Proforma.pd…
PSM Communicable Disease Proforma
PDF Document · PDF
Give an example of this proforma with measles
No need a s a pdf.. give it in text
Fever + Koplik's spots + Cephalocaudal maculopapular rash
| System | Complication |
|---|---|
| Respiratory | Pneumonia (1-6%, most common cause of measles death), laryngotracheobronchitis (croup) |
| Ear | Otitis media (7-9% in developed countries) - most common complication |
| GI | Diarrhoea (8%), protein-losing enteropathy (developing countries) |
| CNS | Post-infectious measles encephalitis (1-4 per 1000-2000 cases) |
| CNS - late | SSPE - Subacute Sclerosing Panencephalitis (1 per 10,000-1,00,000 cases; occurs years after infection) ⚠️ |
| Immunocompromised | Measles inclusion-body encephalitis (MIBE), giant cell pneumonia |
| Nutritional | Precipitating/worsening malnutrition, Vitamin A deficiency, cancrum oris |
| Other | Reactivation of pulmonary TB, cancrum oris, stomatitis |
| Pregnancy | Spontaneous abortion, premature delivery (NO congenital anomalies) |
| Feature | Details |
|---|---|
| Vaccine | MMR (Measles-Mumps-Rubella) / MR vaccine in India |
| Type | Live attenuated virus vaccine |
| Schedule (India - NIS) | 1st dose at 9-12 months (MR vaccine); 2nd dose at 16-24 months |
| Route | Subcutaneous (0.5 mL) |
| Cold chain | +2°C to +8°C; sensitive to heat and light |
| Efficacy | Single dose: ~93%; Two doses: ~97% |
| Herd immunity threshold | ≥95% population immunity required to interrupt transmission |
| Contraindications | Pregnancy, severe immunodeficiency (except HIV not severely immunocompromised), severe allergic reaction to prior dose |
Sources: Park's Textbook of Preventive and Social Medicine (23rd ed.) | Red Book 2021 - AAP | Goldman-Cecil Medicine
These are the diseases that I need similar information on. Under respiratory, measles, congenital rubella, influenza, which includes swine flu and bird flu, tuberculosis. Under intestinal, polio, diarrhea, cholera, typhoid, food poisoning, hepatitis B. Under, under arthropod, dengue, malaria, filariasis. Chikungunya. And then under zoonoses, rabies, Japanese encephalitis, uh, arboviral infections classification, um, and also... Uh... Leptospirosis. Next for surface infections, tetanus, leprosy, AIDS. Also, chickenpox, hookworm infestations, nosocomial infections, chikungunya. Neonatal tetanus. Monday morning fever. So about all of these diseases, I want you to make a nice PDF, and each of these diseases that I have mentioned, I want you to basically use the proforma and make the same thing, like, um, agent factors, host factors, environmental factors, just like in the proforma. Make-- Use all of them. I only mentioned some, but use all of them, and for each disease, I want you to make a specific thing and make it as a nice PDF. Please do it for me.
I think it's better if u just give this info in text
Stop ur not giving nicely
Wait.. I will ask whaich disease I want individuallya nd u give me info properly about it like from the peroforma ok?
Give me pdf of.each disease I ask
Measles
mkdir -p /home/daytona/workspace/disease-pdfs
~/disease-pdfs/measles.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, PageBreak
from reportlab.lib.enums import TA_CENTER, TA_LEFT
OUTPUT = "/home/daytona/workspace/disease-pdfs/Measles_Proforma.pdf"
W, H = A4
CONTENT_W = W - 3.2*cm
# ── Colours ──────────────────────────────────────────────────────────────────
DARK = colors.HexColor("#1A3A5C")
MED_BLUE = colors.HexColor("#2E6DA4")
LIGHT_BLUE = colors.HexColor("#D6E8F7")
ACCENT = colors.HexColor("#E8A020")
LGREY = colors.HexColor("#F4F6F9")
MGREY = colors.HexColor("#7F8C9A")
WHITE = colors.white
GSEC = colors.HexColor("#1B6B3A") # green section
GLIGHT = colors.HexColor("#D4EDDA")
RSEC = colors.HexColor("#8B1A1A") # red section
RLIGHT = colors.HexColor("#FAE0E0")
PURP = colors.HexColor("#4A235A")
PURPLIGHT = colors.HexColor("#EDE0F5")
ORNG = colors.HexColor("#7D4800")
ORNGLIGHT = colors.HexColor("#FFF3CD")
doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
leftMargin=1.6*cm, rightMargin=1.6*cm,
topMargin=1.4*cm, bottomMargin=1.4*cm,
title="Measles – PSM Proforma")
# ── Style factory ─────────────────────────────────────────────────────────────
def S(name, **kw):
return ParagraphStyle(name, **kw)
def sec_hdr(num, title, bg=DARK):
accent_col = ACCENT
num_style = S(f"n{num}", fontName="Helvetica-Bold", fontSize=15,
textColor=accent_col, alignment=TA_CENTER, leading=18)
txt_style = S(f"t{num}", fontName="Helvetica-Bold", fontSize=12,
textColor=WHITE, alignment=TA_LEFT, leading=17)
t = Table([[Paragraph(num, num_style), Paragraph(title, txt_style)]],
colWidths=[1.0*cm, CONTENT_W - 1.0*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 7),
("BOTTOMPADDING", (0,0),(-1,-1), 7),
("LEFTPADDING", (0,0),(0,0), 8),
("LEFTPADDING", (1,0),(1,0), 4),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("ROUNDEDCORNERS",(0,0),(-1,-1), [6,6,6,6]),
]))
return t
def sub_hdr(title, accent=LIGHT_BLUE, txt_col=DARK):
sty = S("sh", fontName="Helvetica-Bold", fontSize=10,
textColor=txt_col, leading=14)
t = Table([[Paragraph(title, sty)]], colWidths=[CONTENT_W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), accent),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("LINEBELOW", (0,0),(-1,-1), 0.5, MED_BLUE),
]))
return t
def bullet(text, indent=12, bold_label=None):
"""bold_label: if given, renders 'bold_label: text' with label bolded"""
sty = S("bl", fontName="Helvetica", fontSize=9.3,
textColor=colors.HexColor("#1a1a1a"), leftIndent=indent,
leading=13.5)
if bold_label:
content = f"<b>{bold_label}:</b> {text}"
else:
content = f"• {text}"
return Paragraph(content, sty)
def kv(label, value):
"""Key-value row"""
sty = S("kv", fontName="Helvetica", fontSize=9.3,
textColor=colors.HexColor("#1a1a1a"), leftIndent=12, leading=13.5)
return Paragraph(f"<b>{label}:</b> {value}", sty)
def note(text):
sty = S("nt", fontName="Helvetica-Oblique", fontSize=8.5,
textColor=MGREY, leftIndent=12, leading=12)
return Paragraph(f"ⓘ {text}", sty)
def box(items, bg=LGREY, border=colors.HexColor("#C5D8EE")):
"""Wrap a list of Paragraph flowables in a shaded box"""
rows = [[item] for item in items]
t = Table(rows, colWidths=[CONTENT_W - 0.3*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 6),
("RIGHTPADDING", (0,0),(-1,-1), 6),
("BOX", (0,0),(-1,-1), 0.5, border),
("ROUNDEDCORNERS",(0,0),(-1,-1), [4,4,4,4]),
]))
return t
def sp(h=0.18):
return Spacer(1, h*cm)
def two_col(left_items, right_items, left_hdr, right_hdr,
lbg=LGREY, rbg=LGREY):
"""Two sub-boxes side by side with headers"""
lw = (CONTENT_W - 0.25*cm) / 2
rw = CONTENT_W - lw - 0.25*cm
def make_inner(hdr_text, items, bg, border_col):
hdr_sty = S("ih", fontName="Helvetica-Bold", fontSize=9.5,
textColor=DARK, leading=13)
rows = [[Paragraph(hdr_text, hdr_sty)]] + [[i] for i in items]
t = Table(rows, colWidths=[lw - 0.1*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), LIGHT_BLUE),
("BACKGROUND", (0,1),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 8),
("RIGHTPADDING", (0,0),(-1,-1), 8),
("BOX", (0,0),(-1,-1), 0.5, border_col),
("LINEBELOW", (0,0),(0,0), 0.5, MED_BLUE),
("ROUNDEDCORNERS",(0,0),(-1,-1), [4,4,4,4]),
]))
return t
li = make_inner(left_hdr, left_items, lbg, colors.HexColor("#B0CCE8"))
ri = make_inner(right_hdr, right_items, rbg, colors.HexColor("#B0CCE8"))
outer = Table([[li, ri]], colWidths=[lw, rw])
outer.setStyle(TableStyle([
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING",(0,0),(-1,-1), 0),
("VALIGN", (0,0),(-1,-1), "TOP"),
("COLPADDING", (0,0),(0,0), 0),
]))
return outer
# ════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════════════════
story = []
# ── TITLE BANNER ─────────────────────────────────────────────────────────────
title_sty = S("TT", fontName="Helvetica-Bold", fontSize=22,
textColor=WHITE, alignment=TA_CENTER, leading=28)
sub_sty = S("TS", fontName="Helvetica", fontSize=10.5,
textColor=LIGHT_BLUE, alignment=TA_CENTER, leading=14)
badge_sty = S("TB", fontName="Helvetica-Bold", fontSize=9,
textColor=ACCENT, alignment=TA_CENTER, leading=12)
title_data = [[Paragraph("MEASLES (Rubeola)", title_sty)]]
t = Table(title_data, colWidths=[CONTENT_W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), DARK),
("TOPPADDING", (0,0),(-1,-1), 14),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 12),
("RIGHTPADDING", (0,0),(-1,-1), 12),
("ROUNDEDCORNERS",(0,0),(-1,-1), [7,7,0,0]),
]))
story.append(t)
sub_data = [[
Paragraph("Group: RESPIRATORY | PSM / Community Medicine Proforma | 3rd Year MBBS", sub_sty)
]]
t2 = Table(sub_data, colWidths=[CONTENT_W])
t2.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), MED_BLUE),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 6),
("LEFTPADDING", (0,0),(-1,-1), 12),
("RIGHTPADDING", (0,0),(-1,-1), 12),
("ROUNDEDCORNERS",(0,0),(-1,-1), [0,0,7,7]),
]))
story.append(t2)
story.append(sp(0.3))
# Quick facts strip
qf_sty = S("qf", fontName="Helvetica-Bold", fontSize=8.5,
textColor=DARK, alignment=TA_CENTER, leading=12)
qf_val = S("qfv", fontName="Helvetica", fontSize=8.5,
textColor=colors.HexColor("#333333"), alignment=TA_CENTER, leading=12)
qf = [
["Causative Agent", "RNA Paramyxovirus\n(Morbillivirus)"],
["Incubation Period", "10 days (fever)\n14 days (rash)"],
["Communicability", "4 days before rash\nto 4 days after"],
["Vaccine", "MMR / MR\n(Live attenuated)"],
["Herd Immunity", "≥ 95%"],
]
qf_data = [[Paragraph(r[0], qf_sty) for r in qf],
[Paragraph(r[1], qf_val) for r in qf]]
qf_table = Table(qf_data, colWidths=[CONTENT_W/5]*5)
qf_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), LIGHT_BLUE),
("BACKGROUND", (0,1),(-1,1), LGREY),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("INNERGRID", (0,0),(-1,-1), 0.4, colors.HexColor("#C5D8EE")),
("BOX", (0,0),(-1,-1), 0.8, MED_BLUE),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
]))
story.append(qf_table)
story.append(sp(0.3))
# ════════ SECTION 1: EPIDEMIOLOGY ════════════════════════════════════════════
story.append(sec_hdr("1", "EPIDEMIOLOGY"))
story.append(sp(0.18))
# Agent + Host side by side
agent_items = [
kv("Agent", "RNA Paramyxovirus — genus Morbillivirus, family Paramyxoviridae"),
kv("Serotypes", "Only 1 serotype known"),
kv("Reservoir", "Humans ONLY — strictly anthroponotic; no animal reservoir"),
kv("Source", "Cases of measles only; NO carrier state"),
kv("Infective material", "Nasal/throat secretions during prodrome & early rash"),
kv("Survival", "Cannot survive outside human body; stable at sub-zero temps"),
kv("Infectivity", "Attack rate 90% in susceptible close contacts — one of the most communicable diseases known"),
]
host_items = [
kv("Age", "6 months–3 years (developing countries); >5 years (developed). Maternal antibodies protect up to 6–9 months"),
kv("Sex", "Equal incidence in males and females"),
kv("Immunity", "One attack → lifelong immunity. Second attacks rare"),
kv("Nutrition", "Malnourished children: mortality up to 400× higher. Vitamin A deficiency = major risk factor"),
kv("Other risks", "Immunocompromised (HIV), infants <1 yr, adults >30 yr"),
]
story.append(two_col(agent_items, host_items,
"Agent Factors", "Host Factors"))
story.append(sp(0.2))
# Env + Transmission
env_items = [
kv("Season (India)", "January–April (winter & early spring)"),
kv("Season (tropics)", "Dry season; temperate = winter (indoor crowding)"),
kv("Geography", "Endemic worldwide; severe in developing countries"),
kv("Socioeconomic", "Overcrowding, malnutrition, poor sanitation accelerate spread"),
kv("Epidemic trigger", "Epidemics when susceptibles reach ~40% of population"),
]
trans_items = [
kv("Mode", "Droplet infection & droplet nuclei (airborne) — person to person"),
kv("Portal of entry", "Respiratory tract (also possibly conjunctiva)"),
kv("Incubation period", "10 days to fever; 14 days to rash (range 8–18 days)"),
kv("Communicability", "4 days BEFORE rash onset to 4 days AFTER rash"),
kv("Special", "Immunocompromised: contagious entire duration of illness"),
kv("Vaccine recipients", "NOT contagious to others"),
]
story.append(two_col(env_items, trans_items,
"Environmental Factors", "Transmission"))
story.append(sp(0.2))
story.append(sub_hdr("Descriptive Epidemiology"))
story.append(sp(0.08))
epi_items = [
bullet("Pre-vaccine era: ~2.6 million deaths/year worldwide (1980)"),
bullet("2018: ~9.7 million cases, >140,000 deaths worldwide — 73% decline since 2000"),
bullet("India 2018: 20,895 cases, 34 deaths (down from 2.47 lakh in 1987 pre-UIP)"),
bullet("Epidemic pattern: Endemic with cyclical epidemics every 2–3 years in pre-vaccine era"),
bullet("Notifiable disease — compulsory notification under IDSP / IHR 2005"),
]
story.append(box(epi_items))
story.append(sp(0.3))
# ════════ SECTION 2: CLINICAL FEATURES ═══════════════════════════════════════
story.append(sec_hdr("2", "CLINICAL FEATURES"))
story.append(sp(0.18))
story.append(sub_hdr("Three Stages of Measles"))
story.append(sp(0.08))
stage_data = [
[Paragraph("STAGE 1\nProdromal\n(Days 10–14)", S("s1h", fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_CENTER, leading=13)),
Paragraph("STAGE 2\nEruptive / Rash\n(Day 14+)", S("s2h", fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_CENTER, leading=13)),
Paragraph("STAGE 3\nPost-Measles\n(Recovery)", S("s3h", fontName="Helvetica-Bold", fontSize=9,
textColor=WHITE, alignment=TA_CENTER, leading=13))],
[Paragraph("• High fever\n• Coryza (sneezing, nasal discharge)\n• Cough\n• Conjunctivitis — redness, lacrimation, photophobia\n• Vomiting / diarrhoea\n• <b>Koplik's spots</b> (1–2 days before rash) — bluish-white spots on red base on buccal mucosa opposite lower molars — PATHOGNOMONIC",
S("sc1", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4)),
Paragraph("• Rash appears Day 14\n• Maculopapular, brick-red\n• Begins on FACE & behind ears\n• Spreads CEPHALOCAUDAL — face→neck→trunk→limbs\n• Confluent on face\n• Fever rises with rash then falls by lysis\n• Rash fades in same cephalocaudal order\n• Leaves brownish discolouration + branny desquamation",
S("sc2", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4)),
Paragraph("• Weight loss, weakness\n• Increased susceptibility to bacterial/viral superinfections\n• Risk of malnutrition & growth retardation\n• Diarrhoea, cancrum oris\n• Reactivation of pulmonary TB\n• Pyogenic infections, candidosis",
S("sc3", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4))],
]
cw = (CONTENT_W) / 3
stage_table = Table(stage_data, colWidths=[cw, cw, cw])
stage_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), colors.HexColor("#1B5E8C")),
("BACKGROUND", (1,0),(1,0), colors.HexColor("#1A6B42")),
("BACKGROUND", (2,0),(2,0), colors.HexColor("#7D4800")),
("BACKGROUND", (0,1),(0,1), colors.HexColor("#EBF4FF")),
("BACKGROUND", (1,1),(1,1), colors.HexColor("#EBF8F2")),
("BACKGROUND", (2,1),(2,1), colors.HexColor("#FFF8EC")),
("TOPPADDING", (0,0),(-1,-1), 6),
("BOTTOMPADDING", (0,0),(-1,-1), 6),
("LEFTPADDING", (0,0),(-1,-1), 7),
("RIGHTPADDING", (0,0),(-1,-1), 7),
("INNERGRID", (0,0),(-1,-1), 0.5, colors.HexColor("#CCCCCC")),
("BOX", (0,0),(-1,-1), 0.8, DARK),
("VALIGN", (0,0),(-1,-1), "TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
]))
story.append(stage_table)
story.append(sp(0.2))
path_sty = S("path", fontName="Helvetica-Bold", fontSize=10,
textColor=WHITE, alignment=TA_CENTER, leading=14)
path_box_data = [[Paragraph(
"PATHOGNOMONIC TRIAD: Fever + Koplik's Spots + Cephalocaudal Maculopapular Rash\n"
"CLINICAL RULE: Diagnosis is unlikely in any febrile rash illness where red eyes AND cough are ABSENT (3 C's = Cough, Coryza, Conjunctivitis)",
S("pb", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE,
alignment=TA_CENTER, leading=14))]]
path_table = Table(path_box_data, colWidths=[CONTENT_W])
path_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), PURP),
("TOPPADDING", (0,0),(-1,-1), 8),
("BOTTOMPADDING", (0,0),(-1,-1), 8),
("LEFTPADDING", (0,0),(-1,-1), 12),
("RIGHTPADDING", (0,0),(-1,-1), 12),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
]))
story.append(path_table)
story.append(sp(0.3))
# ════════ SECTION 3: DIAGNOSIS ════════════════════════════════════════════════
story.append(sec_hdr("3", "DIAGNOSIS", bg=GSEC))
story.append(sp(0.18))
diag_l = [
kv("Clinical diagnosis", "Koplik's spots + 3 C's + characteristic rash"),
kv("Specific IgM (ELISA)", "Preferred method. May be false-negative in first 72 hrs after rash — repeat if negative and rash >72 hrs"),
kv("RT-PCR (Gold Standard)", "Detection of measles RNA in throat swab, nasal swab, urine. Most sensitive; allows viral genotyping"),
kv("IgG paired sera", "Fourfold rise in acute + convalescent samples (≥10 days apart)"),
kv("Virus isolation", "Cell culture — NOT recommended routinely (takes up to 2 weeks)"),
]
case_def = [
kv("Suspected case", "Fever + generalised maculopapular rash + one of: cough / coryza / conjunctivitis"),
kv("Confirmed case", "IgM positive OR RT-PCR positive OR epidemiological link to confirmed case"),
kv("Notifiable", "Yes — compulsory. Notify CMO, IDSP, IHR 2005"),
]
story.append(two_col(diag_l, case_def,
"Laboratory Diagnosis", "WHO Case Definition (IDSP)",
lbg=GLIGHT, rbg=GLIGHT))
story.append(sp(0.3))
# ════════ SECTION 4: TREATMENT ════════════════════════════════════════════════
story.append(sec_hdr("4", "TREATMENT", bg=PURP))
story.append(sp(0.18))
tx_l = [
kv("Specific antiviral", "NONE available (ribavirin — in vitro susceptibility but no controlled trials; NOT licensed for measles)"),
kv("Antipyretics", "Paracetamol — AVOID aspirin in children (Reye's syndrome risk)"),
kv("Hydration", "ORS / IV fluids if dehydrated"),
kv("Nutrition", "Continue breastfeeding; age-appropriate food; prevent/treat malnutrition"),
kv("Antibiotics", "Only for bacterial secondary infections (otitis media, pneumonia) — NOT routine"),
]
vit_a = [
kv("WHO recommendation", "Vitamin A for ALL children with measles regardless of country"),
kv("< 6 months", "50,000 IU once daily × 2 days"),
kv("6–11 months", "100,000 IU once daily × 2 days"),
kv("≥ 12 months", "200,000 IU once daily × 2 days"),
kv("3rd dose", "Given 2–6 weeks later if clinical signs of Vitamin A deficiency"),
kv("Isolation", "Airborne precautions: 4 days after rash onset (immunocompetent); entire illness (immunocompromised)"),
]
story.append(two_col(tx_l, vit_a,
"General & Supportive Treatment", "Vitamin A Treatment (Key PSM Point)",
lbg=PURPLIGHT, rbg=PURPLIGHT))
story.append(sp(0.3))
# ════════ SECTION 5: COMPLICATIONS ════════════════════════════════════════════
story.append(sec_hdr("5", "COMPLICATIONS", bg=RSEC))
story.append(sp(0.18))
comp_data = [
[Paragraph("System", S("ch", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13)),
Paragraph("Complication", S("ch2", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13)),
Paragraph("Notes", S("ch3", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13))],
["Respiratory", "Pneumonia (1–6%)", "Most common cause of measles DEATH"],
["Respiratory", "Laryngotracheobronchitis (Croup)", "In young children"],
["Ear", "Otitis media (7–9%)", "Most COMMON complication overall"],
["GI", "Diarrhoea (8%)", "Protein-losing enteropathy in developing countries"],
["CNS", "Post-infectious encephalitis", "1–4 per 1000–2000 cases"],
["CNS — LATE ⚠️", "SSPE (Subacute Sclerosing Panencephalitis)", "1 per 10,000–1,00,000. Occurs years later. INVARIABLY FATAL"],
["Immunocompromised", "Measles inclusion-body encephalitis (MIBE)", "Acute progressive; fatal"],
["Immunocompromised", "Giant cell pneumonia", "Severe; often fatal"],
["Nutritional", "Malnutrition, Vitamin A deficiency, Cancrum oris", "Especially developing countries"],
["Pregnancy", "Spontaneous abortion, premature delivery", "NO congenital anomalies"],
["Other", "Reactivation of pulmonary TB", "Due to immune suppression"],
]
def make_para(txt, style):
return Paragraph(txt, style)
csty = S("cs", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13)
cwid = [CONTENT_W*0.22, CONTENT_W*0.38, CONTENT_W*0.40]
comp_rows = []
comp_rows.append(comp_data[0])
for row in comp_data[1:]:
comp_rows.append([Paragraph(row[0], csty), Paragraph(row[1], csty), Paragraph(row[2], csty)])
comp_table = Table(comp_rows, colWidths=cwid)
comp_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), RSEC),
("ROWBACKGROUNDS",(0,1),(-1,-1), [RLIGHT, colors.HexColor("#FFF0F0")]),
("BACKGROUND", (0,6),(-1,6), colors.HexColor("#FFD0D0")), # SSPE row highlighted
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LEFTPADDING", (0,0),(-1,-1), 8),
("RIGHTPADDING", (0,0),(-1,-1), 8),
("INNERGRID", (0,0),(-1,-1), 0.3, colors.HexColor("#FFAAAA")),
("BOX", (0,0),(-1,-1), 0.8, RSEC),
("VALIGN", (0,0),(-1,-1), "TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
]))
story.append(comp_table)
story.append(sp(0.15))
story.append(box([
bullet("CFR developing countries: 3–6% (up to 30% in malnourished/displaced populations)", indent=8),
bullet("CFR developed countries: 0.01–0.1%", indent=8),
bullet("Highest mortality: Children <1 year, adults >30 years, HIV-infected children (CFR up to 50%)", indent=8),
], bg=RLIGHT, border=RSEC))
story.append(sp(0.3))
# ════════ SECTION 6: PREVENTION & CONTROL ════════════════════════════════════
story.append(sec_hdr("6", "PREVENTION AND CONTROL [Most Scoring Section]", bg=GSEC))
story.append(sp(0.18))
story.append(sub_hdr("A. Primary Prevention — Health Promotion", accent=GLIGHT, txt_col=GSEC))
story.append(sp(0.08))
story.append(box([
bullet("Health education about measles, its complications and vaccine importance"),
bullet("Vitamin A supplementation for all under-5 children in endemic areas"),
bullet("Nutritional improvement — reduce malnutrition"),
bullet("Improvement in living standards; reduction of overcrowding"),
bullet("Safe water supply and food hygiene"),
], bg=GLIGHT, border=GSEC))
story.append(sp(0.18))
story.append(sub_hdr("B. Primary Prevention — Specific Protection: IMMUNIZATION", accent=GLIGHT, txt_col=GSEC))
story.append(sp(0.08))
vacc_data = [
[Paragraph("Feature", S("vh", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, leading=13)),
Paragraph("Details", S("vh2", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, leading=13))],
["Vaccine name", "MMR (Measles-Mumps-Rubella) / MR vaccine (India)"],
["Vaccine type", "LIVE ATTENUATED virus vaccine"],
["Schedule (India NIS)", "1st dose: 9–12 months (MR vaccine); 2nd dose: 16–24 months"],
["Route & dose", "Subcutaneous, 0.5 mL"],
["Cold chain", "+2°C to +8°C; sensitive to heat and light"],
["Efficacy", "Single dose: ~93%; Two doses: ~97%"],
["Herd immunity threshold", "≥95% population immunity required to interrupt transmission"],
["Contraindications", "Pregnancy, severe immunodeficiency (except non-severely immunocompromised HIV), severe allergy to prior dose"],
["Post-exposure vaccine", "Within 72 hours of exposure — prevents or modifies disease in eligible individuals ≥12 months"],
["Post-exposure IG", "Within 6 days of exposure — for infants <12 months, pregnant women, immunocompromised"],
]
vsty = S("vs", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13)
vacc_rows = [vacc_data[0]]
for row in vacc_data[1:]:
vacc_rows.append([Paragraph(row[0], S("vk", fontName="Helvetica-Bold", fontSize=8.8, textColor=DARK, leading=13)),
Paragraph(row[1], vsty)])
vacc_table = Table(vacc_rows, colWidths=[CONTENT_W*0.32, CONTENT_W*0.68])
vacc_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,0), GSEC),
("ROWBACKGROUNDS",(0,1),(-1,-1), [GLIGHT, colors.HexColor("#E8F8EE")]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LEFTPADDING", (0,0),(-1,-1), 8),
("RIGHTPADDING", (0,0),(-1,-1), 8),
("INNERGRID", (0,0),(-1,-1), 0.3, colors.HexColor("#A8D5B5")),
("BOX", (0,0),(-1,-1), 0.8, GSEC),
("VALIGN", (0,0),(-1,-1), "TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
]))
story.append(vacc_table)
story.append(sp(0.18))
sec_prev = [
bullet("Active case detection + passive surveillance (IDSP / IHIP)"),
bullet("Case-based measles-rubella surveillance with laboratory support"),
bullet("Contact tracing of all exposed individuals"),
bullet("Outbreak investigation: attack rate, spot map, epidemic curve"),
]
tert_prev = [
bullet("Management of SSPE (supportive only — no cure)"),
bullet("Rehabilitation of children with measles-related hearing loss"),
bullet("Neurological rehabilitation post-encephalitis"),
bullet("Nutritional rehabilitation post-measles"),
]
story.append(two_col(sec_prev, tert_prev,
"C. Secondary Prevention (Early Dx + Prompt Rx)",
"D. Tertiary Prevention (Rehabilitation)",
lbg=GLIGHT, rbg=GLIGHT))
story.append(sp(0.18))
story.append(sub_hdr("E. Control During Outbreak", accent=ORNGLIGHT, txt_col=ORNG))
story.append(sp(0.08))
story.append(box([
kv("1. Isolate cases", "Airborne precautions for 4 days after rash onset"),
kv("2. Contact tracing", "Vaccinate all eligible within 72 hrs; give IG to high-risk within 6 days"),
kv("3. Disinfection", "Concurrent disinfection of respiratory-secretion-contaminated articles; terminal disinfection"),
kv("4. Notification", "Notify CMO, State Health Dept, IDSP war room immediately"),
kv("5. SIA", "Supplementary Immunization Activity — mass vaccination in affected area"),
kv("6. Health education", "Community awareness to reduce spread"),
], bg=ORNGLIGHT, border=ORNG))
story.append(sp(0.18))
story.append(sub_hdr("F. National Programme & WHO Goals", accent=LIGHT_BLUE, txt_col=DARK))
story.append(sp(0.08))
story.append(box([
kv("UIP", "Universal Immunization Programme — includes MR vaccine in National Immunization Schedule"),
kv("Mission Indradhanush", "Intensified immunization to reach unvaccinated/under-vaccinated children"),
kv("MR Campaign", "Nationwide MR vaccination campaign (9 months to <15 years) launched across India"),
kv("India Goal", "Measles elimination and Rubella/CRS control by 2023"),
kv("WHO Global Targets", "MCV1 ≥90% nationally; incidence <5 per million; ≥95% reduction in mortality vs 2000"),
], bg=LIGHT_BLUE, border=MED_BLUE))
story.append(sp(0.3))
# ════════ EXAM QUICK RECALL BOX ══════════════════════════════════════════════
recall_sty = S("rec", fontName="Helvetica-Bold", fontSize=9.5,
textColor=DARK, alignment=TA_CENTER, leading=14)
recall_data = [[Paragraph("EXAM QUICK RECALL — MEASLES", recall_sty)]]
recall_hdr = Table(recall_data, colWidths=[CONTENT_W])
recall_hdr.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), ACCENT),
("TOPPADDING", (0,0),(-1,-1), 6),
("BOTTOMPADDING", (0,0),(-1,-1), 6),
("LEFTPADDING", (0,0),(-1,-1), 10),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,0,0]),
]))
story.append(recall_hdr)
recall_items = [
"Pathognomonic = Koplik's spots (bluish-white on buccal mucosa opposite lower molars)",
"3 C's = Cough, Coryza, Conjunctivitis (absent 3 C's → question the diagnosis)",
"Rash = Brick-red maculopapular, CEPHALOCAUDAL spread, Day 14",
"Communicability = 4 days before rash to 4 days after rash",
"Treatment = NO specific drug; Vitamin A is the KEY treatment (give doses by age)",
"Worst complication = SSPE (years later, invariably fatal)",
"Most common complication = Otitis media; Most common cause of death = Pneumonia",
"Vaccine = MMR / MR — LIVE attenuated; Herd immunity = ≥95%; 2 doses in India (9–12 m + 16–24 m)",
"Always mention: UIP, Mission Indradhanush, MR Campaign in prevention",
"Notification = Compulsory under IDSP / IHR 2005",
]
recall_rows = [[Paragraph(f"▶ {item}", S("ri", fontName="Helvetica", fontSize=9,
textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=6))]
for item in recall_items]
recall_table = Table(recall_rows, colWidths=[CONTENT_W])
recall_table.setStyle(TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1), [colors.HexColor("#FFFDE7"), colors.HexColor("#FFF9C4")]),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("BOX", (0,0),(-1,-1), 0.8, ACCENT),
("ROUNDEDCORNERS",(0,0),(-1,-1), [0,0,5,5]),
]))
story.append(recall_table)
story.append(sp(0.2))
# Footer
foot_sty = S("ft", fontName="Helvetica-Oblique", fontSize=8,
textColor=WHITE, alignment=TA_CENTER, leading=11)
foot_data = [[Paragraph(
"Sources: Park's Textbook of PSM (23rd ed.) | Red Book 2021 (AAP) | Goldman-Cecil Medicine — Orris Medical Assistant",
foot_sty)]]
foot_table = Table(foot_data, colWidths=[CONTENT_W])
foot_table.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), DARK),
("TOPPADDING", (0,0),(-1,-1), 6),
("BOTTOMPADDING", (0,0),(-1,-1), 6),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("ROUNDEDCORNERS",(0,0),(-1,-1), [5,5,5,5]),
]))
story.append(foot_table)
doc.build(story)
print(f"Done: {OUTPUT}")
python3 /home/daytona/workspace/disease-pdfs/measles.py 2>&1
ls -lh /home/daytona/workspace/disease-pdfs/Measles_Proforma.pdf
Measles Proforma
PDF Document · PDF
Can u make it with relavent pictures
measles Koplik spots clinical photo wikimedia commons public domain
measles maculopapular rash child clinical photo wikimedia commons public domain
cd /home/daytona/workspace/disease-pdfs && mkdir -p images && \ curl -sL "https:…
Along with the relevant pictures that you're putting, also put, uh, flowcharts wherever needed.
~/disease-pdfs/measles_with_images.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, Image, HRFlowable, PageBreak, KeepTogether)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.graphics.shapes import (Drawing, Rect, String, Arrow, Line,
Polygon, Circle, Group)
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
import os
OUTPUT = "/home/daytona/workspace/disease-pdfs/Measles_Proforma_Full.pdf"
IMG_DIR = "/home/daytona/workspace/disease-pdfs/images/"
W, H = A4
CONTENT_W = W - 3.2*cm
# ── Colours ──────────────────────────────────────────────────────────────────
DARK = colors.HexColor("#1A3A5C")
MED_BLUE = colors.HexColor("#2E6DA4")
LIGHT_BLUE = colors.HexColor("#D6E8F7")
ACCENT = colors.HexColor("#E8A020")
LGREY = colors.HexColor("#F4F6F9")
MGREY = colors.HexColor("#7F8C9A")
WHITE = colors.white
GSEC = colors.HexColor("#1B6B3A")
GLIGHT = colors.HexColor("#D4EDDA")
RSEC = colors.HexColor("#8B1A1A")
RLIGHT = colors.HexColor("#FAE0E0")
PURP = colors.HexColor("#4A235A")
PURPLIGHT = colors.HexColor("#EDE0F5")
ORNG = colors.HexColor("#7D4800")
ORNGLIGHT = colors.HexColor("#FFF3CD")
TEAL = colors.HexColor("#0D6B6B")
TEALLIGHT = colors.HexColor("#D0F0F0")
doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
leftMargin=1.6*cm, rightMargin=1.6*cm,
topMargin=1.4*cm, bottomMargin=1.4*cm,
title="Measles – PSM Proforma with Images & Flowcharts")
# ── Style helpers ─────────────────────────────────────────────────────────────
def S(name, **kw):
return ParagraphStyle(name, **kw)
def sp(h=0.18):
return Spacer(1, h*cm)
def kv(label, value):
sty = S("kv", fontName="Helvetica", fontSize=9.3,
textColor=colors.HexColor("#1a1a1a"), leftIndent=12, leading=13.5)
return Paragraph(f"<b>{label}:</b> {value}", sty)
def bullet(text, indent=14):
sty = S("bl", fontName="Helvetica", fontSize=9.3,
textColor=colors.HexColor("#1a1a1a"), leftIndent=indent, leading=13.5)
return Paragraph(f"• {text}", sty)
def box(items, bg=LGREY, border=colors.HexColor("#C5D8EE")):
rows = [[item] for item in items]
t = Table(rows, colWidths=[CONTENT_W - 0.3*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 6),
("RIGHTPADDING", (0,0),(-1,-1), 6),
("BOX", (0,0),(-1,-1), 0.5, border),
("ROUNDEDCORNERS",(0,0),(-1,-1), [4,4,4,4]),
]))
return t
def sec_hdr(num, title, bg=DARK):
n_sty = S(f"n{num}", fontName="Helvetica-Bold", fontSize=15,
textColor=ACCENT, alignment=TA_CENTER, leading=18)
t_sty = S(f"t{num}", fontName="Helvetica-Bold", fontSize=12,
textColor=WHITE, alignment=TA_LEFT, leading=17)
t = Table([[Paragraph(num, n_sty), Paragraph(title, t_sty)]],
colWidths=[1.0*cm, CONTENT_W - 1.0*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 7),
("BOTTOMPADDING", (0,0),(-1,-1), 7),
("LEFTPADDING", (0,0),(0,0), 8),
("LEFTPADDING", (1,0),(1,0), 4),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("ROUNDEDCORNERS",(0,0),(-1,-1), [6,6,6,6]),
]))
return t
def sub_hdr(title, accent=LIGHT_BLUE, txt_col=DARK):
sty = S("sh", fontName="Helvetica-Bold", fontSize=10,
textColor=txt_col, leading=14)
t = Table([[Paragraph(title, sty)]], colWidths=[CONTENT_W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), accent),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("LINEBELOW", (0,0),(-1,-1), 0.5, MED_BLUE),
]))
return t
def two_col(left_items, right_items, left_hdr, right_hdr, lbg=LGREY, rbg=LGREY):
lw = (CONTENT_W - 0.25*cm) / 2
rw = CONTENT_W - lw - 0.25*cm
def make_inner(hdr_text, items, bg, wid):
hdr_sty = S("ih", fontName="Helvetica-Bold", fontSize=9.5, textColor=DARK, leading=13)
rows = [[Paragraph(hdr_text, hdr_sty)]] + [[i] for i in items]
t = Table(rows, colWidths=[wid - 0.1*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), LIGHT_BLUE),
("BACKGROUND", (0,1),(-1,-1), bg),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 8),
("RIGHTPADDING", (0,0),(-1,-1), 8),
("BOX", (0,0),(-1,-1), 0.5, colors.HexColor("#B0CCE8")),
("LINEBELOW", (0,0),(0,0), 0.5, MED_BLUE),
("ROUNDEDCORNERS",(0,0),(-1,-1), [4,4,4,4]),
]))
return t
li = make_inner(left_hdr, left_items, lbg, lw)
ri = make_inner(right_hdr, right_items, rbg, rw)
outer = Table([[li, ri]], colWidths=[lw, rw])
outer.setStyle(TableStyle([
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING", (0,0),(-1,-1), 0),
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING",(0,0),(-1,-1), 0),
("VALIGN", (0,0),(-1,-1), "TOP"),
]))
return outer
def img_with_caption(path, width, caption):
cap_sty = S("cap", fontName="Helvetica-Oblique", fontSize=8,
textColor=MGREY, alignment=TA_CENTER, leading=11)
img = Image(path, width=width, height=width*0.75)
rows = [[img], [Paragraph(caption, cap_sty)]]
t = Table(rows, colWidths=[width])
t.setStyle(TableStyle([
("ALIGN", (0,0),(-1,-1), "CENTER"),
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING",(0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 2),
("RIGHTPADDING", (0,0),(-1,-1), 2),
("BOX", (0,0),(-1,-1), 0.5, colors.HexColor("#AAAAAA")),
("ROUNDEDCORNERS",(0,0),(-1,-1),[4,4,4,4]),
]))
return t
# ════════════════════════════════════════════════════════════════════════════
# FLOWCHART HELPERS using ReportLab Drawing
# ════════════════════════════════════════════════════════════════════════════
def flow_box(d, x, y, w, h, text, fill_col, text_col=colors.white, font_size=8):
"""Draw a rounded rectangle with centred text in drawing d."""
r = Rect(x, y, w, h, rx=6, ry=6,
fillColor=fill_col, strokeColor=colors.HexColor("#333333"), strokeWidth=0.6)
d.add(r)
# Split text on \n manually
lines = text.split("\n")
line_h = font_size + 2
total_h = len(lines) * line_h
start_y = y + h/2 + total_h/2 - line_h
for i, line in enumerate(lines):
s = String(x + w/2, start_y - i*line_h,
line, fontName="Helvetica-Bold" if i == 0 else "Helvetica",
fontSize=font_size, fillColor=text_col, textAnchor="middle")
d.add(s)
def flow_arrow(d, x1, y1, x2, y2, col=colors.HexColor("#444444")):
"""Draw a line with arrowhead."""
d.add(Line(x1, y1, x2, y2, strokeColor=col, strokeWidth=1.2))
# simple arrowhead triangle
if y2 < y1: # downward
d.add(Polygon([x2-4, y2+7, x2+4, y2+7, x2, y2],
fillColor=col, strokeColor=col, strokeWidth=0))
elif y2 > y1: # upward
d.add(Polygon([x2-4, y2-7, x2+4, y2-7, x2, y2],
fillColor=col, strokeColor=col, strokeWidth=0))
else: # horizontal right
d.add(Polygon([x2-7, y2-4, x2-7, y2+4, x2, y2],
fillColor=col, strokeColor=col, strokeWidth=0))
def flow_label(d, x, y, text, font_size=7.5, col=colors.HexColor("#555555")):
d.add(String(x, y, text, fontName="Helvetica-Oblique",
fontSize=font_size, fillColor=col, textAnchor="middle"))
# ── FLOWCHART 1: Transmission Chain ──────────────────────────────────────────
def make_transmission_flowchart():
dw, dh = 500, 120
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=colors.HexColor("#F0F7FF"),
strokeColor=colors.HexColor("#B0CCE8"), strokeWidth=0.5))
bw, bh = 78, 38
gap = 14
total = 5 * bw + 4 * gap
startx = (dw - total) / 2
cy = dh / 2 - bh / 2
boxes = [
("Source\n(Infected Human)", colors.HexColor("#1A3A5C")),
("Infective Material\n(Droplets/Nuclei)", colors.HexColor("#2E6DA4")),
("Mode\n(Airborne/Droplet)", colors.HexColor("#1B6B3A")),
("Portal of Entry\n(Respiratory Tract)", colors.HexColor("#7D4800")),
("Susceptible\nHost", colors.HexColor("#8B1A1A")),
]
labels = ["", "Nose/Throat\nSecretions", "", "Inhalation", ""]
xs = []
for i, (txt, col) in enumerate(boxes):
x = startx + i * (bw + gap)
xs.append(x)
flow_box(d, x, cy, bw, bh, txt, col, font_size=7)
for i in range(len(boxes) - 1):
ax = xs[i] + bw
ay = cy + bh / 2
flow_arrow(d, ax, ay, xs[i+1], ay)
if labels[i+1]:
flow_label(d, xs[i] + bw + gap/2, ay + 5, labels[i+1], font_size=6.5)
# Title
d.add(String(dw/2, dh - 10, "TRANSMISSION CHAIN OF MEASLES",
fontName="Helvetica-Bold", fontSize=8.5,
fillColor=DARK, textAnchor="middle"))
return d
# ── FLOWCHART 2: Clinical Stages Progression ─────────────────────────────────
def make_stages_flowchart():
dw, dh = 500, 195
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=colors.HexColor("#F8F0FF"),
strokeColor=colors.HexColor("#C8A8E8"), strokeWidth=0.5))
d.add(String(dw/2, dh - 10, "CLINICAL STAGES OF MEASLES — TIME PROGRESSION",
fontName="Helvetica-Bold", fontSize=8.5,
fillColor=PURP, textAnchor="middle"))
stages = [
("EXPOSURE\nDay 0", colors.HexColor("#555555"), ""),
("INCUBATION\nDays 0–10\n(silent)", colors.HexColor("#2E6DA4"),
"Virus replicates\nin lymph nodes"),
("PRODROME\nDays 10–14\nFever, 3 C's,\nKoplik's Spots", colors.HexColor("#1B6B3A"),
"Koplik's spots\n1-2 days before rash"),
("ERUPTIVE\nDay 14+\nBrick-red rash\nCephalocaudal", colors.HexColor("#8B1A1A"),
"MOST infectious\nperiod ends Day 18"),
("POST-MEASLES\nRecovery\nor Complications", colors.HexColor("#7D4800"),
"Watch for SSPE,\npneumonia, otitis"),
]
bw, bh = 82, 62
gap = 10
total = len(stages) * bw + (len(stages)-1) * gap
sx = (dw - total) / 2
cy = 30
for i, (txt, col, note_txt) in enumerate(stages):
x = sx + i*(bw + gap)
flow_box(d, x, cy, bw, bh, txt, col, font_size=7)
if i < len(stages) - 1:
flow_arrow(d, x+bw, cy+bh/2, x+bw+gap, cy+bh/2)
if note_txt:
for j, nl in enumerate(note_txt.split("\n")):
d.add(String(x + bw/2, cy - 10 - j*9, nl,
fontName="Helvetica-Oblique", fontSize=6.5,
fillColor=colors.HexColor("#555555"), textAnchor="middle"))
# Communicability bar
bar_y = 105
comm_x1 = sx + 2*(bw+gap) + bw*0.3
comm_x2 = sx + 3*(bw+gap) + bw*0.7
d.add(Rect(comm_x1, bar_y, comm_x2-comm_x1, 12,
fillColor=colors.HexColor("#FF6B6B"),
strokeColor=colors.HexColor("#CC0000"), strokeWidth=0.5))
d.add(String((comm_x1+comm_x2)/2, bar_y+3,
"Communicable: 4 days before rash → 4 days after rash",
fontName="Helvetica-Bold", fontSize=7,
fillColor=WHITE, textAnchor="middle"))
return d
# ── FLOWCHART 3: Outbreak Control ────────────────────────────────────────────
def make_outbreak_flowchart():
dw, dh = 500, 240
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=colors.HexColor("#FFFDE7"),
strokeColor=colors.HexColor("#F5C518"), strokeWidth=0.5))
d.add(String(dw/2, dh-10, "OUTBREAK CONTROL — STEP BY STEP",
fontName="Helvetica-Bold", fontSize=8.5,
fillColor=ORNG, textAnchor="middle"))
steps = [
("OUTBREAK\nSUSPECTED", colors.HexColor("#1A3A5C")),
("1. NOTIFY\nCMO / IDSP", colors.HexColor("#2E6DA4")),
("2. CONFIRM\nLab Diagnosis", colors.HexColor("#1B6B3A")),
("3. ISOLATE\nCases (4 days)", colors.HexColor("#8B1A1A")),
("4. CONTACT\nTRACING", colors.HexColor("#7D4800")),
("5. VACCINATE\nEligible (<72 hrs)", colors.HexColor("#4A235A")),
("6. IG for\nHigh Risk (<6 days)", colors.HexColor("#0D6B6B")),
("7. DISINFECT\n+ Health Ed", colors.HexColor("#555555")),
("8. EPIDEMIC\nINVESTIGATION", colors.HexColor("#1A3A5C")),
]
bw, bh = 50, 44
per_row = 5
h_gap = 8
v_gap = 22
for i, (txt, col) in enumerate(steps):
row = i // per_row
col_idx = i % per_row
if row == 1:
col_idx = per_row - 1 - col_idx
x = 10 + col_idx * (bw + h_gap)
y = dh - 30 - row * (bh + v_gap) - bh
flow_box(d, x, y, bw, bh, txt, col, font_size=6.5)
# Draw arrows
if i < len(steps) - 1:
next_row = (i+1) // per_row
next_col_idx = (i+1) % per_row
if next_row == 1:
next_col_idx = per_row - 1 - next_col_idx
nx = 10 + next_col_idx*(bw + h_gap)
ny = dh - 30 - next_row*(bh + v_gap) - bh
if row == next_row:
if row == 0:
flow_arrow(d, x+bw, y+bh/2, nx, ny+bh/2)
else:
flow_arrow(d, nx+bw, ny+bh/2, x, y+bh/2)
else:
# turn arrow
cx_now = 10 + (per_row-1)*(bw+h_gap) + bw
flow_arrow(d, x+bw, y+bh/2, cx_now+5, y+bh/2)
flow_arrow(d, cx_now+5, y+bh/2, cx_now+5, ny+bh/2)
flow_arrow(d, cx_now+5, ny+bh/2, nx+bw, ny+bh/2)
return d
# ── FLOWCHART 4: Treatment Algorithm ─────────────────────────────────────────
def make_treatment_flowchart():
dw, dh = 500, 230
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=colors.HexColor("#EDE0F5"),
strokeColor=colors.HexColor("#9B59B6"), strokeWidth=0.5))
d.add(String(dw/2, dh-10, "TREATMENT ALGORITHM FOR MEASLES",
fontName="Helvetica-Bold", fontSize=8.5,
fillColor=PURP, textAnchor="middle"))
# Top box
flow_box(d, 185, 185, 130, 28, "CONFIRMED MEASLES CASE", PURP, font_size=8)
flow_arrow(d, 250, 185, 250, 168)
# Supportive care box
flow_box(d, 145, 135, 210, 30,
"SUPPORTIVE CARE\nParacetamol + ORS/IV fluids + Nutrition", DARK, font_size=7.5)
flow_arrow(d, 250, 135, 250, 118)
# Vitamin A box
flow_box(d, 145, 82, 210, 32,
"VITAMIN A (WHO — ALL children)\n<6m: 50k IU | 6-11m: 100k IU | ≥12m: 200k IU\n× 2 days", GSEC, font_size=7)
flow_arrow(d, 250, 82, 250, 65)
# Decision diamond - complications?
d.add(Polygon([250,62, 310,45, 250,28, 190,45],
fillColor=colors.HexColor("#F39C12"),
strokeColor=colors.HexColor("#D68910"), strokeWidth=0.8))
d.add(String(250, 40, "Bacterial", fontName="Helvetica-Bold",
fontSize=7, fillColor=WHITE, textAnchor="middle"))
d.add(String(250, 31, "Complication?", fontName="Helvetica-Bold",
fontSize=7, fillColor=WHITE, textAnchor="middle"))
# YES branch
flow_arrow(d, 310, 45, 370, 45)
flow_box(d, 370, 30, 110, 30, "ANTIBIOTICS\n(targeted, not routine)", RSEC, font_size=7)
d.add(String(340, 50, "YES", fontName="Helvetica-Bold", fontSize=7,
fillColor=colors.HexColor("#8B1A1A"), textAnchor="middle"))
# NO branch
flow_arrow(d, 250, 28, 250, 14)
flow_box(d, 145, 0, 210, 13, "MONITOR & DISCHARGE when afebrile", MGREY, font_size=7)
d.add(String(262, 19, "NO", fontName="Helvetica-Bold", fontSize=7,
fillColor=GSEC, textAnchor="middle"))
return d
# ════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════════════════
story = []
# ── TITLE BANNER ─────────────────────────────────────────────────────────────
title_sty = S("TT", fontName="Helvetica-Bold", fontSize=22,
textColor=WHITE, alignment=TA_CENTER, leading=28)
sub_sty = S("TS", fontName="Helvetica", fontSize=10.5,
textColor=LIGHT_BLUE, alignment=TA_CENTER, leading=14)
t = Table([[Paragraph("MEASLES (Rubeola)", title_sty)]], colWidths=[CONTENT_W])
t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),DARK),
("TOPPADDING",(0,0),(-1,-1),14),("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),12),("RIGHTPADDING",(0,0),(-1,-1),12),
("ROUNDEDCORNERS",(0,0),(-1,-1),[7,7,0,0])]))
story.append(t)
t2 = Table([[Paragraph("Group: RESPIRATORY | PSM / Community Medicine Proforma | 3rd Year MBBS", sub_sty)]],
colWidths=[CONTENT_W])
t2.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),MED_BLUE),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),12),("RIGHTPADDING",(0,0),(-1,-1),12),
("ROUNDEDCORNERS",(0,0),(-1,-1),[0,0,7,7])]))
story.append(t2)
story.append(sp(0.3))
# Quick facts strip
qf_sty = S("qf", fontName="Helvetica-Bold", fontSize=8.5,
textColor=DARK, alignment=TA_CENTER, leading=12)
qf_val = S("qfv", fontName="Helvetica", fontSize=8.5,
textColor=colors.HexColor("#333333"), alignment=TA_CENTER, leading=12)
qf = [
("Causative Agent", "RNA Paramyxovirus\n(Morbillivirus)"),
("Incubation", "10 days (fever)\n14 days (rash)"),
("Communicability", "4 days before rash\nto 4 days after"),
("Vaccine", "MMR / MR\n(Live attenuated)"),
("Herd Immunity", "≥ 95%"),
]
qf_table = Table([[Paragraph(r[0], qf_sty) for r in qf],
[Paragraph(r[1], qf_val) for r in qf]],
colWidths=[CONTENT_W/5]*5)
qf_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),LIGHT_BLUE),("BACKGROUND",(0,1),(-1,1),LGREY),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
("INNERGRID",(0,0),(-1,-1),0.4,colors.HexColor("#C5D8EE")),
("BOX",(0,0),(-1,-1),0.8,MED_BLUE),("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5]),
("VALIGN",(0,0),(-1,-1),"MIDDLE")]))
story.append(qf_table)
story.append(sp(0.3))
# ════════ SECTION 1: EPIDEMIOLOGY ════════════════════════════════════════════
story.append(sec_hdr("1", "EPIDEMIOLOGY"))
story.append(sp(0.18))
agent_items = [
kv("Agent", "RNA Paramyxovirus — genus Morbillivirus, family Paramyxoviridae"),
kv("Serotypes", "Only 1 serotype known"),
kv("Reservoir", "Humans ONLY — strictly anthroponotic; no animal reservoir"),
kv("Source", "Cases of measles only; NO carrier state"),
kv("Infective material", "Nasal/throat secretions during prodrome & early rash"),
kv("Infectivity", "Attack rate 90% in susceptibles — one of the most communicable diseases"),
]
host_items = [
kv("Age", "6 months–3 years (developing); >5 years (developed). Maternal antibodies protect up to 6–9 months"),
kv("Sex", "Equal incidence"),
kv("Immunity", "One attack → lifelong immunity. Second attacks rare"),
kv("Nutrition", "Malnourished: mortality up to 400× higher. Vitamin A deficiency = major risk"),
kv("Other risks", "Immunocompromised (HIV), infants <1 yr, adults >30 yr"),
]
story.append(two_col(agent_items, host_items, "Agent Factors", "Host Factors"))
story.append(sp(0.2))
env_items = [
kv("Season (India)", "January–April (winter & early spring)"),
kv("Geography", "Endemic worldwide; more severe in developing countries"),
kv("Socioeconomic", "Overcrowding, malnutrition, poor sanitation"),
kv("Epidemic trigger", "Susceptibles reach ~40% of population"),
]
trans_items = [
kv("Mode", "Droplet infection & droplet nuclei (airborne)"),
kv("Portal of entry", "Respiratory tract (also possibly conjunctiva)"),
kv("Incubation period", "10 days to fever; 14 days to rash"),
kv("Communicability", "4 days BEFORE rash to 4 days AFTER rash"),
kv("Special", "Immunocompromised: contagious for entire illness"),
]
story.append(two_col(env_items, trans_items, "Environmental Factors", "Transmission"))
story.append(sp(0.2))
# TRANSMISSION FLOWCHART
story.append(sub_hdr("Transmission Chain — Flowchart"))
story.append(sp(0.1))
tc = make_transmission_flowchart()
story.append(tc)
story.append(sp(0.2))
story.append(sub_hdr("Descriptive Epidemiology"))
story.append(sp(0.08))
story.append(box([
bullet("Pre-vaccine era: ~2.6 million deaths/year worldwide (1980)"),
bullet("2018: ~9.7 million cases, >140,000 deaths — 73% decline since 2000"),
bullet("India 2018: 20,895 cases, 34 deaths (down from 2.47 lakh pre-UIP)"),
bullet("Epidemic pattern: Endemic; cyclical epidemics every 2–3 years in pre-vaccine era"),
bullet("Notifiable disease — compulsory notification under IDSP / IHR 2005"),
]))
story.append(sp(0.3))
# ════════ SECTION 2: CLINICAL FEATURES ═══════════════════════════════════════
story.append(sec_hdr("2", "CLINICAL FEATURES"))
story.append(sp(0.18))
# CLINICAL STAGES FLOWCHART
story.append(sub_hdr("Clinical Stages — Time Progression Flowchart"))
story.append(sp(0.1))
story.append(make_stages_flowchart())
story.append(sp(0.2))
story.append(sub_hdr("Detailed Stage-wise Features"))
story.append(sp(0.08))
stage_data = [
[Paragraph("STAGE 1 — Prodromal (Days 10–14)",
S("s1h", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, alignment=TA_CENTER, leading=13)),
Paragraph("STAGE 2 — Eruptive / Rash (Day 14+)",
S("s2h", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, alignment=TA_CENTER, leading=13)),
Paragraph("STAGE 3 — Post-Measles",
S("s3h", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, alignment=TA_CENTER, leading=13))],
[Paragraph("• High fever\n• Coryza (sneezing, nasal discharge)\n• Cough\n• Conjunctivitis — redness, lacrimation, photophobia\n• Vomiting / diarrhoea\n• <b>Koplik's spots</b> (1–2 days before rash) — bluish-white on buccal mucosa — PATHOGNOMONIC",
S("sc1", fontName="Helvetica", fontSize=8.5, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4)),
Paragraph("• Rash appears Day 14 — maculopapular, BRICK-RED\n• Begins on FACE & behind ears\n• Spreads CEPHALOCAUDAL (face → neck → trunk → limbs)\n• Confluent on face\n• Fever rises then falls by lysis\n• Fades in same order → brownish discolouration + branny desquamation",
S("sc2", fontName="Helvetica", fontSize=8.5, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4)),
Paragraph("• Weight loss, weakness\n• Increased susceptibility to superinfections\n• Risk of malnutrition & growth retardation\n• Diarrhoea, cancrum oris\n• Reactivation of pulmonary TB",
S("sc3", fontName="Helvetica", fontSize=8.5, textColor=colors.HexColor("#1a1a1a"), leading=13, leftIndent=4))],
]
cw = CONTENT_W / 3
stage_table = Table(stage_data, colWidths=[cw, cw, cw])
stage_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,0),colors.HexColor("#1B5E8C")),
("BACKGROUND",(1,0),(1,0),colors.HexColor("#1A6B42")),
("BACKGROUND",(2,0),(2,0),colors.HexColor("#7D4800")),
("BACKGROUND",(0,1),(0,1),colors.HexColor("#EBF4FF")),
("BACKGROUND",(1,1),(1,1),colors.HexColor("#EBF8F2")),
("BACKGROUND",(2,1),(2,1),colors.HexColor("#FFF8EC")),
("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),7),("RIGHTPADDING",(0,0),(-1,-1),7),
("INNERGRID",(0,0),(-1,-1),0.5,colors.HexColor("#CCCCCC")),
("BOX",(0,0),(-1,-1),0.8,DARK),("VALIGN",(0,0),(-1,-1),"TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5])]))
story.append(stage_table)
story.append(sp(0.2))
# PATHOGNOMONIC BOX
path_table = Table([[Paragraph(
"PATHOGNOMONIC TRIAD: Fever + Koplik's Spots + Cephalocaudal Maculopapular Rash\n"
"CLINICAL RULE (Park's): Diagnosis is unlikely in any febrile rash where red eyes AND cough are ABSENT → 3 C's = Cough, Coryza, Conjunctivitis",
S("pb", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, alignment=TA_CENTER, leading=14))
]], colWidths=[CONTENT_W])
path_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),PURP),
("TOPPADDING",(0,0),(-1,-1),8),("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),12),("RIGHTPADDING",(0,0),(-1,-1),12),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5])]))
story.append(path_table)
story.append(sp(0.2))
# ── CLINICAL PHOTOS SECTION ───────────────────────────────────────────────────
story.append(sub_hdr("Clinical Photographs", accent=LIGHT_BLUE, txt_col=DARK))
story.append(sp(0.1))
img_w = (CONTENT_W - 0.5*cm) / 3
koplik_img = img_with_caption(IMG_DIR+"koplik_spots.jpg", img_w, "Koplik's Spots — bluish-white\non buccal mucosa (pathognomonic)")
rash_face = img_with_caption(IMG_DIR+"measles_rash_face.jpg", img_w, "Measles rash on face —\nbrick-red maculopapular, Day 14")
rash_body = img_with_caption(IMG_DIR+"measles_rash_body.jpg", img_w, "Rash on trunk — cephalocaudal\nspread (CDC / Public Domain)")
photo_table = Table([[koplik_img, rash_face, rash_body]],
colWidths=[img_w, img_w, img_w])
photo_table.setStyle(TableStyle([
("ALIGN",(0,0),(-1,-1),"CENTER"),
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(-1,-1),4),
("RIGHTPADDING",(0,0),(-1,-1),4),
("TOPPADDING",(0,0),(-1,-1),2),
("BOTTOMPADDING",(0,0),(-1,-1),2),
]))
story.append(photo_table)
story.append(sp(0.3))
# ════════ SECTION 3: DIAGNOSIS ════════════════════════════════════════════════
story.append(sec_hdr("3", "DIAGNOSIS", bg=GSEC))
story.append(sp(0.18))
diag_l = [
kv("Clinical diagnosis", "Koplik's spots + 3 C's + characteristic rash"),
kv("Specific IgM (ELISA)", "Preferred method. May be false-negative in first 72 hrs — repeat if negative and rash >72 hrs"),
kv("RT-PCR (Gold Standard)", "Measles RNA in throat swab, nasal swab, urine — most sensitive; allows viral genotyping"),
kv("IgG paired sera", "Fourfold rise in acute + convalescent samples (≥10 days apart)"),
kv("Virus isolation", "NOT recommended routinely — takes up to 2 weeks"),
]
case_def = [
kv("Suspected case", "Fever + generalised maculopapular rash + one of: cough / coryza / conjunctivitis"),
kv("Confirmed case", "IgM positive OR RT-PCR positive OR epi-link to confirmed case"),
kv("Notifiable", "Yes — compulsory. Notify CMO, IDSP, IHR 2005"),
]
story.append(two_col(diag_l, case_def,
"Laboratory Diagnosis", "WHO Case Definition",
lbg=GLIGHT, rbg=GLIGHT))
story.append(sp(0.3))
# ════════ SECTION 4: TREATMENT ════════════════════════════════════════════════
story.append(sec_hdr("4", "TREATMENT", bg=PURP))
story.append(sp(0.18))
story.append(sub_hdr("Treatment Algorithm — Flowchart", accent=PURPLIGHT, txt_col=PURP))
story.append(sp(0.1))
story.append(make_treatment_flowchart())
story.append(sp(0.2))
tx_l = [
kv("Specific antiviral", "NONE available"),
kv("Antipyretics", "Paracetamol — AVOID aspirin (Reye's syndrome risk)"),
kv("Hydration", "ORS / IV fluids if dehydrated"),
kv("Nutrition", "Continue breastfeeding; age-appropriate food"),
kv("Antibiotics", "Only for confirmed bacterial secondary infections — NOT routine"),
]
vit_a = [
kv("WHO recommendation", "Vitamin A for ALL children with measles"),
kv("< 6 months", "50,000 IU × 2 days"),
kv("6–11 months", "100,000 IU × 2 days"),
kv("≥ 12 months", "200,000 IU × 2 days"),
kv("3rd dose", "2–6 weeks later if Vitamin A deficiency signs"),
kv("Isolation", "Airborne: 4 days after rash (immunocompetent); full illness (immunocompromised)"),
]
story.append(two_col(tx_l, vit_a,
"General & Supportive Treatment", "Vitamin A Treatment (Key PSM Point)",
lbg=PURPLIGHT, rbg=PURPLIGHT))
story.append(sp(0.3))
# ════════ SECTION 5: COMPLICATIONS ════════════════════════════════════════════
story.append(sec_hdr("5", "COMPLICATIONS", bg=RSEC))
story.append(sp(0.18))
comp_data = [
[Paragraph("System", S("ch", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13)),
Paragraph("Complication", S("ch2", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13)),
Paragraph("Notes", S("ch3", fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE, leading=13))],
]
csty = S("cs", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13)
raw = [
("Respiratory", "Pneumonia (1–6%)", "Most common cause of measles DEATH"),
("Respiratory", "Laryngotracheobronchitis (Croup)", "In young children"),
("Ear", "Otitis media (7–9%)", "Most COMMON complication overall"),
("GI", "Diarrhoea (8%)", "Protein-losing enteropathy (developing countries)"),
("CNS", "Post-infectious encephalitis", "1–4 per 1000–2000 cases"),
("CNS — LATE ⚠️", "SSPE", "1 per 10,000–1,00,000 — occurs years later — INVARIABLY FATAL"),
("Immunocompromised", "Measles inclusion-body encephalitis (MIBE)", "Acute progressive; fatal"),
("Nutritional", "Malnutrition, Vit A deficiency, Cancrum oris", "Especially developing countries"),
("Pregnancy", "Spontaneous abortion, premature delivery", "NO congenital anomalies"),
]
for row in raw:
comp_data.append([Paragraph(row[0], csty), Paragraph(row[1], csty), Paragraph(row[2], csty)])
comp_table = Table(comp_data, colWidths=[CONTENT_W*0.22, CONTENT_W*0.38, CONTENT_W*0.40])
comp_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),RSEC),
("ROWBACKGROUNDS",(0,1),(-1,-1),[RLIGHT, colors.HexColor("#FFF0F0")]),
("BACKGROUND",(0,6),(-1,6),colors.HexColor("#FFD0D0")),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),8),("RIGHTPADDING",(0,0),(-1,-1),8),
("INNERGRID",(0,0),(-1,-1),0.3,colors.HexColor("#FFAAAA")),
("BOX",(0,0),(-1,-1),0.8,RSEC),("VALIGN",(0,0),(-1,-1),"TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5])]))
story.append(comp_table)
story.append(sp(0.12))
story.append(box([
bullet("CFR developing countries: 3–6% (up to 30% in malnourished/displaced)"),
bullet("CFR developed countries: 0.01–0.1%"),
bullet("Highest mortality: Children <1 yr, adults >30 yr, HIV-infected (CFR up to 50%)"),
], bg=RLIGHT, border=RSEC))
story.append(sp(0.3))
# ════════ SECTION 6: PREVENTION & CONTROL ════════════════════════════════════
story.append(sec_hdr("6", "PREVENTION AND CONTROL [Most Scoring Section]", bg=GSEC))
story.append(sp(0.18))
story.append(sub_hdr("A. Primary Prevention — Health Promotion", accent=GLIGHT, txt_col=GSEC))
story.append(sp(0.08))
story.append(box([
bullet("Health education about measles, complications, and vaccine importance"),
bullet("Vitamin A supplementation for all under-5 children in endemic areas"),
bullet("Nutritional improvement — reduce malnutrition"),
bullet("Reduction of overcrowding; safe water supply; food hygiene"),
], bg=GLIGHT, border=GSEC))
story.append(sp(0.18))
story.append(sub_hdr("B. Specific Protection — Immunization", accent=GLIGHT, txt_col=GSEC))
story.append(sp(0.08))
vacc_data = [
[Paragraph("Feature", S("vh", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, leading=13)),
Paragraph("Details", S("vh2", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, leading=13))],
]
vacc_rows_raw = [
("Vaccine name", "MMR (Measles-Mumps-Rubella) / MR vaccine in India"),
("Vaccine type", "LIVE ATTENUATED virus vaccine"),
("Schedule (India NIS)", "1st dose: 9–12 months (MR); 2nd dose: 16–24 months"),
("Route & dose", "Subcutaneous, 0.5 mL"),
("Cold chain", "+2°C to +8°C; sensitive to heat and light"),
("Efficacy", "Single dose ~93%; Two doses ~97%"),
("Herd immunity threshold", "≥95% population immunity to interrupt transmission"),
("Contraindications", "Pregnancy, severe immunodeficiency, severe allergy to prior dose"),
("Post-exposure vaccine", "Within 72 hours of exposure — prevents or modifies disease"),
("Post-exposure IG", "Within 6 days — for infants <12m, pregnant women, immunocompromised"),
]
vsty = S("vs", fontName="Helvetica", fontSize=8.8, textColor=colors.HexColor("#1a1a1a"), leading=13)
for row in vacc_rows_raw:
vacc_data.append([
Paragraph(row[0], S("vk", fontName="Helvetica-Bold", fontSize=8.8, textColor=DARK, leading=13)),
Paragraph(row[1], vsty)
])
vacc_table = Table(vacc_data, colWidths=[CONTENT_W*0.32, CONTENT_W*0.68])
vacc_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,0),GSEC),
("ROWBACKGROUNDS",(0,1),(-1,-1),[GLIGHT, colors.HexColor("#E8F8EE")]),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),8),("RIGHTPADDING",(0,0),(-1,-1),8),
("INNERGRID",(0,0),(-1,-1),0.3,colors.HexColor("#A8D5B5")),
("BOX",(0,0),(-1,-1),0.8,GSEC),("VALIGN",(0,0),(-1,-1),"TOP"),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5])]))
story.append(vacc_table)
story.append(sp(0.18))
sec_prev = [
bullet("Active case detection + passive surveillance (IDSP / IHIP)"),
bullet("Case-based measles-rubella surveillance with laboratory support"),
bullet("Contact tracing of all exposed individuals"),
bullet("Outbreak investigation: attack rate, spot map, epidemic curve"),
]
tert_prev = [
bullet("Management of SSPE (supportive only — no cure)"),
bullet("Rehabilitation: hearing loss, neurological damage"),
bullet("Nutritional rehabilitation post-measles"),
]
story.append(two_col(sec_prev, tert_prev,
"C. Secondary Prevention",
"D. Tertiary Prevention",
lbg=GLIGHT, rbg=GLIGHT))
story.append(sp(0.18))
story.append(sub_hdr("E. Outbreak Control — Flowchart", accent=ORNGLIGHT, txt_col=ORNG))
story.append(sp(0.1))
story.append(make_outbreak_flowchart())
story.append(sp(0.18))
story.append(sub_hdr("F. National Programme & WHO Goals", accent=LIGHT_BLUE, txt_col=DARK))
story.append(sp(0.08))
story.append(box([
kv("UIP", "Universal Immunization Programme — includes MR vaccine in NIS"),
kv("Mission Indradhanush", "Intensified immunization for unvaccinated/under-vaccinated children"),
kv("MR Campaign", "Nationwide MR vaccination (9 months to <15 years) across India"),
kv("India Goal", "Measles elimination and Rubella/CRS control by 2023"),
kv("WHO Targets", "MCV1 ≥90% nationally; incidence <5 per million; ≥95% mortality reduction vs 2000"),
], bg=LIGHT_BLUE, border=MED_BLUE))
story.append(sp(0.3))
# ════════ EXAM QUICK RECALL ══════════════════════════════════════════════════
recall_hdr = Table([[Paragraph("EXAM QUICK RECALL — MEASLES",
S("rec", fontName="Helvetica-Bold", fontSize=9.5, textColor=DARK, alignment=TA_CENTER, leading=14))]],
colWidths=[CONTENT_W])
recall_hdr.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),ACCENT),
("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),10),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,0,0])]))
story.append(recall_hdr)
recall_items = [
"Pathognomonic = Koplik's spots (bluish-white on buccal mucosa opposite lower molars)",
"3 C's = Cough, Coryza, Conjunctivitis — if absent, question the diagnosis",
"Rash = Brick-red maculopapular, CEPHALOCAUDAL spread, appears Day 14",
"Communicability = 4 days before rash to 4 days after rash",
"Treatment = NO specific drug; Vitamin A is the KEY (dose by age group)",
"Worst complication = SSPE (years later, invariably fatal)",
"Most common complication = Otitis media; Leading cause of death = Pneumonia",
"Vaccine = MMR/MR — LIVE attenuated; Herd immunity = ≥95%; 2-dose schedule",
"National programs = UIP, Mission Indradhanush, MR Campaign",
"Notification = Compulsory under IDSP / IHR 2005",
]
recall_rows = [[Paragraph(f"▶ {item}",
S("ri", fontName="Helvetica", fontSize=9, textColor=colors.HexColor("#1a1a1a"),
leading=13, leftIndent=6))] for item in recall_items]
recall_table = Table(recall_rows, colWidths=[CONTENT_W])
recall_table.setStyle(TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[colors.HexColor("#FFFDE7"), colors.HexColor("#FFF9C4")]),
("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),10),("RIGHTPADDING",(0,0),(-1,-1),10),
("BOX",(0,0),(-1,-1),0.8,ACCENT),
("ROUNDEDCORNERS",(0,0),(-1,-1),[0,0,5,5])]))
story.append(recall_table)
story.append(sp(0.2))
# Footer
foot_table = Table([[Paragraph(
"Sources: Park's Textbook of PSM (23rd ed.) | Red Book 2021 (AAP) | Goldman-Cecil Medicine "
"| Images: CDC / Wikimedia Commons (Public Domain) — Orris Medical Assistant",
S("ft", fontName="Helvetica-Oblique", fontSize=8, textColor=WHITE, alignment=TA_CENTER, leading=11))]],
colWidths=[CONTENT_W])
foot_table.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),DARK),
("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6),
("LEFTPADDING",(0,0),(-1,-1),10),("RIGHTPADDING",(0,0),(-1,-1),10),
("ROUNDEDCORNERS",(0,0),(-1,-1),[5,5,5,5])]))
story.append(foot_table)
doc.build(story)
print(f"Done: {OUTPUT}")
python3 /home/daytona/workspace/disease-pdfs/measles_with_images.py 2>&1
python3 -c "from reportlab.graphics.shapes import *; print([x for x in dir() if …
~/disease-pdfs/measles_with_images.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/disease-pdfs/measles_with_images.py'
python3 /home/daytona/workspace/disease-pdfs/measles_with_images.py 2>&1
ls -lh /home/daytona/workspace/disease-pdfs/Measles_Proforma_Full.pdf
Measles Proforma Full
PDF Document · PDF
Ok so no more pdf making just give the info in tex .. stick to the proforma . Give according to the disease I ask ok??