Hi
Can you make notes with images flowchart and export as pdf
What topic should the notes cover? · How detailed should the notes be?
Which medical/biology topic specifically?
Sources Purple book of immunization, Nelson and opghai textbook, iap guidelines
What is the exact topic for the notes? (e.g., Immunization schedule, Vaccine-preventable diseases, Cold chain, Contraindications to vaccines, etc.)
Rota vaccine Pneumococcal vaccine
IAP immunization guidelines 2025 rotavirus pneumococcal vaccine schedule India
I want 1 vaccine in 1 page pdf for a 5 mark question
IAP immunization schedule 2025 rotavirus pneumococcal vaccine India guidelines
https://drbaweja.com/wp-content/uploads/2026/05/acviprecomme…
Medical flowchart for Rotavirus Vaccine (exam-ready, 5-mark format). Clean professional style, white background, blue and green color scheme. Include the following sections as a structured flowchart with boxes and arrows: ROTAVIRUS VACCINE | [PATHOGEN BOX]: Rotavirus - dsRNA virus, Group A most common, causes severe diarrheal disease in infants | [AVAILABLE VACCINES BOX]: - RV1 (Rotarix): Monovalent, live oral, human rotavirus strain - RV5 (RotaTeq): Pentavalent, live oral, bovine-human reassortant - ROTAVAC (India): Monovalent, 116E strain, indigenous - ROTAVAC 5D: Liquid formulation by Bharat Biotech | [DOSE & SCHEDULE TABLE]: Rotarix: 2 doses - 6w & 10w (IAP) | RotaTeq/ROTAVAC: 3 doses - 6w, 10w, 14w | [ROUTE & DOSE BOX]: Oral | 1.5 mL (Rotarix) | 2 mL (RotaTeq) | 0.5 mL (ROTAVAC) | [IAP 2025 SCHEDULE]: 6 weeks, 10 weeks, 14 weeks (3-dose for ROTAVAC/RotaTeq); 6w & 10w for Rotarix | [COLD CHAIN]: 2-8°C | Do NOT freeze | [CONTRAINDICATIONS]: SCID, History of intussusception, Hypersensitivity to components, Age >8 months for last dose | [KEY POINTS]: First dose max by 14 weeks 6 days | Last dose by 8 months | Min interval: 4 weeks | Can give with other vaccines
Medical flowchart for Pneumococcal Vaccine (PCV) - exam-ready, 5-mark format. Clean professional style, white background, purple and orange color scheme. Structured flowchart with boxes and arrows: PNEUMOCOCCAL VACCINE | [PATHOGEN BOX]: Streptococcus pneumoniae - Gram positive diplococcus, >90 serotypes, causes pneumonia, meningitis, bacteremia, otitis media | [TYPES OF VACCINES]: PPV23 (Polysaccharide) --- PCV10 --- PCV13 --- PCV14 (Abbott) --- PCV20 (adults) | [PCV vs PPV23 COMPARISON BOX]: PCV: Conjugate, T-cell dependent, used <2 yrs | PPV23: Polysaccharide, T-cell independent, used >2 yrs | [IAP 2025 SCHEDULE BOX]: Primary: 3 doses at 6w, 10w, 14w (3p+0) OR: 2 doses + 1 booster (2p+1): 6w & 14w + booster at 9-15m Booster: PCV booster at 15 months (IAP recommended) UIP India: PCV1 at 6w, PCV2 at 10w, PCV3 at 14w, Booster at 9m | [DOSE & ROUTE]: 0.5 mL IM | Anterolateral thigh in infants | Deltoid in older children | [COLD CHAIN]: 2-8°C | Do NOT freeze | Discard if frozen | [CONTRAINDICATIONS]: Anaphylaxis to previous dose | Revaccination not recommended after anaphylaxis | [NEWER PCVs 2025]: PCV14-TT (Apexxnar, Abbott) 6-10-14w schedule | Vaximune-13 / Pneumoguard-13 (TT-conjugate) | PCV20 for adults >18 yrs only
mkdir -p /home/daytona/workspace/vaccine-notes && ls /home/daytona/workspace/vaccine-notes/
~/vaccine-notes/create_vaccine_notes.py
import requests
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
from io import BytesIO
import os
# ---- Download images ----
rota_url = "https://cdn.orris.care/image-gen/38c82e5c5aba49fdb61f18e014c5654f.png"
pcv_url = "https://cdn.orris.care/image-gen/6f296adcf4c5476f9491f8185b8e5327.png"
def download_img(url, path):
r = requests.get(url, timeout=30)
with open(path, "wb") as f:
f.write(r.content)
print(f"Downloaded: {path}")
download_img(rota_url, "/home/daytona/workspace/vaccine-notes/rota_flowchart.png")
download_img(pcv_url, "/home/daytona/workspace/vaccine-notes/pcv_flowchart.png")
# ---- Styles ----
W, H = A4
doc = SimpleDocTemplate(
"/home/daytona/workspace/vaccine-notes/Vaccine_Notes_5Mark.pdf",
pagesize=A4,
leftMargin=1.5*cm, rightMargin=1.5*cm,
topMargin=1.2*cm, bottomMargin=1.2*cm
)
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
"VacTitle",
parent=styles["Heading1"],
fontSize=16,
textColor=colors.HexColor("#1a3c6e"),
spaceAfter=4,
spaceBefore=2,
fontName="Helvetica-Bold",
alignment=TA_CENTER
)
subtitle_style = ParagraphStyle(
"SubTitle",
parent=styles["Normal"],
fontSize=8,
textColor=colors.HexColor("#555555"),
spaceAfter=6,
alignment=TA_CENTER,
fontName="Helvetica-Oblique"
)
section_style = ParagraphStyle(
"Section",
parent=styles["Heading2"],
fontSize=10,
textColor=colors.white,
fontName="Helvetica-Bold",
spaceBefore=6,
spaceAfter=2,
leftIndent=0,
backColor=colors.HexColor("#1a3c6e"),
borderPad=3
)
section_style_green = ParagraphStyle(
"SectionGreen",
parent=section_style,
backColor=colors.HexColor("#1e6e3c"),
)
body_style = ParagraphStyle(
"Body",
parent=styles["Normal"],
fontSize=8.5,
leading=12,
spaceAfter=3,
fontName="Helvetica",
textColor=colors.HexColor("#222222")
)
bullet_style = ParagraphStyle(
"Bullet",
parent=body_style,
leftIndent=12,
bulletIndent=4,
spaceAfter=2,
fontSize=8.5
)
key_style = ParagraphStyle(
"Key",
parent=body_style,
fontSize=8.5,
fontName="Helvetica-Bold",
textColor=colors.HexColor("#b30000")
)
footer_style = ParagraphStyle(
"Footer",
parent=styles["Normal"],
fontSize=7,
textColor=colors.HexColor("#888888"),
alignment=TA_CENTER
)
def make_section_header(text, color_hex="#1a3c6e"):
return Table(
[[Paragraph(f"<b>{text}</b>", ParagraphStyle(
"SH", parent=styles["Normal"],
fontSize=9.5, textColor=colors.white,
fontName="Helvetica-Bold"
))]],
colWidths=[W - 3*cm],
style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), colors.HexColor(color_hex)),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 6),
])
)
def make_table(data, col_widths=None, header_color="#1a3c6e"):
if col_widths is None:
col_widths = [(W - 3*cm) / len(data[0])] * len(data[0])
table_data = []
for i, row in enumerate(data):
table_data.append([
Paragraph(str(cell), ParagraphStyle(
"TC",
parent=styles["Normal"],
fontSize=8,
fontName="Helvetica-Bold" if i == 0 else "Helvetica",
textColor=colors.white if i == 0 else colors.HexColor("#222222"),
alignment=TA_CENTER
)) for cell in row
])
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor(header_color)),
("BACKGROUND", (0,1), (-1,-1), colors.HexColor("#f5f8ff")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.HexColor("#f5f8ff"), colors.HexColor("#eaf0ff")]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#cccccc")),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
])
return Table(table_data, colWidths=col_widths, style=ts)
# ===== PAGE 1: ROTAVIRUS VACCINE =====
page1 = []
page1.append(Paragraph("ROTAVIRUS VACCINE", title_style))
page1.append(Paragraph("Sources: Park's Preventive Medicine | Red Book 2021 | IAP-ACVIP 2025 Guidelines", subtitle_style))
page1.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#1a3c6e"), spaceAfter=4))
# Key points banner
kp_table = Table([[
Paragraph("Oral Live Attenuated Vaccine", ParagraphStyle("kp", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#1a3c6e"), alignment=TA_CENTER)),
Paragraph("Prevents Rotavirus Gastroenteritis", ParagraphStyle("kp2", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#1e6e3c"), alignment=TA_CENTER)),
Paragraph("Start at 6 Weeks | Complete by 8 Months", ParagraphStyle("kp3", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#8B4513"), alignment=TA_CENTER)),
]], colWidths=[(W-3*cm)/3]*3,
style=TableStyle([
("BOX", (0,0), (-1,-1), 1, colors.HexColor("#1a3c6e")),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#cccccc")),
("BACKGROUND", (0,0), (0,0), colors.HexColor("#e8f0fe")),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#e8f5ec")),
("BACKGROUND", (2,0), (2,0), colors.HexColor("#fff3e0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
page1.append(kp_table)
page1.append(Spacer(1, 4))
# Two column layout: Left = notes, Right = flowchart
left_content = []
left_content.append(make_section_header("PATHOGEN", "#1a3c6e"))
left_content.append(Paragraph("• Rotavirus: double-stranded RNA (dsRNA) virus, family Reoviridae", bullet_style))
left_content.append(Paragraph("• Group A most important cause of severe diarrhea in infants <5 years", bullet_style))
left_content.append(Paragraph("• Leading cause of vaccine-preventable diarrheal deaths in children", bullet_style))
left_content.append(Spacer(1, 3))
left_content.append(make_section_header("AVAILABLE VACCINES (India)", "#1e6e3c"))
vax_data = [
["Vaccine", "Type", "Doses", "Strain"],
["Rotarix (RV1)", "Monovalent", "2", "Human (89-12)"],
["RotaTeq (RV5)", "Pentavalent", "3", "Bovine-human"],
["ROTAVAC", "Monovalent", "3", "116E (India)"],
["ROTAVAC 5D", "Monovalent", "3", "116E liquid"],
]
left_content.append(make_table(vax_data, header_color="#1e6e3c"))
left_content.append(Spacer(1, 3))
left_content.append(make_section_header("IAP 2025 SCHEDULE", "#6a1a6e"))
sched_data = [
["Vaccine", "Dose 1", "Dose 2", "Dose 3", "Last Dose"],
["Rotarix", "6 weeks", "10 weeks", "-", "By 8 months"],
["RotaTeq", "6 weeks", "10 weeks", "14 weeks", "By 8 months"],
["ROTAVAC/5D", "6 weeks", "10 weeks", "14 weeks", "By 8 months"],
]
left_content.append(make_table(sched_data, header_color="#6a1a6e"))
left_content.append(Spacer(1, 3))
left_content.append(make_section_header("DOSE, ROUTE & COLD CHAIN", "#8B4513"))
left_content.append(Paragraph("• <b>Route:</b> Oral (NOT injectable)", bullet_style))
left_content.append(Paragraph("• <b>Dose:</b> 1.5 mL (Rotarix) | 2 mL (RotaTeq) | 0.5 mL (ROTAVAC)", bullet_style))
left_content.append(Paragraph("• <b>Storage:</b> 2–8°C | Do NOT freeze | Protected from light", bullet_style))
left_content.append(Paragraph("• <b>First dose:</b> Not before 6 weeks, not after 14 weeks 6 days", bullet_style))
left_content.append(Paragraph("• <b>Min interval:</b> 4 weeks between doses", bullet_style))
left_content.append(Spacer(1, 3))
left_content.append(make_section_header("CONTRAINDICATIONS", "#b30000"))
left_content.append(Paragraph("• Severe Combined Immunodeficiency (SCID) - absolute CI", bullet_style))
left_content.append(Paragraph("• History of intussusception - absolute CI", bullet_style))
left_content.append(Paragraph("• Hypersensitivity/anaphylaxis to any vaccine component", bullet_style))
left_content.append(Paragraph("• Age >8 months for last dose", bullet_style))
left_content.append(Spacer(1, 3))
left_content.append(make_section_header("SPECIAL SITUATIONS", "#2c5f8a"))
left_content.append(Paragraph("• <b>Preterm infants:</b> Vaccinate at chronological age ≥6 weeks if clinically stable", bullet_style))
left_content.append(Paragraph("• <b>Immunocompromised household:</b> Can vaccinate; avoid diaper handling for 4 weeks", bullet_style))
left_content.append(Paragraph("• <b>NICU infants:</b> Vaccinate at discharge or at recommended chronologic age", bullet_style))
left_content.append(Paragraph("• <b>Mild illness:</b> Not a contraindication; can vaccinate", bullet_style))
left_content.append(Paragraph("• <b>Mixed series:</b> If any dose was RV5 or unknown → give total 3 doses", bullet_style))
# Build left column as table
left_table_content = [[item] for item in left_content]
# Actually, render as a flat list in left column, flowchart in right column
left_col = left_content # list of flowables
# Right column: flowchart image
right_col_content = [
Spacer(1, 10),
Image("/home/daytona/workspace/vaccine-notes/rota_flowchart.png",
width=8.5*cm, height=14*cm, kind='proportional'),
]
# Two column table
two_col = Table(
[[left_col, right_col_content]],
colWidths=[(W-3*cm)*0.62, (W-3*cm)*0.38]
)
two_col.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (0,0), 0),
("RIGHTPADDING", (0,0), (0,0), 6),
("LEFTPADDING", (1,0), (1,0), 4),
("RIGHTPADDING", (1,0), (1,0), 0),
]))
page1.append(two_col)
page1.append(Spacer(1, 4))
page1.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#1a3c6e"), spaceAfter=2))
page1.append(Paragraph(
"Sources: Park's Textbook of Preventive & Social Medicine | Red Book 2021 (AAP) | IAP-ACVIP Recommended Immunization Schedule 2025 | IAP Guidebook on Immunization 2025",
footer_style
))
page1.append(PageBreak())
# ===== PAGE 2: PNEUMOCOCCAL VACCINE =====
page2 = []
page2.append(Paragraph("PNEUMOCOCCAL VACCINE (PCV / PPV)", title_style))
page2.append(Paragraph("Sources: Park's Preventive Medicine | IAP-ACVIP 2025 Guidelines | IAP Guidebook on Immunization 2025", subtitle_style))
page2.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#6a1a6e"), spaceAfter=4))
# Key banner
kp2_table = Table([[
Paragraph("IM Conjugate Vaccine (PCV)", ParagraphStyle("kp", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#6a1a6e"), alignment=TA_CENTER)),
Paragraph("Prevents Pneumonia, Meningitis, Septicemia", ParagraphStyle("kp2", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#1e6e3c"), alignment=TA_CENTER)),
Paragraph("Schedule: 6w-10w-14w + Booster 15m", ParagraphStyle("kp3", parent=styles["Normal"], fontSize=8, fontName="Helvetica-Bold", textColor=colors.HexColor("#8B4513"), alignment=TA_CENTER)),
]], colWidths=[(W-3*cm)/3]*3,
style=TableStyle([
("BOX", (0,0), (-1,-1), 1, colors.HexColor("#6a1a6e")),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#cccccc")),
("BACKGROUND", (0,0), (0,0), colors.HexColor("#f5e8ff")),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#e8f5ec")),
("BACKGROUND", (2,0), (2,0), colors.HexColor("#fff3e0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
page2.append(kp2_table)
page2.append(Spacer(1, 4))
left2 = []
left2.append(make_section_header("PATHOGEN", "#6a1a6e"))
left2.append(Paragraph("• Streptococcus pneumoniae: Gram-positive diplococcus, lancet-shaped", bullet_style))
left2.append(Paragraph("• >90 serotypes; capsular polysaccharide is main virulence factor", bullet_style))
left2.append(Paragraph("• Diseases: Pneumonia, Meningitis, Bacteremia, Otitis media, Sinusitis", bullet_style))
left2.append(Spacer(1, 3))
left2.append(make_section_header("TYPES OF VACCINES", "#1a3c6e"))
pcv_types = [
["Vaccine", "Serotypes", "Age Group", "T-cell Response"],
["PPV23", "23", ">2 years", "Independent (weak in <2yr)"],
["PCV10", "10", "Infants/Children", "Dependent (strong)"],
["PCV13", "13", "Infants/Children", "Dependent (strong)"],
["PCV14-TT", "14", "6-10-14 weeks", "Dependent (strong)"],
["PCV20", "20", ">18 years", "Dependent (adults only)"],
]
left2.append(make_table(pcv_types, header_color="#1a3c6e"))
left2.append(Spacer(1, 3))
left2.append(make_section_header("IAP 2025 SCHEDULE", "#1e6e3c"))
left2.append(Paragraph("<b>Standard 3p+0 schedule (IAP/UIP):</b>", body_style))
left2.append(Paragraph("• PCV1 at 6 weeks | PCV2 at 10 weeks | PCV3 at 14 weeks", bullet_style))
left2.append(Paragraph("• Booster: 15 months of age (IAP recommended)", bullet_style))
left2.append(Paragraph("<b>Alternate 2p+1 schedule (WHO):</b>", body_style))
left2.append(Paragraph("• 2 primary doses in infancy (≥4–8 weeks apart) + 1 booster at 9–15 months", bullet_style))
left2.append(Paragraph("• PCV14-TT (Abbott/Apexxnar): 6-10-14w schedule, no booster currently recommended", bullet_style))
left2.append(Spacer(1, 3))
left2.append(make_section_header("DOSE, ROUTE & COLD CHAIN", "#8B4513"))
left2.append(Paragraph("• <b>Dose:</b> 0.5 mL IM", bullet_style))
left2.append(Paragraph("• <b>Site:</b> Anterolateral thigh (infants) | Deltoid (older children)", bullet_style))
left2.append(Paragraph("• <b>Storage:</b> 2–8°C | NEVER freeze | Discard if frozen", bullet_style))
left2.append(Paragraph("• <b>PPV23:</b> 0.5 mL IM or SC (25 µg per serotype) | Single dose | Adults/splenectomy", bullet_style))
left2.append(Spacer(1, 3))
left2.append(make_section_header("CONTRAINDICATIONS & ADVERSE EFFECTS", "#b30000"))
left2.append(Paragraph("• Anaphylaxis to previous dose or vaccine component - <b>absolute CI</b>", bullet_style))
left2.append(Paragraph("• Revaccination NOT recommended after anaphylaxis", bullet_style))
left2.append(Paragraph("• <b>AEFI:</b> Local pain, redness, swelling in 30–50% | Systemic reactions uncommon", bullet_style))
left2.append(Spacer(1, 3))
left2.append(make_section_header("SPECIAL NOTES (IAP 2025)", "#2c5f8a"))
left2.append(Paragraph("• <b>HIV positive / Preterm:</b> If 3 primary doses before 12m → booster in 2nd year of life", bullet_style))
left2.append(Paragraph("• <b>PPV23 indications:</b> Splenectomy, sickle cell disease, chronic cardiac/pulmonary/renal/hepatic disease, diabetes, malignancy, organ transplant, age >65 yrs", bullet_style))
left2.append(Paragraph("• <b>PCV + PPV23 combo:</b> PCV first, then PPV23 ≥8 weeks later for high-risk adults", bullet_style))
left2.append(Paragraph("• <b>Newer PCVs 2025:</b> Vaximune-13 / Pneumoguard-13 (TT-conjugate, 6-10-14w) | PCV20 for adults >18 yrs only", bullet_style))
# Right column: flowchart
right2 = [
Spacer(1, 10),
Image("/home/daytona/workspace/vaccine-notes/pcv_flowchart.png",
width=8.5*cm, height=14*cm, kind='proportional'),
]
two_col2 = Table(
[[left2, right2]],
colWidths=[(W-3*cm)*0.62, (W-3*cm)*0.38]
)
two_col2.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (0,0), 0),
("RIGHTPADDING", (0,0), (0,0), 6),
("LEFTPADDING", (1,0), (1,0), 4),
("RIGHTPADDING", (1,0), (1,0), 0),
]))
page2.append(two_col2)
page2.append(Spacer(1, 4))
page2.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#6a1a6e"), spaceAfter=2))
page2.append(Paragraph(
"Sources: Park's Textbook of Preventive & Social Medicine | IAP-ACVIP Recommended Immunization Schedule 2025 | IAP Guidebook on Immunization 2025 (5th ed.)",
footer_style
))
# Build PDF
all_content = page1 + page2
doc.build(all_content)
print("PDF created successfully!")
cd /home/daytona/workspace/vaccine-notes && python create_vaccine_notes.py 2>&1
ls -lh /home/daytona/workspace/vaccine-notes/
Vaccine Notes 5Mark
PDF Document · PDF
Remove flow chart , encha content more like strain efficacy catchup special situation etc for exam writing
rotavirus vaccine strains efficacy ROTAVAC 116E catch-up schedule intussusception IAP 2025
PCV pneumococcal vaccine catch-up schedule special situations HIV preterm IAP 2025 efficacy serotype coverage
~/vaccine-notes/create_vaccine_notes_v2.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
W, H = A4
doc = SimpleDocTemplate(
"/home/daytona/workspace/vaccine-notes/Vaccine_Notes_5Mark_v2.pdf",
pagesize=A4,
leftMargin=1.5*cm, rightMargin=1.5*cm,
topMargin=1.2*cm, bottomMargin=1.2*cm
)
styles = getSampleStyleSheet()
# ---- Style definitions ----
def S(name, **kw):
base = kw.pop("parent", styles["Normal"])
return ParagraphStyle(name, parent=base, **kw)
title_s = S("T", fontSize=17, textColor=colors.HexColor("#1a3c6e"),
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=2, spaceBefore=0)
src_s = S("Src", fontSize=7.5, textColor=colors.HexColor("#666666"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, spaceAfter=5)
body_s = S("B", fontSize=8.5, leading=12.5, spaceAfter=2, fontName="Helvetica")
bull_s = S("Bl", fontSize=8.5, leading=12, leftIndent=12, spaceAfter=2, fontName="Helvetica")
bold_s = S("Bo", fontSize=8.5, leading=12, fontName="Helvetica-Bold", spaceAfter=1)
foot_s = S("F", fontSize=7, textColor=colors.HexColor("#888888"), alignment=TA_CENTER)
key_s = S("K", fontSize=8.5, fontName="Helvetica-Bold",
textColor=colors.HexColor("#b30000"), leading=12, spaceAfter=2)
def hdr(text, bg="#1a3c6e", fg="white"):
return Table(
[[Paragraph(f"<b>{text}</b>",
S("H", fontSize=9, textColor=colors.HexColor(fg),
fontName="Helvetica-Bold"))]],
colWidths=[W - 3*cm],
style=TableStyle([
("BACKGROUND", (0,0),(-1,-1), colors.HexColor(bg)),
("TOPPADDING",(0,0),(-1,-1),3), ("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),6),
])
)
def banner(cells, bgs):
"""Top 3-cell banner"""
col_w = (W-3*cm)/len(cells)
data = [[Paragraph(f"<b>{c}</b>",
S(f"bn{i}", fontSize=8, fontName="Helvetica-Bold",
textColor=colors.HexColor("#222222"), alignment=TA_CENTER))
for i, c in enumerate(cells)]]
ts = TableStyle([
("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5),
("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#cccccc")),
("BOX",(0,0),(-1,-1),1,colors.HexColor("#555555")),
] + [("BACKGROUND",(i,0),(i,0),colors.HexColor(bgs[i])) for i in range(len(cells))])
return Table(data, colWidths=[col_w]*len(cells), style=ts)
def make_tbl(data, col_widths=None, hdr_bg="#1a3c6e"):
if col_widths is None:
col_widths = [(W-3*cm)/len(data[0])]*len(data[0])
rows = []
for i, row in enumerate(data):
rows.append([Paragraph(str(c),
S(f"tc{i}", fontSize=7.8,
fontName="Helvetica-Bold" if i==0 else "Helvetica",
textColor=colors.white if i==0 else colors.HexColor("#222222"),
alignment=TA_CENTER, leading=11)) for c in row])
ts = TableStyle([
("BACKGROUND",(0,0),(-1,0), colors.HexColor(hdr_bg)),
("ROWBACKGROUNDS",(0,1),(-1,-1),[colors.HexColor("#f5f8ff"),colors.HexColor("#eaf0ff")]),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#bbbbbb")),
("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),4),
])
return Table(rows, colWidths=col_widths, style=ts)
def sp(n=4): return Spacer(1, n)
# =====================================================================
# PAGE 1 — ROTAVIRUS VACCINE
# =====================================================================
p1 = []
p1.append(Paragraph("ROTAVIRUS VACCINE", title_s))
p1.append(Paragraph("Sources: Park's Preventive & Social Medicine | Red Book 2021 (AAP) | IAP-ACVIP 2025 | Bharat Biotech (ROTAVAC PI)", src_s))
p1.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#1a3c6e"), spaceAfter=5))
p1.append(banner(
["🦠 Oral Live Attenuated Vaccine", "🎯 Target: Rotavirus Gastroenteritis", "🇮🇳 Indigenous: ROTAVAC 116E (India)"],
["#e3eeff", "#e3ffe8", "#fff7e0"]
))
p1.append(sp(5))
# --- PATHOGEN ---
p1.append(hdr("1. PATHOGEN & EPIDEMIOLOGY", "#1a3c6e"))
p1.append(sp(2))
p1.append(Paragraph("• <b>Virus:</b> Rotavirus — double-stranded RNA (dsRNA) virus, family Reoviridae, non-enveloped, 11 segments", bull_s))
p1.append(Paragraph("• <b>Groups:</b> A, B, C; Group A is responsible for >90% of human disease", bull_s))
p1.append(Paragraph("• <b>Genotypes:</b> Named by G (VP7) and P (VP4) antigens. Common: G1P[8], G2P[4], G3P[8], G4P[8], G9P[8]", bull_s))
p1.append(Paragraph("• <b>Disease:</b> Severe watery diarrhoea + vomiting in infants 6–24 months; leading cause of severe diarrheal deaths <5 yrs globally", bull_s))
p1.append(Paragraph("• <b>Immunity:</b> Natural infection confers partial protection; repeated infections occur but are less severe", bull_s))
p1.append(sp(4))
# --- AVAILABLE VACCINES & STRAINS ---
p1.append(hdr("2. AVAILABLE VACCINES — STRAINS & COMPOSITION", "#1e6e3c"))
p1.append(sp(2))
tbl1 = make_tbl([
["Vaccine", "Type", "Strain / Composition", "Origin", "Doses", "Volume", "WHO Prequalified"],
["Rotarix (RV1)", "Live oral monovalent", "Human G1P[8] (89-12 strain)", "GSK", "2", "1.5 mL", "2008"],
["RotaTeq (RV5)", "Live oral pentavalent", "5 bovine-human reassortants\n(G1,G2,G3,G4 + P[8])", "Merck", "3", "2 mL", "2009"],
["ROTAVAC", "Live oral monovalent", "Human 116E strain (G9P[11])\nNeonatal strain, India", "Bharat Biotech", "3", "0.5 mL", "2018"],
["ROTAVAC 5D", "Live oral monovalent", "116E strain — liquid formulation", "Bharat Biotech", "3", "0.5 mL", "2021"],
], col_widths=[2.8*cm, 3.2*cm, 4.0*cm, 2.8*cm, 1.0*cm, 1.2*cm, 1.8*cm], hdr_bg="#1e6e3c")
p1.append(tbl1)
p1.append(sp(4))
# --- EFFICACY ---
p1.append(hdr("3. EFFICACY", "#6a3e00"))
p1.append(sp(2))
eff_tbl = make_tbl([
["Vaccine", "High-income countries", "Low/middle-income countries", "India-specific"],
["Rotarix (RV1)", "85–96% vs severe RVGE", "49–77%", "—"],
["RotaTeq (RV5)", "98–100% vs severe RVGE (G1–G4)", "43–64%", "—"],
["ROTAVAC (116E)", "No data (LMIC-designed)", "56.4% vs severe RVGE", "56.4% (1st yr); 49% (2nd yr)"],
["ROTAVAC 5D", "—", "Non-inferior to ROTAVAC", "Non-inferior (Zambia study)"],
], col_widths=[2.8*cm, 3.8*cm, 4.0*cm, 3.2*cm], hdr_bg="#6a3e00")
p1.append(eff_tbl)
p1.append(Paragraph(" ★ Efficacy against any severity RVGE: 74–87% (RV1/RV5) | Protection persists into 2nd year of life", bull_s))
p1.append(sp(4))
# --- IAP 2025 SCHEDULE ---
p1.append(hdr("4. IAP-ACVIP 2025 SCHEDULE", "#6a1a6e"))
p1.append(sp(2))
sched = make_tbl([
["Vaccine", "Dose 1", "Dose 2", "Dose 3", "Min 1st dose age", "Max 1st dose", "Min interval", "Max last dose"],
["Rotarix (RV1)", "6 weeks", "10 weeks", "—", "6 weeks", "14w 6d", "4 weeks", "8 months"],
["RotaTeq (RV5)", "6 weeks", "10 weeks", "14 weeks", "6 weeks", "14w 6d", "4 weeks", "8 months"],
["ROTAVAC / 5D", "6 weeks", "10 weeks", "14 weeks", "6 weeks", "14w 6d", "4 weeks", "8 months"],
], col_widths=[2.6*cm, 1.4*cm, 1.4*cm, 1.4*cm, 2.2*cm, 1.8*cm, 1.8*cm, 1.8*cm], hdr_bg="#6a1a6e")
p1.append(sched)
p1.append(Paragraph(" ★ UIP India provides ROTAVAC free at 6, 10, 14 weeks. ROTAVAC 5D booster trial data submitted to DCGI (Oct 2025) — booster NOT yet recommended", bull_s))
p1.append(sp(4))
# --- CATCH-UP ---
p1.append(hdr("5. CATCH-UP VACCINATION", "#8B4513"))
p1.append(sp(2))
p1.append(Paragraph("• Rotavirus vaccine is <b>NOT recommended for catch-up</b> if the child is beyond 8 months of age — risk of intussusception rises significantly after 12 weeks with first dose", bull_s))
p1.append(Paragraph("• <b>Maximum age for first dose:</b> 14 weeks 6 days; <b>Maximum age for any dose:</b> 8 months 0 days", bull_s))
p1.append(Paragraph("• If an infant had rotavirus gastroenteritis before completing the series → <b>continue</b> the remaining doses as per standard schedule", bull_s))
p1.append(Paragraph("• If product used for prior dose is unavailable/unknown → continue with available product; if any RV5 dose was given → complete with 3 doses total", bull_s))
p1.append(sp(4))
# --- CONTRAINDICATIONS + SPECIAL ---
# Two sub-columns for CI and Special Situations
ci_content = [
hdr("6. CONTRAINDICATIONS", "#b30000"),
sp(2),
Paragraph("<b>Absolute:</b>", bold_s),
Paragraph("• SCID (Severe Combined Immunodeficiency) — live virus can cause severe prolonged gastroenteritis", bull_s),
Paragraph("• History of intussusception", bull_s),
Paragraph("• Hypersensitivity/anaphylaxis to any vaccine component", bull_s),
Paragraph("• Age >8 months (last dose)", bull_s),
Paragraph("• Latex allergy (anaphylactic) → avoid RV1 (tip cap has latex) — use RV5 instead", bull_s),
sp(2),
Paragraph("<b>Precautions:</b>", bold_s),
Paragraph("• Altered immunocompetence other than SCID — consult expert", bull_s),
Paragraph("• Acute severe gastroenteritis — defer", bull_s),
Paragraph("• Maternal biologic response modifiers (BRMs) in utero — avoid RV vaccine for first 12 months (exceptions: certolizumab, possibly infliximab)", bull_s),
]
sp_content = [
hdr("7. SPECIAL SITUATIONS", "#2c5f8a"),
sp(2),
Paragraph("<b>Preterm infants:</b>", bold_s),
Paragraph("• Vaccinate at chronological age ≥6 weeks if clinically stable", bull_s),
Paragraph("• Same schedule as term infants; first dose at NICU discharge if eligible", bull_s),
sp(2),
Paragraph("<b>HIV-exposed / HIV-infected infants:</b>", bold_s),
Paragraph("• Administer RV vaccine irrespective of CD4 count/% — same schedule as uninfected", bull_s),
sp(2),
Paragraph("<b>Immunocompromised household contacts:</b>", bold_s),
Paragraph("• Can vaccinate the infant; immunocompromised persons should avoid diaper handling for 4 weeks post-vaccination", bull_s),
sp(2),
Paragraph("<b>Breastfed infants:</b>", bold_s),
Paragraph("• Vaccinate on same schedule — breastfeeding does NOT reduce vaccine efficacy", bull_s),
sp(2),
Paragraph("<b>Spitting/regurgitation during dose:</b>", bold_s),
Paragraph("• Do NOT repeat the dose", bull_s),
sp(2),
Paragraph("<b>Blood products / antibodies:</b>", bold_s),
Paragraph("• Can give before, during, or after blood products — no interaction", bull_s),
]
two_col = Table(
[[ci_content, sp_content]],
colWidths=[(W-3*cm)*0.5, (W-3*cm)*0.5]
)
two_col.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(0,0),0), ("RIGHTPADDING",(0,0),(0,0),5),
("LEFTPADDING",(1,0),(1,0),5), ("RIGHTPADDING",(1,0),(1,0),0),
]))
p1.append(two_col)
p1.append(sp(4))
# --- COLD CHAIN + AEFI ---
p1.append(hdr("8. COLD CHAIN, AEFI & KEY EXAM POINTS", "#444444"))
p1.append(sp(2))
aefi_tbl = make_tbl([
["Parameter", "Detail"],
["Storage temperature", "2–8°C | Do NOT freeze | Discard if frozen"],
["Route", "Oral (NOT injectable)"],
["Co-administration", "Can give with all other childhood vaccines simultaneously"],
["AEFI", "Generally mild — low-grade fever, mild diarrhoea, vomiting; intussusception risk very small (~1–2 per 100,000 first doses) — benefit far outweighs risk"],
["Serotype breadth", "All 4 WHO-prequalified vaccines provide broad cross-protection beyond their included genotypes"],
["Shedding", "Vaccine virus shed in stool for several weeks post-vaccination; transmission risk in household is very low"],
], col_widths=[3.5*cm, (W-3*cm)-3.5*cm], hdr_bg="#444444")
p1.append(aefi_tbl)
p1.append(sp(5))
p1.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#1a3c6e"), spaceAfter=2))
p1.append(Paragraph(
"Sources: Park's Preventive & Social Medicine (23rd ed.) | Red Book 2021 (AAP) | IAP-ACVIP Recommended Immunization Schedule 2025 | ROTAVAC Prescribing Information (Bharat Biotech) | WHO Rotavirus Vaccine Position Paper 2013",
foot_s
))
p1.append(PageBreak())
# =====================================================================
# PAGE 2 — PNEUMOCOCCAL VACCINE
# =====================================================================
p2 = []
p2.append(Paragraph("PNEUMOCOCCAL VACCINE (PCV / PPV23)", title_s))
p2.append(Paragraph("Sources: Park's Preventive & Social Medicine | IAP-ACVIP 2025 | IAP Guidebook on Immunization 2025 (5th ed.) | Red Book 2021", src_s))
p2.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#6a1a6e"), spaceAfter=5))
p2.append(banner(
["💉 Conjugate Vaccine (PCV) — IM injection", "🦠 Target: Streptococcus pneumoniae", "📋 IAP 2025: 6w-10w-14w + Booster 15m"],
["#f5e8ff", "#e3ffe8", "#fff7e0"]
))
p2.append(sp(5))
# --- PATHOGEN ---
p2.append(hdr("1. PATHOGEN & EPIDEMIOLOGY", "#6a1a6e"))
p2.append(sp(2))
p2.append(Paragraph("• <b>Organism:</b> Streptococcus pneumoniae — Gram-positive, alpha-haemolytic, lancet-shaped diplococcus; bile-soluble, optochin-sensitive", bull_s))
p2.append(Paragraph("• <b>Serotypes:</b> >90 capsular serotypes; ~23 cause >85% of invasive disease; serotypes differ by geography and age group", bull_s))
p2.append(Paragraph("• <b>Virulence:</b> Polysaccharide capsule — anti-phagocytic; main target of vaccine immunity", bull_s))
p2.append(Paragraph("• <b>Diseases caused:</b> Pneumonia (most common), Bacteraemia, Meningitis, Otitis media, Sinusitis, Peritonitis", bull_s))
p2.append(Paragraph("• <b>At-risk:</b> Infants <2 yrs, elderly >65 yrs, asplenic, HIV+, immunocompromised, chronic disease patients", bull_s))
p2.append(sp(4))
# --- TYPES ---
p2.append(hdr("2. TYPES OF VACCINES — STRAINS & COMPOSITION", "#1a3c6e"))
p2.append(sp(2))
pcv_types = make_tbl([
["Vaccine", "Serotypes Covered", "Conjugated to", "Age Group", "T-cell Response", "India Availability"],
["PPV23\n(Pneumovax 23)", "1,2,3,4,5,6B,7F,8,9N,9V,10A,\n11A,12F,14,15B,17F,18C,\n19A,19F,20,22F,23F,33F",
"None (polysaccharide only)", ">2 years", "T-independent\n(poor <2yrs)", "Yes"],
["PCV10\n(Synflorix)", "1,4,5,6B,7F,9V,14,18C,19F,23F", "Protein D, TT, DT", "Infants/Children", "T-dependent", "Limited"],
["PCV13\n(Prevenar 13)", "PCV10 + 3,6A,19A", "CRM197", "Infants/Children", "T-dependent", "Yes"],
["PCV14-TT\n(Apexxnar/Abbott)", "1,3,4,5,6B,7F,9V,14,18C,19A,\n19F,22F,23F,33F", "Tetanus Toxoid", "6-10-14 weeks\n(primary only)", "T-dependent", "Yes (2025)"],
["Vaximune-13 /\nPneumoguard-13", "1,3,4,6A,6B,7F,9V,18C,19A,19F,23F\n(13-valent TT)", "Tetanus Toxoid", "6-10-14 weeks\n(primary only)", "T-dependent", "Yes (2025)"],
["PCV20\n(Prevnar 20)", "PCV13 + 8,10A,11A,12F,15B", "CRM197", ">18 years only\n(India 2025)", "T-dependent", "Yes (adults)"],
], col_widths=[2.4*cm, 4.5*cm, 2.2*cm, 2.0*cm, 1.8*cm, 2.0*cm], hdr_bg="#1a3c6e")
p2.append(pcv_types)
p2.append(sp(4))
# --- EFFICACY ---
p2.append(hdr("3. EFFICACY", "#1e6e3c"))
p2.append(sp(2))
eff2 = make_tbl([
["Vaccine", "Efficacy Against Invasive Pneumococcal Disease (IPD)", "Otitis Media", "Nasopharyngeal Carriage"],
["PCV13", ">90% against vaccine-serotype IPD in children", "Moderate reduction", "Significant reduction — herd immunity"],
["PCV10", ">80% against vaccine-serotype IPD", "Moderate reduction", "Some reduction"],
["PPV23", "60–70% against IPD in adults; INEFFECTIVE <2 yrs", "Not effective", "No significant effect"],
["Newer PCVs (14-TT)", "Non-inferior to PCV13 for shared serotypes (IAP 2025)", "—", "—"],
], col_widths=[2.8*cm, 5.5*cm, 2.2*cm, 3.3*cm], hdr_bg="#1e6e3c")
p2.append(eff2)
p2.append(Paragraph(" ★ Herd immunity effect of PCV reduces carriage in unvaccinated household contacts — indirect protection to elders", bull_s))
p2.append(sp(4))
# --- IAP 2025 SCHEDULE ---
p2.append(hdr("4. IAP-ACVIP 2025 SCHEDULE (India)", "#6a1a6e"))
p2.append(sp(2))
sched2 = make_tbl([
["Schedule Type", "Primary Doses", "Booster", "Notes"],
["3p+0 (IAP / UIP Standard)", "6w, 10w, 14w", "15 months (IAP recommended)", "Preferred by IAP for India; UIP provides PCV free at govt centres"],
["2p+1 (WHO alternate)", "6w + 14w (≥8 weeks apart)", "Booster at 9–15 months", "Min interval 4-8 weeks primary; booster at 9-15m"],
["PCV14-TT / Vaximune-13", "6w, 10w, 14w", "NOT recommended (2025)", "Booster trials pending DCGI approval as of 2025"],
["PCV20", "Single dose (adults)", "Not applicable", "Only for >18 yrs in India 2025"],
], col_widths=[3.5*cm, 3.5*cm, 3.0*cm, (W-3*cm)-10.0*cm], hdr_bg="#6a1a6e")
p2.append(sched2)
p2.append(sp(4))
# --- CATCH-UP + SPECIAL ---
catch_content = [
hdr("5. CATCH-UP VACCINATION", "#8B4513"),
sp(2),
Paragraph("<b>Age <12 months unvaccinated:</b>", bold_s),
Paragraph("• 3 doses with ≥4 week intervals; booster at 12–15m", bull_s),
sp(1),
Paragraph("<b>Age 12–24 months unvaccinated:</b>", bold_s),
Paragraph("• 2 doses ≥8 weeks apart", bull_s),
sp(1),
Paragraph("<b>Age 2–5 years unvaccinated (healthy):</b>", bold_s),
Paragraph("• 1 dose PCV13 only", bull_s),
sp(1),
Paragraph("<b>Age 2–5 years with risk factors:</b>", bold_s),
Paragraph("• 2 doses PCV13 ≥8 weeks apart, then PPV23 ≥8 weeks later", bull_s),
sp(1),
Paragraph("<b>Interrupted schedule:</b>", bold_s),
Paragraph("• Resume without repeating; do NOT restart series", bull_s),
sp(1),
Paragraph("<b>Interchangeability:</b>", bold_s),
Paragraph("• PCV10 ↔ PCV13: not documented; complete with same product when possible", bull_s),
Paragraph("• PCV13 → PCV14-TT: newer TT-conjugate PCVs may complete series", bull_s),
]
sp2_content = [
hdr("6. SPECIAL SITUATIONS", "#2c5f8a"),
sp(2),
Paragraph("<b>HIV-positive children:</b>", bold_s),
Paragraph("• Give extra booster in 2nd year of life if 3 primary doses completed before 12 months", bull_s),
Paragraph("• PPV23 at 2 yrs + repeat 5 yrs later", bull_s),
sp(1),
Paragraph("<b>Preterm infants:</b>", bold_s),
Paragraph("• 3 primary doses before 12m → booster in 2nd year", bull_s),
sp(1),
Paragraph("<b>Asplenia / sickle cell disease:</b>", bold_s),
Paragraph("• PCV13 + PPV23 (≥8 wks after PCV); revaccinate with PPV23 every 5 years", bull_s),
sp(1),
Paragraph("<b>Cochlear implant / CSF leak:</b>", bold_s),
Paragraph("• Same as asplenia regimen — both PCV + PPV23", bull_s),
sp(1),
Paragraph("<b>Chronic illness</b> (cardiac, pulmonary, renal, hepatic, DM, alcoholism, malignancy, transplant):", bold_s),
Paragraph("• PPV23 single dose; repeat once after 5 years if <65 yrs at first dose", bull_s),
sp(1),
Paragraph("<b>Elderly >65 years:</b>", bold_s),
Paragraph("• PPV23 single dose routinely; PCV13 then PPV23 in high-risk individuals", bull_s),
sp(1),
Paragraph("<b>DMARD / immunosuppressants:</b>", bold_s),
Paragraph("• Give PCV before starting immunosuppressants if possible; reduced immunogenicity on therapy", bull_s),
]
two_col2 = Table(
[[catch_content, sp2_content]],
colWidths=[(W-3*cm)*0.50, (W-3*cm)*0.50]
)
two_col2.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("LEFTPADDING",(0,0),(0,0),0),("RIGHTPADDING",(0,0),(0,0),5),
("LEFTPADDING",(1,0),(1,0),5),("RIGHTPADDING",(1,0),(1,0),0),
]))
p2.append(two_col2)
p2.append(sp(4))
# --- COLD CHAIN + CI + AEFI ---
p2.append(hdr("7. DOSE / ROUTE / COLD CHAIN / CI / AEFI", "#444444"))
p2.append(sp(2))
final_tbl = make_tbl([
["Parameter", "Detail"],
["Dose", "0.5 mL (all PCVs and PPV23)"],
["Route", "IM (PCV) | IM or SC (PPV23)"],
["Site", "Anterolateral thigh (infants) | Deltoid (older children/adults)"],
["Storage", "2–8°C | DO NOT freeze | Discard if frozen — preservative-free"],
["Absolute CI", "Anaphylaxis to previous dose or any vaccine component; revaccination NOT recommended after anaphylaxis"],
["AEFI", "Local: Erythema, tenderness, swelling (30–50%); more common with 2nd dose of PPV23 and with SC route | Systemic: Rare"],
["Co-administration", "Can give simultaneously with other vaccines at different sites"],
["PPV23 note", "Do NOT mix in same syringe with influenza vaccine; give separately in opposite arm"],
], col_widths=[3.5*cm, (W-3*cm)-3.5*cm], hdr_bg="#444444")
p2.append(final_tbl)
p2.append(sp(4))
p2.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#6a1a6e"), spaceAfter=2))
p2.append(Paragraph(
"Sources: Park's Preventive & Social Medicine (23rd ed.) | IAP-ACVIP Recommended Immunization Schedule 2025 | IAP Guidebook on Immunization 2025 (5th ed., Jaypee) | Red Book 2021 (AAP)",
foot_s
))
# =====================================================================
# BUILD PDF
# =====================================================================
doc.build(p1 + p2)
print("PDF v2 created successfully!")
cd /home/daytona/workspace/vaccine-notes && python create_vaccine_notes_v2.py 2>&1
~/vaccine-notes/create_vaccine_notes_v2.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/vaccine-notes/create_vaccine_notes_v2.py'
cd /home/daytona/workspace/vaccine-notes && python create_vaccine_notes_v2.py 2>&1
ls -lh /home/daytona/workspace/vaccine-notes/Vaccine_Notes_5Mark_v2.pdf
Vaccine Notes 5Mark v2
PDF Document · PDF
It's perfect, try to make master table instead many tables and add about national immunization schedule also
India UIP national immunization schedule 2025 rotavirus PCV doses ages free government
~/vaccine-notes/create_v3.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
W, H = A4
CONTENT_W = W - 2.8*cm
doc = SimpleDocTemplate(
"/home/daytona/workspace/vaccine-notes/Vaccine_Notes_5Mark_v3.pdf",
pagesize=A4,
leftMargin=1.4*cm, rightMargin=1.4*cm,
topMargin=1.0*cm, bottomMargin=1.0*cm
)
styles = getSampleStyleSheet()
def S(name, **kw):
base = kw.pop("parent", styles["Normal"])
return ParagraphStyle(name, parent=base, **kw)
title_s = S("T", fontSize=16, textColor=colors.HexColor("#0d2b6b"),
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=1, spaceBefore=0)
src_s = S("Src", fontSize=7, textColor=colors.HexColor("#666666"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, spaceAfter=4)
foot_s = S("F", fontSize=6.8, textColor=colors.HexColor("#888888"), alignment=TA_CENTER)
sp2 = lambda n=4: Spacer(1, n)
# ── cell text helpers ──────────────────────────────────────────────
def C(txt, bold=False, size=7.8, color="#111111", align=TA_LEFT, wrap=True):
fn = "Helvetica-Bold" if bold else "Helvetica"
return Paragraph(str(txt),
S(f"c{txt[:6]}", fontSize=size, fontName=fn,
textColor=colors.HexColor(color),
leading=11, alignment=align))
def CH(txt, size=8, color="#ffffff"): # header cell
return C(txt, bold=True, size=size, color=color, align=TA_CENTER)
# ── section title bar ──────────────────────────────────────────────
def sec(text, bg="#0d2b6b"):
return Table([[Paragraph(f"<b> {text}</b>",
S("sh", fontSize=9, textColor=colors.white,
fontName="Helvetica-Bold", leading=12))]],
colWidths=[CONTENT_W],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), colors.HexColor(bg)),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
]))
# ── generic master table builder ──────────────────────────────────
def master_table(rows, col_widths, hdr_bg="#0d2b6b",
alt1="#f0f4ff", alt2="#e4eeff",
span_col0=True):
"""
rows: list of lists; first row = header.
If a cell is a tuple (text, span_end), spans columns [col, span_end].
"""
tbl_data = []
for ri, row in enumerate(rows):
tbl_row = []
for ci, cell in enumerate(row):
if ri == 0:
tbl_row.append(CH(cell))
else:
# left col (parameter name) bold
if ci == 0:
tbl_row.append(C(cell, bold=True, size=7.8))
else:
tbl_row.append(C(cell, size=7.8))
tbl_data.append(tbl_row)
style_cmds = [
("BACKGROUND", (0,0), (-1,0), colors.HexColor(hdr_bg)),
("ROWBACKGROUNDS",(0,1),(-1,-1),[colors.HexColor(alt1), colors.HexColor(alt2)]),
("GRID", (0,0), (-1,-1), 0.35, colors.HexColor("#bbbbbb")),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING",(0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "TOP"),
]
return Table(tbl_data, colWidths=col_widths,
style=TableStyle(style_cmds), repeatRows=1)
# ── top banner strip ───────────────────────────────────────────────
def top_banner(items, bgs):
n = len(items)
cw = CONTENT_W / n
data = [[Paragraph(f"<b>{t}</b>",
S(f"bn{i}", fontSize=7.8, fontName="Helvetica-Bold",
textColor=colors.HexColor("#111111"),
alignment=TA_CENTER)) for i, t in enumerate(items)]]
ts = TableStyle(
[("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#aaaaaa")),
("BOX",(0,0),(-1,-1),1,colors.HexColor("#555555"))] +
[("BACKGROUND",(i,0),(i,0),colors.HexColor(bgs[i])) for i in range(n)]
)
return Table(data, colWidths=[cw]*n, style=ts)
# ═══════════════════════════════════════════════════════════════════
# PAGE 1 — ROTAVIRUS VACCINE
# ═══════════════════════════════════════════════════════════════════
P1 = []
P1.append(Paragraph("ROTAVIRUS VACCINE", title_s))
P1.append(Paragraph(
"Park's Preventive Medicine | Red Book 2021 (AAP) | IAP-ACVIP 2025 | NIS India | ROTAVAC Prescribing Info",
src_s))
P1.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#0d2b6b"), spaceAfter=4))
P1.append(top_banner(
["Oral Live Attenuated Vaccine", "dsRNA Virus — Group A commonest", "No Catch-up after 8 months"],
["#dce8ff","#d9f5e5","#fff4dc"]
))
P1.append(sp2(5))
# ── MASTER TABLE ───────────────────────────────────────────────────
P1.append(sec("MASTER REFERENCE TABLE — ROTAVIRUS VACCINE", "#0d2b6b"))
P1.append(sp2(2))
L = CONTENT_W
c0 = 3.4*cm # parameter
c1 = 3.2*cm # RV1 Rotarix
c2 = 3.2*cm # RV5 RotaTeq
c3 = 3.0*cm # ROTAVAC / 5D
c4 = L-c0-c1-c2-c3 # NIS / UIP India
master_rota = master_table([
# HEADER
["Parameter", "RV1 — Rotarix (GSK)", "RV5 — RotaTeq (Merck)", "ROTAVAC / ROTAVAC 5D\n(Bharat Biotech)", "NIS India (UIP / Govt)"],
# PATHOGEN block
["PATHOGEN",
"Rotavirus: dsRNA, Reoviridae, non-enveloped, 11 gene segments; Group A → >90% human disease; genotypes G/P",
"← Same pathogen →",
"← Same pathogen →",
"Target disease: Rotavirus gastroenteritis — #1 cause of severe diarrheal deaths in <5 yr globally"],
["Strain / Composition",
"Monovalent — human G1P[8] attenuated (89-12 strain)",
"Pentavalent — 5 bovine-human reassortants: G1, G2, G3, G4 + P[8]",
"Monovalent — human neonatal 116E strain (G9P[11]); indigenously developed in India;\n5D = liquid formulation",
"ROTAVAC (116E) used in UIP;\nROTAVAC 5D (liquid) — same strain, easier logistics"],
["Vaccine type", "Live attenuated oral vaccine", "Live attenuated oral vaccine",
"Live attenuated oral vaccine", "Live attenuated oral vaccine"],
["Dose (volume)", "1.5 mL", "2 mL", "0.5 mL", "5 drops (ROTAVAC in UIP)"],
["Route", "Oral", "Oral", "Oral", "Oral"],
# SCHEDULE block
["Number of doses", "2 doses", "3 doses", "3 doses",
"3 doses (ROTAVAC)\nNIS: 6w, 10w, 14w"],
["IAP 2025 schedule",
"Dose 1: 6 weeks\nDose 2: 10 weeks",
"Dose 1: 6 weeks\nDose 2: 10 weeks\nDose 3: 14 weeks",
"Dose 1: 6 weeks\nDose 2: 10 weeks\nDose 3: 14 weeks",
"NIS (UIP India):\nRVV-1: 6 weeks\nRVV-2: 10 weeks\nRVV-3: 14 weeks\n(all free at govt centres)"],
["Min age — 1st dose", "6 completed weeks", "6 completed weeks",
"6 completed weeks", "6 completed weeks"],
["Max age — 1st dose", "14 weeks 6 days\n(do NOT start after this)", "14 weeks 6 days",
"14 weeks 6 days", "14 weeks 6 days"],
["Min interval between doses", "4 weeks", "4 weeks",
"4 weeks", "4 weeks"],
["Max age — last dose", "8 months 0 days", "8 months 0 days",
"8 months 0 days", "8 months 0 days"],
["Booster / Catch-up",
"NO booster recommended;\nCatch-up NOT allowed after 8 months",
"NO booster recommended;\nCatch-up NOT allowed after 8 months",
"Booster trial data submitted to DCGI (Oct 2025);\nbooster NOT yet approved/recommended",
"No booster in NIS;\nCatch-up not given in UIP beyond 8 months"],
# EFFICACY block
["Efficacy — high income",
"85–96% vs severe RVGE;\n74–87% vs any RVGE",
"98–100% vs severe G1–G4 RVGE;\n~74% vs any RVGE",
"No data (designed for LMIC)", "—"],
["Efficacy — LMIC / India",
"49–77% vs severe RVGE",
"43–64% vs severe RVGE",
"56.4% vs severe RVGE (Year 1, India RCT);\n49% (Year 2) — protection persists",
"Programme effectiveness data ongoing;\nproxy: ROTAVAC efficacy data"],
["Cross-protection",
"Broad — protects G1-G4, G9, G12 beyond vaccine strain",
"Broad — G1-G4+P[8]; cross-protection vs G9, G12",
"Broad — 116E (G9P[11]) induces heterotypic immunity",
"Cross-protective — covers diverse circulating strains in India"],
# CONTRAINDICATIONS block
["Absolute contraindications",
"SCID; History of intussusception; Anaphylaxis to vaccine component;\nLatex allergy (tip cap has latex) → use RV5 instead",
"SCID; History of intussusception;\nAnaphylaxis to vaccine component",
"SCID; History of intussusception;\nAnaphylaxis to vaccine component",
"SCID; History of intussusception;\nStrict max age 8 months for last dose"],
["Precautions",
"Altered immunocompetence (non-SCID) — consult expert;\nSevere acute gastroenteritis — defer;\nIn utero BRM exposure — avoid for first 12 months (exceptions: certolizumab, infliximab)",
"← Same precautions →",
"No safety/efficacy data in immunocompromised; consult expert",
"Defer in acute severe illness"],
# SPECIAL SITUATIONS block
["Preterm infants",
"Vaccinate at chronological age ≥6 weeks if clinically stable; first dose at NICU discharge",
"← Same →",
"← Same →",
"Vaccinate at ≥6 weeks chronological age — same NIS schedule"],
["HIV-exposed / infected",
"Administer irrespective of CD4 count — same schedule as uninfected (Red Book / IAP 2025)",
"← Same →",
"No specific data; IAP 2025 recommends following standard schedule",
"HIV-exposed infants receive RVV on standard NIS schedule"],
["Immunocompromised household",
"Vaccinate infant;\nImmunocompromised person avoids diaper for 4 weeks post-vaccination",
"← Same →", "← Same →",
"Vaccinate the infant as per schedule"],
["If dose spat/regurgitated", "Do NOT repeat dose", "Do NOT repeat dose", "Do NOT repeat dose", "Do NOT repeat dose"],
["Blood products / Ig",
"Can give before, during, or after blood products — no interaction",
"← Same →", "← Same →", "← Same →"],
["Breastfeeding",
"Vaccinate on same schedule — breastfeeding does NOT reduce efficacy",
"← Same →", "← Same →", "← Same →"],
["Mixed/unknown series",
"If any dose was RV5 or unknown → complete with 3 doses total",
"If any dose was RV5 → use 3 doses total",
"Complete with same product where possible",
"Complete with available ROTAVAC doses"],
# COLD CHAIN / AEFI
["Storage / Cold chain",
"2–8°C | Do NOT freeze | Protect from light",
"2–8°C | Do NOT freeze | Protect from light",
"2–8°C | Do NOT freeze | Lyophilised (ROTAVAC); Liquid (5D)",
"Maintained via UIP cold chain; discard if frozen"],
["AEFI",
"Mild: low-grade fever, loose stools, vomiting (transient);\nIntussusception risk: ~1–2/100,000 first doses (post-marketing, not seen in trials); benefit >> risk",
"← Same → | No increase in intussusception in pre-licensure trials",
"No significant increase in intussusception in India trials",
"AEFI reporting via AEFI surveillance under UIP"],
["Co-administration",
"With all routine vaccines simultaneously (OPV, DPT, IPV, Hib, PCV)",
"← Same →", "← Same →", "Given alongside Pentavalent, fIPV, PCV at same visit"],
["WHO prequalification", "Yes — 2008", "Yes — 2009", "Yes — 2018 (ROTAVAC); 2021 (5D)", "UIP uses WHO PQ vaccines"],
], col_widths=[c0, c1, c2, c3, c4], hdr_bg="#0d2b6b")
P1.append(master_rota)
P1.append(sp2(4))
P1.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#0d2b6b"), spaceAfter=2))
P1.append(Paragraph(
"Sources: Park's Preventive & Social Medicine (23rd ed.) | Red Book 2021 (AAP) | IAP-ACVIP Recommended Immunization Schedule 2025 | "
"NIS India (MoHFW / Co-WIN) | ROTAVAC PI (Bharat Biotech) | WHO Rotavirus Vaccine Position Paper",
foot_s))
P1.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 2 — PNEUMOCOCCAL VACCINE
# ═══════════════════════════════════════════════════════════════════
P2 = []
P2.append(Paragraph("PNEUMOCOCCAL VACCINE (PCV / PPV23)", title_s))
P2.append(Paragraph(
"Park's Preventive Medicine | IAP-ACVIP 2025 | IAP Guidebook on Immunization 2025 (5th ed.) | Red Book 2021 | NIS India",
src_s))
P2.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor("#5a0070"), spaceAfter=4))
P2.append(top_banner(
["Conjugate (PCV) — IM injection", "Target: S. pneumoniae >90 serotypes", "NIS India: 6w–14w + Booster 9-12m"],
["#f3e5ff","#d9f5e5","#fff4dc"]
))
P2.append(sp2(5))
P2.append(sec("MASTER REFERENCE TABLE — PNEUMOCOCCAL VACCINE", "#5a0070"))
P2.append(sp2(2))
c0p = 3.4*cm
c1p = 3.0*cm # PCV13
c2p = 3.0*cm # PPV23
c3p = 3.0*cm # Newer PCVs 2025
c4p = CONTENT_W - c0p - c1p - c2p - c3p # NIS / UIP
master_pcv = master_table([
# HEADER
["Parameter", "PCV13 — Prevenar 13\n(Pfizer/Wyeth)", "PPV23 — Pneumovax 23\n(Polysaccharide)", "Newer PCVs 2025\n(PCV14-TT / Vaximune-13 / PCV20)", "NIS India (UIP / Govt)"],
# PATHOGEN
["PATHOGEN",
"S. pneumoniae — Gram+ve lancet-shaped diplococcus; >90 capsular serotypes; alpha-haemolytic, bile-soluble, optochin-sensitive",
"← Same pathogen →",
"← Same pathogen →",
"Target: IPD (pneumonia, meningitis, bacteraemia) + otitis media"],
["Diseases prevented",
"Invasive pneumococcal disease (IPD): Pneumonia, Meningitis, Bacteraemia; Otitis media; Sinusitis",
"IPD in adults/asplenic patients; does NOT prevent otitis media",
"IPD — broader serotype coverage than PCV13",
"Pneumococcal pneumonia + meningitis in infants"],
["Virulence / immunity basis",
"Polysaccharide capsule = anti-phagocytic virulence factor;\nConjugation to CRM197 → T-cell dependent immunity → immunogenic in <2 yrs",
"Polysaccharide only → T-cell independent → poor response in <2 yrs;\nNo booster response",
"Conjugated to Tetanus Toxoid (TT) → T-dependent;\nBetter immunogenicity in infants",
"PCV13 (Prevenar) used in UIP India"],
# COMPOSITION
["Serotypes covered",
"1, 3, 4, 5, 6A, 6B, 7F, 9V, 14, 18C, 19A, 19F, 23F\n(13 serotypes conjugated to CRM197)",
"23 serotypes:\n1,2,3,4,5,6B,7F,8,9N,9V,10A,11A,12F,14,15B,17F,18C,19A,19F,20,22F,23F,33F\n(25 µg each/0.5 mL)",
"PCV14-TT (Abbott/Apexxnar): 1,3,4,5,6B,7F,9V,14,18C,19A,19F,22F,23F,33F;\nVaximune-13/Pneumoguard-13: 13-valent TT-conjugate;\nPCV20: PCV13 + 8,10A,11A,12F,15B",
"PCV13 (Prevenar 13) used;\ncoverage: 13 key serotypes"],
["% disease burden covered",
"~70–80% of paediatric IPD serotypes covered in India",
">85% of adult IPD serotypes covered",
"PCV14 adds 22F, 33F — ~5% additional serotype coverage over PCV13",
"~70–80% IPD in Indian infants"],
# SCHEDULE
["IAP 2025 schedule",
"3p+0: 6w, 10w, 14w + Booster at 15 months (IAP preferred)\nOR 2p+1: 6w + 14w + booster at 9–15m",
"Single dose IM or SC;\nFor adults >2 yrs, splenectomy, elderly >65 yrs",
"PCV14-TT/Vaximune-13: 6w-10w-14w primary;\nBooster NOT yet recommended (pending DCGI 2025);\nPCV20: Single dose — adults >18 yrs only (India)",
"NIS (UIP):\nPCV-1: 6 weeks\nPCV-2: 14 weeks\nPCV Booster: 9–12 months\n(3-dose 2p+1 schedule in UIP)"],
["Dose (volume)",
"0.5 mL", "0.5 mL", "0.5 mL (all newer PCVs)", "0.5 mL"],
["Route",
"IM only", "IM preferred; SC acceptable (↑local reactions)",
"IM (all newer PCVs)", "IM"],
["Site",
"Anterolateral thigh (infants);\nDeltoid (older children)",
"Deltoid (adults);\nAnterolateral thigh (young children)",
"Anterolateral thigh / Deltoid as per age",
"Anterolateral thigh (right) in infants"],
# EFFICACY
["Efficacy vs IPD",
">90% vs vaccine-serotype IPD in children\n(immunogenic + highly effective)",
"60–70% vs IPD in adults;\nINEFFECTIVE in children <2 years (T-independent, no memory)",
"PCV14-TT: non-inferior to PCV13 for shared serotypes (IAP 2025 data);\nPCV20: non-inferior to PCV13 + PPSV23 combined",
"PCV13 highly effective vs vaccine-type IPD in infants"],
["Efficacy vs otitis media",
"Moderate reduction (~7% overall; 57% vs vaccine-type OM)",
"NOT effective vs otitis media",
"Similar to PCV13 for shared serotypes",
"Indirect benefit through herd immunity"],
["Herd immunity / carriage",
"Significant reduction in nasopharyngeal carriage → indirect protection of unvaccinated (elders, siblings)",
"No effect on carriage",
"Expected herd effect similar to PCV13",
"Herd immunity benefit documented post-UIP introduction"],
# NIS-specific
["NIS — Availability / Cost",
"Free under UIP at all govt health centres;\nAlso available private (paid)",
"Not in NIS; available in private sector for high-risk adults",
"Not yet in NIS; available in private clinics (paid);\nPCV20 for adults only",
"PCV13 free in UIP;\nIntroduced nationally — rolled out to all states"],
["NIS — Programme notes",
"UIP uses 2p+1 schedule:\nPCV1 at 6w, PCV2 at 14w, Booster at 9-12 months\n(differs from IAP 3p+0)",
"Not in NIS", "Not in NIS (2025)", "PCV Booster at 9 months in NIS differs from IAP 15 months"],
# CATCH-UP
["Catch-up: <12 months",
"3 doses with ≥4 week intervals; booster at 12–15m",
"Not applicable",
"PCV14-TT: not established", "Resume as per NIS — no restart"],
["Catch-up: 12–24 months",
"2 doses ≥8 weeks apart", "Not applicable", "2 doses ≥8 weeks apart", "2 doses per IAP"],
["Catch-up: 2–5 yrs (healthy)",
"1 dose PCV13 only", "Not applicable",
"1 dose PCV14-TT (if available)", "Not routinely under NIS after 2 yrs"],
["Catch-up: 2–5 yrs (high risk)",
"2 doses PCV13 (≥8 wks apart) + PPV23 ≥8 wks after last PCV",
"1 dose PPV23 after PCV series",
"Follow PCV13 guidance for shared serotypes",
"IAP catch-up applies; NIS does not cover catch-up"],
["Interrupted schedule",
"Resume WITHOUT repeating; do not restart series",
"Single dose — no series to interrupt",
"Resume without repeating",
"Resume without repeating"],
["Interchangeability",
"PCV10 ↔ PCV13: not documented; complete with same product;\nPCV13 → PCV14-TT possible per IAP 2025",
"N/A", "TT-conjugate PCVs may complete PCV13 series", "Complete with PCV13 in NIS"],
# SPECIAL SITUATIONS
["HIV+ children",
"If 3 primary doses given before 12m → extra booster in 2nd year of life;\nPPV23 at 2 yrs + repeat every 5 yrs",
"PPV23 at 2 yrs; revaccinate every 5 yrs",
"Follow PCV13 regimen then PPV23", "Standard NIS + extra booster (IAP recommendation)"],
["Preterm infants",
"3 primary doses before 12m → booster in 2nd year",
"Not recommended <2 yrs",
"Follow PCV13 guidance", "Standard NIS schedule at chronological age"],
["Asplenia / sickle cell",
"PCV13 complete series + PPV23 ≥8 weeks after PCV",
"PPV23 + revaccinate every 5 yrs (or once if <65 yrs at first dose)",
"PCV14 then PPV23 as per IAP",
"IAP special situation guideline applies; not routinely in NIS"],
["Cochlear implant / CSF leak",
"PCV13 + PPV23 — same as asplenia",
"PPV23 after PCV series",
"PCV14-TT then PPV23",
"IAP high-risk schedule applies"],
["Chronic disease (cardiac, pulmonary,\nrenal, hepatic, DM, malignancy, transplant)",
"PCV13 (if <5 yrs); then PPV23",
"PPV23 single dose; repeat once if <65 yrs at first dose",
"As per individual product guidance",
"Not in NIS; IAP/clinician-driven for high-risk"],
["Elderly >65 yrs",
"PCV13 (1 dose) then PPV23 (≥1 yr later); or shared decision-making",
"PPV23 routinely recommended",
"PCV20 single dose (India 2025) as alternative to PCV13+PPV23",
"Not in NIS (adults not covered by NIS)"],
["DMARDs / Immunosuppressants",
"Vaccinate BEFORE starting therapy if possible; reduced immunogenicity on DMARDs",
"Same — vaccinate before therapy",
"Same principle", "N/A (adults, not NIS)"],
# COLD CHAIN / CI / AEFI
["Storage / Cold chain",
"2–8°C | Do NOT freeze | Discard if frozen | Preservative-free",
"2–8°C | Do NOT freeze | Discard if frozen",
"2–8°C | Do NOT freeze | Discard if frozen",
"UIP cold chain; discard if frozen"],
["Absolute contraindications",
"Anaphylaxis to previous dose or any component;\nRevaccination NOT recommended after anaphylaxis",
"Same; also avoid <2 yrs (ineffective)",
"Anaphylaxis to any component including TT carrier",
"Anaphylaxis CI; no age restriction issue in NIS (started at 6 weeks)"],
["AEFI",
"Local: Pain, redness, swelling (up to 50%); more with 2nd dose & SC route;\nSystemic: Fever (uncommon); severe reactions rare",
"More local reactions with SC route & 2nd dose;\n30–50% mild local reactions",
"Similar to PCV13; TT-conjugate may have more local reactions",
"AEFI reported via UIP surveillance system"],
["Co-administration",
"With all routine vaccines at different sites simultaneously",
"With influenza vaccine ONLY in separate syringe/site; not same syringe",
"With routine vaccines at different sites",
"Given with OPV, Pentavalent, fIPV at same visit in UIP"],
["WHO PQ status",
"Yes — PCV13 (Prevenar 13)", "Yes — PPV23",
"PCV14-TT: under review; PCV20: licensed not yet PQ",
"UIP uses WHO-PQ vaccines only"],
], col_widths=[c0p, c1p, c2p, c3p, c4p], hdr_bg="#5a0070")
P2.append(master_pcv)
P2.append(sp2(4))
P2.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#5a0070"), spaceAfter=2))
P2.append(Paragraph(
"Sources: Park's Preventive & Social Medicine (23rd ed.) | IAP-ACVIP Recommended Immunization Schedule 2025 | "
"IAP Guidebook on Immunization 2025 (5th ed., Jaypee) | Red Book 2021 (AAP) | NIS India (MoHFW) | vaccinesafety.edu",
foot_s))
# ═══ BUILD ═══════════════════════════════════════════════════════
doc.build(P1 + P2)
print("v3 PDF created successfully!")
cd /home/daytona/workspace/vaccine-notes && python create_v3.py 2>&1
ls -lh /home/daytona/workspace/vaccine-notes/Vaccine_Notes_5Mark_v3.pdf
Vaccine Notes 5Mark v3
PDF Document · PDF
Make you single page pdf answers for each question and avoid repition for repeated questions. Merge content of repeated questions and avoid repition
cd /home/daytona/workspace/attachments/09dffecf-3ea8-4ab9-9494-e8574bb6a3df && python3 -c " import pdfplumber, json files = [ 'Pediatric_PG_Vaccines_Drugs.pdf', '9021.pdf', 'Immunization_PG_Exam_Answers.pdf' ] for f in files: print(f'\\n===== {f} =====') try: with pdfplumber.open(f) as pdf: print(f'Pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages[:6]): txt = page.extract_text() if txt: print(f'-- Page {i+1} --') print(txt[:1200]) except Exception as e: print(f'Error: {e}') " 2>&1
cd /home/daytona/workspace/attachments/09dffecf-3ea8-4ab9-9494-e8574bb6a3df && python3 -c " import pdfplumber # Extract all text from all PDFs to identify ALL questions files = [ ('Pediatric_PG_Vaccines_Drugs.pdf', 'PED'), ('9021.pdf', 'IMM'), ('Immunization_PG_Exam_Answers.pdf', 'IMMQ') ] for f, tag in files: print(f'\n\n========== {tag}: {f} ==========') with pdfplumber.open(f) as pdf: print(f'Total pages: {len(pdf.pages)}') full_text = '' for page in pdf.pages: t = page.extract_text() if t: full_text += t + '\n' # print lines that look like question titles for line in full_text.split('\n'): line = line.strip() if line.startswith('Q') and ('.' in line[:5] or line[1:3].isdigit()): print(repr(line[:120])) elif 'Mark' in line and ('Q' in line or 'question' in line.lower()): print(repr(line[:120])) " 2>&1
cd /home/daytona/workspace/attachments/09dffecf-3ea8-4ab9-9494-e8574bb6a3df && python3 -c " import pdfplumber, json files = [ ('Pediatric_PG_Vaccines_Drugs.pdf', 'PED'), ('9021.pdf', 'IMM'), ('Immunization_PG_Exam_Answers.pdf', 'IMMQ') ] all_text = {} for f, tag in files: with pdfplumber.open(f) as pdf: pages = [] for i, page in enumerate(pdf.pages): t = page.extract_text() or '' pages.append(t) all_text[tag] = pages # Save to file for use in PDF builder import pickle with open('/home/daytona/workspace/vaccine-notes/pdf_texts.pkl', 'wb') as fh: pickle.dump(all_text, fh) print('Saved. Page counts:') for k,v in all_text.items(): print(f' {k}: {len(v)} pages') # Print full text of specific high-yield topics def get_q_text(pages, start_kw, end_kw=None, max_pages=3): collecting = False result = [] for p in pages: if start_kw.lower() in p.lower(): collecting = True if collecting: result.append(p) if end_kw and end_kw.lower() in p.lower() and len(result)>1: break if len(result) >= max_pages: break return '\n'.join(result) # Show Rotavirus content from all files print('\n=== ROTAVIRUS from PED ===') print(get_q_text(all_text['PED'], 'Q3. ROTAVIRUS', 'Q4.')[:2500]) print('\n=== ROTAVIRUS from IMM (Q15) ===') print(get_q_text(all_text['IMM'], 'Q15. Rotavirus', 'Q16.')[:2500]) print('\n=== ROTAVIRUS from IMMQ (Q7) ===') print(get_q_text(all_text['IMMQ'], 'Q7. Rotavirus', 'Q8.')[:2500]) " 2>&1
cd /home/daytona/workspace/attachments/09dffecf-3ea8-4ab9-9494-e8574bb6a3df && python3 -c " import pdfplumber, pickle with open('/home/daytona/workspace/vaccine-notes/pdf_texts.pkl', 'rb') as f: all_text = pickle.load(f) def get_pages_between(pages, start_kw, end_kw=None, max_pages=4): collecting = False result = [] for p in pages: if start_kw.lower() in p.lower(): collecting = True if collecting: result.append(p) if end_kw and end_kw.lower() in p.lower() and len(result)>1: break if len(result) >= max_pages: break return '\n'.join(result) # Extract all unique topic areas we need topics = { 'PCV_PED': get_pages_between(all_text['PED'], 'Q4. PNEUMOCOCCAL', 'Q5.'), 'PCV_IMM_Q11': get_pages_between(all_text['IMM'], 'Q11. Pneumococcal Vaccine', 'Q12.'), 'PCV_IMM_Q16': get_pages_between(all_text['IMM'], 'Q16. Pneumococcal Vaccine Indications', 'Q17.'), 'PCV_IMMQ_Q2': get_pages_between(all_text['IMMQ'], 'Q2. Conjugated Pneumococcal', 'Q3.'), 'ROTA_PED_Q3': get_pages_between(all_text['PED'], 'Q3. ROTAVIRUS VACCINE\n', 'Q4.'), 'ROTA_PED_Q8': get_pages_between(all_text['PED'], 'Q8. ROTAVIRUS VACCINE', 'Q9.'), 'HPV_IMM': get_pages_between(all_text['IMM'], 'Q13. Human Papillomavirus', 'Q14.'), 'HPV_IMMQ_Q1': get_pages_between(all_text['IMMQ'], 'Q1. Human Papilloma Virus', 'Q2.'), 'HPV_IMMQ_Q3': get_pages_between(all_text['IMMQ'], 'Q3. HPV Vaccine', 'Q4.'), 'HPV_IMMQ_Q4': get_pages_between(all_text['IMMQ'], 'Q4. HPV Vaccine', 'Q5.'), 'POLYSC_PED': get_pages_between(all_text['PED'], 'Q6. POLYSACCHARIDE', 'Q7.'), 'POLYSC_IMM': get_pages_between(all_text['IMM'], 'Q12. Polysaccharide Vaccines', 'Q13.'), 'INFLUENZA_PED': get_pages_between(all_text['PED'], 'Q9. INFLUENZA', 'Q10.'), 'INFLUENZA_IMM': get_pages_between(all_text['IMM'], 'Q20. Influenza Vaccine', 'Q21.'), 'HIB_PED': get_pages_between(all_text['PED'], 'Q2. Hib VACCINE', 'Q3.'), 'HIB_IMMQ': get_pages_between(all_text['IMMQ'], 'Q5. Conjugated Haemophilus', 'Q6.'), 'MALARIADRUG_PED': get_pages_between(all_text['PED'], 'Q1. NEWER ANTI-MALARIAL', 'Q2.'), 'MALARIAVAX_IMM': get_pages_between(all_text['IMM'], 'Q18. Malaria Vaccine', 'Q19.'), 'NEWER_VAX_PED': get_pages_between(all_text['PED'], 'Q7. NEWER VACCINES', 'Q8.'), 'ADOLESCENT_IMM': get_pages_between(all_text['IMM'], 'Q19. Adolescent Vaccination', 'Q20.'), 'COLDCHAIN_IMM': get_pages_between(all_text['IMM'], 'Q21. Vaccine Storage and Cold Chain', 'Q22.'), 'SPLENECTOMY_IMM': get_pages_between(all_text['IMM'], 'Q14. Immunization and Chemoprophylaxis', 'Q15.'), 'IMMUNOCOMP_IMMQ': get_pages_between(all_text['IMMQ'], 'Q8. Immunization in an Immunocompromised', 'Q9.'), 'HEPA_IMMQ': get_pages_between(all_text['IMMQ'], 'Q9. Hepatitis A Vaccine', 'Q10.'), 'NATL_SCHED_IMMQ': get_pages_between(all_text['IMMQ'], 'Q6. Factors Determining Vaccination', 'Q7.'), 'NATL_SCHED_IMMQ10': get_pages_between(all_text['IMMQ'], 'Q10. Vaccination Factors, National Schedule', 'Q11.'), 'UNIMMUNIZED_IMM': get_pages_between(all_text['IMM'], 'Q17. Immunisation Schedule for 4-Year', 'Q18.'), 'APERTUSSIS_PED': get_pages_between(all_text['PED'], 'Q5. ACELLULAR PERTUSSIS', 'Q6.'), 'IPV_PED': get_pages_between(all_text['PED'], 'Q10. INACTIVATED POLIO VACCINE', 'Q11.'), 'IVIG_PED': get_pages_between(all_text['PED'], 'Q11. IVIg THERAPY', 'Q12.'), 'ONDANSETRON_PED': get_pages_between(all_text['PED'], 'Q12. ONDANSETRON', 'Q13.'), 'MIDAZOLAM_PED': get_pages_between(all_text['PED'], 'Q13. MIDAZOLAM', 'Q14.'), } # Save import pickle with open('/home/daytona/workspace/vaccine-notes/topic_texts.pkl','wb') as f: pickle.dump(topics, f) print('Topics extracted:') for k, v in topics.items(): print(f' {k}: {len(v)} chars') " 2>&1
Output pfg
ls /home/daytona/workspace/vaccine-notes/ && python3 -c " import pickle with open('/home/daytona/workspace/vaccine-notes/topic_texts.pkl','rb') as f: t = pickle.load(f) print('Topics available:', list(t.keys())) " 2>&1