HIV: ETIOPATHOGENISIS EPIDEMIOLOGY, CLINICAL FEATURES AND MANAGEMENT in NEWBORN OF HIV+ MOTHER Ppt for paediatrics final year
HIV AIDS pediatric clinical features newborn
mkdir -p /tmp/workspace/hiv-newborn-ppt && ls /tmp/workspace/hiv-newborn-ppt/
~/hiv-newborn-ppt/create_ppt.py
#!/usr/bin/env python3
"""
HIV in Newborns of HIV+ Mothers - Paediatrics Final Year PPT
Comprehensive presentation covering etiopathogenesis, epidemiology,
clinical features and management
"""
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import json, subprocess, base64
from io import BytesIO
# ── Colour Palette (Deep Medical Theme) ──────────────────────────────────────
RED = RGBColor(0xC0, 0x22, 0x2B) # deep crimson
DARK_BLUE = RGBColor(0x0D, 0x2B, 0x5C) # navy
MID_BLUE = RGBColor(0x1A, 0x53, 0x99) # medium blue
LIGHT_BLUE= RGBColor(0xD6, 0xE8, 0xF7) # very light blue
TEAL = RGBColor(0x00, 0x7B, 0x83) # teal accent
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
NEAR_BLACK= RGBColor(0x1A, 0x1A, 0x2E)
LIGHT_GRAY= RGBColor(0xF4, 0xF6, 0xF9)
ACCENT = RGBColor(0xF9, 0xA8, 0x25) # amber for highlights
DARK_RED = RGBColor(0x8B, 0x00, 0x00)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ── Helper functions ─────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_color, border_color=None, border_width=None):
from pptx.util import Pt
from pptx.oxml.ns import qn
import lxml.etree as etree
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
Inches(x), Inches(y), Inches(w), Inches(h)
)
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
shape.line.fill.background() # no border by default
if border_color:
shape.line.color.rgb = border_color
if border_width:
shape.line.width = Pt(border_width)
return shape
def add_textbox(slide, x, y, w, h, text, font_size=18, bold=False,
color=NEAR_BLACK, align=PP_ALIGN.LEFT, wrap=True,
italic=False, font_name="Calibri"):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.margin_left = Pt(2)
tf.margin_right = Pt(2)
tf.margin_top = Pt(1)
tf.margin_bottom = Pt(1)
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(font_size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
run.font.name = font_name
return tf
def add_multiline_textbox(slide, x, y, w, h, lines, font_size=16,
bold=False, color=NEAR_BLACK,
align=PP_ALIGN.LEFT, line_spacing=None,
font_name="Calibri", italic=False):
"""lines: list of (text, bold_override, size_override, color_override)
or list of plain strings"""
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
first = True
for line in lines:
if isinstance(line, str):
txt = line; b = bold; sz = font_size; c = color; it = italic
else:
txt = line[0]
b = line[1] if len(line) > 1 else bold
sz = line[2] if len(line) > 2 else font_size
c = line[3] if len(line) > 3 else color
it = line[4] if len(line) > 4 else italic
if first:
p = tf.paragraphs[0]; first = False
else:
p = tf.add_paragraph()
p.alignment = align
if line_spacing:
from pptx.util import Pt as Pt2
from pptx.oxml.ns import qn
import lxml.etree as etree
pPr = p._pPr
if pPr is None:
pPr = p._p.get_or_add_pPr()
lnSpc = etree.SubElement(pPr, qn('a:lnSpc'))
spcPts = etree.SubElement(lnSpc, qn('a:spcPts'))
spcPts.set('val', str(int(line_spacing * 100)))
run = p.add_run()
run.text = txt
run.font.size = Pt(sz)
run.font.bold = b
run.font.italic = it
run.font.color.rgb = c
run.font.name = font_name
return tf
def slide_header(slide, title, subtitle=None, title_x=0.4, title_y=0.08,
title_w=12.5, title_h=0.65):
"""Standard slide header bar with title"""
# Background gradient header
hdr = add_rect(slide, 0, 0, 13.333, 1.1, DARK_BLUE)
# Red accent strip
add_rect(slide, 0, 0, 0.18, 1.1, RED)
# White line separator
add_rect(slide, 0.18, 0, 13.1, 0.05, WHITE)
# Title
add_textbox(slide, title_x+0.1, title_y+0.05, title_w, title_h,
title, font_size=28, bold=True, color=WHITE,
align=PP_ALIGN.LEFT, font_name="Calibri")
if subtitle:
add_textbox(slide, title_x+0.1, title_y+0.65, title_w, 0.4,
subtitle, font_size=16, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.LEFT, font_name="Calibri", italic=True)
def slide_bg(slide, color=LIGHT_GRAY):
add_rect(slide, 0, 0, 13.333, 7.5, color)
def bullet_slide(slide, items, x=0.5, y=1.2, w=12.3, font_size=17,
bullet_color=RED, text_color=NEAR_BLACK, line_h=0.42,
bold_items=None, sub_items=None):
"""Add bullet points to a slide"""
cur_y = y
for i, item in enumerate(items):
is_bold = bold_items and item in bold_items
is_sub = sub_items and item in sub_items
bx = x + (0.3 if is_sub else 0)
bw = w - (0.3 if is_sub else 0)
fs = font_size - 2 if is_sub else font_size
# bullet dot
dot = slide.shapes.add_shape(1, Inches(bx), Inches(cur_y+0.13),
Inches(0.08), Inches(0.08))
dot.fill.solid()
dot.fill.fore_color.rgb = bullet_color if not is_sub else TEAL
dot.line.fill.background()
# text
add_textbox(slide, bx+0.15, cur_y, bw-0.2, line_h+0.05, item,
font_size=fs, bold=is_bold, color=text_color,
wrap=True, font_name="Calibri")
cur_y += line_h if not is_sub else line_h - 0.06
return cur_y
def footer(slide, slide_num, total=20):
add_rect(slide, 0, 7.15, 13.333, 0.35, DARK_BLUE)
add_textbox(slide, 0.3, 7.17, 6, 0.28, "Paediatrics - Final Year | HIV in Newborns of HIV+ Mothers",
font_size=9, color=LIGHT_BLUE, font_name="Calibri", italic=True)
add_textbox(slide, 11.8, 7.17, 1.3, 0.28, f"{slide_num} / {total}",
font_size=9, color=WHITE, align=PP_ALIGN.RIGHT, font_name="Calibri")
TOTAL_SLIDES = 22
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 1 - TITLE SLIDE
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
# Full dark background
add_rect(s, 0, 0, 13.333, 7.5, DARK_BLUE)
# Red accent bar left
add_rect(s, 0, 0, 0.35, 7.5, RED)
# Bottom teal strip
add_rect(s, 0, 6.8, 13.333, 0.7, TEAL)
# Light blue overlay panel
add_rect(s, 0.5, 1.2, 12.3, 5.4, RGBColor(0x12, 0x38, 0x7A))
# Red banner
add_rect(s, 0.5, 1.2, 12.3, 0.12, RED)
# Main title
add_textbox(s, 0.7, 1.4, 12, 1.2,
"HIV IN NEWBORNS OF HIV+ MOTHERS",
font_size=36, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
# Subtitle line
add_rect(s, 3.5, 2.65, 6.3, 0.05, ACCENT)
# Subtitle text
add_textbox(s, 0.7, 2.75, 12, 0.5,
"Etiopathogenesis | Epidemiology | Clinical Features | Management",
font_size=18, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.CENTER, font_name="Calibri", italic=True)
add_textbox(s, 0.7, 3.4, 12, 0.5,
"PREVENTION OF MOTHER-TO-CHILD TRANSMISSION (PMTCT)",
font_size=20, bold=True, color=ACCENT,
align=PP_ALIGN.CENTER, font_name="Calibri")
# Department label
add_textbox(s, 0.7, 4.3, 12, 0.5,
"Department of Paediatrics",
font_size=16, bold=False, color=WHITE,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_textbox(s, 0.7, 4.7, 12, 0.5,
"Final Year MBBS",
font_size=15, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.CENTER, font_name="Calibri")
add_textbox(s, 0.5, 6.85, 12.3, 0.3,
"Red Book 2021 (AAP) | Harrison's 22e | Park's Textbook | WHO Guidelines",
font_size=9, color=WHITE, align=PP_ALIGN.CENTER, font_name="Calibri", italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 2 - CONTENTS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Table of Contents")
footer(s, 2, TOTAL_SLIDES)
topics = [
("1.", "Introduction & Overview"),
("2.", "Etiology — The HIV Virus"),
("3.", "Pathogenesis of HIV Infection"),
("4.", "Routes of Mother-to-Child Transmission (MTCT)"),
("5.", "Epidemiology — Global & Indian Burden"),
("6.", "Risk Factors for Perinatal Transmission"),
("7.", "Clinical Features — Early vs Late Presenters"),
("8.", "CDC Classification of Pediatric HIV"),
("9.", "Opportunistic Infections in Pediatric HIV"),
("10.", "Diagnosis — Laboratory Approach"),
("11.", "Diagnostic Algorithm for Exposed Newborn"),
("12.", "PMTCT — Antenatal Interventions"),
("13.", "Intrapartum & Postpartum Prophylaxis"),
("14.", "Neonatal ARV Prophylaxis Protocol"),
("15.", "ART in HIV-Infected Infants"),
("16.", "Cotrimoxazole Prophylaxis & Immunizations"),
("17.", "Infant Feeding in HIV"),
("18.", "Monitoring & Follow-up"),
("19.", "Prognosis"),
("20.", "Key Points Summary"),
]
# 2 columns
col1 = topics[:10]
col2 = topics[10:]
for i, (num, topic) in enumerate(col1):
y = 1.2 + i * 0.55
add_rect(s, 0.4, y, 0.45, 0.38, DARK_BLUE)
add_textbox(s, 0.42, y, 0.42, 0.38, num, font_size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
add_textbox(s, 0.93, y, 5.3, 0.38, topic, font_size=14, color=NEAR_BLACK)
for i, (num, topic) in enumerate(col2):
y = 1.2 + i * 0.55
add_rect(s, 7.0, y, 0.45, 0.38, TEAL)
add_textbox(s, 7.02, y, 0.42, 0.38, num, font_size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
add_textbox(s, 7.53, y, 5.3, 0.38, topic, font_size=14, color=NEAR_BLACK)
# Vertical divider
add_rect(s, 6.7, 1.15, 0.04, 6.0, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 3 - INTRODUCTION
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Introduction", "Why Pediatric HIV Matters")
footer(s, 3, TOTAL_SLIDES)
add_rect(s, 0.4, 1.2, 12.5, 0.06, MID_BLUE)
items = [
"HIV (Human Immunodeficiency Virus) — a single-stranded RNA retrovirus (family: Retroviridae, genus: Lentivirus)",
"Two types: HIV-1 (pandemic, more virulent) and HIV-2 (less virulent, mainly West Africa)",
"Targets CD4+ T-lymphocytes → profound immunodeficiency → opportunistic infections & malignancies",
"In children, the PREDOMINANT route of HIV infection is Mother-to-Child Transmission (MTCT) — also called perinatal or vertical transmission",
"Without intervention: ~30% of babies born to HIV+ mothers acquire infection",
"With complete PMTCT: transmission can be reduced to <1%",
"Globally ~1.5 million children <15 yrs living with HIV (UNAIDS 2022); most in sub-Saharan Africa",
"India: ~93,000 children living with HIV; ~17,000 new pediatric infections annually",
]
bullet_slide(s, items, y=1.35, font_size=16, line_h=0.73)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 4 - ETIOLOGY / VIROLOGY
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Etiology — The HIV Virus", "Structure, Classification & Replication")
footer(s, 4, TOTAL_SLIDES)
# Left column
add_rect(s, 0.3, 1.2, 6.0, 0.38, DARK_BLUE)
add_textbox(s, 0.35, 1.22, 5.9, 0.38, "Classification & Structure",
font_size=15, bold=True, color=WHITE)
items_l = [
"Family: Retroviridae | Genus: Lentivirus",
"Enveloped RNA virus — 2 copies of ssRNA",
"Diameter: ~120 nm, icosahedral core",
"Key structural proteins:",
" • gp120 — surface glycoprotein (receptor binding)",
" • gp41 — transmembrane (fusion)",
" • p24 — core capsid antigen (diagnostic marker)",
" • p17 — matrix protein",
"Enzymes: Reverse transcriptase, Integrase, Protease",
"Genome: gag, pol, env + regulatory genes (tat, rev, nef, vif, vpr, vpu)",
]
cur_y = 1.65
for item in items_l:
is_sub = item.startswith(" •")
add_textbox(s, 0.5 if not is_sub else 0.8, cur_y, 5.7, 0.36,
item.strip(), font_size=14 if not is_sub else 13,
bold=item.startswith("Key") or item.startswith("Enzymes") or item.startswith("Genome"),
color=NEAR_BLACK if not is_sub else MID_BLUE)
cur_y += 0.36 if not is_sub else 0.32
# Right column
add_rect(s, 6.8, 1.2, 6.2, 0.38, TEAL)
add_textbox(s, 6.85, 1.22, 6.1, 0.38, "Replication Cycle",
font_size=15, bold=True, color=WHITE)
steps = [
("1. Attachment", "gp120 binds CD4 receptor + CCR5/CXCR4 co-receptor"),
("2. Fusion", "gp41 mediates membrane fusion → viral entry"),
("3. Reverse Transcription", "RNA → DNA (by reverse transcriptase)"),
("4. Integration", "Viral DNA → host genome (by integrase) → PROVIRUS"),
("5. Transcription", "Host machinery reads viral genes"),
("6. Translation", "Viral proteins synthesized"),
("7. Assembly & Budding", "New virions assembled and released"),
("8. Maturation", "Protease cleaves polyproteins → mature virion"),
]
cur_y = 1.65
for step, detail in steps:
add_textbox(s, 7.0, cur_y, 2.1, 0.38, step, font_size=13, bold=True, color=RED)
add_textbox(s, 9.15, cur_y, 3.7, 0.4, detail, font_size=12.5, color=NEAR_BLACK)
cur_y += 0.42
# Clinical note box
add_rect(s, 0.3, 6.6, 12.7, 0.5, RGBColor(0xFF, 0xF0, 0xC0))
add_textbox(s, 0.45, 6.62, 12.4, 0.45,
"Clinical Relevance: ARV drugs target specific steps — NRTIs/NNRTIs block RT, Integrase inhibitors block integration, PIs block protease, Entry inhibitors block attachment/fusion",
font_size=12, bold=False, color=DARK_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 5 - PATHOGENESIS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Pathogenesis of HIV Infection", "Why Children Are More Vulnerable")
footer(s, 5, TOTAL_SLIDES)
# Main flow
steps_path = [
("HIV enters via MTCT\n(in utero / intrapartum / breastfeeding)", DARK_BLUE),
("Binds CD4+ T-cells, macrophages,\ndendritic cells via gp120-CD4 interaction", MID_BLUE),
("Viral replication → cell lysis\nor latent provirus formation", TEAL),
("Progressive CD4+ T-cell depletion\n(normal infant CD4 >1500 cells/µL)", RED),
("Loss of cell-mediated immunity\n(also B-cell dysfunction — hypergammaglobulinemia)", DARK_BLUE),
("Opportunistic infections,\nmalignancies, multi-organ disease", RED),
]
box_w = 1.85; box_h = 0.92; start_x = 0.35; start_y = 1.3; gap = 0.15
for i, (txt, col) in enumerate(steps_path):
bx = start_x + i * (box_w + gap)
add_rect(s, bx, start_y, box_w, box_h, col)
add_textbox(s, bx+0.05, start_y+0.05, box_w-0.1, box_h-0.1,
txt, font_size=12, bold=False, color=WHITE,
align=PP_ALIGN.CENTER, wrap=True, font_name="Calibri")
if i < len(steps_path)-1:
# Arrow
arr = slide.shapes if False else s.shapes
add_textbox(s, bx+box_w+0.01, start_y+0.35, gap+0.05, 0.3,
"→", font_size=18, bold=True, color=MID_BLUE,
align=PP_ALIGN.CENTER)
# Paediatric specifics
add_rect(s, 0.3, 2.4, 12.7, 0.38, DARK_BLUE)
add_textbox(s, 0.35, 2.42, 12.6, 0.38, "Why Children — Especially Neonates — Are More Vulnerable",
font_size=14, bold=True, color=WHITE)
items_path = [
"Immature immune system: CD4 counts higher at birth but lower absolute immune competence",
"High viral replication rate: Viral load in neonates can reach 100,000–10 million copies/mL (cf. adults)",
"Rapid CD4 decline if untreated → 20–30% die before age 1 without ART",
"Thymic dysfunction: HIV directly infects thymus → impaired T-cell maturation",
"Two disease patterns: Rapid progressors (20–30%, die by age 3-5) vs. Slow progressors (70-80%)",
"Hypergammaglobulinemia (polyclonal B-cell activation) but impaired specific antibody response",
"In utero transmission → worst outcomes (longer viral exposure, immune dysmaturation)",
]
bullet_slide(s, items_path, y=2.85, font_size=15, line_h=0.59)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 6 - ROUTES OF TRANSMISSION
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Mother-to-Child Transmission (MTCT)", "Routes, Timing & Proportions")
footer(s, 6, TOTAL_SLIDES)
# Three transmission box panels
panels = [
("IN UTERO\n(Transplacental)", "5–10%", [
"1st trimester (rare)",
"2nd/3rd trimester (more common)",
"Transplacental passage of virus",
"High maternal viremia → higher risk",
"Associated with placental inflammation",
], DARK_BLUE),
("INTRAPARTUM\n(During Labour)", "10–20%", [
"MOST COMMON route (60–70% of MTCT)",
"Exposure to infected blood/secretions",
"Prolonged labour increases risk",
"Rupture of membranes >4 hrs: 2x risk",
"Vaginal delivery: higher than C-section",
"Instrumental delivery: higher risk",
], RED),
("POSTPARTUM\n(Breastfeeding)", "5–20%", [
"1/3 to 1/2 of all MTCT worldwide",
"Risk: 0.1–0.6% per month of breastfeeding",
"Higher in mastitis, cracked nipples",
"Higher if mother newly seroconverts",
"Exclusive breastfeeding safer than mixed",
"Risk persists throughout breastfeeding",
], TEAL),
]
for i, (title, pct, items, col) in enumerate(panels):
bx = 0.35 + i * 4.33
bw = 4.1
add_rect(s, bx, 1.15, bw, 0.75, col)
add_textbox(s, bx+0.1, 1.18, bw-0.2, 0.5, title,
font_size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_rect(s, bx, 1.9, bw, 0.45, ACCENT)
add_textbox(s, bx+0.1, 1.92, bw-0.2, 0.4, f"Risk: {pct} without intervention",
font_size=14, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
cy = 2.42
for item in items:
dot = s.shapes.add_shape(1, Inches(bx+0.1), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = col; dot.line.fill.background()
add_textbox(s, bx+0.22, cy, bw-0.35, 0.37, item, font_size=13, color=NEAR_BLACK)
cy += 0.38
# Bottom note
add_rect(s, 0.3, 6.6, 12.7, 0.52, RGBColor(0xE8, 0xF4, 0xF8))
add_textbox(s, 0.45, 6.62, 12.4, 0.48,
"Overall MTCT without any intervention: ~15–45% | With complete PMTCT (ART + elective LSCS + no breastfeeding): <1% | "
"Risk is CUMULATIVE across all three phases",
font_size=13, color=DARK_BLUE, bold=False)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 7 - EPIDEMIOLOGY
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Epidemiology", "Global & Indian Burden of Pediatric HIV")
footer(s, 7, TOTAL_SLIDES)
# Global stats panel
add_rect(s, 0.3, 1.15, 6.1, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 6.0, 0.4, "Global Statistics (UNAIDS/WHO)",
font_size=15, bold=True, color=WHITE)
global_stats = [
"~39 million people living with HIV worldwide (2022)",
"~1.5 million children <15 years living with HIV",
"~130,000 new child infections per year (down from 3.4 million in 1996)",
"Sub-Saharan Africa: >90% of pediatric HIV burden",
"2 million AIDS-related deaths prevented in children since ART scale-up",
"Only ~52% of HIV+ children on ART (coverage gap)",
"Global target: 95-95-95 — 95% diagnosed, 95% on ART, 95% virally suppressed",
]
cy = 1.62
for item in global_stats:
dot = s.shapes.add_shape(1, Inches(0.45), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = MID_BLUE; dot.line.fill.background()
add_textbox(s, 0.58, cy, 5.7, 0.38, item, font_size=14, color=NEAR_BLACK)
cy += 0.39
# Indian stats panel
add_rect(s, 6.7, 1.15, 6.3, 0.4, RED)
add_textbox(s, 6.75, 1.17, 6.2, 0.4, "India-Specific Data (NACO)",
font_size=15, bold=True, color=WHITE)
india_stats = [
"India: 3rd largest HIV burden globally",
"~2.35 million PLHIV; ~93,000 children (<15 yrs)",
"~17,000 new pediatric infections per year",
"Estimated ~56,000 HIV+ pregnant women/year",
"States with highest burden: Maharashtra, AP, TN, Karnataka, Manipur",
"ICTC (Integrated Counselling & Testing Centre) network: >21,000 centers",
"PPTCT (Prevention of Parent-to-Child Transmission) program under NACP",
"Opt-out HIV testing for all pregnant women at ANC",
]
cy = 1.62
for item in india_stats:
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = RED; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.38, item, font_size=14, color=NEAR_BLACK)
cy += 0.39
# Divider
add_rect(s, 6.55, 1.15, 0.04, 5.8, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 8 - RISK FACTORS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Risk Factors for Perinatal HIV Transmission")
footer(s, 8, TOTAL_SLIDES)
# Table format
add_rect(s, 0.3, 1.15, 12.7, 0.45, DARK_BLUE)
cols = ["Category", "Risk Factor", "Mechanism / Comment"]
widths = [2.5, 4.5, 5.5]
xs = [0.35, 2.9, 7.45]
for col_name, cx, cw in zip(cols, xs, widths):
add_textbox(s, cx+0.05, 1.17, cw-0.1, 0.45, col_name,
font_size=14, bold=True, color=WHITE)
rows = [
("Maternal Viral Load", "High viral load (>1000 copies/mL)", "Most important predictor; undetectable VL = near-zero MTCT"),
("Maternal Viral Load", "Advanced AIDS (low CD4)", "Inversely proportional to CD4 count"),
("Maternal", "Primary HIV infection in pregnancy", "High VL during seroconversion window"),
("Obstetric", "Prolonged rupture of membranes (>4 hrs)", "Increases intrapartum exposure"),
("Obstetric", "Vaginal delivery vs. elective LSCS", "LSCS recommended if VL >1000 copies/mL"),
("Obstetric", "Chorioamnionitis / STIs (syphilis, herpes)", "Disrupts placental/cervical barriers"),
("Obstetric", "Invasive procedures (amniocentesis, EFM)", "Breach of protective barriers"),
("Infant", "Prematurity / low birth weight", "Immature skin/mucosal barriers"),
("Infant", "Oral ulcers / mucosal breaks", "Facilitate breastfeeding transmission"),
("Breastfeeding", "Mastitis, cracked nipples, breast abscess", "Increases HIV in breast milk"),
("Breastfeeding", "Prolonged / mixed feeding", "Mixed feeding worse than exclusive"),
("ARV", "No ANC / no ARV prophylaxis", "Untreated VL highest risk"),
]
row_colors = [LIGHT_GRAY, WHITE]
cy = 1.65
for i, (cat, risk, comment) in enumerate(rows):
bg = row_colors[i % 2]
add_rect(s, 0.3, cy, 12.7, 0.37, bg)
add_textbox(s, 0.35, cy+0.02, 2.45, 0.35, cat, font_size=12.5,
bold=True, color=RED if i % 2 == 0 else DARK_BLUE)
add_textbox(s, 2.9, cy+0.02, 4.45, 0.35, risk, font_size=12.5, color=NEAR_BLACK, bold=False)
add_textbox(s, 7.45, cy+0.02, 5.45, 0.35, comment, font_size=12, color=NEAR_BLACK, italic=True)
cy += 0.38
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 9 - CLINICAL FEATURES
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Clinical Features of Pediatric HIV", "Symptoms in HIV-Exposed & Infected Infants")
footer(s, 9, TOTAL_SLIDES)
# Two patterns
add_rect(s, 0.3, 1.15, 6.1, 0.45, RED)
add_textbox(s, 0.35, 1.17, 6.0, 0.45, "RAPID PROGRESSORS (20-30%)",
font_size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_rect(s, 0.3, 1.65, 6.1, 0.28, RGBColor(0xFF, 0xEE, 0xEE))
add_textbox(s, 0.35, 1.66, 6.0, 0.28, "Present within first 6 months of life; die by age 3-5 without ART",
font_size=12, italic=True, color=DARK_RED)
rapid_items = [
"Lymphadenopathy (generalized) — earliest sign",
"Hepatosplenomegaly",
"Failure to thrive / wasting",
"Recurrent/persistent oral candidiasis (thrush)",
"Recurrent bacterial infections",
"Encephalopathy — developmental delay, microcephaly",
"Opportunistic infections (PCP, CMV)",
"Parotid enlargement",
]
cy = 2.0
for item in rapid_items:
dot = s.shapes.add_shape(1, Inches(0.45), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = RED; dot.line.fill.background()
add_textbox(s, 0.58, cy, 5.7, 0.36, item, font_size=14, color=NEAR_BLACK)
cy += 0.37
add_rect(s, 6.7, 1.15, 6.3, 0.45, TEAL)
add_textbox(s, 6.75, 1.17, 6.2, 0.45, "SLOW PROGRESSORS (70-80%)",
font_size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_rect(s, 6.7, 1.65, 6.3, 0.28, RGBColor(0xE8, 0xF8, 0xF8))
add_textbox(s, 6.75, 1.66, 6.2, 0.28, "Asymptomatic for years; AIDS develops in childhood/adolescence",
font_size=12, italic=True, color=TEAL)
slow_items = [
"Chronic generalized lymphadenopathy",
"Recurrent URTIs / sinusitis / otitis media",
"Chronic/recurrent diarrhoea",
"Lymphocytic interstitial pneumonitis (LIP)",
"Parotid gland enlargement",
"Mild developmental delay",
"Dermatological: seborrhoeic dermatitis, molluscum",
"Short stature / growth failure",
"Clubbing, digital/nail changes",
]
cy = 2.0
for item in slow_items:
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = TEAL; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.36, item, font_size=14, color=NEAR_BLACK)
cy += 0.37
add_rect(s, 6.55, 1.15, 0.04, 5.8, MID_BLUE)
# Bottom note
add_rect(s, 0.3, 6.6, 12.7, 0.5, RGBColor(0xFF, 0xF3, 0xCD))
add_textbox(s, 0.45, 6.62, 12.4, 0.47,
"Key: HIV-exposed infants may be antibody-positive until 18 months (maternal Ab). Symptomatic HIV = AIDS-defining illness. "
"Normal CD4 for age must be used (not adult values)",
font_size=12.5, color=DARK_BLUE, bold=False)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 10 - CDC CLASSIFICATION
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "CDC Classification of Pediatric HIV (2014)")
footer(s, 10, TOTAL_SLIDES)
# Immunologic categories header
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.4, "Immunologic Categories Based on CD4 Count / Percentage",
font_size=14, bold=True, color=WHITE)
# CD4 table
headers = ["Age", "No suppression (1)", "Moderate suppression (2)", "Severe suppression (3)"]
head_w = [2.5, 3.3, 3.5, 3.2]
head_x = [0.3, 2.85, 6.2, 9.75]
add_rect(s, 0.3, 1.6, 12.7, 0.38, MID_BLUE)
for h, hx, hw in zip(headers, head_x, head_w):
add_textbox(s, hx+0.05, 1.62, hw-0.1, 0.38, h, font_size=13, bold=True, color=WHITE)
cd4_rows = [
("<1 year", "≥1500 cells/µL (≥34%)", "750–1499 cells/µL (26–33%)", "<750 cells/µL (<26%)"),
("1–5 years", "≥1000 cells/µL (≥26%)", "500–999 cells/µL (22–25%)", "<500 cells/µL (<22%)"),
("6–12 years", "≥500 cells/µL (≥26%)", "200–499 cells/µL (14–25%)", "<200 cells/µL (<14%)"),
]
row_colors = [LIGHT_GRAY, WHITE, LIGHT_GRAY]
cy = 2.02
for i, (age, c1, c2, c3) in enumerate(cd4_rows):
add_rect(s, 0.3, cy, 12.7, 0.38, row_colors[i])
for val, hx, hw in zip([age, c1, c2, c3], head_x, head_w):
add_textbox(s, hx+0.05, cy+0.03, hw-0.1, 0.35, val, font_size=13,
bold=(val==age), color=NEAR_BLACK if val!=c3 else RED)
cy += 0.39
# Clinical categories
add_rect(s, 0.3, 3.25, 12.7, 0.4, TEAL)
add_textbox(s, 0.35, 3.27, 12.6, 0.4, "Clinical Categories",
font_size=14, bold=True, color=WHITE)
clin_cats = [
("Category N", "Not symptomatic", "No signs/symptoms; OR only 1 condition in Category A"),
("Category A", "Mildly symptomatic", "2 or more: lymphadenopathy, hepatomegaly, splenomegaly, dermatitis, parotitis, recurrent URTIs"),
("Category B", "Moderately symptomatic", "Conditions beyond A but not in C: anemia, LIP, bacterial meningitis, cardiomyopathy, CMV <1mo, herpes stomatitis"),
("Category C", "Severely symptomatic", "AIDS-defining conditions: PCP, recurrent bacterial infections, CMV disease, cerebral toxoplasmosis, KS, wasting syndrome"),
]
cy = 3.7
for cat, severity, desc in clin_cats:
add_rect(s, 0.3, cy, 12.7, 0.5, WHITE if cy%1 < 0.6 else LIGHT_GRAY)
add_textbox(s, 0.35, cy+0.05, 2.0, 0.42, cat, font_size=13, bold=True, color=RED)
add_textbox(s, 2.4, cy+0.05, 2.5, 0.42, severity, font_size=13, bold=True, color=DARK_BLUE)
add_textbox(s, 4.95, cy+0.05, 7.9, 0.42, desc, font_size=12.5, color=NEAR_BLACK)
cy += 0.51
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 11 - OPPORTUNISTIC INFECTIONS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Opportunistic Infections in Pediatric HIV", "Common OIs & Thresholds")
footer(s, 11, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
headers2 = ["Organism / Disease", "CD4 Threshold", "Clinical Presentation", "Management"]
heads_w2 = [3.2, 1.8, 4.5, 3.0]
heads_x2 = [0.3, 3.55, 5.4, 9.95]
for h, hx, hw in zip(headers2, heads_x2, heads_w2):
add_textbox(s, hx+0.05, 1.17, hw-0.1, 0.4, h, font_size=13, bold=True, color=WHITE)
oi_rows = [
("PCP (Pneumocystis jirovecii pneumonia)", "<200", "Hypoxia, tachypnoea, dry cough, CXR bilateral infiltrates", "Co-trimoxazole (TMP-SMX)"),
("CMV (Cytomegalovirus)", "<50", "Retinitis, colitis, pneumonitis, encephalitis", "Ganciclovir IV"),
("MAC (M. avium complex)", "<50", "Fever, night sweats, weight loss, diarrhoea", "Azithromycin + ethambutol"),
("Candida (esophageal)", "Any", "Dysphagia, odynophagia, white plaques", "Fluconazole"),
("Cryptococcus meningitis", "<100", "Headache, fever, altered sensorium, raised ICP", "AmBisome + fluconazole"),
("Toxoplasma encephalitis", "<100", "Seizures, focal neuro deficits, ring-enhancing lesion", "Pyrimethamine + sulfadiazine"),
("Mycobacterium tuberculosis", "Any", "Most common OI in India; weight loss, cough, fever", "Standard 4-drug ATT"),
("LIP (Lymphocytic interstitial pneumonitis)", "Any", "Slowly progressive respiratory failure, clubbing, lymphadenopathy", "Steroids ± ART"),
("Kaposi Sarcoma (HHV-8)", "<200", "Skin, lymph node, visceral lesions", "ART + chemotherapy"),
]
cy = 1.6
for i, (org, cd4, pres, mgmt) in enumerate(oi_rows):
bg = LIGHT_GRAY if i%2==0 else WHITE
add_rect(s, 0.3, cy, 12.7, 0.42, bg)
for val, hx, hw in zip([org, cd4, pres, mgmt], heads_x2, heads_w2):
add_textbox(s, hx+0.05, cy+0.03, hw-0.1, 0.38, val, font_size=12,
bold=(val==org), color=RED if val==cd4 else NEAR_BLACK)
cy += 0.43
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 12 - DIAGNOSIS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Diagnosis of HIV in Infants & Children", "Testing Algorithm Based on Age")
footer(s, 12, TOTAL_SLIDES)
# Key principle box
add_rect(s, 0.3, 1.15, 12.7, 0.5, RED)
add_textbox(s, 0.4, 1.18, 12.5, 0.45,
"CRITICAL: Maternal IgG antibodies cross the placenta → ALL infants of HIV+ mothers are antibody-positive until ~18 months. "
"Antibody tests are UNRELIABLE for diagnosis before 18 months — use virologic tests (HIV DNA/RNA PCR)",
font_size=13, bold=False, color=WHITE, wrap=True)
# Age-based testing
add_rect(s, 0.3, 1.72, 6.1, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.74, 6.0, 0.4, "< 18 Months: Virologic Tests",
font_size=14, bold=True, color=WHITE)
tests_young = [
"HIV DNA PCR — detects proviral DNA in PBMCs",
"HIV RNA PCR (Viral Load) — preferred by current guidelines",
"Both DNA and RNA PCR are equally recommended",
"RNA identifies 25-58% at week 1, 60% by 1 month, 90-100% by 2-3 months",
"Timing: At birth (within 48 hrs), 14-21 days, 1-2 months, 4-6 months",
"2 positive tests = HIV-confirmed | 2 negative tests after 4 wks = uninfected",
"After 18 months: antibody assay (EIA/ELISA) can be used",
]
cy = 2.17
for item in tests_young:
is_key = item.startswith("2 positive") or item.startswith("Timing")
dot = s.shapes.add_shape(1, Inches(0.45), Inches(cy+0.12), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = MID_BLUE; dot.line.fill.background()
add_textbox(s, 0.58, cy, 5.65, 0.39, item, font_size=13,
bold=is_key, color=RED if is_key else NEAR_BLACK)
cy += 0.41
add_rect(s, 6.7, 1.72, 6.3, 0.4, TEAL)
add_textbox(s, 6.75, 1.74, 6.2, 0.4, "≥ 18 Months: Serology & Virologic",
font_size=14, bold=True, color=WHITE)
tests_older = [
"4th generation Ag/Ab combination EIA (p24 antigen + antibody)",
"Reactive → HIV-1/HIV-2 antibody differentiation assay",
"Indeterminate → HIV-1 NAAT (RNA PCR) for confirmation",
"Western Blot — confirmatory (antibody to ≥2 of: p24, gp41, gp120/160)",
"CD4 count & CD4% — for staging and monitoring",
"Viral load — for treatment monitoring",
"CBC, LFT, RFT, lipid profile — before starting ART",
"Resistance testing — before starting ART where available",
]
cy = 2.17
for item in tests_older:
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.12), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = TEAL; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.39, item, font_size=13, color=NEAR_BLACK)
cy += 0.41
add_rect(s, 6.55, 1.72, 0.04, 5.0, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 13 - DIAGNOSTIC ALGORITHM FLOWCHART (with image)
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Neonatal Testing & ARV Prophylaxis Protocol", "Based on Level of Perinatal HIV Risk")
footer(s, 13, TOTAL_SLIDES)
add_textbox(s, 0.4, 1.15, 12.5, 0.4,
"All infants born to HIV+ mothers should be risk-stratified at birth to determine appropriate testing and prophylaxis regimen",
font_size=14, color=DARK_BLUE, italic=True)
# Insert the ARV flowchart image
import subprocess, base64, json
from io import BytesIO
img_url = "https://cdn.orris.care/cdss_images/6b4c7f12814731640acee0daef473147864931689e3e36218b5887efd399697d.png"
result = json.loads(subprocess.check_output(
["python", "/tmp/skills/shared/scripts/fetch_images.py", img_url]
))
if result and result[0].get("base64"):
raw = base64.b64decode(result[0]["base64"].split(",",1)[-1])
img_stream = BytesIO(raw)
s.shapes.add_picture(img_stream, Inches(0.5), Inches(1.6), Inches(12.3), Inches(5.6))
else:
add_textbox(s, 0.5, 2.0, 12.3, 1.0,
"[Flowchart: Newborn Testing & Prophylaxis — Red Book 2021, AAP]",
font_size=14, italic=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 14 - PMTCT ANTENATAL
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "PMTCT — Antenatal Interventions", "Prevention of Mother-to-Child Transmission")
footer(s, 14, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.4, "WHO Option B+ Strategy: ALL HIV+ Pregnant Women → Lifelong ART Regardless of CD4 Count",
font_size=14, bold=True, color=WHITE)
# Left: ART regimens
add_rect(s, 0.3, 1.62, 6.1, 0.38, MID_BLUE)
add_textbox(s, 0.35, 1.64, 6.0, 0.38, "Preferred ART Regimen (Antepartum)",
font_size=14, bold=True, color=WHITE)
art_items = [
"PREFERRED: TDF + 3TC (or FTC) + DTG (dolutegravir)",
" → Start as early as possible in pregnancy",
" → Continue throughout pregnancy, delivery & breastfeeding",
" → Lifelong treatment (Option B+)",
"ALTERNATIVE: TDF + 3TC + EFV (efavirenz) — acceptable",
"AVOID: EFV in 1st trimester (historical concern); ddI+d4T (toxicity)",
"Goal: Viral load <50 copies/mL at delivery",
"Monitor: VL at 4 weeks, 3 months, then 3-monthly; CD4 every 6 months",
"Elective LSCS at 38 weeks if VL >1000 copies/mL or unknown",
"IV Zidovudine intrapartum: if VL >1000 copies/mL at delivery",
]
cy = 2.05
for item in art_items:
is_sub = item.startswith(" →")
add_textbox(s, 0.45 if not is_sub else 0.65, cy, 5.8, 0.34 if not is_sub else 0.3,
item.strip(), font_size=13 if not is_sub else 12.5,
bold=item.startswith("PREFERRED") or item.startswith("Goal") or item.startswith("Monitor"),
color=RED if item.startswith("AVOID") else (TEAL if is_sub else NEAR_BLACK))
cy += 0.34 if not is_sub else 0.30
# Right: Counselling
add_rect(s, 6.7, 1.62, 6.3, 0.38, TEAL)
add_textbox(s, 6.75, 1.64, 6.2, 0.38, "Counselling & Other ANC Interventions",
font_size=14, bold=True, color=WHITE)
counsel_items = [
"Opt-out HIV testing at 1st ANC visit (repeat 3rd trimester in high-risk)",
"Disclose HIV status with counselling; partner testing",
"Adherence counselling — ART must be taken consistently",
"Nutritional support — micronutrients, vitamin A, iron-folate",
"Safe sex education — consistent condom use",
"Management of co-infections: TB, STIs, hepatitis B/C",
"Avoid invasive procedures: amniocentesis, fetal scalp electrodes",
"Plan institutional delivery; avoid prolonged labour",
"Pre-delivery planning: neonatal team informed, cord blood for PCR",
"Psychosocial support and peer support groups",
]
cy = 2.05
for item in counsel_items:
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = TEAL; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.35, item, font_size=13, color=NEAR_BLACK)
cy += 0.36
add_rect(s, 6.55, 1.62, 0.04, 5.0, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 15 - NEONATAL ARV PROPHYLAXIS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Neonatal ARV Prophylaxis", "Postnatal Prevention Based on Risk Stratification")
footer(s, 15, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.4,
"All HIV-exposed newborns receive ARV prophylaxis. Regimen depends on risk level and gestational age (Red Book 2021 / AAP)",
font_size=13, bold=False, color=WHITE)
# Standard vs Higher-risk
add_rect(s, 0.3, 1.62, 6.1, 0.42, TEAL)
add_textbox(s, 0.35, 1.64, 6.0, 0.42, "STANDARD RISK — Zidovudine Monotherapy",
font_size=14, bold=True, color=WHITE)
add_textbox(s, 0.4, 2.1, 5.9, 0.35,
"(Mother on ART with VL <50 copies/mL near delivery)", font_size=12.5, italic=True, color=TEAL)
std_regimen = [
("≥35 weeks GA:", "ZDV 4 mg/kg PO BID × 4 weeks"),
("30–35 weeks GA:", "ZDV 2 mg/kg PO BID × 2 weeks, then 3 mg/kg PO BID × 2 weeks"),
("<30 weeks GA:", "ZDV 2 mg/kg PO BID × 4 weeks"),
("Cannot take PO:", "ZDV IV = 75% of oral dose, same interval"),
]
cy = 2.5
for age, regimen in std_regimen:
add_textbox(s, 0.4, cy, 1.8, 0.38, age, font_size=13, bold=True, color=DARK_BLUE)
add_textbox(s, 2.25, cy, 4.0, 0.38, regimen, font_size=13, color=NEAR_BLACK)
cy += 0.4
add_rect(s, 6.7, 1.62, 6.3, 0.42, RED)
add_textbox(s, 6.75, 1.64, 6.2, 0.42, "HIGHER RISK — 3-Drug Presumptive Therapy",
font_size=14, bold=True, color=WHITE)
add_textbox(s, 6.8, 2.1, 6.1, 0.35,
"(Untreated mother / VL>1000 / no antepartum ARV)", font_size=12.5, italic=True, color=RED)
high_risk = [
"Preferred: ZDV + 3TC + Nevirapine × 6 weeks",
" → ZDV: ≥35 wks: 4mg/kg BID; <35 wks: 2-3mg/kg BID",
" → 3TC: <4 wks: 2mg/kg BID; >4 wks: 4mg/kg BID",
" → NVP: ≥37 wks: 6mg/kg BID; 34-37 wks: 4-6mg/kg BID",
"OR: ZDV + 3TC + Raltegravir (≥37 wks only)",
" → Raltegravir dose: birth→1wk: 1.5mg/kg QD",
" → 1 wk→4 wks: 3mg/kg BID",
" → 4 wks→6 wks: 6mg/kg BID",
"For <32 wks or <1.5 kg: Consult HIV specialist",
"Test with HIV DNA/RNA PCR at birth, 2-3 weeks, 1-2 months, 4-6 months",
]
cy = 2.5
for item in high_risk:
is_sub = item.startswith(" →")
add_textbox(s, 6.85 if not is_sub else 7.15, cy, 6.0 if not is_sub else 5.7, 0.33,
item.strip(), font_size=13 if not is_sub else 12,
bold=item.startswith("Preferred") or item.startswith("OR") or item.startswith("For") or item.startswith("Test"),
color=RED if item.startswith("Preferred") or item.startswith("OR") else (TEAL if is_sub else NEAR_BLACK))
cy += 0.33 if not is_sub else 0.30
add_rect(s, 6.55, 1.62, 0.04, 5.0, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 16 - ART IN HIV-INFECTED INFANTS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "ART in HIV-Infected Infants & Children", "When to Start and What to Use")
footer(s, 16, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.45, RED)
add_textbox(s, 0.35, 1.17, 12.6, 0.45,
"WHO/NACO Recommendation: ALL HIV-infected infants <2 years should start ART IMMEDIATELY regardless of CD4 count or clinical stage",
font_size=14, bold=True, color=WHITE)
# Preferred regimens by age
add_rect(s, 0.3, 1.67, 12.7, 0.38, DARK_BLUE)
add_textbox(s, 0.35, 1.69, 12.6, 0.38, "Preferred First-Line ART Regimens (WHO 2021 / NACO)",
font_size=14, bold=True, color=WHITE)
age_regimens = [
("<4 weeks", "AZT + 3TC + NVP (if no NVP prophylaxis) or AZT + 3TC + LPV/r", "DTG not approved <4 wks"),
("4 weeks – 3 years", "ABC + 3TC + LPV/r OR AZT + 3TC + LPV/r", "DTG approved ≥4 weeks in some guidelines"),
("3 – <6 years", "ABC + 3TC + DTG (preferred) OR ABC + 3TC + LPV/r", "LPV/r as alternative"),
("≥6 years", "ABC + 3TC + DTG (preferred) OR TDF + 3TC + DTG", "TDF + 3TC + EFV if DTG unavailable"),
("Any age (2nd line)", "PI-based regimen (LPV/r, ATV/r) + change backbone", "After virological failure on NNRTI-based 1st line"),
]
cy = 2.1
row_cols = [LIGHT_GRAY, WHITE, LIGHT_GRAY, WHITE, LIGHT_GRAY]
for i, (age, regimen, note) in enumerate(age_regimens):
add_rect(s, 0.3, cy, 12.7, 0.45, row_cols[i])
add_textbox(s, 0.35, cy+0.04, 1.9, 0.42, age, font_size=13, bold=True, color=RED)
add_textbox(s, 2.3, cy+0.04, 6.5, 0.42, regimen, font_size=13, color=NEAR_BLACK)
add_textbox(s, 8.85, cy+0.04, 4.1, 0.42, note, font_size=12, italic=True, color=TEAL)
cy += 0.46
# Monitoring
add_rect(s, 0.3, cy+0.05, 12.7, 0.38, MID_BLUE)
add_textbox(s, 0.35, cy+0.07, 12.6, 0.38, "Monitoring on ART",
font_size=14, bold=True, color=WHITE)
cy += 0.48
monitor_items = [
"Viral Load: at 4 weeks (treatment initiation), 3 months, 6 months, then every 6 months — TARGET: <50 copies/mL",
"CD4 count: baseline, every 3-6 months during treatment",
"CBC, LFT, RFT: baseline, at 2 weeks (especially if NVP), every 6 months",
"Growth monitoring: weight, height, head circumference — plotted on growth charts",
"Neurodevelopmental assessment: at each visit; school performance in older children",
"Virological failure: VL >1000 copies/mL on 2 occasions → adherence counselling → consider 2nd-line",
]
for item in monitor_items:
dot = s.shapes.add_shape(1, Inches(0.45), Inches(cy+0.1), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = MID_BLUE; dot.line.fill.background()
add_textbox(s, 0.58, cy, 12.5, 0.35, item, font_size=13, color=NEAR_BLACK)
cy += 0.36
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 17 - COTRIMOXAZOLE & IMMUNIZATION
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Cotrimoxazole Prophylaxis & Immunization")
footer(s, 17, TOTAL_SLIDES)
# Left: CTX prophylaxis
add_rect(s, 0.3, 1.15, 6.1, 0.42, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 6.0, 0.42, "Cotrimoxazole (TMP-SMX) Prophylaxis",
font_size=14, bold=True, color=WHITE)
ctx_items = [
"Prophylaxis against: PCP, Toxoplasmosis, Isospora, bacterial infections",
"WHO recommendation: START at 4-6 weeks for ALL HIV-exposed infants",
"Continue until HIV infection excluded (2 negative PCRs, no breastfeeding)",
"For confirmed HIV: continue until CD4 > 25% (or >350 cells) on ART for ≥6 months",
"Dose (TMP component): 5 mg/kg/day once daily OR 2.5 mg/kg BID",
"Practical dose:",
" • 4-6 kg: 2.5 mL (single-strength syrup) OD",
" • 6-10 kg: 5 mL (single-strength) OD",
" • >10 kg: 1 SS tablet OD",
"Contraindications: sulfa allergy, severe hepatic disease",
"Side effects: rash, GI upset, bone marrow suppression",
]
cy = 1.62
for item in ctx_items:
is_sub = item.startswith(" •")
add_textbox(s, 0.45 if not is_sub else 0.7, cy, 5.8 if not is_sub else 5.6, 0.34,
item.strip(), font_size=13 if not is_sub else 12.5,
bold=item.startswith("WHO") or item.startswith("Dose"),
color=RED if item.startswith("Contra") else (TEAL if is_sub else NEAR_BLACK))
cy += 0.34 if not is_sub else 0.30
# Right: Immunization
add_rect(s, 6.7, 1.15, 6.3, 0.42, TEAL)
add_textbox(s, 6.75, 1.17, 6.2, 0.42, "Immunization in HIV-Exposed/Infected Children",
font_size=14, bold=True, color=WHITE)
vacc_items = [
("BCG", "At birth if asymptomatic; AVOID if symptomatic/confirmed HIV"),
("OPV", "Use IPV instead of OPV for confirmed HIV-infected"),
("DTP", "As per schedule — safe in HIV"),
("Hep B", "Routine schedule — full dose"),
("PCV (pneumococcal)", "STRONGLY recommended — increased doses for HIV-infected"),
("Hib vaccine", "Routine — important in HIV"),
("MMR", "Give if CD4 ≥15% (age <5) or ≥200 (age ≥5) — LIVE vaccine"),
("Varicella", "Give if CD4 adequate — monitor for rash"),
("Influenza", "Annually — inactivated vaccine"),
("HPV (≥9 yrs)", "3-dose schedule recommended"),
("AVOID in severe immunosuppression", "BCG, OPV (use IPV), Yellow fever, all live vaccines"),
]
cy = 1.62
for vax, note in vacc_items:
is_avoid = vax.startswith("AVOID")
add_textbox(s, 6.85, cy, 1.8, 0.37, vax,
font_size=12.5, bold=True, color=RED if is_avoid else DARK_BLUE)
add_textbox(s, 8.7, cy, 4.15, 0.37, note, font_size=12.5, color=NEAR_BLACK,
italic=is_avoid)
cy += 0.39
add_rect(s, 6.55, 1.15, 0.04, 5.8, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 18 - INFANT FEEDING
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Infant Feeding in HIV", "Balancing Nutrition vs. Transmission Risk")
footer(s, 18, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.42, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.42,
"Breastfeeding accounts for 1/3 to 1/2 of all MTCT worldwide. The decision must balance nutritional benefits vs. transmission risk.",
font_size=13, color=WHITE)
# Two scenarios
add_rect(s, 0.3, 1.64, 6.1, 0.42, RED)
add_textbox(s, 0.35, 1.66, 6.0, 0.42, "Resource-Rich Settings (US, Europe, India — urban)",
font_size=13, bold=True, color=WHITE)
rr_items = [
"REPLACEMENT FEEDING (formula) strongly recommended",
"Safe water, affordable formula — reduces MTCT to near zero",
"No breastfeeding if safe alternatives available",
"Exception: if mother on suppressive ART with undetectable VL AND counselled",
"If mother chooses to breastfeed despite advice:",
" → Exclusive breastfeeding × 6 months",
" → Maternal ART + infant NVP prophylaxis throughout",
" → Frequent maternal VL monitoring",
" → Frequent infant HIV testing",
" → Avoid mixed feeding (increases gut permeability)",
"Premastication of food by caregiver: DISCOURAGED (HIV transmission possible)",
]
cy = 2.11
for item in rr_items:
is_sub = item.startswith(" →")
add_textbox(s, 0.45 if not is_sub else 0.7, cy, 5.8, 0.33,
item.strip(), font_size=13 if not is_sub else 12,
bold=item.startswith("REPLACEMENT") or item.startswith("No breast"),
color=RED if item.startswith("REPLACE") else (TEAL if is_sub else NEAR_BLACK))
cy += 0.33 if not is_sub else 0.28
add_rect(s, 6.7, 1.64, 6.3, 0.42, TEAL)
add_textbox(s, 6.75, 1.66, 6.2, 0.42, "Resource-Limited Settings (Sub-Saharan Africa, rural)",
font_size=13, bold=True, color=WHITE)
rl_items = [
"WHO recommends BREASTFEEDING with maternal ART (Option B+)",
"Formula feeding has high morbidity/mortality risk (diarrhoea, malnutrition)",
"Exclusive breastfeeding × 6 months, then complementary foods",
"Continue breastfeeding up to 12-24 months with ART",
"AVOID mixed feeding — increases HIV transmission risk",
"Maternal VL monitoring throughout — goal: undetectable",
"If mother newly seroconverts while breastfeeding: highest transmission risk",
"Breastfeeding should stop when safe alternatives are reliably available",
"India (NACO): formula recommended in urban settings; breastfeeding with ART in rural/tribal areas",
]
cy = 2.11
for item in rl_items:
is_sub = item.startswith(" →")
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.11), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = TEAL; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.35, item, font_size=13, color=NEAR_BLACK)
cy += 0.36
add_rect(s, 6.55, 1.64, 0.04, 5.0, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 19 - MONITORING & FOLLOW-UP
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Monitoring & Follow-Up of HIV-Exposed Infant")
footer(s, 19, TOTAL_SLIDES)
# Timeline
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.4, "Schedule of Follow-Up Visits & Investigations",
font_size=14, bold=True, color=WHITE)
visits = [
("Birth\n(within 48 hrs)", [
"ARV prophylaxis started",
"HIV DNA/RNA PCR #1",
"CTX prophylaxis started (4-6 wks)",
"Inform paediatric team",
"Infant feeding counselling",
]),
("2-3 Weeks", [
"Clinical assessment",
"ARV compliance check",
"HIV DNA/RNA PCR #2",
"CBC if on ZDV",
]),
("1-2 Months", [
"Clinical + growth assessment",
"HIV DNA/RNA PCR #3",
"Immunization check",
"NVP dose adjustment (weight)",
]),
("4-6 Months", [
"HIV PCR #4 (definitive)",
"If ≥2 negative PCRs and no BF: uninfected",
"CD4 if HIV confirmed",
"Growth and development",
]),
("12 Months", [
"Antibody test if still BF",
"Growth & neurodevelopment",
"Transition to paediatric HIV clinic if infected",
"ART review",
]),
("18-24 Months", [
"Final HIV antibody test",
"If negative: CONFIRMED uninfected",
"Discharge from HIV program",
"Continue routine paediatric follow-up",
]),
]
box_w = 2.05; cy_box = 1.62; cx = 0.3
for i, (visit, items) in enumerate(visits):
bx = cx + i * (box_w + 0.05)
add_rect(s, bx, cy_box, box_w, 0.55, RED if i in [0,3] else DARK_BLUE)
add_textbox(s, bx+0.05, cy_box+0.05, box_w-0.1, 0.5, visit,
font_size=11.5, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
cur_y = cy_box + 0.6
for itm in items:
add_textbox(s, bx+0.08, cur_y, box_w-0.12, 0.32, "• " + itm,
font_size=10.5, color=NEAR_BLACK)
cur_y += 0.33
# Confirmed uninfected criteria
add_rect(s, 0.3, 5.65, 5.9, 0.6, RGBColor(0xD5, 0xF5, 0xE3))
add_textbox(s, 0.4, 5.67, 5.7, 0.55,
"CONFIRMED UNINFECTED:\n2 negative HIV PCRs (after ≥4 wks of age) AND negative antibody at ≥18 months AND not breastfeeding",
font_size=12.5, bold=True, color=RGBColor(0x1E, 0x8B, 0x4C))
add_rect(s, 6.7, 5.65, 6.3, 0.6, RGBColor(0xFF, 0xEB, 0xEB))
add_textbox(s, 6.8, 5.67, 6.1, 0.55,
"CONFIRMED INFECTED:\n2 positive HIV PCRs OR 1 positive PCR with clinical/immunologic criteria → START ART IMMEDIATELY",
font_size=12.5, bold=True, color=RED)
add_rect(s, 6.55, 5.65, 0.04, 0.6, MID_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 20 - PROGNOSIS
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Prognosis of Pediatric HIV")
footer(s, 20, TOTAL_SLIDES)
add_rect(s, 0.3, 1.15, 12.7, 0.4, DARK_BLUE)
add_textbox(s, 0.35, 1.17, 12.6, 0.4, "Prognosis depends on timing of ART initiation, viral load control, and CD4 trajectory",
font_size=14, italic=True, color=WHITE)
# Without ART
add_rect(s, 0.3, 1.62, 6.1, 0.4, RED)
add_textbox(s, 0.35, 1.64, 6.0, 0.4, "Without ART", font_size=15, bold=True, color=WHITE)
no_art = [
"~25-30% rapid progressors: die by age 1-2 years",
"Most children die before age 5 without treatment",
"Median survival: 9.4 years from infection",
"Opportunistic infections = most common cause of death",
"PCP: most common fatal OI in infants",
"Encephalopathy: poor neurodevelopmental outcome",
"In utero transmission: worst prognosis",
]
cy = 2.08
for item in no_art:
dot = s.shapes.add_shape(1, Inches(0.45), Inches(cy+0.12), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = RED; dot.line.fill.background()
add_textbox(s, 0.58, cy, 5.65, 0.38, item, font_size=14, color=NEAR_BLACK)
cy += 0.4
# With ART
add_rect(s, 6.7, 1.62, 6.3, 0.4, TEAL)
add_textbox(s, 6.75, 1.64, 6.2, 0.4, "With Effective ART", font_size=15, bold=True, color=WHITE)
with_art = [
"Near-normal life expectancy with early ART",
"Viral suppression in >90% if adherent",
"CD4 recovery to normal range in most children",
"Normal growth and neurodevelopment",
"Can attend regular school, lead normal life",
"ART must be LIFELONG — no cure currently",
"New challenges: adherence, toxicity, drug resistance, transition to adult care",
"Cure strategies (broadly neutralizing antibodies, gene therapy) under research",
]
cy = 2.08
for item in with_art:
dot = s.shapes.add_shape(1, Inches(6.85), Inches(cy+0.12), Inches(0.07), Inches(0.07))
dot.fill.solid(); dot.fill.fore_color.rgb = TEAL; dot.line.fill.background()
add_textbox(s, 7.0, cy, 5.85, 0.38, item, font_size=14, color=NEAR_BLACK)
cy += 0.4
add_rect(s, 6.55, 1.62, 0.04, 5.0, MID_BLUE)
# Poor prognostic factors box
add_rect(s, 0.3, 5.42, 12.7, 0.88, RGBColor(0xFF, 0xF0, 0xC0))
add_textbox(s, 0.4, 5.44, 12.5, 0.35, "Poor Prognostic Factors:", font_size=13, bold=True, color=DARK_RED)
add_textbox(s, 0.4, 5.78, 12.5, 0.45,
"In utero transmission | High viral load (>750,000 copies) | Low CD4 (<15%) | No ART | "
"OIs (especially PCP, CMV, MAC) | Encephalopathy | Poor adherence | Malnutrition",
font_size=13, color=DARK_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 21 - KEY POINTS SUMMARY
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
slide_bg(s, LIGHT_GRAY)
slide_header(s, "Key Points Summary", "Must-Know Facts for Paediatrics Finals")
footer(s, 21, TOTAL_SLIDES)
key_points = [
("1", "HIV = Retrovirus; CD4+ T-cell receptor; gp120 binds CD4 + CCR5/CXCR4 co-receptor"),
("2", "MTCT: intrapartum = most common route; breastfeeding = 1/3 to 1/2 of all MTCT worldwide"),
("3", "Without PMTCT: ~30% transmission risk; with complete PMTCT: <1%"),
("4", "HIV Ab tests unreliable <18 months (maternal antibodies); use HIV DNA/RNA PCR"),
("5", "PCR schedule: birth, 14-21 days, 1-2 months, 4-6 months → 2 negatives = uninfected"),
("6", "Neonatal ARV prophylaxis: ALL exposed newborns (ZDV monotherapy or 3-drug for high-risk)"),
("7", "CTX prophylaxis: start at 4-6 weeks for ALL HIV-exposed infants, continue until excluded"),
("8", "ART: ALL HIV-infected infants <2 years start ART immediately; preferred: ABC+3TC+DTG (≥6 yrs)"),
("9", "No BCG if symptomatic; use IPV not OPV; MMR/VZV safe if CD4 adequate"),
("10", "Breastfeeding: avoid in resource-rich settings; if breastfeeding, exclusive + maternal ART + NVP prophylaxis"),
("11", "CDC staging: N/A/B/C (clinical) + 1/2/3 (immunologic CD4-based)"),
("12", "Rapid progressors (20-30%): severe disease in first 6 months; slow progressors (70-80%): years of mild disease"),
("13", "Most common OI in Indian children = TB; most common fatal OI in infants = PCP → prevent with CTX"),
("14", "Viral load = best predictor of transmission risk and treatment response; undetectable VL = near-zero MTCT"),
("15", "India: PPTCT program under NACP; opt-out HIV testing at ANC; >21,000 ICTC centers"),
]
cy = 1.2
for num, point in key_points:
add_rect(s, 0.3, cy, 0.42, 0.34, RED)
add_textbox(s, 0.32, cy+0.02, 0.40, 0.32, num, font_size=12, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
add_textbox(s, 0.78, cy+0.02, 12.1, 0.34, point, font_size=13.5, color=NEAR_BLACK)
cy += 0.37
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 22 - THANK YOU
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, DARK_BLUE)
add_rect(s, 0, 0, 0.35, 7.5, RED)
add_rect(s, 0, 6.8, 13.333, 0.7, TEAL)
add_rect(s, 0.5, 2.0, 12.3, 0.12, RED)
add_textbox(s, 0.7, 2.2, 12, 0.8,
"THANK YOU",
font_size=48, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_rect(s, 3.5, 3.15, 6.3, 0.05, ACCENT)
add_textbox(s, 0.7, 3.3, 12, 0.5,
"\"The best protection we can offer a child born to an HIV+ mother is knowledge, timely testing, and effective PMTCT\"",
font_size=15, italic=True, color=LIGHT_BLUE, align=PP_ALIGN.CENTER)
add_textbox(s, 0.7, 4.2, 12, 0.45,
"References: Red Book 2021 (AAP) | Harrison's Principles of Internal Medicine 22e | Park's Textbook of Preventive and Social Medicine | WHO/UNAIDS 2022 | NACO Guidelines",
font_size=11, italic=True, color=RGBColor(0xB0, 0xC4, 0xDE), align=PP_ALIGN.CENTER)
add_textbox(s, 0.5, 6.85, 12.3, 0.3,
"Department of Paediatrics | Final Year MBBS",
font_size=10, color=WHITE, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════════════
# SAVE
# ════════════════════════════════════════════════════════════════════════════
output_path = "/tmp/workspace/hiv-newborn-ppt/HIV_Newborn_Paediatrics.pptx"
buf = BytesIO()
prs.save(buf)
with open(output_path, "wb") as f:
f.write(buf.getvalue())
print(f"SUCCESS: Saved to {output_path}")
print(f"Slides: {len(prs.slides)}")
cd /tmp/workspace/hiv-newborn-ppt && python create_ppt.py 2>&1
find /tmp/skills -name "fetch_images.py" 2>/dev/null; ls /tmp/skills/ 2>/dev/null
~/hiv-newborn-ppt/create_ppt.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/hiv-newborn-ppt/create_ppt.py'
cd /tmp/workspace/hiv-newborn-ppt && python create_ppt.py 2>&1
ls -lh /tmp/workspace/hiv-newborn-ppt/HIV_Newborn_Paediatrics.pptx
HIV Newborn Paediatrics
Presentation · PPTX
| # | Slide Title | Key Content |
|---|---|---|
| 1 | Title Slide | Full topic title + subtitle modules |
| 2 | Table of Contents | 20-topic dual-column index |
| 3 | Introduction | HIV overview, MTCT definition, global/India burden |
| 4 | Etiology / Virology | HIV structure (gp120, gp41, p24), replication cycle, drug targets |
| 5 | Pathogenesis | Step-by-step cascade, rapid vs slow progressors, thymic dysfunction |
| 6 | Routes of MTCT | In utero / Intrapartum / Breastfeeding — risk percentages for each |
| 7 | Epidemiology | Global (UNAIDS 2022) + India-specific (NACO) statistics |
| 8 | Risk Factors | Colour-coded table: maternal VL, obstetric, infant, breastfeeding, ARV |
| 9 | Clinical Features | Rapid progressors (20-30%) vs. Slow progressors (70-80%) |
| 10 | CDC Classification | CD4-based immunologic categories by age + Clinical N/A/B/C |
| 11 | Opportunistic Infections | Full table: organism, CD4 threshold, presentation, treatment |
| 12 | Diagnosis | Virologic (<18 months) vs. Serologic (≥18 months); PCR schedule |
| 13 | Neonatal ARV Flowchart | Red Book 2021 (AAP) algorithm image embedded |
| 14 | PMTCT Antenatal | Option B+ ART; TDF+3TC+DTG; LSCS indications; counselling |
| 15 | Neonatal ARV Prophylaxis | Standard risk (ZDV mono) vs. Higher risk (3-drug) regimens with doses |
| 16 | ART in Infected Infants | Age-based first-line regimens (WHO 2021/NACO); monitoring schedule |
| 17 | CTX Prophylaxis & Immunization | Dosing table; BCG/OPV/MMR/VZV caveats for HIV |
| 18 | Infant Feeding | Resource-rich vs. resource-limited settings; NACO guidance |
| 19 | Monitoring & Follow-up | 6-visit timeline from birth to 18-24 months; confirmed infected/uninfected criteria |
| 20 | Prognosis | Without ART vs. with ART; poor prognostic factors |
| 21 | Key Points Summary | 15 must-know facts numbered for quick revision |
| 22 | Thank You | References: Red Book 2021, Harrison's 22e, Park's, WHO/NACO |
Create a quick reference PDF (1-2 pages) with diagnostic algorithm and dosing regimens
~/hiv-newborn-ppt/create_qr_pdf.py
#!/usr/bin/env python3
"""
HIV in Newborns of HIV+ Mothers — Quick Reference Card
2-page A4 PDF: Diagnostic Algorithm + Dosing Regimens
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.platypus import (SimpleDocTemplate, Table, TableStyle, Paragraph,
Spacer, HRFlowable, KeepTogether)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus.flowables import Flowable
from reportlab.pdfbase import pdfmetrics
from io import BytesIO
# ── Colour palette ────────────────────────────────────────────────────────
NAVY = colors.HexColor('#0D2B5C')
RED = colors.HexColor('#C0222B')
TEAL = colors.HexColor('#007B83')
MID_BLUE = colors.HexColor('#1A5399')
AMBER = colors.HexColor('#F9A825')
LT_BLUE = colors.HexColor('#D6E8F7')
LT_TEAL = colors.HexColor('#E0F4F5')
LT_RED = colors.HexColor('#FDECEA')
LT_AMBER = colors.HexColor('#FFF8E1')
LT_NAVY = colors.HexColor('#EEF1F8')
WHITE = colors.white
BLACK = colors.HexColor('#1A1A2E')
DARK_RED = colors.HexColor('#8B0000')
GREEN = colors.HexColor('#1E8B4C')
LT_GREEN = colors.HexColor('#D5F5E3')
W, H = A4 # 595.27 x 841.89 pt
# ── Styles ────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
# Base styles
base = S('base', fontName='Helvetica', fontSize=7.5, leading=9.5, textColor=BLACK)
bold = S('bold', fontName='Helvetica-Bold', fontSize=7.5, leading=9.5, textColor=BLACK)
hdr1 = S('hdr1', fontName='Helvetica-Bold', fontSize=11, leading=13, textColor=WHITE, alignment=TA_CENTER)
hdr2 = S('hdr2', fontName='Helvetica-Bold', fontSize=9, leading=11, textColor=WHITE)
hdr3 = S('hdr3', fontName='Helvetica-Bold', fontSize=8, leading=10, textColor=WHITE, alignment=TA_CENTER)
sec = S('sec', fontName='Helvetica-Bold', fontSize=8.5, leading=10.5, textColor=NAVY)
note = S('note', fontName='Helvetica-Oblique', fontSize=6.8, leading=8.5, textColor=BLACK)
warn = S('warn', fontName='Helvetica-Bold', fontSize=7.5, leading=9.5, textColor=RED)
green_bold = S('gbold', fontName='Helvetica-Bold', fontSize=7.5, leading=9.5, textColor=GREEN)
center_base = S('cbase', fontName='Helvetica', fontSize=7.5, leading=9.5, textColor=BLACK, alignment=TA_CENTER)
center_bold = S('cbold', fontName='Helvetica-Bold', fontSize=7.5, leading=9.5, textColor=WHITE, alignment=TA_CENTER)
tiny = S('tiny', fontName='Helvetica', fontSize=6.5, leading=8, textColor=BLACK)
tiny_bold = S('tinybold', fontName='Helvetica-Bold', fontSize=6.5, leading=8, textColor=WHITE, alignment=TA_CENTER)
def P(text, style=None):
if style is None: style = base
return Paragraph(text, style)
def Pn(text, **kw):
st = S('_tmp', fontName='Helvetica', fontSize=7.5, leading=9.5, textColor=BLACK, **kw)
return Paragraph(text, st)
def tbl_style(cmd_list):
return TableStyle(cmd_list)
# ── Shared table commands ─────────────────────────────────────────────────
def header_row(bg=NAVY, fg=WHITE):
return [
('BACKGROUND', (0,0), (-1,0), bg),
('TEXTCOLOR', (0,0), (-1,0), fg),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 7.5),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('INNERGRID', (0,0), (-1,-1), 0.3, colors.HexColor('#CCCCCC')),
('BOX', (0,0), (-1,-1), 0.5, NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LT_NAVY]),
('FONTSIZE', (0,1), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 3),
('RIGHTPADDING', (0,0), (-1,-1), 3),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING',(0,0), (-1,-1), 2),
]
# ════════════════════════════════════════════════════════════════════════════
# PAGE 1 — DIAGNOSTIC ALGORITHM
# ════════════════════════════════════════════════════════════════════════════
def page1_content():
story = []
M = 12*mm # margins set in doc
# ── Page header ──────────────────────────────────────────────────────
hdr_data = [[P('<b><font color="white" size="13">HIV IN NEWBORNS OF HIV+ MOTHERS</font></b><br/>'
'<font color="#D6E8F7" size="8">DIAGNOSTIC ALGORITHM & TESTING PROTOCOL</font>',
S('_h', fontName='Helvetica-Bold', fontSize=13, leading=16, textColor=WHITE, alignment=TA_CENTER))]]
hdr_tbl = Table(hdr_data, colWidths=[W - 2*M])
hdr_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(hdr_tbl)
story.append(Spacer(1, 3*mm))
# ── KEY PRINCIPLE BOX ────────────────────────────────────────────────
key_data = [[
P('<b><font color="white">⚠ KEY PRINCIPLE:</font></b> '
'<font color="white">Maternal IgG antibodies cross the placenta → ALL infants of HIV+ mothers are '
'antibody-positive until ~18 months. Antibody-based tests (ELISA/Western Blot) are '
'<b>UNRELIABLE before 18 months</b>. Use <b>virologic tests (HIV DNA or RNA PCR)</b> '
'for diagnosis in infants <18 months.</font>',
S('_kp', fontName='Helvetica', fontSize=7.5, leading=9.5, textColor=WHITE))
]]
key_tbl = Table(key_data, colWidths=[W - 2*M])
key_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('BOX', (0,0), (-1,-1), 0.5, DARK_RED),
]))
story.append(key_tbl)
story.append(Spacer(1, 3*mm))
# ── SECTION 1: HIV DIAGNOSTIC ALGORITHM ──────────────────────────────
sec1_hdr = Table([[P('<b><font color="white">SECTION 1: HIV TESTING ALGORITHM IN HIV-EXPOSED INFANT</font></b>',
hdr2)]], colWidths=[W - 2*M])
sec1_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(sec1_hdr)
story.append(Spacer(1, 2*mm))
# Algo box — two-column layout
col_w = (W - 2*M - 4*mm) / 2
# LEFT: < 18 months
lt18_rows = [
[P('<b><font color="white">AGE < 18 MONTHS: VIROLOGIC TESTS</font></b>', hdr3)],
[P('<b>Preferred Tests:</b>', sec)],
[P('• HIV-1 DNA PCR (detects proviral DNA in PBMCs)\n• HIV-1 RNA PCR / Viral Load (plasma)\n → Both equally recommended (AAP/WHO 2021)', base)],
[P('<b>Testing Schedule:</b>', sec)],
[P('<b>Birth (within 48 hrs)</b> → PCR #1', bold)],
[P('14–21 days → PCR #2', base)],
[P('1–2 months → PCR #3', base)],
[P('<b>4–6 months → PCR #4 (definitive)</b>', bold)],
[P('<b>Performance of RNA PCR:</b>', sec)],
[P('Week 1: 25–58% sensitivity\n1 month: 60%\n2–3 months: 90–100%', base)],
[P('<b>Interpretation:</b>', sec)],
[P('<font color="#1E8B4C"><b>2 negative PCRs</b></font> (≥1 at ≥4 wks, ≥1 at ≥4 months)\n+ no breastfeeding → <b>HIV UNINFECTED</b>', base)],
[P('<font color="#C0222B"><b>2 positive PCRs</b></font> → <b>HIV CONFIRMED</b>\n→ Start ART IMMEDIATELY', base)],
[P('<i>1 positive PCR → repeat urgently (do not wait)</i>', note)],
]
lt18_tbl = Table(lt18_rows, colWidths=[col_w])
lt18_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), TEAL),
('BACKGROUND', (0,1), (-1,-1), LT_TEAL),
('BOX', (0,0), (-1,-1), 0.5, TEAL),
('INNERGRID', (0,0), (-1,-1), 0.2, colors.HexColor('#AADDDD')),
('TOPPADDING', (0,0), (-1,-1), 2), ('BOTTOMPADDING', (0,0), (-1,-1), 2),
('LEFTPADDING', (0,0), (-1,-1), 4), ('RIGHTPADDING', (0,0), (-1,-1), 4),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
# RIGHT: ≥ 18 months
ge18_rows = [
[P('<b><font color="white">AGE ≥ 18 MONTHS: SEROLOGY + VIROLOGIC</font></b>', hdr3)],
[P('<b>Step 1 — Screening:</b>', sec)],
[P('4th-generation Ag/Ab combination EIA\n(detects p24 antigen + HIV-1/2 antibodies)', base)],
[P('<b>Step 2 — if Reactive:</b>', sec)],
[P('HIV-1/HIV-2 antibody differentiation assay', base)],
[P('<b>Step 3 — if Indeterminate:</b>', sec)],
[P('HIV-1 NAAT (RNA PCR) for confirmation', base)],
[P('<b>Confirmatory: Western Blot</b>', sec)],
[P('Positive: bands at ≥2 of: p24, gp41, gp120/160', base)],
[P('<b>Additional Tests Once Confirmed:</b>', sec)],
[P('• CD4 count + CD4% (staging)\n• Viral Load (baseline before ART)\n• CBC, LFT, RFT, Lipid profile\n• Resistance testing (where available)', base)],
[P('<b>Maternal antibody seroreversion:</b>', sec)],
[P('Median: 13.9 months\n14% remain seropositive at 18 months\n4.3% at 21 months | 1.2% at 24 months\n<i>→ some may need PCR even at 18 months</i>', base)],
]
ge18_tbl = Table(ge18_rows, colWidths=[col_w])
ge18_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), MID_BLUE),
('BACKGROUND', (0,1), (-1,-1), LT_BLUE),
('BOX', (0,0), (-1,-1), 0.5, MID_BLUE),
('INNERGRID', (0,0), (-1,-1), 0.2, colors.HexColor('#AACCEE')),
('TOPPADDING', (0,0), (-1,-1), 2), ('BOTTOMPADDING', (0,0), (-1,-1), 2),
('LEFTPADDING', (0,0), (-1,-1), 4), ('RIGHTPADDING', (0,0), (-1,-1), 4),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
two_col = Table([[lt18_tbl, Spacer(4*mm,1), ge18_tbl]],
colWidths=[col_w, 4*mm, col_w])
two_col.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
]))
story.append(two_col)
story.append(Spacer(1, 3*mm))
# ── SECTION 2: RISK STRATIFICATION ───────────────────────────────────
sec2_hdr = Table([[P('<b><font color="white">SECTION 2: RISK STRATIFICATION OF HIV-EXPOSED NEWBORN</font></b>', hdr2)]],
colWidths=[W - 2*M])
sec2_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(sec2_hdr)
story.append(Spacer(1, 2*mm))
risk_w = [(W-2*M)*0.16, (W-2*M)*0.40, (W-2*M)*0.44]
risk_data = [
[P('<b>Risk Level</b>', bold), P('<b>Criteria</b>', bold), P('<b>Action</b>', bold)],
[P('<b><font color="#007B83">STANDARD</font></b><br/><font size="6.5">Lower risk</font>', base),
P('Mother on ART with <b>VL <50 copies/mL</b> near delivery\nReceived adequate antepartum + intrapartum ARVs', base),
P('<b>ZDV monotherapy × 4 weeks</b>\nHIV PCR at birth, 4–6 wks, 4–6 months\nCTX from 4–6 weeks', base)],
[P('<b><font color="#C0222B">HIGHER RISK</font></b><br/><font size="6.5">Criteria below</font>', base),
P('(1) No antepartum/intrapartum ARVs\n(2) Intrapartum ARVs only\n(3) ARVs but VL >1000 copies at delivery\n(4) Acute HIV seroconversion in pregnancy/breastfeeding', base),
P('<b>3-Drug Presumptive Therapy × 6 weeks</b>\n(ZDV + 3TC + NVP or Raltegravir)\nHIV PCR at birth (cord blood), 2–3 wks, 1–2 months, 4–6 months\nCTX from 4–6 weeks', base)],
]
risk_tbl = Table(risk_data, colWidths=risk_w)
risk_tbl.setStyle(TableStyle(header_row(NAVY) + [
('BACKGROUND', (0,1), (-1,1), LT_TEAL),
('BACKGROUND', (0,2), (-1,2), LT_RED),
('FONTNAME', (0,1), (0,1), 'Helvetica-Bold'),
('FONTNAME', (0,2), (0,2), 'Helvetica-Bold'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(risk_tbl)
story.append(Spacer(1, 3*mm))
# ── SECTION 3: CDC CLASSIFICATION ────────────────────────────────────
sec3_hdr = Table([[P('<b><font color="white">SECTION 3: CDC CLASSIFICATION (2014) — QUICK REFERENCE</font></b>', hdr2)]],
colWidths=[W - 2*M])
sec3_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(sec3_hdr)
story.append(Spacer(1, 2*mm))
# CD4 table + Clinical categories side by side
cd4_w = [(W-2*M)*0.21, (W-2*M)*0.26, (W-2*M)*0.26, (W-2*M)*0.25]
cd4_data = [
[P('<b>Age</b>', bold), P('<b>Cat 1 (None)</b>', bold), P('<b>Cat 2 (Moderate)</b>', bold), P('<b>Cat 3 (Severe)</b>', bold)],
[P('<1 year', base), P('≥1500 (≥34%)', base), P('750–1499 (26–33%)', base), P('<font color="#C0222B"><b><750 (<26%)</b></font>', base)],
[P('1–5 years', base), P('≥1000 (≥26%)', base), P('500–999 (22–25%)', base), P('<font color="#C0222B"><b><500 (<22%)</b></font>', base)],
[P('6–12 years', base), P('≥500 (≥26%)', base), P('200–499 (14–25%)', base), P('<font color="#C0222B"><b><200 (<14%)</b></font>', base)],
]
cd4_tbl = Table(cd4_data, colWidths=cd4_w)
cd4_tbl.setStyle(TableStyle(header_row(NAVY) + [
('FONTSIZE', (0,0), (-1,0), 7),
]))
clin_w = [(W-2*M)*0.12, (W-2*M)*0.88]
clin_data = [
[P('<b>Cat N</b>', bold), P('Not symptomatic / ≤1 condition in A', base)],
[P('<b>Cat A</b>', bold), P('≥2 mild: lymphadenopathy, hepatomegaly, splenomegaly, dermatitis, parotitis, recurrent URTIs', base)],
[P('<b>Cat B</b>', bold), P('Moderate: LIP, anemia, cardiomyopathy, CMV <1 mo, bacterial meningitis, candidiasis (>2 mo)', base)],
[P('<font color="#C0222B"><b>Cat C</b></font>', base), P('<font color="#C0222B"><b>AIDS-defining: PCP, recurrent bacterial infections, CMV disease, toxoplasmosis, KS, wasting syndrome, HIV encephalopathy</b></font>', base)],
]
clin_tbl = Table(clin_data, colWidths=clin_w)
clin_tbl.setStyle(TableStyle([
('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, LT_NAVY, WHITE, LT_RED]),
('BOX', (0,0), (-1,-1), 0.5, NAVY),
('INNERGRID', (0,0), (-1,-1), 0.2, colors.HexColor('#CCCCCC')),
('TOPPADDING', (0,0), (-1,-1), 2), ('BOTTOMPADDING', (0,0), (-1,-1), 2),
('LEFTPADDING', (0,0), (-1,-1), 3), ('RIGHTPADDING', (0,0), (-1,-1), 3),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTSIZE', (0,0), (-1,-1), 7),
]))
story.append(Table([[cd4_tbl], [Spacer(1,2*mm)], [P('<b>Clinical Categories:</b>', sec)], [clin_tbl]],
colWidths=[W-2*M]))
story.append(Spacer(1, 3*mm))
# ── FOOTER ───────────────────────────────────────────────────────────
ft_data = [[
P('<font color="white"><b>Page 1 / 2</b></font>',
S('_ft', fontName='Helvetica-Bold', fontSize=7, textColor=WHITE)),
P('<font color="white">HIV in Newborns of HIV+ Mothers — Quick Reference | Paediatrics Final Year</font>',
S('_ftc', fontName='Helvetica', fontSize=7, textColor=WHITE, alignment=TA_CENTER)),
P('<font color="white">Red Book 2021 (AAP) | WHO 2021 | NACO</font>',
S('_ftr', fontName='Helvetica-Oblique', fontSize=6.5, textColor=WHITE, alignment=TA_RIGHT)),
]]
ft_tbl = Table(ft_data, colWidths=[(W-2*M)*0.15, (W-2*M)*0.55, (W-2*M)*0.30])
ft_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(ft_tbl)
return story
# ════════════════════════════════════════════════════════════════════════════
# PAGE 2 — DOSING REGIMENS
# ════════════════════════════════════════════════════════════════════════════
def page2_content():
story = []
M = 12*mm
# ── Page 2 Header ─────────────────────────────────────────────────────
hdr_data = [[P('<b><font color="white" size="13">HIV IN NEWBORNS OF HIV+ MOTHERS</font></b><br/>'
'<font color="#D6E8F7" size="8">ARV DOSING REGIMENS, ART, COTRIMOXAZOLE & IMMUNIZATION</font>',
S('_h2', fontName='Helvetica-Bold', fontSize=13, leading=16, textColor=WHITE, alignment=TA_CENTER))]]
hdr_tbl = Table(hdr_data, colWidths=[W - 2*M])
hdr_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('TOPPADDING', (0,0), (-1,-1), 6), ('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(hdr_tbl)
story.append(Spacer(1, 3*mm))
# ── SECTION 4: NEONATAL ARV PROPHYLAXIS ──────────────────────────────
sec4_hdr = Table([[P('<b><font color="white">SECTION 4: NEONATAL ARV PROPHYLAXIS — ALL HIV-EXPOSED NEWBORNS (Red Book 2021, AAP)</font></b>', hdr2)]],
colWidths=[W - 2*M])
sec4_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(sec4_hdr)
story.append(Spacer(1, 2*mm))
# Standard risk
std_hdr = Table([[P('<b><font color="white">A. STANDARD RISK: ZDV (Zidovudine) Monotherapy</font></b>',
S('_sh', fontName='Helvetica-Bold', fontSize=8, textColor=WHITE))]],
colWidths=[W-2*M])
std_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(std_hdr)
std_w = [(W-2*M)*0.22, (W-2*M)*0.40, (W-2*M)*0.38]
std_data = [
[P('<b>Gestational Age</b>', bold), P('<b>ZDV Dose</b>', bold), P('<b>Duration & Notes</b>', bold)],
[P('≥35 weeks', base), P('<b>4 mg/kg PO BID</b>', bold), P('× 4 weeks', base)],
[P('30–34 weeks', base), P('<b>2 mg/kg PO BID</b> × 2 wks\nthen <b>3 mg/kg PO BID</b> × 2 wks', bold), P('× 4 weeks total', base)],
[P('<30 weeks', base), P('<b>2 mg/kg PO BID</b>', bold), P('× 4 weeks', base)],
[P('Cannot take PO\n(any GA)', base), P('IV ZDV = <b>75% of oral dose</b>, same interval', base), P('Switch to PO as soon as tolerated', base)],
]
std_tbl = Table(std_data, colWidths=std_w)
std_tbl.setStyle(TableStyle(header_row(MID_BLUE) + [
('BACKGROUND', (0,0), (-1,0), MID_BLUE),
]))
story.append(std_tbl)
story.append(Spacer(1, 2*mm))
# Higher risk
hi_hdr = Table([[P('<b><font color="white">B. HIGHER RISK: 3-Drug Presumptive HIV Therapy × 6 Weeks (PREFERRED)</font></b>',
S('_hh', fontName='Helvetica-Bold', fontSize=8, textColor=WHITE))]],
colWidths=[W-2*M])
hi_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(hi_hdr)
# ZDV + 3TC + NVP or RAL
hi_w = [(W-2*M)*0.14, (W-2*M)*0.18, (W-2*M)*0.68]
hi_data = [
[P('<b>Drug</b>', bold), P('<b>GA / Age</b>', bold), P('<b>Dose</b>', bold)],
[P('<b>ZDV</b>', bold), P('GA ≥35 wks\nGA <35 wks', base),
P('4 mg/kg PO BID\n2 mg/kg PO BID (birth→2 wks), then 3 mg/kg PO BID', base)],
[P('<b>3TC</b>', bold), P('Birth→4 wks\n>4 wks', base),
P('2 mg/kg PO BID\n4 mg/kg PO BID', base)],
[P('<b>NVP</b>\n(Nevirapine)', bold), P('GA ≥37 wks\nGA 34–<37 wks\n(birth→1 wk)\nGA 34–<37 wks\n(>1 wk)', base),
P('6 mg/kg PO BID\n4 mg/kg PO BID\n\n6 mg/kg PO BID', base)],
[P('<b>OR RAL</b>\n(Raltegravir)\nGA ≥37 wks\nonly', bold), P('Birth→1 wk\n1 wk→4 wks\n4 wks→6 wks', base),
P('1.5 mg/kg PO QD\n3 mg/kg PO BID\n6 mg/kg PO BID', base)],
[P('<font color="#C0222B"><b>NOTE</b></font>', base),
P('All GAs', base),
P('<font color="#C0222B">If mother took raltegravir 2–24 hrs before delivery → delay neonate\'s first RAL dose to 24–48 hrs post-birth | Do NOT use RAL if GA <37 weeks</font>', base)],
]
hi_tbl = Table(hi_data, colWidths=hi_w)
hi_tbl.setStyle(TableStyle(header_row(RED) + [
('BACKGROUND', (0,-1), (-1,-1), LT_RED),
('FONTNAME', (0,-1), (0,-1), 'Helvetica-Bold'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(hi_tbl)
story.append(Spacer(1, 1*mm))
note_box = Table([[P('<b>Higher-Risk Criteria:</b> (1) No ante/intrapartum ARVs <b>|</b> '
'(2) Intrapartum ARVs only <b>|</b> '
'(3) ARVs but VL ≥50 copies/mL near delivery <b>|</b> '
'(4) Acute HIV during pregnancy/breastfeeding',
S('_nb', fontName='Helvetica', fontSize=7, leading=9, textColor=DARK_RED))]],
colWidths=[W-2*M])
note_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), LT_RED),
('BOX', (0,0), (-1,-1), 0.5, RED),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(note_box)
story.append(Spacer(1, 3*mm))
# ── SECTION 5: ART IN CONFIRMED HIV-INFECTED INFANTS ──────────────────
sec5_hdr = Table([[P('<b><font color="white">SECTION 5: ART IN CONFIRMED HIV-INFECTED INFANTS/CHILDREN (WHO 2021 / NACO)</font></b>', hdr2)]],
colWidths=[W - 2*M])
sec5_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(sec5_hdr)
story.append(Spacer(1, 2*mm))
art_w = [(W-2*M)*0.18, (W-2*M)*0.82]
start_data = [[
P('<b><font color="white">WHEN TO START</font></b>',
S('_ws', fontName='Helvetica-Bold', fontSize=7.5, textColor=WHITE, alignment=TA_CENTER)),
P('<font color="white"><b>ALL HIV-infected infants <2 years → START ART IMMEDIATELY regardless of CD4 or clinical stage</b><br/>'
'Children ≥2 years → ART regardless of CD4; urgently if Cat C or Cat 3 immunosuppression</font>',
S('_wst', fontName='Helvetica', fontSize=7.5, leading=9.5, textColor=WHITE))
]]
start_tbl = Table(start_data, colWidths=art_w)
start_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), RED),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4), ('RIGHTPADDING', (0,0), (-1,-1), 4),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(start_tbl)
story.append(Spacer(1, 1.5*mm))
art_reg_w = [(W-2*M)*0.20, (W-2*M)*0.46, (W-2*M)*0.34]
art_reg = [
[P('<b>Age Group</b>', bold), P('<b>Preferred First-Line Regimen</b>', bold), P('<b>Alternative</b>', bold)],
[P('<b><4 weeks</b>', bold), P('AZT + 3TC + NVP', base), P('AZT + 3TC + LPV/r\n(if NVP prophylaxis given)', base)],
[P('<b>4 wks – 3 years</b>', bold), P('<b>ABC + 3TC + LPV/r</b>', bold), P('AZT + 3TC + LPV/r', base)],
[P('<b>3 – <6 years</b>', bold), P('<b>ABC + 3TC + DTG</b> (preferred)', bold), P('ABC + 3TC + LPV/r', base)],
[P('<b>≥6 years</b>', bold), P('<b>ABC + 3TC + DTG</b> or <b>TDF + 3TC + DTG</b>', bold), P('TDF + 3TC + EFV (if DTG unavailable)', base)],
[P('<b>2nd Line\n(any age)</b>', bold), P('Change backbone + PI: <b>LPV/r</b> or <b>ATV/r</b>', base), P('After virological failure on NNRTI-based 1st line', base)],
]
art_tbl = Table(art_reg, colWidths=art_reg_w)
art_tbl.setStyle(TableStyle(header_row(NAVY) + [
('BACKGROUND', (0,-1), (-1,-1), LT_AMBER),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(art_tbl)
story.append(Spacer(1, 3*mm))
# ── SECTION 6: CTX + IMMUNIZATION in 2-col ────────────────────────────
col_w = (W - 2*M - 4*mm) / 2
# CTX
ctx_sec = Table([[P('<b><font color="white">SECTION 6: COTRIMOXAZOLE (TMP-SMX) PROPHYLAXIS</font></b>', hdr2)]],
colWidths=[col_w])
ctx_sec.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 4),
]))
ctx_rows = [
[P('<b>Indication</b>', bold)],
[P('ALL HIV-exposed infants from <b>4–6 weeks of age</b> until HIV excluded', base)],
[P('ALL confirmed HIV-infected children (continue until CD4 >25% stable on ART ×6 months)', base)],
[Spacer(1,1*mm)],
[P('<b>Dose (TMP component): 5 mg/kg/day OD</b>', bold)],
[P('• 4–6 kg: 2.5 mL single-strength syrup OD\n• 6–10 kg: 5 mL single-strength syrup OD\n• 10–14 kg: ½ SS tablet OD\n• >14 kg: 1 SS tablet OD\n• Adult: 1 DS tablet OD', base)],
[Spacer(1,1*mm)],
[P('<b>Covers:</b> PCP | Toxoplasma | Isospora | Bacterial infections', bold)],
[P('<b>Stop when:</b> HIV excluded (2 neg PCRs, off BF) OR CD4 adequate on ART', base)],
[P('<font color="#C0222B"><b>Contraindicated:</b> Sulfa allergy | Severe hepatic disease</font>', base)],
]
ctx_tbl = Table(ctx_rows, colWidths=[col_w])
ctx_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), LT_TEAL),
('BOX', (0,0), (-1,-1), 0.5, TEAL),
('TOPPADDING', (0,0), (-1,-1), 2), ('BOTTOMPADDING', (0,0), (-1,-1), 2),
('LEFTPADDING', (0,0), (-1,-1), 4), ('RIGHTPADDING', (0,0), (-1,-1), 4),
]))
# Immunization
imm_sec = Table([[P('<b><font color="white">SECTION 7: IMMUNIZATION IN HIV-EXPOSED/INFECTED</font></b>', hdr2)]],
colWidths=[col_w])
imm_sec.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), MID_BLUE),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 4),
]))
imm_w = [col_w*0.28, col_w*0.72]
imm_rows = [
[P('<b>Vaccine</b>', bold), P('<b>Recommendation</b>', bold)],
[P('BCG', base), P('At birth <b>if asymptomatic</b>; AVOID if symptomatic/confirmed HIV', base)],
[P('OPV', base), P('Use <b>IPV</b> (not OPV) for confirmed HIV-infected', base)],
[P('DTP / Hep B / Hib', base), P('As per schedule — SAFE', base)],
[P('PCV', base), P('<b>Strongly recommended</b> — extra dose for HIV-infected', base)],
[P('MMR / Varicella\n(LIVE)', base), P('Give if CD4 ≥15% (<5 yrs) or ≥200 (>5 yrs)\n<b>AVOID in severe immunosuppression</b>', base)],
[P('Influenza', base), P('Annually — <b>inactivated</b> vaccine only', base)],
[P('HPV (≥9 yrs)', base), P('3-dose schedule recommended', base)],
[P('<font color="#C0222B"><b>AVOID</b></font>', base),
P('<font color="#C0222B">BCG (if symptomatic) | OPV | Yellow fever | Any live vaccine in severe immunosuppression (CD4 <15%)</font>', base)],
]
imm_tbl = Table(imm_rows, colWidths=imm_w)
imm_tbl.setStyle(TableStyle(header_row(MID_BLUE) + [
('BACKGROUND', (0,-1), (-1,-1), LT_RED),
('FONTNAME', (0,-1), (0,-1), 'Helvetica-Bold'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
left_col = Table([[ctx_sec], [ctx_tbl]], colWidths=[col_w])
right_col = Table([[imm_sec], [imm_tbl]], colWidths=[col_w])
left_col.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),0),('BOTTOMPADDING',(0,0),(-1,-1),0),
('LEFTPADDING',(0,0),(-1,-1),0),('RIGHTPADDING',(0,0),(-1,-1),0)]))
right_col.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),0),('BOTTOMPADDING',(0,0),(-1,-1),0),
('LEFTPADDING',(0,0),(-1,-1),0),('RIGHTPADDING',(0,0),(-1,-1),0)]))
two_col = Table([[left_col, Spacer(4*mm,1), right_col]], colWidths=[col_w, 4*mm, col_w])
two_col.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 0), ('RIGHTPADDING', (0,0), (-1,-1), 0),
]))
story.append(two_col)
story.append(Spacer(1, 3*mm))
# ── SECTION 8: MONITORING ──────────────────────────────────────────────
mon_hdr = Table([[P('<b><font color="white">SECTION 8: FOLLOW-UP & MONITORING SCHEDULE</font></b>', hdr2)]],
colWidths=[W-2*M])
mon_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(mon_hdr)
story.append(Spacer(1, 1.5*mm))
mon_w = [(W-2*M)*0.16, (W-2*M)*0.84]
mon_data = [
[P('<b>Time Point</b>', bold), P('<b>Actions</b>', bold)],
[P('<b>Birth</b>\n(within 48 hrs)', bold),
P('Start ARV prophylaxis | HIV PCR #1 (cord blood) | Inform paediatric team | CTX to start at 4–6 wks | Infant feeding counselling', base)],
[P('<b>4–6 weeks</b>', bold),
P('Start CTX prophylaxis | Clinical assessment | ARV compliance | PCR #2 (if not done at 2–3 wks) | Immunizations per schedule', base)],
[P('<b>1–2 months</b>', bold),
P('HIV PCR #3 | Growth assessment | NVP/ARV dose adjustment for weight | Hep B booster | CBC if on ZDV', base)],
[P('<b>4–6 months</b>', bold),
P('<b>Definitive HIV PCR #4</b> | If ≥2 neg PCRs + no BF → CONFIRMED UNINFECTED | If positive → start ART immediately + CD4 | Immunization review', base)],
[P('<b>12 months</b>', bold),
P('HIV antibody test if still breastfeeding | Growth + neurodevelopment | Transition to paediatric HIV clinic if infected | ART monitoring (VL, CD4)', base)],
[P('<b>18–24 months</b>', bold),
P('Final HIV antibody test | If negative → CONFIRMED UNINFECTED → discharge from HIV program | Continue routine paediatric follow-up', base)],
[P('<b>On ART\n(ongoing)</b>', bold),
P('<b>VL:</b> at 4 wks, 3 months, 6 months, then every 6 months — target <50 copies/mL | <b>CD4:</b> every 3–6 months | '
'<b>CBC/LFT/RFT:</b> baseline, 2 wks (if NVP), every 6 months | Growth + neurodevelopment every visit', base)],
]
mon_tbl = Table(mon_data, colWidths=mon_w)
mon_tbl.setStyle(TableStyle(header_row(NAVY) + [
('BACKGROUND', (0,-1), (-1,-1), LT_BLUE),
('FONTNAME', (0,-1), (0,-1), 'Helvetica-Bold'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(mon_tbl)
story.append(Spacer(1, 2*mm))
# ── Quick reminder strip ──────────────────────────────────────────────
strip_data = [[
P('<b><font color="white">🔑 REMEMBER:</font></b> <font color="white">VL undetectable = <1% MTCT | All HIV+ infants <2 yrs = START ART NOW | '
'2 negative PCRs = uninfected | CTX from 4–6 weeks ALL exposed | IPV not OPV | '
'BCG contraindicated if symptomatic HIV | Breastfeeding: replace OR exclusive BF + maternal ART + NVP prophylaxis</font>',
S('_strip', fontName='Helvetica', fontSize=7, leading=9, textColor=WHITE))
]]
strip_tbl = Table(strip_data, colWidths=[W-2*M])
strip_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('BOX', (0,0), (-1,-1), 0.5, NAVY),
]))
story.append(strip_tbl)
story.append(Spacer(1, 2*mm))
# ── Footer ────────────────────────────────────────────────────────────
ft_data = [[
P('<font color="white"><b>Page 2 / 2</b></font>',
S('_ft2', fontName='Helvetica-Bold', fontSize=7, textColor=WHITE)),
P('<font color="white">HIV in Newborns of HIV+ Mothers — Quick Reference | Paediatrics Final Year</font>',
S('_ftc2', fontName='Helvetica', fontSize=7, textColor=WHITE, alignment=TA_CENTER)),
P('<font color="white">Red Book 2021 (AAP) | WHO 2021 | NACO</font>',
S('_ftr2', fontName='Helvetica-Oblique', fontSize=6.5, textColor=WHITE, alignment=TA_RIGHT)),
]]
ft_tbl = Table(ft_data, colWidths=[(W-2*M)*0.15, (W-2*M)*0.55, (W-2*M)*0.30])
ft_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(ft_tbl)
return story
# ════════════════════════════════════════════════════════════════════════════
# BUILD PDF
# ════════════════════════════════════════════════════════════════════════════
from reportlab.platypus import PageBreak
output_path = "/tmp/workspace/hiv-newborn-ppt/HIV_QuickRef.pdf"
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
leftMargin=12*mm, rightMargin=12*mm,
topMargin=10*mm, bottomMargin=10*mm,
title="HIV in Newborns of HIV+ Mothers — Quick Reference",
author="Paediatrics Final Year",
subject="PMTCT Diagnostic Algorithm and Dosing Regimens",
)
story = page1_content()
story.append(PageBreak())
story += page2_content()
doc.build(story)
print(f"SUCCESS: {output_path}")
import os
size_kb = os.path.getsize(output_path) // 1024
print(f"File size: {size_kb} KB")
cd /tmp/workspace/hiv-newborn-ppt && python create_qr_pdf.py 2>&1
HIV QuickRef
PDF Document · PDF
| Section | Content |
|---|---|
| Key Principle | Red alert box: why antibody tests fail before 18 months |
| Section 1 | Side-by-side testing protocols: <18 months (DNA/RNA PCR schedule: birth → 2-3 wks → 1-2 mo → 4-6 mo) vs ≥18 months (4th-gen Ag/Ab EIA → differentiation assay → NAAT) |
| Section 2 | Risk stratification table: Standard risk (VL <50) vs Higher risk (4 criteria) with actions for each |
| Section 3 | CDC 2014 classification: CD4-based immunologic categories (by age) + Clinical N/A/B/C categories |
| Section | Content |
|---|---|
| Section 4 | Neonatal ARV prophylaxis: Standard risk (ZDV doses by GA) + Higher risk (ZDV + 3TC + NVP/RAL full dosing table with GA-specific doses) |
| Section 5 | ART regimens: start criteria + age-grouped first-line/alternative regimens (<4 wks → ≥6 yrs) |
| Section 6 | CTX prophylaxis: weight-based dosing table + when to stop |
| Section 7 | Immunization: vaccine-by-vaccine recommendations with contraindications in HIV |
| Section 8 | Follow-up schedule: birth → 48 hrs → 4-6 wks → 1-2 mo → 4-6 mo → 12 mo → 18-24 mo + ongoing ART monitoring targets |
| Reminder strip | 7 must-remember rules in a single teal banner |