Detailed information regarding Tuberculosis acc to Harrison and management acc to latest standard guidelines in India including regimens and new guidelines and modified a tt
India TB management guidelines 2025 RNTCP NTEP new regimens updated treatment
"tuberculosis"[MeSH Terms] AND "drug therapy"[MeSH Terms]
https://tbcindia.mohfw.gov.in/guidelines
tuberculosis chest X-ray pulmonary cavitation

This diagnostic image is a frontal (posteroanterior) chest X-ray demonstrating significant bilateral pulmonary pathology. In the right lung, there is a dense, heterogeneous lobar consolidation primarily occupying the right upper lobe. Within this opacification, a radiolucent area is visible, highly suggestive of cavitation. The left lung displays sublobar, patchy infiltrates and consolidation, also predominantly in the upper zone, with subtle features indicating potential central cavitation. The cardiac silhouette appears within normal limits, though the mediastinal borders are partially obscured by the adjacent pulmonary opacities. These findings are classically associated with infectious processes such as pulmonary tuberculosis (TB) or necrotizing pneumonia. In the provided clinical context of a co-infection involving COVID-19 and tuberculosis, the imaging illustrates the characteristic upper-lobe predilection and cavitary nature of reactivated TB, while the more diffuse patchy elements may represent overlapping viral pneumonia patterns.

Diagnostic imaging composite of a 66-year-old male with active pulmonary tuberculosis (TB), comprising a posteroanterior chest X-ray (A), a lateral chest X-ray (B), and an axial High-Resolution Computed Tomography (HRCT) scan (C). Panels A and B demonstrate increased opacity in the left upper lung zone indicative of consolidation, with radiolucent areas representing cavitation (white arrows). Panel C, the HRCT at the level of the lower lobes, provides a detailed view of the pulmonary pathology. It reveals a focal area of dense consolidation containing a central air-filled cavity (white arrow) in the left lung. Additionally, characteristic 'tree-in-bud' patterns are visible (black arrows), consisting of small centrilobular nodules and branching linear opacities that indicate endobronchial spread of infection within the upper segment of the left lower lobe. These imaging findings are hallmark radiological features of secondary or active tuberculosis, illustrating parenchymal destruction and small airway involvement.

This diagnostic image is a posteroanterior (PA) chest X-ray demonstrating bilateral pulmonary pathology consistent with active tuberculosis. In the right lung, there is a large, heterogeneous infiltrative lesion in the upper field containing a distinct cavitary lesion measuring approximately 35 x 30 mm with irregular borders. The left lung shows an infiltrative opacity at the apex and multiple nodular, fibrous lesions distributed throughout the middle lung field, suggesting a chronic or granulomatous process. The cardiac silhouette appears within normal limits, and the left costophrenic angle is sharp and clear. This radiograph serves as a classic educational example of secondary pulmonary tuberculosis, highlighting hallmark features such as apical predilection, parenchymal infiltration, and cavitation. These findings are clinically significant for the assessment of disease severity and the risk of hemoptysis in patients with Mycobacterium tuberculosis complex infections.
https://www.scribd.com/presentation/859518920/NTEP-Summary-1



| Site | Features |
|---|---|
| Lymph node TB (most common extrapulmonary, 35% worldwide) | Painless cervical/supraclavicular swelling ("scrofula"); may form discharging sinus; FNAC yield ~80% |
| Pleural TB (~20% of extrapulmonary) | Exudative effusion; lymphocyte-predominant; ADA elevated (>40 U/L); may be first presentation |
| TB meningitis | Subacute onset; basal meningitis; CN palsies; hydrocephalus; CSF - lymphocytes, high protein, low glucose; high mortality |
| Spinal TB (Pott's disease) | Thoracic > lumbar; vertebral body destruction; "gibbus deformity"; paravertebral abscess |
| Genitourinary TB | "Sterile pyuria"; dysuria; haematuria; renal parenchymal destruction; ureteric stricture |
| Abdominal/Peritoneal TB | Ascites; doughy abdomen; ileocaecal involvement; obstruction |
| Pericardial TB | Exudative pericarditis; constrictive pericarditis (late) |
| Miliary TB | Haematogenous dissemination; classic millet-seed pattern on CXR; very high mortality; common in HIV |
| Bone/Joint TB | Monoarthritis; cold abscess |
| Test | Sensitivity | Comments |
|---|---|---|
| AFB smear (ZN/Auramine) | 40-60% (pulmonary) | Rapid, cheap; requires 5,000-10,000 AFB/mL |
| Culture (LJ medium) | Gold standard; 80-90% | Takes 3-8 weeks (solid) or 10-14 days (liquid MGIT) |
| Xpert MTB/RIF (GeneXpert) | 88% (smear+ve); 68% (smear-ve) | Detects MTB and RIF resistance in 2 hrs; First-line in NTEP India |
| Xpert MTB/RIF Ultra | Higher sensitivity than standard Xpert | Better for paucibacillary/EPTB |
| LPA (Line Probe Assay) | High for MTB + resistance | Genotype MTBDRplus detects H and R resistance |
| NAAT | Variable | Rapid molecular detection |
| Regimen | Schedule | Duration | Notes |
|---|---|---|---|
| Isoniazid + Rifapentine (3HP) | INH 900 mg + RPT 900 mg weekly | 3 months | First choice in adults and children >2 yrs incl. HIV+; requires DOT for once-weekly; supplement with pyridoxine; NOT in pregnancy |
| Rifampin (4R) | 600 mg/d (10 mg/kg) | 4 months | HIV-negative preferred; no data in HIV+ |
| INH + Rifampin (3HR) | INH 300 mg/d + RIF 600 mg/d | 3 months | Caution in HIV (drug interactions) |
| Isoniazid (6H or 9H) | 300 mg/d or 900 mg twice weekly | 6-9 months | Older standard; 9 months more effective but hepatotoxic; twice-weekly needs DOT |
| Drug | Daily Dose | Adverse Effects |
|---|---|---|
| Isoniazid (H) | 5 mg/kg (max 300 mg/d) | Hepatotoxicity, peripheral neuropathy (prevented by pyridoxine 25-50 mg/d), lupus-like syndrome |
| Rifampin (R) | 10 mg/kg (max 600 mg/d) | Hepatotoxicity, orange discoloration of secretions, drug interactions (CYP450 inducer), flu-like syndrome |
| Pyrazinamide (Z) | 25 mg/kg (max 2 g/d) | Hepatotoxicity, hyperuricemia, arthralgia, rash |
| Ethambutol (E) | 15-20 mg/kg/d | Optic neuritis (check visual acuity before and during treatment; avoid in young children) |
| Streptomycin (S) | 15 mg/kg IM/IV | Ototoxicity, nephrotoxicity |
| Type | Definition |
|---|---|
| Mono-resistance | Resistant to 1 first-line drug |
| Poly-resistance | Resistant to >1 first-line drug (not H+R combination) |
| MDR-TB | Resistant to at least INH + Rifampin |
| Pre-XDR-TB (2021 WHO definition) | MDR/RR-TB + any fluoroquinolone resistance |
| XDR-TB | MDR/RR-TB + fluoroquinolone resistance + at least one Group A drug resistance (bedaquiline or linezolid) |
| Feature | Old RNTCP | NTEP 2020-present |
|---|---|---|
| Treatment regimen | Thrice-weekly DOT | Daily regimen (fixed-dose combinations) |
| Notification | Optional (public sector) | Mandatory for ALL (public + private) |
| Diagnostic test | Sputum smear (primarily) | Molecular test (GeneXpert) as first-line |
| Drug supply | Intermittent-dose FDCs | Daily weight-band FDCs |
| Beneficiary support | Limited | Ni-kshay Poshan Yojana (₹500/month nutritional support) |
| Case finding | Passive | Active case finding (including Pradhan Mantri TB Mukt Bharat Abhiyaan) |
| Weight Band | Intensive Phase (2 months) HRZE | Continuation Phase (4 months) HR |
|---|---|---|
| 25-39 kg | 2 tabs | 2 tabs |
| 40-54 kg | 3 tabs | 3 tabs |
| 55-69 kg | 4 tabs | 4 tabs |
| ≥70 kg | 5 tabs | 5 tabs |
| Category | Definition | Regimen Group |
|---|---|---|
| RR-TB | Rifampicin-resistant (any) | Treat as MDR |
| MDR-TB | INH + RIF resistant | BPaL or longer regimen |
| Pre-XDR-TB | MDR + any FQ resistance | Modified regimen |
| XDR-TB | MDR + FQ + Bdq/Lzd resistance | Individualized |
| TB Type | Regimen | Duration |
|---|---|---|
| MDR/RR-TB (FQ-susceptible) | BPaLM (Bdq + Pretomanid + Lzd + Mfx) | 6 months |
| MDR/RR-TB (FQ-resistant) | BPaL (Bdq + Pretomanid + Lzd) | 6 months |
| MDR-TB shorter oral | Bdq + Lfx/Mfx + Cfz + Z + E + Eto/Pto | 9-11 months |
| Pre-XDR/XDR-TB | Individualized ≥5 drugs (Group A+B+C) | 18-20 months |
| Monitoring | Frequency |
|---|---|
| Sputum AFB smear + culture | Monthly during intensive phase |
| ECG (QTc for Bdq, Dlm, Cfz, Mfx) | Baseline, then monthly |
| LFT | Baseline, then monthly (Lzd hepatotoxic) |
| CBC | Monthly (Lzd - myelosuppression) |
| Peripheral neuropathy assessment | Monthly (Lzd, Cs) |
| Ophthalmology | Baseline + every 6 months (Ethambutol, Lzd) |
| TSH | Baseline + 6-monthly (Eto/Pto + PAS) |
| Renal function | Monthly if aminoglycosides used |
| Initiative | Details |
|---|---|
| Nikshay | IT system for case notification, treatment tracking, outcome reporting |
| Nikshay Poshan Yojana | ₹500/month direct benefit transfer to all TB patients for nutrition |
| Nikshay Mitra | Corporate/individual adoption of TB patients for additional support (2022 onwards, updated 2026) |
| Pradhan Mantri TB Mukt Bharat Abhiyaan | PM-level campaign for TB elimination; district-level targets |
| Universal Drug Susceptibility Testing (UDST) | All bacteriologically confirmed TB cases undergo Xpert; culture + DST for all presumptive DR-TB |
| Daily FDC regimen | Replaced 3x/week DOTS; daily therapy improves outcomes and reduces resistance |
| Differentiated TB Care (March 2025) | Risk-stratified approach: identifying high-risk patients for intensified monitoring |
| Active Case Finding | Systematic screening in tribal, urban slums, congregate settings, PLWH, DM patients |
PRESUMPTIVE TB
↓
Xpert MTB/RIF (first-line molecular test)
↓
MTB detected?
YES → RIF sensitive?
YES → DS-TB: 2HRZE/4HR (daily FDC, weight-based)
NO → RR/MDR-TB → LPA + Culture/DST → BPaLM/BPaL
NO → Clinical/radiological diagnosis if strong suspicion
↓
EPTB? → Xpert on relevant specimen (CSF, tissue, fluid)
↓
TB diagnosed → Notify on Nikshay → Start daily FDC
↓
Monitor: Monthly sputum, LFT, ADR assessment
↓
Contact investigation → TPT for eligible contacts
Convert this information into ppt
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
mkdir -p /tmp/workspace/tb-ppt && echo "done"
~/tb-ppt/create_tb_ppt.py
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
from io import BytesIO
import copy
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ── Colour palette ─────────────────────────────────────────────────────────
C_DARK_BLUE = RGBColor(0x1A, 0x37, 0x6C) # dark navy
C_MED_BLUE = RGBColor(0x1E, 0x6F, 0xB4) # mid blue
C_ACCENT = RGBColor(0xE8, 0x4A, 0x4A) # red accent
C_LIGHT_BG = RGBColor(0xF0, 0xF4, 0xFA) # very light blue-grey
C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
C_TEXT_DARK = RGBColor(0x1C, 0x1C, 0x1C)
C_GOLD = RGBColor(0xF5, 0xA6, 0x23)
C_GREEN = RGBColor(0x1A, 0x7A, 0x3C)
C_ORANGE = RGBColor(0xD9, 0x65, 0x00)
C_SUBHEAD = RGBColor(0x1E, 0x6F, 0xB4)
# ── Helpers ─────────────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_color, transparency=0):
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()
return shape
def add_text(slide, text, x, y, w, h, font_size=18, bold=False,
color=C_TEXT_DARK, align=PP_ALIGN.LEFT, italic=False,
wrap=True, v_anchor=MSO_ANCHOR.TOP):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.vertical_anchor = v_anchor
tf.margin_left = Pt(0)
tf.margin_right = Pt(0)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
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 = "Calibri"
return tf
def add_multiline(slide, lines, x, y, w, h, font_size=14,
color=C_TEXT_DARK, bold_first=False, line_spacing=1.2,
bullet=True):
"""lines: list of strings; bold_first makes first run bold in each line"""
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)
from pptx.oxml.ns import qn
from lxml import etree
first = True
for i, line in enumerate(lines):
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
if bullet:
p.space_before = Pt(2)
run = p.add_run()
if isinstance(line, tuple):
run.text = line[0]
run.font.bold = True
run.font.color.rgb = line[1] if len(line) > 1 else color
if len(line) > 2:
run2 = p.add_run()
run2.text = line[2]
run2.font.bold = False
run2.font.color.rgb = color
run2.font.size = Pt(font_size)
run2.font.name = "Calibri"
else:
run.text = ("• " if bullet else "") + line
run.font.bold = False
run.font.color.rgb = color
run.font.size = Pt(font_size)
run.font.name = "Calibri"
return tf
def slide_header(slide, title, subtitle=None):
"""Top banner with title"""
add_rect(slide, 0, 0, 13.333, 1.1, C_DARK_BLUE)
add_text(slide, title, 0.25, 0.05, 12, 0.75,
font_size=30, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT)
if subtitle:
add_text(slide, subtitle, 0.25, 0.78, 12, 0.35,
font_size=13, bold=False, color=C_GOLD, align=PP_ALIGN.LEFT)
# bottom accent line
add_rect(slide, 0, 1.1, 13.333, 0.06, C_ACCENT)
def section_box(slide, title, x, y, w, h, content_lines, font_size=12,
title_color=C_WHITE, box_color=C_MED_BLUE, text_color=C_TEXT_DARK,
bg_color=C_LIGHT_BG):
"""A titled box with bullet content"""
add_rect(slide, x, y, w, 0.38, box_color)
add_text(slide, title, x+0.08, y+0.02, w-0.1, 0.35,
font_size=13, bold=True, color=title_color, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, x, y+0.38, w, h-0.38, bg_color)
add_multiline(slide, content_lines, x+0.08, y+0.42, w-0.16, h-0.5,
font_size=font_size, color=text_color)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — Title slide
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_DARK_BLUE)
add_rect(s, 0, 5.8, 13.333, 1.7, C_MED_BLUE)
add_rect(s, 0, 3.3, 13.333, 0.08, C_ACCENT)
add_rect(s, 0, 5.72, 13.333, 0.08, C_GOLD)
add_text(s, "TUBERCULOSIS", 0.5, 0.8, 12.5, 1.5,
font_size=60, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER)
add_text(s, "Comprehensive Review", 0.5, 2.3, 12.5, 0.8,
font_size=28, bold=False, color=C_GOLD, align=PP_ALIGN.CENTER, italic=True)
add_text(s, "Pathogenesis • Diagnosis • Management", 0.5, 3.0, 12.5, 0.5,
font_size=18, bold=False, color=RGBColor(0xAA, 0xCC, 0xFF), align=PP_ALIGN.CENTER)
add_text(s, "Based on Harrison's Principles of Internal Medicine 22E (2025)", 0.5, 3.55, 12.5, 0.4,
font_size=13, bold=False, color=C_GOLD, align=PP_ALIGN.CENTER, italic=True)
add_text(s, "India Management: NTEP / Central TB Division Guidelines 2025", 0.5, 4.0, 12.5, 0.4,
font_size=13, bold=False, color=RGBColor(0xAA, 0xCC, 0xFF), align=PP_ALIGN.CENTER)
add_text(s, "National Tuberculosis Elimination Programme | MoHFW, Government of India",
0.5, 6.1, 12.5, 0.4,
font_size=12, bold=False, color=C_WHITE, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — Overview & Epidemiology
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Overview & Epidemiology", "Harrison's 22E Ch. 183 | WHO Global TB Report 2024")
add_rect(s, 0.25, 1.3, 8.2, 2.5, C_LIGHT_BG)
add_rect(s, 0.25, 1.3, 8.2, 0.38, C_DARK_BLUE)
add_text(s, "Global Burden", 0.35, 1.32, 8, 0.35, font_size=13, bold=True, color=C_WHITE)
add_multiline(s, [
"Caused by Mycobacterium tuberculosis complex",
"~10.8 million new cases globally in 2023",
"Returned as #1 infectious disease killer after COVID-19 (2023)",
"M. tuberculosis emerged ~70,000 years ago in Africa",
"Affects lungs primarily; extrapulmonary in up to 1/3 of cases",
"If untreated: fatal in >70% of cases"
], 0.33, 1.72, 8.05, 2.0, font_size=12.5, text_color=C_TEXT_DARK)
add_rect(s, 0.25, 3.95, 8.2, 2.45, C_LIGHT_BG)
add_rect(s, 0.25, 3.95, 8.2, 0.38, C_MED_BLUE)
add_text(s, "India's TB Burden (NTEP)", 0.35, 3.97, 8, 0.35, font_size=13, bold=True, color=C_WHITE)
add_multiline(s, [
"India accounts for ~26% of global TB burden (highest of any country)",
"National Strategic Plan 2020-2025: Target TB-free India by 2025 (5 yrs ahead of SDG 2030)",
"PM TB Mukt Bharat Abhiyaan: District-level elimination drive",
"NTEP (replaced RNTCP): daily regimen, universal DST, mandatory notification",
"~87% treatment success rate in DS-TB (2023)"
], 0.33, 4.37, 8.05, 1.9, font_size=12.5, text_color=C_TEXT_DARK)
# Right: key numbers panel
add_rect(s, 8.7, 1.3, 4.35, 5.1, C_DARK_BLUE)
for val, label, yy in [
("10.8M", "New cases / year", 1.45),
("1.25M", "Deaths / year", 2.5),
("26%", "Global burden\nin India", 3.55),
("87%", "India treatment\nsuccess rate", 4.7),
]:
add_text(s, val, 8.85, yy, 4.0, 0.55,
font_size=28, bold=True, color=C_GOLD, align=PP_ALIGN.CENTER)
add_text(s, label, 8.85, yy+0.52, 4.0, 0.45,
font_size=11, bold=False, color=C_WHITE, align=PP_ALIGN.CENTER)
add_text(s, "Source: Harrison's 22E | WHO 2024 | NTEP Annual Report 2023",
0.25, 6.6, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — Etiologic Agent
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Etiologic Agent", "M. tuberculosis complex — morphology & characteristics")
section_box(s, "M. tuberculosis Complex — Members", 0.25, 1.28, 6.1, 3.6, [
"M. tuberculosis — principal human pathogen",
"M. africanum — West/Central/East Africa",
"M. bovis — zoonotic; resistant to PZA; unpasteurized milk",
"M. caprae — related to M. bovis",
"M. canetti — rare; East Africa; unusual smooth colonies",
"M. microti — 'vole bacillus'; less virulent",
"No known environmental reservoir"
], font_size=12.5)
section_box(s, "Bacteriological Properties", 6.6, 1.28, 6.45, 3.6, [
"Rod-shaped, non-spore-forming, thin AEROBE (0.5 × 3 μm)",
"Neutral on Gram stain → classified as ACID-FAST BACILLI (AFB)",
"Acid-fastness: HIGH mycolic acid content in cell wall",
"Cannot be decolorized by acid-alcohol (Ziehl-Neelsen stain)",
"Very slow doubling time (~15-20 hours)",
"Thick waxy cell wall → resists disinfectants & complement",
"Other AFB: Nocardia, Rhodococcus, Legionella micdadei"
], font_size=12.5)
section_box(s, "Cell Wall Significance", 0.25, 5.05, 6.1, 1.85, [
"Mycolic acids + arabinogalactan + peptidoglycan",
"Low permeability → intrinsic drug resistance",
"Stimulates granuloma formation via TLR2/TLR4 signaling"
], font_size=12.5)
section_box(s, "Staining Methods", 6.6, 5.05, 6.45, 1.85, [
"Ziehl-Neelsen (ZN): hot carbol fuchsin → red bacilli on blue BG",
"Auramine-rhodamine: fluorescence microscopy (more sensitive)",
"Both detect AFBs but NOT species-specific"
], font_size=12.5)
add_text(s, "Source: Harrison's Principles of Internal Medicine 22E, Chapter 183",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — Pathogenesis & Transmission
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Pathogenesis & Transmission")
section_box(s, "Transmission", 0.25, 1.28, 4.1, 2.8, [
"Airborne — droplet nuclei (1-5 μm)",
"Produced by coughing, sneezing, speaking",
"Can remain suspended in air for hours",
"1-10 bacilli per droplet nucleus sufficient",
"NOT via fomites or brief contact",
"Infectiousness ↑ with: cavitary disease, smear+ve, laryngeal TB"
], font_size=12)
section_box(s, "Outcomes after Inhalation", 4.6, 1.28, 4.55, 2.8, [
"Immediate clearance (strong innate immunity)",
"Primary progressive TB (immunocompromised/infants)",
"Latent TB infection / LTBI (most common ~90%)",
"Reactivation TB (lifetime risk 5-10%)",
"Disseminated/miliary TB (hematogenous)"
], font_size=12)
section_box(s, "Granuloma Formation", 9.4, 1.28, 3.65, 2.8, [
"Hallmark of TB pathology",
"Macrophages engulf bacilli → attract CD4+ T cells",
"Central caseous necrosis",
"Surrounded by epithelioid macrophages",
"Langhans giant cells (peripheral nuclei)",
"Outer ring of lymphocytes",
"Key cytokines: TNF-α, IFN-γ, IL-12"
], font_size=12)
section_box(s, "Risk Factors — Progression from LTBI to Active TB", 0.25, 4.25, 12.8, 2.7, [
("HIV infection", C_ACCENT, " — Greatest risk; 5-10% per year (vs. 0.1% lifetime in HIV-negative)"),
("TNF-α inhibitors", C_ACCENT, " — Infliximab, adalimumab (screen before starting)"),
("Recent infection", C_MED_BLUE, " — Within last 2 years"),
("Diabetes mellitus", C_MED_BLUE, " — 3x increased risk"),
("Silicosis", C_MED_BLUE, " — 30x increased risk"),
("Chronic kidney disease, malnutrition, malignancy (esp. hematologic)", C_TEXT_DARK, ""),
("Extremes of age (infants, elderly), corticosteroids, other immunosuppressants", C_TEXT_DARK, "")
], font_size=12, text_color=C_TEXT_DARK)
add_text(s, "Source: Harrison's Principles of Internal Medicine 22E, Chapter 183",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — Clinical Features: Pulmonary TB
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Clinical Features — Pulmonary TB", "Most common form (~2/3 of all TB cases)")
section_box(s, "Primary TB", 0.25, 1.28, 4.1, 2.7, [
"Often asymptomatic or mild",
"Ghon focus: subpleural parenchymal lesion",
"Ghon complex = Ghon focus + hilar LN",
"May progress to effusion or dissemination",
"Children and immunocompromised at risk",
"Usually self-limiting in immunocompetent"
], font_size=12)
section_box(s, "Reactivation (Post-Primary) TB", 4.6, 1.28, 4.55, 2.7, [
"Weeks-to-months history",
"Productive cough ± hemoptysis",
"Fever (low-grade, afternoon)",
"Drenching night sweats",
"Weight loss, anorexia, fatigue",
"Upper lobe predilection (high O₂)",
"Signs: crackles, bronchial breathing"
], font_size=12)
section_box(s, "Chest X-Ray / CT Findings", 9.4, 1.28, 3.65, 2.7, [
"Upper lobe infiltrates / consolidation",
"Cavitation (pathognomonic when present)",
"Tree-in-bud pattern on CT",
"Centrilobular nodules (endobronchial spread)",
"Fibrotic streaks, calcification (healed)",
"Bilateral in severe disease",
"Miliary pattern (disseminated)"
], font_size=12)
# Complications section
section_box(s, "Complications of Pulmonary TB", 0.25, 4.15, 12.8, 2.75, [
("Hemoptysis", C_ACCENT, " — Erosion of Rasmussen's aneurysm; massive hemoptysis is life-threatening"),
("Pneumothorax", C_ACCENT, " — Rupture of subpleural cavity"),
("Bronchopleural fistula", C_MED_BLUE, " — Cavity connects to pleural space"),
("Aspergilloma", C_MED_BLUE, " — Fungal colonization of residual cavity (Aspergillus)"),
("Cor pulmonale", C_TEXT_DARK, " — End-stage fibrotic disease with pulmonary hypertension"),
("Amyloidosis (AA type)", C_TEXT_DARK, " — Chronic inflammation → secondary amyloidosis")
], font_size=12, text_color=C_TEXT_DARK)
add_text(s, "Source: Harrison's Principles of Internal Medicine 22E, Chapter 183",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — Extrapulmonary TB
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Extrapulmonary Tuberculosis", "Up to 1/3 of all TB cases; higher in HIV/AIDS")
data = [
("Lymph Node TB\n(most common EPTB, 35%)", "Painless cervical/supraclavicular swelling (scrofula)\nFNAC yield ~80%; may form discharging sinus", C_MED_BLUE),
("Pleural TB\n(~20% of EPTB)", "Exudative effusion; lymphocyte-predominant\nADA >40 U/L; protein >3 g/dL; pH ~7.3", C_MED_BLUE),
("TB Meningitis\n(most severe)", "Subacute onset; basal meningitis; CN palsies\nHydrocephalus; CSF: lymphocytes, high protein, low glucose", C_ACCENT),
("Spinal TB\n(Pott's disease)", "Thoracic > lumbar vertebrae; vertebral body destruction\nGibbus deformity; paravertebral cold abscess", C_ACCENT),
("Genitourinary TB", "Sterile pyuria; dysuria; hematuria\nRenal parenchymal destruction; ureteric stricture", C_DARK_BLUE),
("Peritoneal / Abdominal TB", "Ascites (doughy abdomen); ileocaecal involvement\nObstruction; ADA >33 U/L in ascitic fluid", C_DARK_BLUE),
]
col_w = 6.35
for idx, (title, body, col) in enumerate(data):
col_num = idx % 2
row_num = idx // 2
x = 0.25 + col_num * (col_w + 0.28)
y = 1.35 + row_num * 1.9
add_rect(s, x, y, col_w, 0.42, col)
add_text(s, title, x+0.1, y+0.03, col_w-0.15, 0.4,
font_size=11.5, bold=True, color=C_WHITE)
add_rect(s, x, y+0.42, col_w, 1.38, C_LIGHT_BG)
add_multiline(s, body.split("\n"), x+0.1, y+0.46, col_w-0.15, 1.28,
font_size=11.5, text_color=C_TEXT_DARK, bullet=False)
add_rect(s, 0.25, 7.02, 12.8, 0.35, RGBColor(0xD0,0xE4,0xF8))
add_text(s, "Note: TB pericarditis, miliary TB, and bone/joint TB are additional important sites. | Adjunct steroids recommended in TB meningitis and TB pericarditis",
0.35, 7.04, 12.6, 0.3, font_size=10, color=C_DARK_BLUE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — Diagnosis
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Diagnosis of Tuberculosis", "NTEP: GeneXpert is first-line molecular test in India")
# Left column
section_box(s, "Tuberculin Skin Test (TST / Mantoux)", 0.25, 1.28, 6.1, 1.85, [
"5 TU PPD intradermal; read at 48-72 hrs",
"≥5 mm: HIV+, close contacts, immunosuppressed, abnormal CXR",
"≥10 mm: HCW, immigrants, DM, CKD, prisoners",
"≥15 mm: low-risk individuals",
"Limitations: False+ve (BCG, NTM); False-ve (anergy in advanced TB/HIV)"
], font_size=11.5)
section_box(s, "IGRA (Interferon-Gamma Release Assay)", 0.25, 3.3, 6.1, 1.7, [
"QuantiFERON-TB Gold Plus, T-SPOT.TB",
"Detects IFN-γ response to ESAT-6 and CFP-10",
"More specific than TST (not affected by BCG)",
"Preferred in India for LTBI diagnosis",
"Cannot distinguish LTBI from active TB"
], font_size=11.5)
section_box(s, "Other Tests", 0.25, 5.15, 6.1, 1.75, [
"ADA (Adenosine Deaminase): pleural >40, CSF >10, ascites >33 U/L",
"Bronchoscopy + BAL: when sputum unavailable",
"Biopsy: lymph node FNAC (yield ~80%); pleural biopsy",
"Histopathology: caseating granuloma with Langhans giant cells"
], font_size=11.5)
# Right column — microbiological tests table
add_rect(s, 6.6, 1.28, 6.45, 5.62, C_LIGHT_BG)
add_rect(s, 6.6, 1.28, 6.45, 0.42, C_DARK_BLUE)
add_text(s, "Microbiological / Molecular Diagnosis", 6.72, 1.30, 6.2, 0.38,
font_size=13, bold=True, color=C_WHITE)
rows = [
("AFB Smear (ZN/Auramine)", "40-60%", "Rapid, cheap; requires 5,000+ AFB/mL"),
("Culture (LJ / MGIT)", "80-90% (gold std)", "3-8 wks (LJ) or 10-14 days (MGIT liquid)"),
("Xpert MTB/RIF", "88% (smear+ve)\n68% (smear-ve)", "Detects MTB + RIF resistance in ~2 hrs\nFirst-line in NTEP India"),
("Xpert Ultra", "Higher sensitivity", "Better for EPTB, paucibacillary disease"),
("LPA (Line Probe Assay)", "High for H+R resistance", "Detects H and R resistance; done on smear+ve"),
]
col_xs = [6.65, 9.05, 10.25]
col_ws = [2.35, 1.15, 2.7]
headers = ["Test", "Sensitivity", "Comments"]
for ci, (h, cx, cw) in enumerate(zip(headers, col_xs, col_ws)):
add_rect(s, cx, 1.72, cw, 0.35, C_MED_BLUE)
add_text(s, h, cx+0.05, 1.73, cw-0.08, 0.33,
font_size=10.5, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER)
row_colors = [C_WHITE, RGBColor(0xE8, 0xF0, 0xFB)]
for ri, (test, sens, comment) in enumerate(rows):
row_bg = row_colors[ri % 2]
row_y = 2.09 + ri * 0.88
for ci, (val, cx, cw) in enumerate(zip([test, sens, comment], col_xs, col_ws)):
add_rect(s, cx, row_y, cw, 0.86, row_bg)
add_text(s, val, cx+0.05, row_y+0.02, cw-0.08, 0.82,
font_size=10, bold=(ci == 0), color=C_TEXT_DARK, wrap=True)
add_text(s, "Source: Harrison's 22E | NTEP Technical Guidelines",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — Treatment: LTBI + DS-TB (Harrison's)
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Treatment of TB — Drug-Susceptible Disease", "Harrison's 22E | ATS/CDC/ERS/IDSA 2025 Guidelines")
# LTBI
add_rect(s, 0.25, 1.28, 12.8, 0.42, C_MED_BLUE)
add_text(s, "LATENT TB INFECTION (LTBI) Treatment Regimens", 0.4, 1.3, 12.5, 0.38,
font_size=14, bold=True, color=C_WHITE)
ltbi_rows = [
("3HP (PREFERRED)", "INH 900mg + Rifapentine 900mg Weekly", "3 months", "1st choice in adults & children >2 yrs incl. HIV+; NOT in pregnancy; pyridoxine supplement"),
("4R", "Rifampin 600mg daily", "4 months", "HIV-negative preferred; no definitive data in HIV+; preferred over 6-9H"),
("3HR", "INH 300mg/d + RIF 600mg/d", "3 months", "Caution in HIV (drug interactions, possible rifampin resistance)"),
("6H or 9H", "INH 300mg/d or 900mg twice weekly", "6-9 months", "Older standard; 9 months more effective but higher hepatotoxicity; twice-weekly needs DOT"),
]
ltbi_col_xs = [0.25, 3.0, 7.5, 9.3]
ltbi_col_ws = [2.7, 4.45, 1.75, 3.8]
ltbi_headers = ["Regimen", "Drug / Dose", "Duration", "Comments"]
for ci, (h, cx, cw) in enumerate(zip(ltbi_headers, ltbi_col_xs, ltbi_col_ws)):
add_rect(s, cx, 1.72, cw, 0.32, C_DARK_BLUE)
add_text(s, h, cx+0.05, 1.73, cw-0.08, 0.3,
font_size=10, bold=True, color=C_GOLD, align=PP_ALIGN.CENTER)
for ri, (reg, drug, dur, comm) in enumerate(ltbi_rows):
row_bg = [C_WHITE, C_LIGHT_BG][ri % 2]
ry = 2.06 + ri * 0.52
for val, cx, cw, is_reg in zip([reg, drug, dur, comm],
ltbi_col_xs, ltbi_col_ws,
[True, False, False, False]):
add_rect(s, cx, ry, cw, 0.5, row_bg)
add_text(s, val, cx+0.05, ry+0.02, cw-0.08, 0.46,
font_size=9.5, bold=is_reg, color=C_DARK_BLUE if is_reg else C_TEXT_DARK, wrap=True)
# Active DS-TB
add_rect(s, 0.25, 4.22, 12.8, 0.42, C_ACCENT)
add_text(s, "ACTIVE TB — Drug-Susceptible Disease (DS-TB)", 0.4, 4.24, 12.5, 0.38,
font_size=14, bold=True, color=C_WHITE)
section_box(s, "Standard 6-Month Regimen: 2HRZE / 4HR", 0.25, 4.66, 6.1, 2.22, [
"Intensive Phase (2 months): H + R + Z + E daily",
"Continuation Phase (4 months): H + R daily",
"Extend to 9 months (2HRZE/7HR) if:",
" — Cavitary disease",
" — 2-month pyrazinamide course not completed",
" — Sputum culture positive at month 2"
], font_size=12)
section_box(s, "NEW 4-Month Regimen (TBTC S31 Trial, 2020) — ATS/CDC/ERS Conditional Recommendation", 6.6, 4.66, 6.45, 2.22, [
"2 months: Rifapentine + INH + PZA + Moxifloxacin (daily)",
"Then ~9 weeks: Rifapentine + INH + Moxifloxacin (daily)",
"Noninferior to standard 6-month HRZE in large RCT",
"Includes HIV patients with CD4 >100",
"No ethambutol in this regimen"
], font_size=12)
add_text(s, "H=Isoniazid | R=Rifampin | Z=Pyrazinamide | E=Ethambutol | P=Rifapentine | M=Moxifloxacin",
0.25, 7.1, 12.8, 0.3, font_size=9.5, color=RGBColor(0x44,0x44,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — First-Line Drug Profiles
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "First-Line Anti-TB Drug Profiles", "Doses, Mechanisms & Adverse Effects")
drugs = [
("Isoniazid (H)", "5 mg/kg/d\nmax 300 mg/d", "Inhibits mycolic acid synthesis\n(InhA enzyme, KatG activation)", "Hepatotoxicity (↑ with age/alcohol)\nPeripheral neuropathy (prevent with pyridoxine 25-50 mg/d)\nLupus-like syndrome, seizures", C_DARK_BLUE),
("Rifampin (R)", "10 mg/kg/d\nmax 600 mg/d", "Inhibits RNA polymerase\n(β-subunit, rpoB gene)", "Hepatotoxicity\nOrange discoloration of secretions\nPotent CYP450 inducer (↑↑ drug interactions)\nFlu-like syndrome (intermittent use)", C_MED_BLUE),
("Pyrazinamide (Z)", "25 mg/kg/d\nmax 2 g/d", "Disrupts membrane energetics\n(active in acidic environment)", "Hepatotoxicity (most common cause)\nHyperuricemia / Gout\nArthralgia, rash, photosensitivity", C_ACCENT),
("Ethambutol (E)", "15-20 mg/kg/d", "Inhibits arabinogalactan synthesis\n(embB gene)", "Optic neuritis: color blindness, ↓visual acuity\nCheck vision before and during treatment\nAvoid in young children (monitoring difficult)", C_GREEN),
("Streptomycin (S)", "15 mg/kg IM/IV", "Inhibits 30S ribosomal subunit\n(protein synthesis)", "Ototoxicity (vestibular > cochlear)\nNephrotoxicity\nCONTRAINDICATED in pregnancy", C_ORANGE),
]
col_titles = ["Drug", "Dose (Adult)", "Mechanism", "Key Adverse Effects"]
col_xs = [0.25, 2.5, 4.55, 8.2]
col_ws = [2.2, 2.0, 3.6, 4.85]
for ci, (h, cx, cw) in enumerate(zip(col_titles, col_xs, col_ws)):
add_rect(s, cx, 1.28, cw, 0.38, C_DARK_BLUE)
add_text(s, h, cx+0.06, 1.3, cw-0.1, 0.35,
font_size=12, bold=True, color=C_GOLD, align=PP_ALIGN.CENTER)
for ri, (name, dose, mech, adv, dc) in enumerate(drugs):
ry = 1.68 + ri * 1.06
# Drug name cell
add_rect(s, col_xs[0], ry, col_ws[0], 1.04, dc)
add_text(s, name, col_xs[0]+0.06, ry+0.08, col_ws[0]-0.1, 0.88,
font_size=12, bold=True, color=C_WHITE, v_anchor=MSO_ANCHOR.MIDDLE)
# Dose
row_bg = [C_WHITE, C_LIGHT_BG][ri % 2]
add_rect(s, col_xs[1], ry, col_ws[1], 1.04, row_bg)
add_text(s, dose, col_xs[1]+0.06, ry+0.04, col_ws[1]-0.1, 0.96,
font_size=11, bold=False, color=C_TEXT_DARK, wrap=True)
# Mechanism
add_rect(s, col_xs[2], ry, col_ws[2], 1.04, row_bg)
add_text(s, mech, col_xs[2]+0.06, ry+0.04, col_xs[3]-col_xs[2]-0.1, 0.96,
font_size=10.5, bold=False, color=C_TEXT_DARK, wrap=True)
# Adverse
add_rect(s, col_xs[3], ry, col_ws[3], 1.04, row_bg)
add_text(s, adv, col_xs[3]+0.06, ry+0.04, col_ws[3]-0.1, 0.96,
font_size=10.5, bold=False, color=C_TEXT_DARK, wrap=True)
add_text(s, "Source: Harrison's Principles of Internal Medicine 22E | NTEP Drug Manual",
0.25, 7.08, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — NTEP India: DS-TB Management
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "NTEP India — Drug-Susceptible TB Management", "National TB Elimination Programme | MoHFW 2025")
section_box(s, "Key Changes from RNTCP → NTEP", 0.25, 1.28, 6.1, 2.6, [
"Thrice-weekly DOT ABOLISHED → DAILY regimen (FDC)",
"Cat I / Cat II system ABOLISHED → DST-based individualized Rx",
"Mandatory notification: ALL providers (public + private)",
"Universal DST: All confirmed TB → Xpert MTB/RIF first",
"Daily FDC tablets (weight-band based)",
"Nikshay IT system: case tracking, treatment monitoring"
], font_size=12)
section_box(s, "DS-TB Treatment (2HRZE / 4HR — Daily FDC)", 6.6, 1.28, 6.45, 2.6, [
"FDC tablet: INH 75mg + RIF 150mg + PZA 400mg + EMB 275mg",
"Weight ≤39 kg: 2 tablets; 40-54 kg: 3 tablets",
"55-69 kg: 4 tablets; ≥70 kg: 5 tablets",
"Extension to 12 months: CNS TB, Spinal TB, Bone/Joint TB",
"Miliary TB: treat as 2HRZE/10HR (12 months)",
"Pyridoxine (B6) supplement with INH in all cases"
], font_size=12)
section_box(s, "TB Preventive Treatment (TPT) — NTEP 2021", 0.25, 4.04, 6.1, 2.85, [
"Indications: HIV+, household contacts <5 yrs, immunosuppressed",
"6H: INH 5-10 mg/kg/d (max 300mg) × 6 months",
"3HP: INH + Rifapentine weekly × 3 months",
"1HP: INH + Rifapentine daily × 1 month (HIV+, conditional)",
"Screen for active TB before starting TPT",
"Do NOT start TPT if active TB suspected"
], font_size=12)
section_box(s, "Special Populations (NTEP)", 6.6, 4.04, 6.45, 2.85, [
"TB in children: weight-based dosing; ethionamide replaces EMB <5 yrs",
"TB-HIV: start ART within 2 weeks (CD4<50) or 8 weeks (others)",
"Use efavirenz-based ART with rifampin-containing regimens",
"Pregnancy: H, R, Z safe; Streptomycin CONTRAINDICATED",
"Renal impairment: reduce PZA, EMB doses; avoid aminoglycosides",
"Monitor for IRIS in TB-HIV (incidence 15-30%)"
], font_size=12)
add_text(s, "Source: NTEP Technical & Operational Guidelines | Central TB Division, MoHFW India 2025",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 11 — Drug-Resistant TB Classification
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Drug-Resistant TB — Classification & Drug Groups", "NTEP / WHO 2022 Updated Classification")
# DR-TB classification table
add_rect(s, 0.25, 1.28, 12.8, 0.38, C_DARK_BLUE)
add_text(s, "DR-TB Classification", 0.4, 1.30, 12.5, 0.35,
font_size=14, bold=True, color=C_WHITE)
dr_rows = [
("Mono-resistance", "Resistant to 1 first-line drug only", C_GREEN),
("Poly-resistance", "Resistant to >1 first-line drug (NOT the combination H+R)", C_GREEN),
("RR-TB\n(Rifampicin-Resistant)", "Any Rifampin resistance (with or without other resistance)\nTreated as MDR-TB", C_MED_BLUE),
("MDR-TB", "Resistant to BOTH Isoniazid AND Rifampin\nMost important category", C_ACCENT),
("Pre-XDR-TB\n(WHO 2021 definition)", "MDR/RR-TB + resistance to ANY Fluoroquinolone", RGBColor(0xB0,0x30,0xB0)),
("XDR-TB", "MDR/RR-TB + Fluoroquinolone resistance + Bedaquiline or Linezolid resistance", C_DARK_BLUE),
]
for ri, (cat, defn, col) in enumerate(dr_rows):
ry = 1.7 + ri * 0.7
add_rect(s, 0.25, ry, 3.5, 0.68, col)
add_text(s, cat, 0.35, ry+0.04, 3.3, 0.6,
font_size=11.5, bold=True, color=C_WHITE, v_anchor=MSO_ANCHOR.MIDDLE)
row_bg = [C_WHITE, C_LIGHT_BG][ri % 2]
add_rect(s, 3.77, ry, 9.3, 0.68, row_bg)
add_text(s, defn, 3.87, ry+0.04, 9.1, 0.6,
font_size=11.5, bold=False, color=C_TEXT_DARK, wrap=True)
# Drug groups
add_rect(s, 0.25, 6.02, 12.8, 0.38, C_MED_BLUE)
add_text(s, "WHO / NTEP Drug Groups for MDR-TB Treatment", 0.4, 6.04, 12.5, 0.35,
font_size=13, bold=True, color=C_WHITE)
groups = [
("Group A\n(Use ALL 3)", "Levofloxacin / Moxifloxacin\nBedaquiline (Bdq)\nLinezolid (Lzd)", C_GREEN),
("Group B\n(Add 1-2)", "Clofazimine (Cfz)\nCycloserine (Cs) / Terizidone", C_MED_BLUE),
("Group C\n(Add to complete regimen)", "Ethambutol, Delamanid, PZA\nImipenem-cilastatin, Amikacin\nEthionamide/Pto, PAS", C_DARK_BLUE),
]
gx = [0.25, 4.5, 8.75]
gw = 4.1
for (gtitle, gdrugs, gcol), gxi in zip(groups, gx):
add_rect(s, gxi, 6.42, gw, 0.35, gcol)
add_text(s, gtitle, gxi+0.08, 6.43, gw-0.12, 0.33,
font_size=11, bold=True, color=C_WHITE)
add_rect(s, gxi, 6.79, gw, 0.6, C_LIGHT_BG)
add_text(s, gdrugs, gxi+0.08, 6.8, gw-0.12, 0.58,
font_size=10, bold=False, color=C_TEXT_DARK, wrap=True)
add_text(s, "Source: WHO 2022 Consolidated Guidelines | NTEP National Guidelines for DR-TB Management March 2025",
0.25, 7.38, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 12 — MDR-TB Treatment Regimens (NTEP 2025)
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "MDR-TB Treatment — NTEP India 2025", "National Guidelines for Management of DR-TB — March 27, 2025")
# BPaLM box
add_rect(s, 0.25, 1.28, 6.1, 3.1, RGBColor(0xE8,0xF8,0xE8))
add_rect(s, 0.25, 1.28, 6.1, 0.42, C_GREEN)
add_text(s, "BPaLM Regimen (PREFERRED for FQ-susceptible MDR/RR-TB)", 0.35, 1.30, 5.9, 0.38,
font_size=12, bold=True, color=C_WHITE)
add_multiline(s, [
"Bedaquiline + Pretomanid + Linezolid + Moxifloxacin",
"Duration: 6 months (all-oral, shorter)",
"Bdq: 400mg/d × 2 wks → 200mg 3×/wk × 24 wks",
"Pretomanid: 200mg daily × 26 weeks",
"Linezolid: 600mg daily × 26 weeks",
"Evidence: TB-PRACTECAL trial (2022) — superior to standard of care",
"WHO Conditional Recommendation | NTEP 2025 adopted"
], 0.33, 1.73, 5.9, 2.55, font_size=11.5, text_color=C_TEXT_DARK)
# BPaL box
add_rect(s, 6.6, 1.28, 6.45, 3.1, RGBColor(0xFFF5E8))
add_rect(s, 6.6, 1.28, 6.45, 0.42, C_ORANGE)
add_text(s, "BPaL Regimen (for FQ-RESISTANT MDR/RR-TB or XDR-TB)", 6.7, 1.30, 6.25, 0.38,
font_size=12, bold=True, color=C_WHITE)
add_multiline(s, [
"Bedaquiline + Pretomanid + Linezolid",
"Duration: 6 months",
"Same drug doses as BPaLM (without Moxifloxacin)",
"Evidence: ZeNix trial (2022)",
"Lzd 600mg preferred (vs 1200mg: less toxic, comparable efficacy)",
"Used when FQ resistance confirmed or suspected"
], 6.68, 1.73, 6.27, 2.55, font_size=11.5, text_color=C_TEXT_DARK)
# Shorter 9-11 month regimen
section_box(s, "Shorter MDR-TB Oral Regimen (9-11 months) — STREAM Stage 1", 0.25, 4.55, 6.1, 2.4, [
"For FQ-susceptible MDR-TB without Group A drug resistance",
"Intensive (4-6m): Bdq + Mfx/Lfx + Cfz + Z + E + H(HD) + Eto/Pto",
"Continuation (5m): Mfx/Lfx + Cfz + Z + E",
"Delamanid may be added in complex cases",
"Monthly sputum culture mandatory"
], font_size=11.5)
section_box(s, "Longer Regimen (18-20 months) for Pre-XDR/XDR-TB", 6.6, 4.55, 6.45, 2.4, [
"When BPaL/BPaLM not feasible or resistance to Bdq/Lzd",
"At least 5 active drugs in intensive phase",
"Use all available Group A + B + C drugs",
"Delamanid: 100mg BD × 24 weeks as add-on",
"QTc monitoring essential (Bdq + Dlm + Cfz combination)",
"Individualized by DR-TB expert committee"
], font_size=11.5)
add_text(s, "Bdq=Bedaquiline | Pa=Pretomanid | L=Linezolid | M=Moxifloxacin | Cfz=Clofazimine | Dlm=Delamanid | Eto=Ethionamide",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x44,0x44,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 13 — DR-TB Monitoring & Adverse Effects
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "DR-TB Treatment Monitoring", "Adverse Effect Surveillance During Treatment")
# Monitoring table
add_rect(s, 0.25, 1.28, 7.0, 0.38, C_DARK_BLUE)
add_text(s, "Monitoring Schedule", 0.4, 1.3, 6.7, 0.35,
font_size=13, bold=True, color=C_WHITE)
mon_rows = [
("Sputum smear + culture", "Monthly during intensive phase; every 2m in continuation"),
("ECG (QTc interval)", "Baseline → monthly (Bdq, Dlm, Cfz, Mfx all prolong QT)"),
("Liver function tests (LFT)", "Baseline → monthly (Lzd, Eto, PZA hepatotoxic)"),
("Complete Blood Count (CBC)", "Monthly (Linezolid: myelosuppression, anaemia)"),
("Peripheral neuropathy check", "Monthly (Linezolid, Cycloserine)"),
("Visual acuity / colour vision", "Baseline + every 6m (Ethambutol, Linezolid)"),
("Thyroid function (TSH)", "Baseline + every 6m (Ethionamide + PAS)"),
("Renal function (creatinine)", "Monthly if aminoglycosides used (ototoxicity, nephrotoxicity)"),
("Audiometry", "Baseline + regular if aminoglycosides used"),
("Psychiatric/mood assessment", "Monthly (Cycloserine: psychosis, depression)"),
]
for ri, (test, freq) in enumerate(mon_rows):
ry = 1.68 + ri * 0.5
row_bg = [C_WHITE, C_LIGHT_BG][ri % 2]
add_rect(s, 0.25, ry, 3.3, 0.48, row_bg)
add_text(s, test, 0.32, ry+0.02, 3.15, 0.44,
font_size=11, bold=True, color=C_DARK_BLUE)
add_rect(s, 3.57, ry, 3.65, 0.48, row_bg)
add_text(s, freq, 3.64, ry+0.02, 3.5, 0.44,
font_size=11, bold=False, color=C_TEXT_DARK, wrap=True)
# Right panel: key adverse effects
section_box(s, "Key Drug Adverse Effects", 7.5, 1.28, 5.55, 5.75, [
("Bedaquiline:", C_ACCENT, " QTc prolongation, hepatotoxicity, nausea"),
("Linezolid:", C_ACCENT, " Myelosuppression, peripheral/optic neuropathy, lactic acidosis"),
("Pretomanid:", C_MED_BLUE, " Hepatotoxicity, peripheral neuropathy, QTc prolongation"),
("Moxifloxacin:", C_MED_BLUE, " QTc prolongation, tendinopathy, photosensitivity"),
("Clofazimine:", C_MED_BLUE, " Skin discoloration (orange-brown), QTc prolongation"),
("Delamanid:", C_DARK_BLUE, " QTc prolongation, hepatotoxicity, dizziness"),
("Cycloserine:", C_DARK_BLUE, " Psychosis, seizures, depression, peripheral neuropathy"),
("Ethionamide:", C_DARK_BLUE, " Nausea, hepatotoxicity, hypothyroidism (with PAS)"),
("Amikacin:", C_TEXT_DARK, " Ototoxicity (irreversible), nephrotoxicity"),
("Note:", C_ACCENT, " Avoid Bdq + Dlm + Mfx together without rigorous QTc monitoring"),
], font_size=11.5, text_color=C_TEXT_DARK, bg_color=RGBColor(0xFF, 0xF5, 0xF5))
add_text(s, "Source: NTEP National Guidelines for DR-TB Management March 2025 | ZeNix & TB-PRACTECAL trials",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 14 — NTEP Programmatic Initiatives
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "NTEP — Key Programmatic Initiatives (India 2025)", "National Tuberculosis Elimination Programme | PM TB Mukt Bharat")
initiatives = [
("Nikshay IT Platform", "Mandatory case notification system for all public and private providers\nReal-time treatment tracking, outcome reporting, DST results", C_DARK_BLUE),
("Nikshay Poshan Yojana", "₹500/month direct benefit transfer (DBT) to all TB patients\nNutritional support throughout treatment duration", C_GREEN),
("Nikshay Mitra Initiative", "Corporate/NGO/individual adoption of TB patients\nProvides nutritional, diagnostic & vocational support\nUpdated guidelines 2026", C_MED_BLUE),
("PM TB Mukt Bharat Abhiyaan", "PM-level national campaign for TB elimination\nDistrict-level targets; 5 years ahead of global SDG timeline\nTB-free India by 2025 target", C_ACCENT),
("Universal DST (UDST)", "All bacteriologically confirmed TB → Xpert MTB/RIF\nCulture + DST for all presumptive DR-TB patients\nRapid molecular testing at district level", C_DARK_BLUE),
("Differentiated TB Care (2025)", "Risk-stratified approach: high-risk patients identified\nIntensified monitoring for vulnerable groups\nNew guidance issued March 2025", C_MED_BLUE),
("Active Case Finding (ACF)", "Systematic screening in tribal areas, urban slums, prisons\nTargeted screening: PLWH, DM, silicosis, healthcare workers", C_GREEN),
("Daily FDC Regimen", "Replaced intermittent thrice-weekly DOTS\nWeight-band based fixed-dose combinations\nImproves adherence and reduces acquired resistance", C_ORANGE),
]
for idx, (title, body, col) in enumerate(initiatives):
col_num = idx % 2
row_num = idx // 2
x = 0.25 + col_num * 6.6
y = 1.35 + row_num * 1.45
bw = 6.35
add_rect(s, x, y, bw, 0.38, col)
add_text(s, title, x+0.08, y+0.03, bw-0.12, 0.34,
font_size=12, bold=True, color=C_WHITE)
add_rect(s, x, y+0.38, bw, 0.97, C_LIGHT_BG)
add_text(s, body, x+0.1, y+0.42, bw-0.18, 0.9,
font_size=11, bold=False, color=C_TEXT_DARK, wrap=True)
add_text(s, "Source: Central TB Division, MoHFW India | tbcindia.mohfw.gov.in | NSP 2020-2025",
0.25, 7.25, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 15 — TB-HIV Co-infection
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "TB-HIV Co-infection — Management", "Harrison's 22E | NTEP / NACO Guidelines India")
section_box(s, "Epidemiology & Pathogenesis", 0.25, 1.28, 6.1, 2.4, [
"HIV is greatest risk factor for LTBI → active TB (5-10%/year)",
"Extrapulmonary TB more common in HIV",
"Atypical CXR presentations (lower lobe, miliary)",
"Smear-negative TB more frequent",
"Granulomas less well-organized; higher bacterial loads",
"Mortality significantly higher if untreated"
], font_size=12)
section_box(s, "ART Timing (Critical Decision)", 6.6, 1.28, 6.45, 2.4, [
"Start ART within 2 WEEKS if CD4 <50 cells/μL",
"Start ART within 8 WEEKS if CD4 ≥50 cells/μL",
"ART must not be delayed in TB meningitis (risk of IRIS)",
"Exception: TB meningitis — delay ART 4-8 weeks (high IRIS risk)",
"Efavirenz-based ART preferred with rifampin-containing TB regimens",
"Rifabutin substituted for Rifampin when using PIs"
], font_size=12)
section_box(s, "Drug Interactions", 0.25, 3.85, 6.1, 2.0, [
"Rifampin: potent CYP3A4 inducer → ↓ PI levels (>75%)",
"Use efavirenz 600mg/d (dose adjustment not needed)",
"Rifabutin (150mg/d) with PIs: less interaction",
"Integrase inhibitors (dolutegravir): double dose with rifampin",
"Monitor for overlapping hepatotoxicity (rifampin + NVP)"
], font_size=12)
section_box(s, "IRIS (Immune Reconstitution Inflammatory Syndrome)", 6.6, 3.85, 6.45, 2.0, [
"Incidence: 15-30% after ART initiation in TB patients",
"Paradoxical worsening of TB symptoms after ART",
"Typically 2-8 weeks after starting ART",
"Manage with NSAIDs; steroids for severe IRIS",
"Do NOT stop ART or anti-TB treatment",
"High-risk: CD4 <50, disseminated TB"
], font_size=12)
section_box(s, "Co-trimoxazole Prophylaxis & Other Measures", 0.25, 5.97, 12.8, 1.35, [
"Co-trimoxazole prophylaxis: ALL TB-HIV patients (prevents PCP, toxoplasma, bacterial infections)",
"TPT (6H or 3HP): all HIV+ patients without active TB — reduces TB incidence by 60-90%",
"Nutritional support, Nikshay Poshan Yojana, adherence counseling",
"HIV VL + CD4 monitoring during anti-TB treatment"
], font_size=12, bg_color=RGBColor(0xE8,0xF0,0xFF))
add_text(s, "Source: Harrison's Principles 22E | NTEP/NACO National Guidelines | WHO 2023 Consolidated HIV Guidelines",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 16 — Treatment Algorithm (India)
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "TB Management Algorithm — India (NTEP 2025)", "Diagnostic & Treatment Pathway")
# Flow diagram using boxes and arrows
box_data = [
(5.5, 1.3, 2.5, 0.55, "PRESUMPTIVE TB", C_DARK_BLUE, C_WHITE),
(5.5, 2.25, 2.5, 0.6, "Xpert MTB/RIF\n(First-Line Molecular Test)", C_MED_BLUE, C_WHITE),
]
for bx, by, bw, bh, bt, bc, tc in box_data:
add_rect(s, bx, by, bw, bh, bc)
add_text(s, bt, bx+0.06, by+0.04, bw-0.1, bh-0.06,
font_size=11, bold=True, color=tc, align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# Arrow
add_rect(s, bx+bw/2-0.04, by+bh, 0.08, 0.3, C_DARK_BLUE)
# MTB Detected? branch
add_rect(s, 5.5, 3.15, 2.5, 0.5, C_GOLD)
add_text(s, "MTB Detected?", 5.56, 3.17, 2.38, 0.46,
font_size=11, bold=True, color=C_DARK_BLUE, align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# YES branch left
add_rect(s, 5.5, 3.67, 0.08, 0.38, C_DARK_BLUE)
add_rect(s, 1.0, 4.07, 0.08, 0.3, C_DARK_BLUE)
add_rect(s, 5.5, 4.05, 2.5, 0.5, C_GREEN)
add_text(s, "Rifampin Sensitive?", 5.56, 4.07, 2.38, 0.46,
font_size=11, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# DS-TB box
add_rect(s, 2.5, 4.85, 3.5, 0.85, RGBColor(0xD8,0xF0,0xD8))
add_rect(s, 2.5, 4.85, 3.5, 0.32, C_GREEN)
add_text(s, "DS-TB (RIF Sensitive)", 2.58, 4.87, 3.35, 0.28,
font_size=10.5, bold=True, color=C_WHITE)
add_text(s, "2HRZE/4HR — Daily FDC\nWeight-band based dosing\nNotify on Nikshay", 2.58, 5.19, 3.35, 0.48,
font_size=10, color=C_TEXT_DARK, wrap=True)
# DR-TB box
add_rect(s, 7.4, 4.85, 3.5, 0.85, RGBColor(0xFF,0xEE,0xDD))
add_rect(s, 7.4, 4.85, 3.5, 0.32, C_ACCENT)
add_text(s, "DR-TB (RIF Resistant)", 7.5, 4.87, 3.35, 0.28,
font_size=10.5, bold=True, color=C_WHITE)
add_text(s, "LPA + Culture/DST\nBPaLM (FQ-sensitive)\nBPaL (FQ-resistant)", 7.5, 5.19, 3.35, 0.48,
font_size=10, color=C_TEXT_DARK, wrap=True)
# Clinical diagnosis box (MTB not detected)
add_rect(s, 9.4, 3.15, 3.55, 0.75, RGBColor(0xF8,0xF0,0xFF))
add_rect(s, 9.4, 3.15, 3.55, 0.28, RGBColor(0x88,0x44,0xAA))
add_text(s, "MTB Not Detected", 9.48, 3.17, 3.38, 0.26, font_size=10, bold=True, color=C_WHITE)
add_text(s, "Clinical/radiological diagnosis\nif strong suspicion; consider\nEPTB workup", 9.48, 3.45, 3.38, 0.42,
font_size=10, color=C_TEXT_DARK, wrap=True)
# Bottom: common steps
add_rect(s, 0.25, 6.0, 12.8, 0.38, C_DARK_BLUE)
add_text(s, "FOR ALL CONFIRMED TB:", 0.35, 6.02, 3.5, 0.35, font_size=11, bold=True, color=C_GOLD)
add_text(s, "Notify on Nikshay | Nikshay Poshan Yojana (₹500/m) | Contact investigation + TPT for eligible | Monthly sputum monitoring | Adherence support",
3.85, 6.02, 9.1, 0.35, font_size=10.5, bold=False, color=C_WHITE)
add_rect(s, 0.25, 6.45, 12.8, 0.45, C_LIGHT_BG)
add_text(s, "EPTB: Use Xpert on relevant specimen (CSF, tissue, fluid, urine) | Pleural TB: ADA + Xpert on biopsy | CNS/Spine/Bone TB: 12 months treatment | Adjunct steroids: TB meningitis, TB pericarditis",
0.35, 6.47, 12.6, 0.4, font_size=10.5, bold=False, color=C_DARK_BLUE, wrap=True)
add_text(s, "Source: NTEP Technical & Operational Guidelines 2025 | Central TB Division, MoHFW India",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 17 — Recent Evidence & Summary
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, C_WHITE)
slide_header(s, "Recent Evidence & Key Takeaways", "PubMed 2024-2025 | Summary Points")
section_box(s, "Recent Evidence (PubMed 2024-2025)", 0.25, 1.28, 8.1, 4.0, [
("BPaL/BPaLM Meta-analysis 2025 (PMID 40172415):", C_ACCENT, " Bdq+Lzd based regimens show superior treatment success and favorable safety vs. traditional longer MDR-TB regimens"),
("Shorter MDR-TB Regimens NMA 2024 (PMID 39354416):", C_ACCENT, " 6-month BPaL and BPaLM are most efficacious among all shorter regimens in network meta-analysis"),
("Therapeutic Drug Monitoring SR 2025 (PMID 40256853):", C_MED_BLUE, " TDM improves outcomes especially in MDR-TB, HIV co-infection, DM, extremes of weight — being incorporated into NTEP guidance"),
("Quinolones as first-line (Meta-analysis 2024):", C_MED_BLUE, " Conditional support for moxifloxacin in 4-month regimen — already reflected in ATS/CDC/ERS 2025 guidelines"),
("4-Month Regimen (TBTC S31/A5349 Trial):", C_GREEN, " Rifapentine+INH+PZA+Moxifloxacin noninferior to 6-month HRZE — Conditionally recommended by ATS/CDC/ERS/IDSA 2025"),
], font_size=12, text_color=C_TEXT_DARK)
section_box(s, "Key Takeaways", 8.6, 1.28, 4.45, 4.0, [
"India = 26% of global TB burden",
"NTEP: daily FDC, universal DST, mandatory notification",
"GeneXpert MTB/RIF = first-line diagnostic in India",
"DS-TB: 2HRZE/4HR (daily FDC)",
"CNS/Spinal/Bone TB: 12 months treatment",
"MDR/RR-TB: BPaLM (6m) is new standard",
"HIV+TB: ART within 2 weeks (CD4<50)",
"TPT: 6H or 3HP for eligible contacts",
"Nikshay Poshan Yojana: ₹500/month to all TB patients",
"QTc monitoring mandatory with Bdq/Dlm/Cfz/Mfx"
], font_size=12.5, text_color=C_TEXT_DARK)
# Treatment outcomes box
add_rect(s, 0.25, 5.42, 12.8, 0.38, C_MED_BLUE)
add_text(s, "NTEP Treatment Outcome Definitions", 0.4, 5.44, 12.4, 0.35,
font_size=13, bold=True, color=C_WHITE)
outcomes = [
("Cured", "Bacteriologically confirmed; negative sputum at end of treatment", C_GREEN),
("Completed", "Completed without final bacteriological result", C_MED_BLUE),
("Failed", "Positive sputum at month 5 or later", C_ACCENT),
("LTFU", "Interrupted ≥2 consecutive months", C_ORANGE),
("Died", "Death from any cause during treatment", C_DARK_BLUE),
]
ox = 0.25
for oname, odef, ocol in outcomes:
ow = 2.54
add_rect(s, ox, 5.82, ow, 0.35, ocol)
add_text(s, oname, ox+0.05, 5.83, ow-0.08, 0.33,
font_size=10.5, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER)
add_rect(s, ox, 6.19, ow, 0.58, C_LIGHT_BG)
add_text(s, odef, ox+0.05, 6.2, ow-0.08, 0.55,
font_size=9.5, color=C_TEXT_DARK, wrap=True, align=PP_ALIGN.CENTER)
ox += ow + 0.06
add_text(s, "Sources: Harrison's 22E (2025) | NTEP National Guidelines DR-TB March 2025 | ATS/CDC/ERS/IDSA 2025 TB Guidelines | PMIDs 40172415, 39354416, 40256853",
0.25, 7.1, 12.8, 0.3, font_size=9, color=RGBColor(0x88,0x88,0x88), italic=True)
# ════════════════════════════════════════════════════════════════════════════
# SAVE
# ════════════════════════════════════════════════════════════════════════════
out_path = "/tmp/workspace/tb-ppt/Tuberculosis_Harrison_NTEP_2025.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out_path}")
print(f"Total slides: {len(prs.slides)}")
cd /tmp/workspace/tb-ppt && python create_tb_ppt.py 2>&1
~/tb-ppt/create_tb_ppt.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/tb-ppt/create_tb_ppt.py'
~/tb-ppt/create_tb_ppt.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/tb-ppt/create_tb_ppt.py'
cd /tmp/workspace/tb-ppt && python create_tb_ppt.py 2>&1
grep -n "RGBColor(0xFF" /tmp/workspace/tb-ppt/create_tb_ppt.py | head -20
sed -i 's/RGBColor(0xFFF5E8)/RGBColor(0xFF, 0xF5, 0xE8)/g' /tmp/workspace/tb-ppt/create_tb_ppt.py && python /tmp/workspace/tb-ppt/create_tb_ppt.py 2>&1
Tuberculosis Harrison NTEP 2025
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide (professional dark navy design) |
| 2 | Overview & Epidemiology (Global + India burden with stat panels) |
| 3 | Etiologic Agent (M. tuberculosis complex, morphology, AFB properties) |
| 4 | Pathogenesis & Transmission (granuloma formation, risk factors) |
| 5 | Clinical Features — Pulmonary TB (primary vs. reactivation, CXR, complications) |
| 6 | Extrapulmonary TB (6 main sites in visual card layout) |
| 7 | Diagnosis (TST, IGRA, AFB smear, GeneXpert, LPA — sensitivity table) |
| 8 | Treatment of DS-TB — Harrison's (LTBI regimens + active TB 6/4-month) |
| 9 | First-Line Drug Profiles (dose, mechanism, adverse effects — all 5 drugs) |
| 10 | NTEP India — DS-TB Management (daily FDC, weight bands, TPT, special populations) |
| 11 | DR-TB Classification & Drug Groups A/B/C |
| 12 | MDR-TB Regimens — NTEP 2025 (BPaLM, BPaL, 9-11m, 18-20m longer) |
| 13 | DR-TB Monitoring & Adverse Effects (QTc, LFT, CBC schedule) |
| 14 | NTEP Programmatic Initiatives (Nikshay, Poshan Yojana, Nikshay Mitra, PM Abhiyaan) |
| 15 | TB-HIV Co-infection (ART timing, drug interactions, IRIS) |
| 16 | Management Algorithm India (diagnostic + treatment flowchart) |
| 17 | Recent Evidence & Key Takeaways (PubMed 2024-25 + outcome definitions) |
Flowchart of management of TB given in Indian latest guidelines given in inda in colored pdf format pdf fo
~/tb-ppt/tb_flowchart.py
"""
TB Management Flowchart — India NTEP 2025 Guidelines
Coloured, detailed, A3 landscape PDF using ReportLab
"""
from reportlab.lib.pagesizes import A3, landscape
from reportlab.lib.units import cm, mm
from reportlab.lib.colors import (
HexColor, white, black
)
from reportlab.pdfgen import canvas
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import Paragraph
from reportlab.lib.styles import ParagraphStyle
import math
# ── Palette ──────────────────────────────────────────────────────────────────
NAVY = HexColor("#1A376C")
BLUE = HexColor("#1E6FB4")
LT_BLUE = HexColor("#D6E8F8")
GREEN = HexColor("#1A7A3C")
LT_GREEN = HexColor("#D6F0E0")
RED = HexColor("#C0392B")
LT_RED = HexColor("#FADADD")
ORANGE = HexColor("#D96500")
LT_ORANGE = HexColor("#FFF0DA")
PURPLE = HexColor("#6B2FA0")
LT_PURPLE = HexColor("#EEE0FF")
YELLOW = HexColor("#F5A623")
LT_YELLOW = HexColor("#FFF8E1")
GREY = HexColor("#F0F4FA")
MID_GREY = HexColor("#AAAAAA")
TEAL = HexColor("#0A7B83")
LT_TEAL = HexColor("#D6F3F5")
WHITE = white
BLACK = black
W, H = landscape(A3) # 42 x 29.7 cm → in points: ~1190 x 842
MARGIN = 18
def make_canvas(path):
c = canvas.Canvas(path, pagesize=landscape(A3))
c.setTitle("TB Management Flowchart — NTEP India 2025")
c.setAuthor("NTEP / Central TB Division, MoHFW India")
c.setSubject("National Tuberculosis Elimination Programme — Management Guidelines 2025")
return c
# ── Drawing helpers ───────────────────────────────────────────────────────────
def rect(c, x, y, w, h, fill=GREY, stroke=NAVY, radius=6, stroke_width=1.2, alpha=1):
c.saveState()
c.setFillColor(fill)
c.setStrokeColor(stroke)
c.setLineWidth(stroke_width)
c.roundRect(x, y, w, h, radius, fill=1, stroke=1)
c.restoreState()
def diamond(c, cx, cy, hw, hh, fill=LT_YELLOW, stroke=ORANGE, stroke_width=1.5):
"""Draw a diamond centred at (cx,cy) with half-widths hw, hh"""
c.saveState()
c.setFillColor(fill)
c.setStrokeColor(stroke)
c.setLineWidth(stroke_width)
p = c.beginPath()
p.moveTo(cx, cy + hh)
p.lineTo(cx + hw, cy)
p.lineTo(cx, cy - hh)
p.lineTo(cx - hw, cy)
p.closePath()
c.drawPath(p, fill=1, stroke=1)
c.restoreState()
def arrow(c, x1, y1, x2, y2, color=NAVY, width=1.4, label=None, label_color=NAVY):
"""Draw arrow from (x1,y1) to (x2,y2) with optional label"""
c.saveState()
c.setStrokeColor(color)
c.setFillColor(color)
c.setLineWidth(width)
c.line(x1, y1, x2, y2)
# arrowhead
angle = math.atan2(y2 - y1, x2 - x1)
ah = 8
aw = 5
ax1 = x2 - ah * math.cos(angle) + aw * math.sin(angle)
ay1 = y2 - ah * math.sin(angle) - aw * math.cos(angle)
ax2 = x2 - ah * math.cos(angle) - aw * math.sin(angle)
ay2 = y2 - ah * math.sin(angle) + aw * math.cos(angle)
p = c.beginPath()
p.moveTo(x2, y2)
p.lineTo(ax1, ay1)
p.lineTo(ax2, ay2)
p.closePath()
c.drawPath(p, fill=1, stroke=0)
if label:
mx = (x1 + x2) / 2
my = (y1 + y2) / 2
c.setFont("Helvetica-Bold", 8)
c.setFillColor(label_color)
c.drawCentredString(mx + 6, my + 3, label)
c.restoreState()
def text_in_box(c, x, y, w, h, lines, font="Helvetica-Bold", size=9,
color=BLACK, align="center", v_pad=4):
"""Write multi-line text centred inside a box"""
c.saveState()
c.setFont(font, size)
c.setFillColor(color)
total_h = len(lines) * (size + 2)
start_y = y + h / 2 + total_h / 2 - size
for i, line in enumerate(lines):
ly = start_y - i * (size + 2)
if align == "center":
c.drawCentredString(x + w / 2, ly, line)
else:
c.drawString(x + 6, ly, line)
c.restoreState()
def small_box(c, x, y, w, h, lines, fill, stroke, fsize=8.5, bold=False):
rect(c, x, y, w, h, fill=fill, stroke=stroke, radius=5)
font = "Helvetica-Bold" if bold else "Helvetica"
text_in_box(c, x, y, w, h, lines, font=font, size=fsize, color=BLACK)
def bullet_box(c, x, y, w, h, title, bullets, fill, stroke, title_fill,
title_fsize=8.5, bullet_fsize=7.8):
"""Box with coloured title bar and bullet list"""
# outer box
rect(c, x, y, w, h, fill=fill, stroke=stroke, radius=5)
# title bar
rect(c, x, y + h - 20, w, 20, fill=title_fill, stroke=stroke, radius=5)
c.saveState()
c.setFont("Helvetica-Bold", title_fsize)
c.setFillColor(WHITE)
c.drawCentredString(x + w / 2, y + h - 14, title)
c.restoreState()
# bullets
c.saveState()
c.setFont("Helvetica", bullet_fsize)
c.setFillColor(BLACK)
bx = x + 8
by = y + h - 26
for b in bullets:
by -= (bullet_fsize + 3)
if by < y + 4:
break
c.drawString(bx, by, "\u2022 " + b)
c.restoreState()
# ════════════════════════════════════════════════════════════════════════════
# PAGE 1 — DS-TB (Drug-Susceptible) Flowchart
# ════════════════════════════════════════════════════════════════════════════
def page1(c):
# Background gradient strip
c.setFillColor(HexColor("#EBF3FC"))
c.rect(0, 0, W, H, fill=1, stroke=0)
# Header
c.setFillColor(NAVY)
c.rect(0, H - 52, W, 52, fill=1, stroke=0)
c.setFillColor(YELLOW)
c.rect(0, H - 56, W, 4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 18)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, H - 36, "TB MANAGEMENT FLOWCHART — INDIA (NTEP 2025)")
c.setFont("Helvetica", 10)
c.setFillColor(YELLOW)
c.drawCentredString(W / 2, H - 50, "Drug-Susceptible TB (DS-TB) | National Tuberculosis Elimination Programme | Central TB Division, MoHFW")
# Footer
c.setFillColor(NAVY)
c.rect(0, 0, W, 22, fill=1, stroke=0)
c.setFont("Helvetica", 7.5)
c.setFillColor(WHITE)
c.drawString(10, 7, "Source: NTEP Technical & Operational Guidelines 2025 | National Guidelines for DR-TB Management March 2025 | tbcindia.mohfw.gov.in")
c.drawRightString(W - 10, 7, "Page 1 of 2")
# ── Layout constants ─────────────────────────────────────────────────────
TOP = H - 70
bw = 180 # standard box width
bh = 38 # standard box height
dw = 100 # diamond half-width
dh = 32 # diamond half-height
# COLUMN X centres
CX = W / 2
LEFT_COL = 155
RIGHT_COL = W - 155
# ── NODE 1: Presumptive TB ───────────────────────────────────────────────
n1x = CX - 110; n1y = TOP - bh; n1w = 220; n1h = 44
rect(c, n1x, n1y, n1w, n1h, fill=NAVY, stroke=NAVY, radius=8, stroke_width=2)
text_in_box(c, n1x, n1y, n1w, n1h,
["PRESUMPTIVE TB", "Cough \u22652 wks | fever | wt loss | night sweats"],
font="Helvetica-Bold", size=10, color=WHITE)
# Arrow down
arrow(c, CX, n1y, CX, n1y - 24, color=NAVY)
# ── NODE 2: Sputum collection ─────────────────────────────────────────
n2x = CX - 120; n2y = n1y - 24 - 40; n2w = 240; n2h = 40
rect(c, n2x, n2y, n2w, n2h, fill=LT_BLUE, stroke=BLUE, radius=6, stroke_width=1.5)
text_in_box(c, n2x, n2y, n2w, n2h,
["SPUTUM COLLECTION",
"2 samples (spot + early morning)",
"Expectorated / induced / gastric lavage (children)"],
font="Helvetica-Bold", size=8.5, color=NAVY)
arrow(c, CX, n2y, CX, n2y - 20, color=NAVY)
# ── NODE 3: Xpert MTB/RIF ───────────────────────────────────────────────
n3x = CX - 130; n3y = n2y - 20 - 44; n3w = 260; n3h = 44
rect(c, n3x, n3y, n3w, n3h, fill=BLUE, stroke=NAVY, radius=6, stroke_width=2)
text_in_box(c, n3x, n3y, n3w, n3h,
["Xpert MTB/RIF (GeneXpert)",
"FIRST-LINE MOLECULAR TEST (NTEP)",
"Result in ~2 hours"],
font="Helvetica-Bold", size=9, color=WHITE)
arrow(c, CX, n3y, CX, n3y - 22, color=NAVY)
# ── DIAMOND 1: MTB Detected? ─────────────────────────────────────────────
d1cx = CX; d1cy = n3y - 22 - dh
diamond(c, d1cx, d1cy, dw + 20, dh, fill=LT_YELLOW, stroke=ORANGE, stroke_width=2)
text_in_box(c, d1cx - dw - 20, d1cy - dh, (dw + 20) * 2, dh * 2,
["MTB DETECTED?"],
font="Helvetica-Bold", size=9.5, color=ORANGE)
# YES — left branch
arrow(c, d1cx - dw - 20, d1cy, 310, d1cy, color=GREEN, label="YES", label_color=GREEN)
# NO — right branch
arrow(c, d1cx + dw + 20, d1cy, W - 310, d1cy, color=RED, label="NO", label_color=RED)
# ═══ LEFT BRANCH (MTB Detected) ════════════════════════════════════════
# DIAMOND 2: RIF Resistant?
d2cx = 195; d2cy = d1cy
diamond(c, d2cx, d2cy, 88, 28, fill=LT_GREEN, stroke=GREEN, stroke_width=1.8)
text_in_box(c, d2cx - 88, d2cy - 28, 176, 56,
["RIF", "Resistant?"],
font="Helvetica-Bold", size=8.5, color=GREEN)
# NO (RIF sensitive) → DS-TB — straight down
ds_x = d2cx; ds_y_top = d2cy - 28
arrow(c, d2cx, ds_y_top, d2cx, ds_y_top - 22, color=GREEN, label="NO (Sensitive)", label_color=GREEN)
# DS-TB BOX
ds_bx = d2cx - 110; ds_by = ds_y_top - 22 - 44; ds_bw = 220; ds_bh = 44
rect(c, ds_bx, ds_by, ds_bw, ds_bh, fill=GREEN, stroke=GREEN, radius=7, stroke_width=2)
text_in_box(c, ds_bx, ds_by, ds_bw, ds_bh,
["DS-TB", "Drug-Susceptible TB", "→ Standard Treatment"],
font="Helvetica-Bold", size=9.5, color=WHITE)
arrow(c, d2cx, ds_by, d2cx, ds_by - 22, color=GREEN)
# Treatment regimen boxes
tr_y = ds_by - 22 - 50; tr_bw = 210; tr_bh = 50
# Intensive
rect(c, d2cx - tr_bw - 8, tr_y, tr_bw, tr_bh, fill=LT_GREEN, stroke=GREEN, radius=5)
text_in_box(c, d2cx - tr_bw - 8, tr_y, tr_bw, tr_bh,
["Intensive Phase (2 months)",
"H + R + Z + E (Daily FDC)",
"Weight-band based dosing"],
size=8.5, color=GREEN)
# Continuation
rect(c, d2cx + 8, tr_y, tr_bw, tr_bh, fill=LT_BLUE, stroke=BLUE, radius=5)
text_in_box(c, d2cx + 8, tr_y, tr_bw, tr_bh,
["Continuation Phase (4 months)",
"H + R (Daily FDC)",
"Total = 6 months"],
size=8.5, color=BLUE)
arrow(c, d2cx, tr_y, d2cx, tr_y - 20, color=NAVY)
# Weight band table
wb_y = tr_y - 20 - 72; wb_bw = 230; wb_bh = 72
rect(c, d2cx - wb_bw / 2, wb_y, wb_bw, wb_bh, fill=GREY, stroke=NAVY, radius=4)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(NAVY)
c.drawCentredString(d2cx, wb_y + wb_bh - 10, "Daily FDC — Weight Band Dosing")
c.setFont("Helvetica", 7.8)
c.setFillColor(BLACK)
wb_data = [
("25-39 kg", "2 tablets HRZE / 2 tab HR"),
("40-54 kg", "3 tablets HRZE / 3 tab HR"),
("55-69 kg", "4 tablets HRZE / 4 tab HR"),
("\u226570 kg", "5 tablets HRZE / 5 tab HR"),
]
for i, (wt, dose) in enumerate(wb_data):
row_y = wb_y + wb_bh - 24 - i * 14
bg = LT_BLUE if i % 2 == 0 else WHITE
c.setFillColor(bg)
c.rect(d2cx - wb_bw / 2 + 2, row_y - 2, wb_bw - 4, 13, fill=1, stroke=0)
c.setFillColor(BLACK)
c.drawString(d2cx - wb_bw / 2 + 6, row_y + 1, wt)
c.drawString(d2cx - 20, row_y + 1, dose)
arrow(c, d2cx, wb_y, d2cx, wb_y - 18, color=NAVY)
# Extensions box
ext_y = wb_y - 18 - 52; ext_bw = 260; ext_bh = 52
rect(c, d2cx - ext_bw / 2, ext_y, ext_bw, ext_bh, fill=LT_ORANGE, stroke=ORANGE, radius=5)
text_in_box(c, d2cx - ext_bw / 2, ext_y, ext_bw, ext_bh,
["EXTENDED TREATMENT (12 months: 2HRZE/10HR)",
"CNS TB | Spinal TB (Pott's) | Bone & Joint TB",
"Severe Miliary TB"],
size=8, color=ORANGE)
# YES (RIF Resistant) → DR-TB → arrow downward
dr_from_x = d2cx; dr_from_y = d2cy + 28
arrow(c, d2cx, d2cy - 28, d2cx, d2cy - 28 - 18, color=RED, label="YES", label_color=RED)
# small note
rect(c, d2cx - 80, d2cy - 28 - 18 - 28, 160, 28, fill=LT_RED, stroke=RED, radius=4)
text_in_box(c, d2cx - 80, d2cy - 28 - 18 - 28, 160, 28,
["DR-TB", "\u2192 See Page 2"], size=8.5, color=RED)
# ═══ RIGHT BRANCH (MTB Not Detected) ══════════════════════════════════
rnd_cx = W - 195
# Clinical suspicion diamond
d3cx = rnd_cx; d3cy = d1cy
diamond(c, d3cx, d3cy, 95, 30, fill=LT_PURPLE, stroke=PURPLE, stroke_width=1.8)
text_in_box(c, d3cx - 95, d3cy - 30, 190, 60,
["Clinical / CXR", "Suspicion?"],
font="Helvetica-Bold", size=8.5, color=PURPLE)
# YES → Clinical diagnosis
arrow(c, d3cx, d3cy - 30, d3cx, d3cy - 30 - 22, color=PURPLE, label="Strong", label_color=PURPLE)
clin_bx = d3cx - 105; clin_by = d3cy - 30 - 22 - 40; clin_bw = 210; clin_bh = 40
rect(c, clin_bx, clin_by, clin_bw, clin_bh, fill=LT_PURPLE, stroke=PURPLE, radius=5)
text_in_box(c, clin_bx, clin_by, clin_bw, clin_bh,
["Clinical/Radiological Diagnosis",
"CXR + Clinical Criteria",
"Consider EPTB workup"],
size=8.5, color=PURPLE)
arrow(c, d3cx, clin_by, d3cx, clin_by - 18, color=PURPLE)
# Treat empirically
emp_bx = d3cx - 100; emp_by = clin_by - 18 - 36; emp_bw = 200; emp_bh = 36
rect(c, emp_bx, emp_by, emp_bw, emp_bh, fill=PURPLE, stroke=PURPLE, radius=5)
text_in_box(c, emp_bx, emp_by, emp_bw, emp_bh,
["Empirical Anti-TB Treatment",
"2HRZE / 4HR (Clinical Diagnosis)"],
font="Helvetica-Bold", size=8.5, color=WHITE)
# NO → Investigate further
arrow(c, d3cx + 95, d3cy, d3cx + 95 + 50, d3cy, color=MID_GREY, label="Low", label_color=MID_GREY)
inv_bx = d3cx + 145; inv_by = d3cy - 20; inv_bw = 150; inv_bh = 40
rect(c, inv_bx, inv_by, inv_bw, inv_bh, fill=GREY, stroke=MID_GREY, radius=4)
text_in_box(c, inv_bx, inv_by, inv_bw, inv_bh,
["Consider Alternative Dx",
"Monitor / Reassess"],
size=8, color=HexColor("#555555"))
# ═══ EPTB SECTION ════════════════════════════════════════════════════════
eptb_y = 90
eptb_bx = MARGIN; eptb_bw = W - 2 * MARGIN; eptb_bh = 60
rect(c, eptb_bx, eptb_y, eptb_bw, eptb_bh, fill=LT_TEAL, stroke=TEAL, radius=6, stroke_width=1.5)
c.setFillColor(TEAL)
c.rect(eptb_bx, eptb_y + eptb_bh - 20, eptb_bw, 20, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, eptb_y + eptb_bh - 13, "EXTRAPULMONARY TB (EPTB) — Use Xpert on Relevant Specimen")
eptb_data = [
("Lymph Node TB", "FNAC + ZN + Xpert | LN biopsy culture"),
("Pleural TB", "Pleural fluid ADA (>40) + Xpert on biopsy"),
("TB Meningitis", "CSF: Xpert + culture + ADA (>10)\nDexamethasone adjunct"),
("Spinal TB", "CT/MRI guided biopsy + Xpert\n12 months treatment"),
("Peritoneal TB", "Ascites ADA (>33) + laparoscopy + biopsy"),
("GU TB", "Urine: Xpert / culture (3 samples)"),
]
col_w_e = (eptb_bw - 20) / len(eptb_data)
for i, (site, note) in enumerate(eptb_data):
ex = eptb_bx + 10 + i * col_w_e
c.setFont("Helvetica-Bold", 7.5)
c.setFillColor(TEAL)
c.drawString(ex, eptb_y + eptb_bh - 32, site)
c.setFont("Helvetica", 7)
c.setFillColor(BLACK)
for j, ln in enumerate(note.split("\n")):
c.drawString(ex, eptb_y + eptb_bh - 44 - j * 10, ln)
# ═══ COMMON ACTIONS FOOTER (above page footer) ═══════════════════════════
ca_y = eptb_y - 4
ca_bx = MARGIN; ca_bw = W - 2 * MARGIN; ca_bh = 26
# already above footer; shift up
ca_y = 26
rect(c, ca_bx, ca_y, ca_bw, ca_bh, fill=NAVY, stroke=NAVY, radius=4)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(YELLOW)
c.drawCentredString(W / 2, ca_y + 16, "FOR ALL TB PATIENTS:")
c.setFont("Helvetica", 7.5)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, ca_y + 6,
"Notify on Nikshay \u2502 Nikshay Poshan Yojana (\u20b9500/month) \u2502 Contact investigation + TPT (6H/3HP) \u2502 Pyridoxine (B6) with INH \u2502 Monthly sputum monitoring \u2502 Adherence counselling")
# Legend
legend_items = [
(NAVY, "Diagnostic Step"),
(GREEN, "DS-TB Treatment"),
(ORANGE, "Decision / Branch"),
(RED, "DR-TB Pathway"),
(TEAL, "EPTB"),
(PURPLE, "Clinical Suspicion"),
]
lx = W - 220; ly = H - 130
c.setFont("Helvetica-Bold", 8)
c.setFillColor(NAVY)
c.drawString(lx, ly + 12, "LEGEND")
for i, (col, label) in enumerate(legend_items):
c.setFillColor(col)
c.rect(lx, ly - 4 - i * 14, 12, 10, fill=1, stroke=0)
c.setFillColor(BLACK)
c.setFont("Helvetica", 7.5)
c.drawString(lx + 16, ly - 3 - i * 14, label)
c.showPage()
# ════════════════════════════════════════════════════════════════════════════
# PAGE 2 — DR-TB Flowchart
# ════════════════════════════════════════════════════════════════════════════
def page2(c):
c.setFillColor(HexColor("#FFF5F0"))
c.rect(0, 0, W, H, fill=1, stroke=0)
# Header
c.setFillColor(RED)
c.rect(0, H - 52, W, 52, fill=1, stroke=0)
c.setFillColor(YELLOW)
c.rect(0, H - 56, W, 4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 18)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, H - 36, "DR-TB MANAGEMENT FLOWCHART — INDIA (NTEP 2025)")
c.setFont("Helvetica", 10)
c.setFillColor(YELLOW)
c.drawCentredString(W / 2, H - 50, "Drug-Resistant TB | National Guidelines for Management of DR-TB — March 27, 2025 | MoHFW India")
# Footer
c.setFillColor(NAVY)
c.rect(0, 0, W, 22, fill=1, stroke=0)
c.setFont("Helvetica", 7.5)
c.setFillColor(WHITE)
c.drawString(10, 7, "Source: NTEP National Guidelines for DR-TB Management March 2025 | ZeNix trial | TB-PRACTECAL trial | tbcindia.mohfw.gov.in")
c.drawRightString(W - 10, 7, "Page 2 of 2")
TOP = H - 70
CX = W / 2
dh = 30
# ── NODE: RR/MDR-TB Confirmed ────────────────────────────────────────────
n1x = CX - 150; n1y = TOP - 44; n1w = 300; n1h = 44
rect(c, n1x, n1y, n1w, n1h, fill=RED, stroke=HexColor("#8B0000"), radius=8, stroke_width=2)
text_in_box(c, n1x, n1y, n1w, n1h,
["MDR-TB / RR-TB CONFIRMED",
"Xpert MTB/RIF: RIF Resistant",
"Send for LPA + Culture + Full DST"],
font="Helvetica-Bold", size=10, color=WHITE)
arrow(c, CX, n1y, CX, n1y - 22, color=RED, width=2)
# ── DST Results ─────────────────────────────────────────────────────────
dst_x = CX - 130; dst_y = n1y - 22 - 38; dst_w = 260; dst_h = 38
rect(c, dst_x, dst_y, dst_w, dst_h, fill=LT_RED, stroke=RED, radius=5)
text_in_box(c, dst_x, dst_y, dst_w, dst_h,
["AWAIT DST RESULTS",
"LPA: Detect H & R resistance",
"Culture DST: FQ, Group A/B drug susceptibility"],
size=8.5, color=RED)
arrow(c, CX, dst_y, CX, dst_y - 20, color=RED, width=1.8)
# ── DIAMOND: FQ Susceptible? ──────────────────────────────────────────
d1cx = CX; d1cy = dst_y - 20 - dh
diamond(c, d1cx, d1cy, 105, dh, fill=LT_YELLOW, stroke=ORANGE, stroke_width=2)
text_in_box(c, d1cx - 105, d1cy - dh, 210, dh * 2,
["Fluoroquinolone (FQ)", "Susceptible?"],
font="Helvetica-Bold", size=9, color=ORANGE)
# ══ YES (FQ Susceptible) — LEFT ══════════════════════════════════════
arrow(c, d1cx - 105, d1cy, 195, d1cy, color=GREEN, width=1.8, label="YES", label_color=GREEN)
# BPaLM BOX
bpalm_cx = 170
bpalm_bx = bpalm_cx - 155; bpalm_by = d1cy - 28 - 60; bpalm_bw = 310; bpalm_bh = 60
arrow(c, bpalm_cx, d1cy - dh * 0, bpalm_cx, bpalm_by + bpalm_bh, color=GREEN, width=1.8)
# shift arrow start
arrow(c, 195, d1cy, bpalm_cx, d1cy, color=GREEN, width=1.2)
arrow(c, bpalm_cx, d1cy, bpalm_cx, bpalm_by + bpalm_bh, color=GREEN, width=1.5)
rect(c, bpalm_bx, bpalm_by, bpalm_bw, bpalm_bh, fill=GREEN, stroke=HexColor("#0D4D26"), radius=7, stroke_width=2)
text_in_box(c, bpalm_bx, bpalm_by, bpalm_bw, bpalm_bh,
["BPaLM REGIMEN (PREFERRED)",
"Bedaquiline + Pretomanid + Linezolid + Moxifloxacin",
"Duration: 6 months (all-oral, shorter)"],
font="Helvetica-Bold", size=9.5, color=WHITE)
arrow(c, bpalm_cx, bpalm_by, bpalm_cx, bpalm_by - 18, color=GREEN, width=1.5)
# BPaLM details sub-box
bd_bx = bpalm_cx - 155; bd_by = bpalm_by - 18 - 80; bd_bw = 310; bd_bh = 80
rect(c, bd_bx, bd_by, bd_bw, bd_bh, fill=LT_GREEN, stroke=GREEN, radius=5)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(GREEN)
c.drawCentredString(bpalm_cx, bd_by + bd_bh - 12, "BPaLM Dosing")
c.setFont("Helvetica", 8)
c.setFillColor(BLACK)
bpalm_doses = [
"Bedaquiline (Bdq): 400 mg/d \u00d7 2 wks \u2192 200 mg 3\u00d7/wk \u00d7 24 wks",
"Pretomanid (Pa): 200 mg daily \u00d7 26 weeks",
"Linezolid (Lzd): 600 mg daily \u00d7 26 weeks",
"Moxifloxacin (Mfx): 400 mg daily \u00d7 26 weeks",
"Evidence: TB-PRACTECAL trial (2022)",
]
for i, d in enumerate(bpalm_doses):
c.drawString(bd_bx + 8, bd_by + bd_bh - 26 - i * 12, "\u2022 " + d)
# ══ NO (FQ Resistant) — RIGHT ══════════════════════════════════════
arrow(c, d1cx + 105, d1cy, W - 190, d1cy, color=RED, width=1.8, label="NO (FQ Resistant)", label_color=RED)
bpal_cx = W - 170
bpal_bx = bpal_cx - 150; bpal_by = d1cy - 28 - 60; bpal_bw = 300; bpal_bh = 60
arrow(c, W - 190, d1cy, bpal_cx, d1cy, color=RED, width=1.2)
arrow(c, bpal_cx, d1cy, bpal_cx, bpal_by + bpal_bh, color=RED, width=1.5)
rect(c, bpal_bx, bpal_by, bpal_bw, bpal_bh, fill=RED, stroke=HexColor("#8B0000"), radius=7, stroke_width=2)
text_in_box(c, bpal_bx, bpal_by, bpal_bw, bpal_bh,
["BPaL REGIMEN",
"Bedaquiline + Pretomanid + Linezolid",
"Duration: 6 months"],
font="Helvetica-Bold", size=9.5, color=WHITE)
arrow(c, bpal_cx, bpal_by, bpal_cx, bpal_by - 18, color=RED, width=1.5)
bd2_bx = bpal_cx - 150; bd2_by = bpal_by - 18 - 80; bd2_bw = 300; bd2_bh = 80
rect(c, bd2_bx, bd2_by, bd2_bw, bd2_bh, fill=LT_RED, stroke=RED, radius=5)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(RED)
c.drawCentredString(bpal_cx, bd2_by + bd2_bh - 12, "BPaL Dosing (ZeNix Trial)")
c.setFont("Helvetica", 8)
c.setFillColor(BLACK)
bpal_doses = [
"Bedaquiline (Bdq): 400mg/d \u00d7 2wks \u2192 200mg 3\u00d7/wk \u00d7 24wks",
"Pretomanid (Pa): 200 mg daily \u00d7 26 weeks",
"Linezolid (Lzd): 600 mg daily \u00d7 26 weeks",
"Note: 600mg Lzd preferred (less toxic vs 1200mg)",
"Use when FQ resistance confirmed or XDR-TB",
]
for i, d in enumerate(bpal_doses):
c.drawString(bd2_bx + 8, bd2_by + bd2_bh - 26 - i * 12, "\u2022 " + d)
# ══ CENTRE: 9-11 month option ════════════════════════════════════════
alt_bx = CX - 130; alt_by = bd_by - 18; alt_bw = 260; alt_bh = 58
arrow(c, CX, d1cy - dh, CX, alt_by + alt_bh, color=ORANGE, width=1.2)
rect(c, alt_bx, alt_by, alt_bw, alt_bh, fill=LT_ORANGE, stroke=ORANGE, radius=5, stroke_width=1.5)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(ORANGE)
c.drawCentredString(CX, alt_by + alt_bh - 12, "SHORTER REGIMEN (9-11 months) — STREAM")
c.setFont("Helvetica", 8)
c.setFillColor(BLACK)
alt_lines = [
"Intensive (4-6m): Bdq + Lfx/Mfx + Cfz + Z + E + H(HD) + Eto",
"Continuation (5m): Lfx/Mfx + Cfz + Z + E",
"Use when BPaLM/BPaL not feasible | FQ-susceptible MDR-TB",
]
for i, ln in enumerate(alt_lines):
c.drawString(alt_bx + 8, alt_by + alt_bh - 26 - i * 12, "\u2022 " + ln)
# ══ MONITORING BOX ═══════════════════════════════════════════════════
mon_y = min(bd_by, bd2_by) - 30
mon_bx = MARGIN; mon_bw = W - 2 * MARGIN; mon_bh = 68
mon_by = mon_y - mon_bh
rect(c, mon_bx, mon_by, mon_bw, mon_bh, fill=LT_BLUE, stroke=BLUE, radius=5, stroke_width=1.5)
c.setFillColor(BLUE)
c.rect(mon_bx, mon_by + mon_bh - 20, mon_bw, 20, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, mon_by + mon_bh - 13, "MANDATORY MONITORING DURING DR-TB TREATMENT")
mon_cols = [
("Sputum smear + culture", "Monthly (intensive) → 2-monthly (continuation)"),
("ECG (QTc)", "Baseline → Monthly (Bdq, Dlm, Cfz, Mfx)"),
("LFT", "Baseline → Monthly (Lzd, Eto, PZA)"),
("CBC", "Monthly (Linezolid: myelosuppression)"),
("Peripheral neuropathy", "Monthly (Lzd, Cycloserine)"),
("Visual acuity", "Baseline + 6-monthly (EMB, Lzd)"),
("TSH", "Baseline + 6-monthly (Eto + PAS)"),
("Renal function", "Monthly if aminoglycoside used"),
]
col_w_m = (mon_bw - 20) / len(mon_cols)
for i, (test, freq) in enumerate(mon_cols):
mx = mon_bx + 10 + i * col_w_m
c.setFont("Helvetica-Bold", 7.5)
c.setFillColor(BLUE)
c.drawString(mx, mon_by + mon_bh - 32, test)
c.setFont("Helvetica", 7)
c.setFillColor(BLACK)
c.drawString(mx, mon_by + mon_bh - 44, freq)
# ══ DRUG GROUPS ══════════════════════════════════════════════════════
dg_y = mon_by - 14
dg_bx = MARGIN; dg_bw = W - 2 * MARGIN; dg_bh = 70
dg_by = dg_y - dg_bh
rect(c, dg_bx, dg_by, dg_bw, dg_bh, fill=GREY, stroke=NAVY, radius=5)
c.setFillColor(NAVY)
c.rect(dg_bx, dg_by + dg_bh - 20, dg_bw, 20, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(WHITE)
c.drawCentredString(W / 2, dg_by + dg_bh - 13, "WHO / NTEP DRUG GROUPS FOR MDR-TB TREATMENT")
grp_data = [
("GROUP A\n(Use ALL 3)", "Levofloxacin / Moxifloxacin\nBedaquiline (Bdq)\nLinezolid (Lzd)", GREEN, LT_GREEN),
("GROUP B\n(Add 1-2)", "Clofazimine (Cfz)\nCycloserine (Cs) / Terizidone", BLUE, LT_BLUE),
("GROUP C\n(Add to complete)", "Ethambutol, Delamanid, PZA\nImipenem-cilastatin, Amikacin\nEthionamide/Prothionamide, PAS", ORANGE, LT_ORANGE),
("DELAMANID\n(Add-on)", "100mg BD \u00d7 24 weeks\nFor MDR+FQ resist, XDR-TB\nQTc monitoring mandatory", PURPLE, LT_PURPLE),
("REGIMEN DURATIONS", "BPaLM: 6 months\nBPaL: 6 months\nShorter: 9-11 months\nLonger: 18-20 months", NAVY, HexColor("#D6E8F8")),
]
grp_cw = (dg_bw - 20) / len(grp_data)
for i, (gname, gdrugs, gcol, gbg) in enumerate(grp_data):
gx = dg_bx + 10 + i * grp_cw
rect(c, gx, dg_by + 4, grp_cw - 4, dg_bh - 28, fill=gbg, stroke=gcol, radius=4)
c.setFillColor(gcol)
c.rect(gx, dg_by + dg_bh - 28, grp_cw - 4, 12, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 7.5)
c.setFillColor(WHITE)
c.drawCentredString(gx + (grp_cw - 4) / 2, dg_by + dg_bh - 21, gname.split("\n")[0])
c.setFont("Helvetica", 7)
c.setFillColor(BLACK)
for j, ln in enumerate(gdrugs.split("\n")):
c.drawString(gx + 4, dg_by + dg_bh - 38 - j * 11, ln)
# ══ XDR/Pre-XDR note ═══════════════════════════════════════════════════
xdr_by = dg_by - 36
rect(c, MARGIN, xdr_by, W - 2 * MARGIN, 30, fill=LT_RED, stroke=RED, radius=4)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(RED)
c.drawString(MARGIN + 10, xdr_by + 18, "Pre-XDR / XDR-TB:")
c.setFont("Helvetica", 8)
c.setFillColor(BLACK)
c.drawString(MARGIN + 110, xdr_by + 18,
"Individualized regimen \u2265 5 active drugs | Use all available Group A + B + C drugs | Duration 18-20 months | Refer to DR-TB Centre")
c.drawString(MARGIN + 10, xdr_by + 6,
"XDR-TB Definition (WHO 2021): MDR/RR-TB + ANY FQ resistance + Bedaquiline OR Linezolid resistance | QTc monitoring: avoid Bdq+Dlm+Mfx without rigorous ECG monitoring")
# ══ NIKSHAY / SUPPORT FOOTER ═══════════════════════════════════════════
nik_by = 26
rect(c, MARGIN, nik_by, W - 2 * MARGIN, 26, fill=NAVY, stroke=NAVY, radius=4)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(YELLOW)
c.drawString(MARGIN + 10, nik_by + 16, "ALL DR-TB PATIENTS:")
c.setFont("Helvetica", 7.5)
c.setFillColor(WHITE)
c.drawString(MARGIN + 130, nik_by + 16,
"Notify on Nikshay \u2502 Nikshay Poshan Yojana (\u20b9500/month) \u2502 Nikshay Mitra support \u2502 Counselling on QTc-prolonging drugs \u2502 Refer to DR-TB Centre")
c.setFont("Helvetica", 7.5)
c.setFillColor(YELLOW)
c.drawString(MARGIN + 10, nik_by + 5, "TPT for contacts:")
c.setFont("Helvetica", 7.5)
c.setFillColor(WHITE)
c.drawString(MARGIN + 80, nik_by + 5,
"Household contacts of DR-TB: do NOT give standard TPT; refer for specialist opinion | Screen all contacts with Xpert")
c.showPage()
# ════════════════════════════════════════════════════════════════════════════
# MAIN
# ════════════════════════════════════════════════════════════════════════════
out = "/tmp/workspace/tb-ppt/TB_Management_Flowchart_NTEP_India_2025.pdf"
c = make_canvas(out)
page1(c)
page2(c)
c.save()
print(f"Saved: {out}")
cd /tmp/workspace/tb-ppt && python tb_flowchart.py 2>&1
Management of TB acc to national indian guidelines in flowchart
Create a TB management flowchart document in Word format for easy editing