tuberculosis complete with abdominal and tbm

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Finding Sources
Reading File
Reading File
I now have comprehensive content from multiple authoritative textbooks. Let me compile the complete, detailed answer.

Tuberculosis: Complete Review

Overview and Epidemiology

Tuberculosis (TB) is caused by Mycobacterium tuberculosis, an obligate intracellular aerobe, and remains the world's leading infectious disease killer. In 2018, approximately 10 million new TB cases were reported globally with 1.5 million deaths. Latent TB infects one-quarter of the world's population, carrying a lifetime reactivation risk of 5-15%. HIV coinfection accounts for ~9% of new cases and dramatically raises the risk - the incidence of TB in persons with full-blown HIV is nearly 500 times that of the general population.
Extrapulmonary TB (EPTB) accounts for 15% of global TB cases. Most commonly affected sites:
  1. Lymphatic
  2. Pleural
  3. Skeletal
  4. Genitourinary
  5. Gastrointestinal (next most common)
  6. CNS (~5% of EPTB in the US)

I. PULMONARY TUBERCULOSIS

Pathogenesis and Disease Spectrum

After initial infection, the spectrum of outcomes includes:
  • Bacterial elimination (no disease)
  • Latent TB infection (TST/IGRA positive, asymptomatic, culture negative)
  • Subclinical disease
  • Progressive primary disease (within 1 year of infection)
  • Reactivation (post-primary disease, distant from initial infection)
Spectrum of outcomes after TB infection - Goldman-Cecil Medicine

Clinical Features

  • Most common symptom: Persistent cough (productive or nonproductive) - up to 25% of culture-confirmed cases do not report cough
  • Constitutional symptoms: Fever, chills, night sweats, weight loss
  • Hemoptysis - occurs in advanced disease
  • Physical exam: Post-tussive rales in upper lung zones; amphoric breath sounds indicate a cavity; lymphadenopathy uncommon in immunocompetent adults

Chest Radiology

  • Primary TB: Parenchymal consolidation, hilar/paratracheal lymphadenopathy, pleural effusion
  • Post-primary/Reactivation: Upper lobe predominance, cavitation, fibrosis, volume loss
  • Miliary TB: Diffuse 1-2 mm nodules throughout both lung fields

TB Pleuritis

TB pleuritis is due to a type IV (delayed) hypersensitivity reaction triggered by release of TB antigens into the pleural space from rupture of subpleural disease. Key points:
  • Pleural fluid is exudative, predominantly lymphocytic
  • Fulminant TB empyema is much rarer
  • 10% of patients develop restrictive spirometric defects after a median of 23 months
  • Cochrane evidence shows oral corticosteroids may improve radiographic appearances of residual pleural changes but do not improve long-term respiratory function and are associated with more adverse events

II. ABDOMINAL TUBERCULOSIS

Abdominal TB encompasses three main compartments: gastrointestinal (intestinal), peritoneal, and lymph node disease.

A. Gastrointestinal (Intestinal) Tuberculosis

Epidemiology:
  • 3.5% of extrapulmonary cases in the US
  • Ileocecal region: most common site (64% of GI TB cases), followed by jejunum and colon
  • Only 15-25% of GI TB cases have concomitant pulmonary TB
  • M. bovis from unpasteurized dairy products is an additional cause in developing countries
Pathogenesis routes:
  1. Swallowing of infected sputum (direct seeding)
  2. Hematogenous spread
  3. Lymphatic spread
  4. Direct spread from adjacent structures (lymph nodes, fallopian tubes)
Clinical Features:
  • Abdominal pain and GI obstruction (most common presentation)
  • Fever, nausea, diarrhea, weight loss
  • Gastrointestinal bleeding
  • Palpable mass in ileocecal region
  • Can mimic Crohn disease, acute appendicitis, or carcinoma
Differential Diagnosis of Intestinal TB (Box 145.1 - Yamada's Gastroenterology):
  • Crohn's disease (key mimic - granulomas are noncaseating, <400 μm, poorly organized)
  • Appendicitis, malignancies (lymphoma, carcinoma)
  • Sarcoidosis, amyloidosis
  • NSAIDs-related enteropathy
  • Infectious: Salmonellosis, Yersiniosis, Cytomegalovirus, Histoplasmosis, MAC enteritis
  • Actinomycosis, Anisakiasis, Typhlitis, Eosinophilic enteritis, Vasculitides, Ischemia
Diagnosis:
  • AFB smear/culture of tissue (gold standard but positive in <40% of cases with ZN staining positive in only ~3%)
  • Endoscopic biopsy showing caseating granulomas
  • PCR/Xpert MTB-RIF assay (sensitivity 50-100%, specificity 62-97% - further validation needed)
  • CD4+ T-cell activation markers (CD38, HLA-DR, Ki67+) are being studied as differentiating tools

B. Peritoneal Tuberculosis

Pathogenesis: M. tuberculosis enters the peritoneal space from adjacent lymph nodes.
Clinical Features:
  • Subacute abdominal pain, anorexia, abdominal swelling
  • Systemic symptoms: fever, night sweats, weight loss
  • Can mimic acute abdomen
  • Often underlies liver disease (cirrhosis) - may obscure TB symptoms
  • Intra-abdominal lymphadenopathy on CT
  • Active pulmonary TB is uncommon in patients with TB peritonitis
  • Fever + abdominal tenderness in a person with ascites should always prompt paracentesis
Ascitic Fluid Analysis:
ParameterFinding
CharacterExudative
WBC count50-10,000 leukocytes/μL, predominantly lymphocytes
AFB smearRarely positive
Culture~50% positive (increases with large volume)
SAAGLow (<1.1 g/dL) in non-cirrhotic; high in cirrhotic (cirrhosis dominates)
ADAHigh sensitivity 93-100%, specificity 96-97%; cut-off 36-40 IU/L (optimal 39 IU/L)
Diagnosis:
  • Laparoscopy with biopsy = best diagnostic test (characteristic findings + histology + culture)
  • ADA in ascitic fluid: sensitivity 100%, specificity 97% at cut-off 39 IU/L (meta-analysis of 12 studies)
  • In cirrhotic patients, ADA may be less sensitive (but not confirmed by systematic reviews)
  • Paracentesis mandatory whenever TB peritonitis is suspected

III. TUBERCULOUS MENINGITIS (TBM)

Pathogenesis

TBM results from two sequential events:
  1. Hematogenous seeding of meninges and subpial regions → formation of tubercles
  2. Rupture of one or more tubercles → discharge of bacteria into the subarachnoid space
The rich's concept: TBM always originates from a subependymal tubercle (part of miliary disease), though conventional hematogenous implantation is debated.

Pathological Findings

  • Small, discrete white tubercles scattered over the base of the cerebral hemispheres (and lesser degree on convexities)
  • Thick, gelatinous exudate accumulates in basal meninges - obliterating the pontine and interpeduncular cisterns, extending to the floor of the 3rd ventricle, optic chiasm, and undersurfaces of temporal lobes
  • Microscopically: central zone of caseation surrounded by epithelioid cells, giant cells, lymphocytes, plasma cells
  • Cranial nerves frequently involved as they traverse the subarachnoid space
  • Arteries become inflamed and occluded → brain infarction
  • Blockage of basal cisterns → obstructive hydrocephalus
  • Process is a true meningoencephalitis (penetrates pia and ependymia into brain parenchyma)

MRI in Tuberculous Meningitis

MRI in TBM - gadolinium enhancement of basal meninges, multiple abscesses, hydrocephalus - Adams & Victor's Neurology
Gadolinium-enhanced MRI demonstrating enhancement of basal meninges reflecting multiple abscesses, with accompanying hydrocephalus and cranial nerve palsies (Adams & Victor's Principles of Neurology, 12th ed.).

Clinical Features

Prodrome (weeks 1-2):
  • Low-grade fever, malaise, headache (>50% of cases), lethargy, confusion
  • Stiff neck (75% of cases), Kernig and Brudzinski signs
  • Symptom evolution over 1-2 weeks - much slower than bacterial meningitis
In young children and infants: Apathy, hyperirritability, vomiting, seizures - stiff neck may be absent
Later features (reflecting basal disease):
  • Cranial nerve palsies - ocular palsies (most common), facial palsy, deafness - in 20% at diagnosis
  • Papilledema
  • Diplopia (basilar exudate) - up to 70% of patients
  • Focal neurologic deficit from hemorrhagic infarction
  • Hypothermia and hyponatremia (SIADH is common)
  • Lacunar infarcts / movement disorders (basal ganglia vessel involvement)
  • Hemiparesis / hemiplegia (middle cerebral artery involvement)
  • Ultimate evolution: coma, hydrocephalus, intracranial hypertension
In ~two-thirds of TBM patients: Evidence of active TB elsewhere (usually lungs, occasionally small bowel, bone, kidney, or ear)

CSF Findings

ParameterFinding in TBM
Opening pressureElevated
LeukocytesUp to 1000/μL (up to 1500); lymphocyte predominance; PMNs may predominate early
ProteinElevated 1-8 g/L (100-800 mg/dL)
GlucoseLow (typically)
AFB smearInfrequently positive (repeated LPs increase yield)
CulturePositive up to 80% - gold standard
Xpert MTB/RIFSensitivity up to 80% - preferred initial test

Neuroradiology (Classic Triad on CT/MRI)

  1. Basal meningeal enhancement
  2. Hydrocephalus
  3. Cerebral or brainstem infarction

Tuberculoma

  • Tumor-like masses of tuberculous granulation tissue, 2-12 mm
  • Multiple or single, in brain parenchyma
  • Can cause mass effect, periventricular obstructive hydrocephalus, seizures, focal signs
  • CT/MRI: contrast-enhanced ring lesions
  • In developing countries: 5-30% of all intracranial mass lesions
  • CSF: small lymphocytosis, increased protein, glucose not reduced (serous meningitis pattern)
  • Biopsy required for diagnosis; responds to anti-TB drugs
Tuberculoma of the pons - gadolinium MRI before and after treatment
Tuberculoma of the pons on gadolinium-enhanced MRI (left: thick uniform enhancing rim; right: same lesion after antituberculous treatment) - Adams & Victor's Neurology.

Tuberculous Serous Meningitis

A self-limited meningitis from adjacent tuberculous focus. CSF: modest pleocytosis, normal/elevated protein, normal glucose. Mild meningeal signs, headache, confusion.

IV. TREATMENT

Standard Anti-TB Regimen (All Forms)

Two-phase approach:
PhaseDurationDrugsNotes
Intensive2 monthsHRZE - Isoniazid (H) + Rifampicin (R) + Pyrazinamide (Z) + Ethambutol (E)4-drug regimen
Continuation4 monthsHR - Isoniazid + Rifampicin85% global success rate
Patients at higher risk of relapse: up to 9 months total.

Dosing (Adults)

DrugDoseKey Side Effects
Isoniazid (INH)5 mg/kg/day (single dose)Peripheral neuropathy, hepatitis (give pyridoxine 50 mg/day to prevent neuropathy)
Rifampin10 mg/kg/dayHepatitis, drug interactions, orange discoloration of secretions
Pyrazinamide20-35 mg/kg/dayHepatitis, rash, GI upset, hyperuricemia
Ethambutol15 mg/kg/dayOptic neuropathy (visual acuity + red-green color discrimination monitoring required)
Ethionamide (MDR-TB)15-25 mg/kg/day (divided doses)Gastric irritation, optic neuropathy
INH is the single most effective drug. INH and rifampin can be given parenterally; all others only orally/NG tube.

TBM-Specific Treatment

  • Same 4-drug regimen (HRZE) for first 2 months
  • Total duration: 9-12 months
  • Alternative: INH + PZA + high-dose rifampin + moxifloxacin
  • Adjunctive dexamethasone (IV 0.4 mg/kg/day with tapering) reduces mortality from 41% to 32% (RCT, Thwaites et al, Vietnam) - WHO recommends dexamethasone or prednisolone tapered over 6-8 weeks
    • Note: A recent placebo-controlled study showed no benefit in PLWH (people living with HIV)
  • For intracranial tuberculoma: same regimen; surgical excision if mass effect persists or if no radiological response
  • For Pott disease with cord compression: surgical exploration + triple-drug therapy

GI TB Treatment

Same standard 4-drug 6-month regimen. Start immediately if clinical picture is compatible + positive AFB stain or caseating granulomas on histology (don't wait for culture results). In untreated HIV-infected patients, disease progresses rapidly and is invariably fatal.

V. DIAGNOSIS SUMMARY

TestPulmonary TBAbdominal/Peritoneal TBTBM
TST/IGRAPositive in active diseasePositivePositive
Smear (AFB)Positive or negativeRarely positive (ascitic fluid ~3%)Rarely positive (CSF)
CultureGold standard~50% ascitic fluid; best with laparoscopic biopsyUp to 80% CSF
Xpert MTB/RIFPreferred initial testEquivocal for pericardial/peritonealSensitivity up to 80%; preferred initial test
ADAPleural fluid (high sensitivity)Ascitic fluid ≥39 IU/L (sensitivity 100%, specificity 97%)CSF ADA elevated
ImagingCXR: cavitation, upper lobe; CT: miliaryCT: LAD, omental thickening, ascitesCT/MRI: basal enhancement, hydrocephalus, infarction
Laparoscopy/Biopsy-Best diagnostic test for peritoneal TBLP is cornerstone

VI. OTHER EXTRAPULMONARY MANIFESTATIONS (Brief)

  • Osteoarticular TB (Pott disease): Lower thoracic/upper lumbar vertebral involvement; starts in subchondral anterior vertebral body; involves two adjacent vertebrae + intervertebral disc; paravertebral abscesses; gibbus deformity; spinal cord compression
  • Pericardial TB: Exudative pericardial effusion (serosanguineous); ADA sensitivity 87%, specificity 89%; chronic constrictive pericarditis in 30-60%
  • Immunologic manifestations: Erythema nodosum, erythema induratum (tuberculids); Poncet disease (reactive arthritis + erythema nodosum); TB-IRIS (5-50% of patients starting ART)
  • Genitourinary TB: Presents as sterile pyuria; dysuria, hematuria
  • Lymphadenitis: Most common site of EPTB

Sources:

Search for latest WHO TB treatment guidelines and drug-resistant TB protocols

Searching the Web

WHO tuberculosis treatment guidelines 2024 2025 update drug resistant

Searching PubMed

"tuberculosis" AND "treatment guidelines" AND "drug resistant"

Searching the Web

WHO DR-TB MDR-TB XDR-TB BPaLM regimen 2025 guidelines update

Reading Web Page

https://www.who.int/teams/global-programme-on-tuberculosis-a…

Searching PubMed

"tuberculosis" AND "BPaLM" OR "bedaquiline pretomanid linezolid"

Reading Web Page

https://clinician.nejm.org/management-drug-susceptible-drug-…

Reading Article

PMID: 39813501

Reading Article

PMID: 37980911

Searching the Web

WHO 2025 consolidated TB guidelines Module 4 drug susceptible 4-month regimen rifapentine moxifloxacin

I now have rich, current data from WHO 2025, ATS/CDC/ERS/IDSA 2025, and the pivotal trials. Let me compile the full answer.

WHO TB Treatment Guidelines: 2025 Updates

This covers the WHO Consolidated Guidelines on Tuberculosis, Module 4 (2025) and the parallel ATS/CDC/ERS/IDSA 2025 update - the most significant revision in a decade, driven by multiple phase 3 trials that have fundamentally shortened treatment across both drug-susceptible and drug-resistant TB.

PART 1: DRUG-SUSCEPTIBLE TB (DS-TB)

Standard Regimen (Still Valid)

The classic 6-month regimen remains the backbone and is still the preferred option for certain groups:
PhaseDurationDrugsNotation
Intensive2 monthsIsoniazid + Rifampin + Pyrazinamide + Ethambutol2HRZE
Continuation4 monthsIsoniazid + Rifampin4HR
Preferred for: PLHIV with CD4 <100 cells/mm³, children <12 years, pregnant/breastfeeding women.

NEW: 4-Month Regimen (2025 WHO + ATS/CDC/ERS/IDSA Update)

This is the landmark new option based on the TBTC Study 31/ACTG A5349 phase 3 trial (Dorman et al., NEJM 2021):
PhaseDurationDrugsNotation
Intensive2 monthsIsoniazid + Rifapentine + Moxifloxacin + Pyrazinamide2HPMZ
Continuation2 monthsIsoniazid + Rifapentine + Moxifloxacin2HPM
Key changes vs. standard:
  • Ethambutol replaced by Moxifloxacin (fluoroquinolone backbone)
  • Rifampin replaced by Rifapentine (longer half-life, more potent rifamycin)
  • Total duration: 4 months vs. 6 months
Dosing (fixed):
  • Rifapentine: 1200 mg daily (7 days/week)
  • Moxifloxacin: 400 mg daily
Trial evidence:
  • Non-inferiority demonstrated vs. 2HRZE/4HR in adults and adolescents ≥12 years
  • Cure rate 84.5%, retention 99.7%, all-cause mortality 0.4% at end of treatment
  • Grade 3+ adverse events: 18.8% (4-month arm) vs. 19.3% (6-month arm) - similar safety
Eligible patients (ATS/CDC/ERS/IDSA 2025):
  • Adults and adolescents ≥12 years
  • Smear and culture-positive pulmonary DS-TB
NOT eligible for 4-month regimen:
  • PLHIV with CD4 <100 cells/mm³ (6-month preferred)
  • Children <12 years
  • Pregnant, breastfeeding, or postpartum women
  • Those who fail eligibility criteria for the pivotal trials
Note: A 2025 commentary in AJRCCM (Wilson et al., Mayo Clinic) urges caution in broad adoption of the 4-month regimen pending real-world evidence outside controlled trial settings.

PART 2: DRUG-RESISTANT TB (DR-TB) - 2025 WHO Guidelines

Definitions

ClassificationResistance Pattern
Isoniazid-resistant TB (Hr-TB)Isoniazid-resistant, rifampicin-susceptible
RR-TBRifampicin-resistant (any pattern)
MDR-TBResistant to both isoniazid + rifampicin
Pre-XDR-TBMDR/RR-TB + resistance to any fluoroquinolone
XDR-TBMDR/RR-TB + resistance to any fluoroquinolone + ≥1 of bedaquiline or linezolid

Three Tiers of DR-TB Regimens (WHO 2025)

Tier 1 - Preferred: 6-Month All-Oral Regimens

For MDR/RR-TB (fluoroquinolone-susceptible) - Two options:
RegimenDrugsDuration
BPaLMBedaquiline + Pretomanid + Linezolid + Moxifloxacin6 months
BDLLfx (NEW in 2025)Bedaquiline + Delamanid + Linezolid + Levofloxacin + Clofazimine6 months
The BDLLfx (also written BDLLfxC) regimen was added in 2025 based on evidence from the BEAT-TB and endTB clinical trials.
For pre-XDR-TB (fluoroquinolone-resistant) - Two options:
RegimenDrugsDuration
BPaLBedaquiline + Pretomanid + Linezolid6 months
BDLCBedaquiline + Delamanid + Linezolid + Clofazimine6 months
Extension to 9 months is permitted for severe/extensive disease or immunosuppression.

BPaLM Evidence - TB-PRACTECAL Trial (Lancet Respir Med, 2024, PMID 37980911)

This phase 2B-3 non-inferiority RCT (7 sites, Uzbekistan/Belarus/South Africa) directly established BPaLM superiority:
  • Unfavorable outcomes: BPaLM 12% vs. standard care 41% (risk difference -29.2%, p<0.0001)
  • Grade 3+ or serious adverse events: 23% vs. 48% (risk difference -25.2%)
  • Deaths: 0 in BPaLM vs. 5 in standard care group
  • Conclusion: BPaLM is both more effective and safer than standard of care

BPaLM Systematic Review (Silva et al., J Bras Pneumol, 2025, PMID 39813501)

  • BPaLM reduced risk of unfavorable composite outcome (NNT = 7)
  • Reduced early treatment discontinuation (NNT = 8)
  • Reduced serious adverse events (NNT = 5)
  • Better safety profile than standard of care

Tier 2: 9-Month All-Oral Short Regimens

For MDR/RR-TB when fluoroquinolone resistance is excluded. Modified 9-month regimens endorsed in 2025. As of end of 2024, 99 countries were using 9-month regimens.

Tier 3 - Last Resort: 18-20 Month Individualized Regimens

For XDR-TB or when bedaquiline/linezolid intolerance prevents use of shorter regimens. May include injectable agents (amikacin). Individualized combination therapy guided by drug susceptibility testing.

Drug Key (Abbreviations)

LetterDrug
BBedaquiline
PaPretomanid
LLinezolid
MMoxifloxacin
DDelamanid
LfxLevofloxacin
CClofazimine
HIsoniazid
RRifampicin
ZPyrazinamide
EEthambutol
PRifapentine

Isoniazid-Resistant TB (Hr-TB)

WHO recommends: 6RZES (rifampin + pyrazinamide + ethambutol + streptomycin) or 6RZE - without isoniazid. Fluoroquinolone-containing regimens are an alternative.

PART 3: SPECIAL SITUATIONS

TB-HIV Coinfection

  • Start ART in all TB patients regardless of CD4 count (expanded 2025 recommendation)
  • Preferred DS-TB regimen in PLHIV with CD4 <100 cells/mm³: 6-month 2HRZE/4HR
  • The 4-month rifapentine-moxifloxacin regimen has been studied in PLHIV but the 6-month regimen is still preferred at very low CD4 counts
  • For TBM in PLHIV: a recent placebo-controlled trial showed no survival benefit from adjunctive dexamethasone (unlike non-HIV patients)
  • TB-IRIS: Occurs in 5-50% starting ART; high morbidity when CNS involvement

TB in Pregnancy

  • 4-month rifapentine-moxifloxacin regimen is NOT recommended (women excluded from S31/A5349 trial)
  • Standard 6-month 2HRZE/4HR is used
  • Avoid: Pyrazinamide in first trimester per some guidelines; streptomycin (ototoxic to fetus); fluoroquinolones (teratogenic concern)

TB Meningitis

  • 4-drug regimen (HRZE) for 2 months, then HR to complete 9-12 months total
  • Adjunctive dexamethasone IV (0.4 mg/kg/day tapering over 6-8 weeks) - WHO-recommended for non-HIV TBM patients; reduces mortality
  • Drugs with best CNS penetration: INH > PZA > rifampin > ethambutol

PART 4: NEW WHO 2025 MODULE 6 - TB AND UNDERNUTRITION (October 2025)

  • Nutritional assessment and counselling for ALL people with TB and their household contacts (formal recommendation for the first time)
  • Nutritional interventions for TB patients with undernutrition regardless of age, drug resistance status, pregnancy, or severity
  • Food assistance to prevent TB in household contacts in food-insecure settings (based on RATIONS trial)

REAL-WORLD ADOPTION (WHO Global TB Report 2025)

YearCountries using 6-month MDR/RR-TB regimensPeople started on 6-month regimens
2022411,744
2023605,653
20249734,256
This ~6x increase from 2023 to 2024 reflects rapid scale-up of BPaLM globally after WHO endorsement.

SUMMARY COMPARISON TABLE

FeatureDS-TB (Standard)DS-TB (New)MDR/RR-TB (Preferred)Pre-XDR/XDR-TB
Duration6 months4 months6 months6-9 months (individualized 18-20 months for XDR)
Key drugsHRZE / HRHPMZ / HPMBPaLM or BDLLfxBPaL or BDLC
RouteOralOralAll-oralAll-oral (injectable as last resort)
Guideline yearClassic20252022-20252025

Key references:
The full video walkthrough of the ATS/CDC/ERS/IDSA 2025 update is available here:

arrange all this material in on single pdf including treatment

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not found"

Running Command

python3 -c "import reportlab; print('reportlab ok')" && python3 -c "from reportlab.lib.pagesizes import A4; print('A4 ok')"

Running Command

mkdir -p /home/daytona/workspace/tb-pdf

Writing File

~/tb-pdf/generate_tb_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.colors import HexColor
import datetime

# ── Colour palette ──────────────────────────────────────────────────────────
C_NAVY   = HexColor("#1A3557")
C_TEAL   = HexColor("#1D7A8A")
C_MINT   = HexColor("#E8F5F7")
C_AMBER  = HexColor("#F5A623")
C_RED    = HexColor("#C0392B")
C_GREEN  = HexColor("#27AE60")
C_LGRAY  = HexColor("#F4F6F8")
C_DGRAY  = HexColor("#2C3E50")
C_WHITE  = colors.white
C_BLACK  = colors.black
C_WARN   = HexColor("#FFF3CD")
C_WARNBR = HexColor("#856404")

W, H = A4

# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()

def make_style(name, parent="Normal", **kw):
    s = ParagraphStyle(name, parent=base[parent], **kw)
    return s

sTitle = make_style("sTitle",
    fontSize=28, textColor=C_WHITE, fontName="Helvetica-Bold",
    alignment=TA_CENTER, leading=36, spaceAfter=4)

sSubtitle = make_style("sSubtitle",
    fontSize=13, textColor=HexColor("#B0D4E0"), fontName="Helvetica",
    alignment=TA_CENTER, leading=18)

sH1 = make_style("sH1",
    fontSize=16, textColor=C_WHITE, fontName="Helvetica-Bold",
    leading=20, spaceBefore=4, spaceAfter=4)

sH2 = make_style("sH2",
    fontSize=13, textColor=C_NAVY, fontName="Helvetica-Bold",
    leading=17, spaceBefore=10, spaceAfter=4,
    borderPad=4)

sH3 = make_style("sH3",
    fontSize=11, textColor=C_TEAL, fontName="Helvetica-Bold",
    leading=15, spaceBefore=7, spaceAfter=3)

sBody = make_style("sBody",
    fontSize=9.5, textColor=C_DGRAY, fontName="Helvetica",
    leading=14, spaceAfter=5, alignment=TA_JUSTIFY)

sBullet = make_style("sBullet",
    fontSize=9.5, textColor=C_DGRAY, fontName="Helvetica",
    leading=14, spaceAfter=3, leftIndent=14, firstLineIndent=-10)

sSmall = make_style("sSmall",
    fontSize=8, textColor=HexColor("#666666"), fontName="Helvetica",
    leading=11, spaceAfter=4, alignment=TA_CENTER)

sWarn = make_style("sWarn",
    fontSize=9, textColor=C_WARNBR, fontName="Helvetica-Bold",
    leading=13, spaceAfter=4, leftIndent=8)

sLabel = make_style("sLabel",
    fontSize=8, textColor=C_WHITE, fontName="Helvetica-Bold",
    leading=11, alignment=TA_CENTER)

sFooter = make_style("sFooter",
    fontSize=7.5, textColor=HexColor("#999999"), fontName="Helvetica",
    leading=10, alignment=TA_CENTER)

# ── Helper builders ──────────────────────────────────────────────────────────

def section_header(title, color=C_NAVY):
    """Full-width coloured section header bar."""
    tbl = Table([[Paragraph(title, sH1)]], colWidths=[W - 4*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 14),
        ("RIGHTPADDING",  (0,0), (-1,-1), 14),
        ("ROUNDEDCORNERS", [4]),
    ]))
    return tbl

def info_box(title, items, bg=C_MINT, border=C_TEAL):
    """Shaded info box with bullet items."""
    content = [Paragraph(f"<b>{title}</b>", make_style("_ib",
        fontSize=9.5, textColor=C_NAVY, fontName="Helvetica-Bold", leading=14))]
    for item in items:
        content.append(Paragraph(f"• {item}", sBullet))
    tbl = Table([[content]], colWidths=[W - 4*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 12),
        ("RIGHTPADDING",  (0,0), (-1,-1), 12),
        ("LINEABOVE",   (0,0), (-1,0), 2, border),
        ("LINEBELOW",   (0,-1), (-1,-1), 0.5, border),
        ("LINEBEFORE",  (0,0), (0,-1), 3, border),
    ]))
    return tbl

def warn_box(text, bg=C_WARN, border=C_AMBER):
    tbl = Table([[Paragraph(f"⚠  {text}", sWarn)]], colWidths=[W - 4*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,-1), bg),
        ("TOPPADDING",   (0,0), (-1,-1), 7),
        ("BOTTOMPADDING",(0,0), (-1,-1), 7),
        ("LEFTPADDING",  (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 10),
        ("LINEBEFORE",   (0,0), (0,-1), 4, border),
        ("ROUNDEDCORNERS", [3]),
    ]))
    return tbl

def drug_table(header_row, rows, col_w=None):
    data = [header_row] + rows
    if col_w is None:
        col_w = [(W - 4*cm) / len(header_row)] * len(header_row)
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    style = [
        ("BACKGROUND",    (0,0), (-1,0), C_NAVY),
        ("TEXTCOLOR",     (0,0), (-1,0), C_WHITE),
        ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,-1), 8.5),
        ("LEADING",       (0,0), (-1,-1), 12),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("RIGHTPADDING",  (0,0), (-1,-1), 6),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_LGRAY]),
        ("GRID",          (0,0), (-1,-1), 0.4, HexColor("#CCCCCC")),
        ("ALIGN",         (0,0), (-1,-1), "LEFT"),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ]
    tbl.setStyle(TableStyle(style))
    return tbl

def p(text, style=sBody):
    return Paragraph(text, style)

def b(text):
    return Paragraph(f"• {text}", sBullet)

def sp(n=6):
    return Spacer(1, n)

def hr(color=C_TEAL, thickness=0.5):
    return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4, spaceBefore=4)

# ── Cover page ───────────────────────────────────────────────────────────────

def cover_page():
    elems = []
    # Blue cover banner
    cover_data = [[
        Paragraph("TUBERCULOSIS", sTitle),
    ]]
    cover_tbl = Table(cover_data, colWidths=[W - 4*cm])
    cover_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 40),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    elems.append(cover_tbl)

    sub_data = [[
        Paragraph("Complete Clinical Reference", sSubtitle),
    ]]
    sub_tbl = Table(sub_data, colWidths=[W - 4*cm])
    sub_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 0),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    elems.append(sub_tbl)

    sub2_data = [[
        Paragraph("Pulmonary TB · Abdominal TB · TB Meningitis · Drug-Resistant TB · 2025 WHO &amp; ATS/CDC/ERS/IDSA Guidelines", sSubtitle),
    ]]
    sub2_tbl = Table(sub2_data, colWidths=[W - 4*cm])
    sub2_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 0),
        ("BOTTOMPADDING", (0,0), (-1,-1), 30),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    elems.append(sub2_tbl)
    elems.append(sp(20))

    # Cover key stats boxes
    stats = [
        ("10 M+", "New TB cases\nglobally per year"),
        ("1.5 M", "Deaths annually\n(TB is #1 infectious killer)"),
        ("25%", "World population\nhas latent TB"),
        ("500K", "New MDR/RR-TB\ncases per year"),
    ]
    stat_cells = []
    for val, label in stats:
        cell_content = [
            Paragraph(f'<font color="#F5A623"><b>{val}</b></font>',
                make_style("_sv", fontSize=20, fontName="Helvetica-Bold",
                           alignment=TA_CENTER, leading=24, textColor=C_AMBER)),
            Paragraph(label,
                make_style("_sl", fontSize=8, fontName="Helvetica",
                           alignment=TA_CENTER, leading=11, textColor=HexColor("#CCDDEE"))),
        ]
        stat_cells.append(cell_content)

    stat_tbl = Table([stat_cells], colWidths=[(W - 4*cm)/4]*4)
    stat_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_DGRAY),
        ("TOPPADDING",    (0,0), (-1,-1), 14),
        ("BOTTOMPADDING", (0,0), (-1,-1), 14),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("LINEBEFORE",    (1,0), (-1,-1), 0.5, HexColor("#445566")),
    ]))
    elems.append(stat_tbl)
    elems.append(sp(30))

    date_str = datetime.date.today().strftime("%B %Y")
    elems.append(p(
        f"Sources: Goldman-Cecil Medicine 26e · Harrison's Principles 22e (2025) · Adams &amp; Victor's Neurology 12e · "
        f"Murray &amp; Nadel's Respiratory Medicine · Yamada's Gastroenterology 7e · "
        f"WHO Consolidated TB Guidelines Module 4 (2025) · ATS/CDC/ERS/IDSA 2025 Update · "
        f"TB-PRACTECAL Trial (Lancet Respir Med, 2024) · WHO Global TB Report 2025",
        sSmall
    ))
    elems.append(p(f"Compiled: {date_str}", sSmall))
    elems.append(PageBreak())
    return elems

# ── Table of Contents page ───────────────────────────────────────────────────

def toc_page():
    elems = []
    elems.append(section_header("TABLE OF CONTENTS", C_TEAL))
    elems.append(sp(10))
    toc_items = [
        ("1.", "Overview and Epidemiology", "3"),
        ("2.", "Pulmonary Tuberculosis", "3"),
        ("  2.1", "Pathogenesis and Disease Spectrum", "3"),
        ("  2.2", "Clinical Features", "4"),
        ("  2.3", "Radiology", "4"),
        ("  2.4", "TB Pleuritis", "4"),
        ("3.", "Abdominal Tuberculosis", "5"),
        ("  3.1", "Gastrointestinal (Intestinal) TB", "5"),
        ("  3.2", "Peritoneal TB", "6"),
        ("4.", "Tuberculous Meningitis (TBM)", "7"),
        ("  4.1", "Pathogenesis and Pathology", "7"),
        ("  4.2", "Clinical Features", "7"),
        ("  4.3", "CSF Findings", "8"),
        ("  4.4", "Neuroradiology", "8"),
        ("  4.5", "Tuberculoma", "8"),
        ("5.", "Diagnosis Summary", "9"),
        ("6.", "Treatment", "10"),
        ("  6.1", "Drug-Susceptible TB — Standard 6-Month Regimen", "10"),
        ("  6.2", "NEW: 4-Month Regimen (2025 Update)", "10"),
        ("  6.3", "Drug Dosing and Side Effects", "11"),
        ("7.", "Drug-Resistant TB Treatment (WHO 2025)", "12"),
        ("  7.1", "Definitions", "12"),
        ("  7.2", "6-Month All-Oral Regimens (Preferred)", "12"),
        ("  7.3", "9-Month and 18-20 Month Regimens", "13"),
        ("  7.4", "Key Trial Evidence", "13"),
        ("8.", "Special Situations", "14"),
        ("  8.1", "TB-HIV Coinfection", "14"),
        ("  8.2", "TB Meningitis Treatment", "14"),
        ("  8.3", "TB in Pregnancy", "14"),
        ("9.", "Other Extrapulmonary Manifestations", "15"),
        ("10.", "2025 WHO Nutrition Guidelines (Module 6)", "15"),
    ]
    toc_data = [[
        Paragraph(f"<b>{n}</b>", make_style("_tn", fontSize=9, fontName="Helvetica-Bold", textColor=C_NAVY, leading=13)),
        Paragraph(title, make_style("_tt", fontSize=9, fontName="Helvetica", textColor=C_DGRAY, leading=13)),
        Paragraph(pg, make_style("_tp", fontSize=9, fontName="Helvetica", textColor=C_TEAL, leading=13, alignment=TA_CENTER)),
    ] for n, title, pg in toc_items]

    toc_tbl = Table(toc_data, colWidths=[1.2*cm, 13.5*cm, 1.3*cm])
    toc_tbl.setStyle(TableStyle([
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 4),
        ("RIGHTPADDING",  (0,0), (-1,-1), 4),
        ("ROWBACKGROUNDS",(0,0), (-1,-1), [C_WHITE, C_LGRAY]),
        ("LINEBELOW",     (0,-1), (-1,-1), 0.5, HexColor("#DDDDDD")),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ]))
    elems.append(toc_tbl)
    elems.append(PageBreak())
    return elems

# ── Section 1: Epidemiology ──────────────────────────────────────────────────

def section1():
    e = []
    e.append(section_header("1. OVERVIEW AND EPIDEMIOLOGY"))
    e.append(sp(8))
    e.append(p("Tuberculosis (TB) is caused by <i>Mycobacterium tuberculosis</i>, an obligate intracellular aerobe and acid-fast bacillus. It remains the world's leading infectious disease killer, with approximately <b>10 million new cases</b> and <b>1.5 million deaths</b> per year globally. HIV coinfection accounts for ~9% of new cases; TB incidence in persons with full-blown HIV is nearly <b>500 times</b> that of the general population."))
    e.append(sp(6))

    epid_data = [
        [Paragraph("<b>Parameter</b>", sLabel), Paragraph("<b>Data</b>", sLabel)],
        ["New TB cases/year", "~10 million"],
        ["Deaths/year", "1.5 million"],
        ["Latent TB (world population)", "~25%"],
        ["Lifetime reactivation risk", "5–15%"],
        ["EPTB proportion", "15% of all TB cases (range 8–24%)"],
        ["HIV coinfection", "~9% of new cases"],
        ["MDR/RR-TB new cases/year", "~500,000"],
        ["GI TB (% of EPTB)", "15–25% of EPTB; ileocecal region most common (64%)"],
        ["CNS TB (% of EPTB)", "~5% in USA"],
    ]
    tbl = drug_table(epid_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in epid_data[1:]
    ], col_w=[8*cm, 8*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(info_box("EPTB Most Common Sites (in order)", [
        "Lymphatic nodes",
        "Pleura",
        "Skeletal system",
        "Genitourinary tract",
        "Gastrointestinal tract",
        "Central nervous system",
    ]))
    e.append(sp(8))
    e.append(info_box("Risk Factors for TB Reactivation / EPTB", [
        "HIV infection (CD4 <200 cells/mm³ = greatest risk)",
        "Diabetes mellitus, malignancies, renal impairment",
        "TNF-α antagonists (infliximab, etanercept) — screen before starting",
        "Corticosteroids ≥15 mg/day prednisone for ≥1 month",
        "Malnutrition, hypoalbuminaemia",
        "Birth/residence in high-incidence country (>100/100,000/yr)",
        "Homelessness, incarceration, close contact with infectious case",
        "Female gender, younger age, certain bacterial genotypes (for EPTB)",
    ]))
    return e

# ── Section 2: Pulmonary TB ──────────────────────────────────────────────────

def section2():
    e = []
    e.append(PageBreak())
    e.append(section_header("2. PULMONARY TUBERCULOSIS"))
    e.append(sp(8))

    e.append(p("<b>2.1 Pathogenesis and Disease Spectrum</b>", sH2))
    e.append(p("After initial infection, the outcome depends on the host immune response. The spectrum ranges from bacterial elimination to active disease. The Mantoux and IGRA tests cannot distinguish latent from active disease — clinical, microbiological, and radiological assessment is required."))
    e.append(sp(6))

    spectrum_data = [
        [Paragraph("<b>Stage</b>", sLabel), Paragraph("<b>TST/IGRA</b>", sLabel), Paragraph("<b>Culture</b>", sLabel), Paragraph("<b>Symptoms</b>", sLabel), Paragraph("<b>Infectious</b>", sLabel)],
        ["Uninfected", "Negative", "Negative", "None", "No"],
        ["Latent TB infection", "Positive", "Negative", "None", "No"],
        ["Subclinical disease", "Positive", "Intermittent +ve", "Mild or none", "Sporadically"],
        ["Active TB disease", "Usually positive", "Positive", "Mild to severe", "Yes"],
    ]
    tbl = drug_table(spectrum_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(5)] for r in spectrum_data[1:]
    ], col_w=[3.5*cm, 2.8*cm, 2.8*cm, 3*cm, 2.4*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>2.2 Clinical Features</b>", sH2))
    e.append(p("<b>Symptoms:</b>"))
    for item in [
        "Persistent cough — productive or nonproductive (most common; absent in up to 25% of culture-confirmed cases)",
        "Fever, chills, night sweats, weight loss",
        "Haemoptysis — occurs in advanced cavitary disease",
        "Fatigue, anorexia, malaise",
    ]:
        e.append(b(item))
    e.append(sp(4))
    e.append(p("<b>Physical examination:</b>"))
    for item in [
        "Post-tussive rales in upper lung zones",
        "Amphoric breath sounds — indicates a cavity",
        "Lymphadenopathy — uncommon in immunocompetent adults (common in primary TB of children)",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>2.3 Chest Radiology</b>", sH2))
    radio_data = [
        [Paragraph("<b>Type</b>", sLabel), Paragraph("<b>Radiological Features</b>", sLabel)],
        ["Primary TB", "Parenchymal consolidation (any lobe), hilar/paratracheal lymphadenopathy, pleural effusion; Ghon focus + Ranke complex"],
        ["Post-primary (Reactivation)", "Upper lobe predominance, cavitation, fibrosis, volume loss, bronchogenic spread"],
        ["Miliary TB", "Diffuse 1–2 mm 'millet-seed' nodules bilaterally — haematogenous spread"],
        ["TB Pleuritis", "Unilateral exudative pleural effusion; often without parenchymal changes"],
    ]
    tbl = drug_table(radio_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in radio_data[1:]
    ], col_w=[4.5*cm, 12*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>2.4 TB Pleuritis</b>", sH2))
    e.append(p("TB pleuritis results from a <b>type IV (delayed) hypersensitivity reaction</b> triggered by release of TB antigens from rupture of subpleural disease into the pleural space. Fulminant TB empyema (direct infection) is much rarer."))
    e.append(sp(4))
    for item in [
        "Pleural fluid: exudative, predominantly lymphocytic",
        "10% of patients develop restrictive spirometric defects after a median 23 months follow-up",
        "Corticosteroids: may improve residual pleural changes on CXR but do <b>not</b> improve long-term respiratory function and increase adverse events (Cochrane)",
        "Early pleural drainage may reduce breathlessness and limit lung function impairment at 12 months",
    ]:
        e.append(b(item))
    return e

# ── Section 3: Abdominal TB ──────────────────────────────────────────────────

def section3():
    e = []
    e.append(PageBreak())
    e.append(section_header("3. ABDOMINAL TUBERCULOSIS"))
    e.append(sp(8))
    e.append(p("Abdominal TB encompasses three main compartments: <b>gastrointestinal (intestinal) TB</b>, <b>peritoneal TB</b>, and <b>lymph node TB</b>. GI TB accounts for 3.5% of EPTB in the USA."))
    e.append(sp(8))

    # 3.1 Intestinal TB
    e.append(p("<b>3.1 Gastrointestinal (Intestinal) Tuberculosis</b>", sH2))
    e.append(p("<b>Sites of involvement (% of GI TB cases):</b>"))
    sites_data = [
        [Paragraph("<b>Site</b>", sLabel), Paragraph("<b>Frequency</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["Ileocecal region", "64% (most common)", "Terminal ileum + cecum; produces obstructive picture"],
        ["Jejunum", "Next most common", "Proximal lesions are rare"],
        ["Colon", "Less common", "Colonic TB can mimic malignancy"],
        ["Mouth to anus", "Any site possible", "Lesions proximal to terminal ileum are unusual"],
    ]
    tbl = drug_table(sites_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in sites_data[1:]
    ], col_w=[4*cm, 4*cm, 8.5*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>Pathogenesis routes:</b>"))
    for item in [
        "Swallowing of infected sputum (direct mucosal seeding) — primary route in pulmonary TB",
        "Haematogenous spread",
        "Lymphatic spread",
        "Direct spread from adjacent structures (lymph nodes, fallopian tubes, Pott's disease)",
        "<i>M. bovis</i> from unpasteurised dairy products (developing nations)",
    ]:
        e.append(b(item))
    e.append(sp(6))

    e.append(p("<b>Clinical Features:</b>"))
    e.append(p("Only 15–25% of GI TB cases have concomitant pulmonary TB."))
    for item in [
        "Abdominal pain + GI obstruction — most common presentation",
        "Fever, nausea, diarrhoea, weight loss, anorexia",
        "GI bleeding",
        "Palpable mass in the ileocecal region",
        "Can mimic <b>Crohn's disease</b>, acute appendicitis, or colorectal carcinoma",
    ]:
        e.append(b(item))
    e.append(sp(6))

    e.append(p("<b>Differential Diagnosis of Intestinal TB:</b>", sH3))
    dd_items = [
        "Crohn's disease (key mimic — granulomas are noncaseating, <400 μm, poorly organised)",
        "Acute appendicitis",
        "Malignancies (lymphoma, carcinoma)",
        "NSAIDs-related enteropathy",
        "Sarcoidosis, Amyloidosis",
        "Salmonellosis, Yersiniosis, CMV, Histoplasmosis",
        "MAC (M. avium complex) enteritis — especially in HIV",
        "Actinomycosis, Anisakiasis, Typhlitis, Eosinophilic enteritis",
        "Whipple's disease, Vasculitides, Ischaemia",
    ]
    e.append(info_box("Differential Diagnosis of Intestinal TB", dd_items, bg=HexColor("#FFF5E6"), border=C_AMBER))
    e.append(sp(8))

    e.append(p("<b>Diagnosis:</b>"))
    for item in [
        "AFB smear of tissue (Ziehl-Neelsen) — positive in only ~3% of proven cases",
        "AFB culture — gold standard but takes 4–8 weeks; <40% of patients have positive cultures",
        "Endoscopic biopsy: caseating granulomas on histology",
        "PCR / Xpert MTB/RIF: sensitivity 50–100%, specificity 62–97% (further validation needed)",
        "CD4+ T-cell activation markers (CD38, HLA-DR, Ki67+) — emerging tools to differentiate active from latent and EPTB from pulmonary TB",
    ]:
        e.append(b(item))
    e.append(sp(10))

    # 3.2 Peritoneal TB
    e.append(p("<b>3.2 Peritoneal Tuberculosis (TB Peritonitis)</b>", sH2))
    e.append(p("M. tuberculosis enters the peritoneal space from adjacent lymph nodes. Active pulmonary TB is <b>uncommon</b> in patients with TB peritonitis. Frequently coexists with cirrhosis, which may mask TB symptoms."))
    e.append(sp(6))

    e.append(p("<b>Clinical Features:</b>"))
    for item in [
        "Subacute abdominal pain, anorexia, abdominal swelling",
        "Systemic symptoms: fever, night sweats, weight loss",
        "Combination of fever + abdominal tenderness in a patient with ascites → ALWAYS perform paracentesis",
        "Can mimic an acute abdomen",
        "Intra-abdominal lymphadenopathy visible on CT scan",
    ]:
        e.append(b(item))
    e.append(sp(6))

    e.append(p("<b>Ascitic Fluid Analysis in TB Peritonitis:</b>", sH3))
    ascites_data = [
        [Paragraph("<b>Parameter</b>", sLabel), Paragraph("<b>Finding</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["Character", "Exudative", "High protein, low SAAG (<1.1 g/dL) in non-cirrhotic"],
        ["WBC count", "50–10,000 cells/μL", "Predominantly lymphocytes; PMNs may predominate early"],
        ["AFB smear", "Rarely positive (~3%)", "Low yield; do not rely on smear alone"],
        ["AFB culture", "~50% positive", "Yield increases with large-volume submission"],
        ["SAAG", "<1.1 g/dL (non-cirrhotic)", "In cirrhotic patients SAAG may be >1.1 (cirrhosis dominates)"],
        ["ADA (ascitic fluid)", "≥39 IU/L = positive", "Sensitivity 93–100%, specificity 96–97% (optimal cut-off 39 IU/L)"],
        ["Laparoscopy", "Best test", "Characteristic visual findings + biopsy + histology + culture"],
    ]
    tbl = drug_table(ascites_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in ascites_data[1:]
    ], col_w=[3.5*cm, 5*cm, 8*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(warn_box("In cirrhotic patients, ADA may be less sensitive for TB peritonitis (high SAAG dominates the ascitic picture). Laparoscopy with biopsy remains the gold standard."))
    return e

# ── Section 4: TBM ───────────────────────────────────────────────────────────

def section4():
    e = []
    e.append(PageBreak())
    e.append(section_header("4. TUBERCULOUS MENINGITIS (TBM)"))
    e.append(sp(8))

    e.append(p("TB of the CNS accounts for ~5% of EPTB in the USA. Peak incidence: neonates to 4-year-old children; also significant in adults (especially HIV-infected). If unrecognised, TBM is uniformly fatal."))
    e.append(sp(8))

    e.append(p("<b>4.1 Pathogenesis</b>", sH2))
    e.append(p("TBM results from two sequential events:"))
    for item in [
        "<b>Step 1:</b> Haematogenous seeding of meninges and subpial regions → formation of subependymal tubercles",
        "<b>Step 2:</b> Rupture of one or more tubercles → discharge of bacteria into the subarachnoid space",
        "When complicating miliary TB, meningitis develops within weeks of infection",
        "In children, TBM is an early post-primary event (usually within 6 months)",
    ]:
        e.append(b(item))
    e.append(sp(6))

    e.append(p("<b>Pathological Findings:</b>", sH3))
    for item in [
        "Thick gelatinous exudate at base of brain — obliterates pontine and interpeduncular cisterns",
        "Extends to floor of 3rd ventricle, optic chiasm, undersurfaces of temporal lobes",
        "Microscopically: central caseation + epithelioid cells + Langhans giant cells + lymphocytes + plasma cells",
        "Cranial nerve involvement as they traverse the subarachnoid space",
        "Arteritis → brain infarction (basal ganglia lacunar infarcts; MCA → hemiparesis)",
        "Blockage of basal cisterns → obstructive hydrocephalus",
        "True meningoencephalitis — disease penetrates pia and ependyma into brain parenchyma",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>4.2 Clinical Features</b>", sH2))
    e.append(p("<b>Key distinguishing feature:</b> symptoms evolve over <b>1–2 weeks</b> — much more insidious than acute bacterial meningitis."))
    e.append(sp(4))

    clin_data = [
        [Paragraph("<b>Stage</b>", sLabel), Paragraph("<b>Features</b>", sLabel)],
        ["Prodrome\n(Days–weeks)", "Low-grade fever; malaise; headache (>50%); lethargy; confusion; stiff neck (75%); Kernig and Brudzinski signs"],
        ["Intermediate", "Cranial nerve palsies — ocular (most common), facial, deafness (20% at diagnosis); papilloedema; diplopia (up to 70%); hyponatraemia (SIADH is common)"],
        ["Late / Severe", "Focal neurologic deficits from haemorrhagic infarction; signs of raised ICP; coma; hydrocephalus"],
        ["Children/Infants", "Apathy, hyperirritability, vomiting, seizures; stiff neck may be absent"],
    ]
    tbl = drug_table(clin_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in clin_data[1:]
    ], col_w=[4*cm, 12.5*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(warn_box("In ~2/3 of TBM patients, evidence of active TB is found elsewhere (usually lungs; occasionally small bowel, bone, kidney, or ear). Always obtain CXR and sputum AFB in suspected TBM."))
    e.append(sp(8))

    e.append(p("<b>4.3 CSF Findings in TBM</b>", sH2))
    csf_data = [
        [Paragraph("<b>Parameter</b>", sLabel), Paragraph("<b>Finding in TBM</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["Opening pressure", "Elevated", "Hydrocephalus common"],
        ["Appearance", "Clear / slightly turbid / xanthochromic", "May be turbid in severe disease"],
        ["WBC count", "Up to 1000–1500 cells/μL", "Lymphocyte predominance; PMNs may predominate early"],
        ["Protein", "Elevated: 1–8 g/L (100–800 mg/dL)", "Markedly elevated protein is typical"],
        ["Glucose", "Low (typically)", "CSF:serum glucose ratio <0.5; any of 3 parameters can be normal"],
        ["AFB smear", "Infrequently positive", "Repeated LPs increase yield; use large volume"],
        ["AFB culture", "Positive in up to 80%", "Gold standard; takes 4–8 weeks"],
        ["Xpert MTB/RIF", "Sensitivity up to 80%", "Preferred initial molecular test; negative does not exclude TB"],
        ["ADA", "Elevated", "Elevated in CSF; supports diagnosis"],
    ]
    tbl = drug_table(csf_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in csf_data[1:]
    ], col_w=[3.5*cm, 5.5*cm, 7.5*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>4.4 Neuroradiology — Classic Triad on CT/MRI</b>", sH2))
    for item in [
        "<b>Basal meningeal enhancement</b> (gadolinium-enhanced MRI/CT) — thick gelatinous exudate at base of brain",
        "<b>Hydrocephalus</b> — obstructive, from blockage of basal cisterns",
        "<b>Cerebral or brainstem infarction</b> — from arteritis of vessels traversing the exudate",
    ]:
        e.append(b(item))
    e.append(sp(4))
    e.append(p("CT/MRI may also show rounded, contrast-enhancing ring lesions = tuberculomas."))
    e.append(sp(8))

    e.append(p("<b>4.5 Tuberculoma</b>", sH2))
    e.append(p("Tumour-like masses of tuberculous granulation tissue (2–12 mm) in brain parenchyma. In the USA, rare; in developing countries they constitute 5–30% of all intracranial mass lesions."))
    e.append(sp(4))
    for item in [
        "CT/MRI: contrast-enhanced ring lesions — biopsy required for definitive diagnosis",
        "CSF: small lymphocytosis, elevated protein, <b>normal glucose</b> (serous meningitis pattern — key difference from TBM)",
        "Responds to standard anti-TB chemotherapy; surgery if mass effect persists or no radiological response",
        "Cerebellar tuberculomas are the most frequent intracranial tumours in children in some tropical countries",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>4.6 Prognosis</b>", sH2))
    prog_data = [
        [Paragraph("<b>Population</b>", sLabel), Paragraph("<b>Mortality</b>", sLabel), Paragraph("<b>Residual Sequelae</b>", sLabel)],
        ["Overall CNS TB", "~10%", "20–30% of survivors: cognitive deficits, seizures, cranial nerve palsies, hemiparesis"],
        ["HIV-infected patients", "~21%", "Higher due to diagnosis delays and drug resistance"],
        ["Diagnosed late (coma)", "~50%", "Near-complete mortality when treatment starts in coma"],
    ]
    tbl = drug_table(prog_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in prog_data[1:]
    ], col_w=[5*cm, 4*cm, 7.5*cm])
    e.append(tbl)
    return e

# ── Section 5: Diagnosis ─────────────────────────────────────────────────────

def section5():
    e = []
    e.append(PageBreak())
    e.append(section_header("5. DIAGNOSIS SUMMARY"))
    e.append(sp(8))

    diag_data = [
        [Paragraph("<b>Test</b>", sLabel),
         Paragraph("<b>Pulmonary TB</b>", sLabel),
         Paragraph("<b>Abdominal/Peritoneal TB</b>", sLabel),
         Paragraph("<b>TB Meningitis</b>", sLabel)],
        ["TST / IGRA", "Positive (active); positive (latent)", "Positive", "Positive"],
        ["AFB smear", "+ve or –ve (sputum)", "Rarely +ve (ascitic fluid ~3%)", "Rarely +ve (CSF)"],
        ["AFB culture", "Gold standard; sputum", "~50% ascitic fluid; best from laparoscopic biopsy", "Up to 80% CSF; gold standard"],
        ["Xpert MTB/RIF", "Preferred initial test", "Equivocal for peritoneal TB", "Sensitivity up to 80%; preferred initial molecular test"],
        ["ADA", "Pleural fluid (high sensitivity)", "Ascitic fluid ≥39 IU/L (sens 100%, spec 97%)", "Elevated in CSF"],
        ["Imaging", "CXR: cavitation, upper lobe disease, miliary", "CT: LAD, omental thickening, ascites", "CT/MRI: basal enhancement, hydrocephalus, infarction"],
        ["Laparoscopy / LP", "Bronchoscopy BAL for difficult cases", "Best test for peritoneal TB (visual + biopsy)", "LP is cornerstone of diagnosis"],
        ["Histology", "BAL or biopsy: caseating granulomas", "Caseating granulomas on biopsy", "CSF: lymphocytosis, high protein, low glucose"],
    ]
    tbl = drug_table(diag_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in diag_data[1:]
    ], col_w=[3*cm, 4*cm, 5.5*cm, 4*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>Tuberculin Skin Test (TST) Cut-offs for Positivity:</b>", sH3))
    tst_data = [
        [Paragraph("<b>Induration</b>", sLabel), Paragraph("<b>Positive in:</b>", sLabel)],
        ["≥5 mm", "HIV-infected persons; recent TB contacts; fibrotic CXR changes; organ transplant or immunosuppressed patients"],
        ["≥10 mm", "High-risk medical conditions; healthcare workers; immigrants from high-incidence countries; children <4 years; residents of high-risk facilities"],
        ["≥15 mm", "Persons with no known risk factors for TB"],
    ]
    tbl = drug_table(tst_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in tst_data[1:]
    ], col_w=[3*cm, 13.5*cm])
    e.append(tbl)
    return e

# ── Section 6: Treatment DS-TB ───────────────────────────────────────────────

def section6():
    e = []
    e.append(PageBreak())
    e.append(section_header("6. TREATMENT — DRUG-SUSCEPTIBLE TB (DS-TB)"))
    e.append(sp(8))

    e.append(p("<b>6.1 Standard 6-Month Regimen (Classic — Still Preferred for Certain Groups)</b>", sH2))
    std_data = [
        [Paragraph("<b>Phase</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Notation</b>", sLabel)],
        ["Intensive", "2 months", "Isoniazid (H) + Rifampin (R) + Pyrazinamide (Z) + Ethambutol (E)", "2HRZE"],
        ["Continuation", "4 months", "Isoniazid (H) + Rifampin (R)", "4HR"],
    ]
    tbl = drug_table(std_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in std_data[1:]
    ], col_w=[2.5*cm, 2.5*cm, 9*cm, 2.5*cm])
    e.append(tbl)
    e.append(sp(4))
    e.append(p("Global treatment success rate: <b>85%</b> (range 76–91%). Patients at higher risk of relapse: treat up to <b>9 months</b>."))
    e.append(sp(8))

    e.append(p("<b>6.2 NEW: 4-Month Regimen (2025 WHO + ATS/CDC/ERS/IDSA Update)</b>", sH2))
    e.append(p("Based on the pivotal <b>TBTC Study 31/ACTG A5349</b> phase 3 RCT (Dorman et al., NEJM 2021), the 4-month regimen is now endorsed as non-inferior to 6 months for eligible patients."))
    e.append(sp(6))
    new_data = [
        [Paragraph("<b>Phase</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Notation</b>", sLabel)],
        ["Intensive", "2 months", "Isoniazid (H) + Rifapentine (P) + Moxifloxacin (M) + Pyrazinamide (Z)", "2HPMZ"],
        ["Continuation", "2 months", "Isoniazid (H) + Rifapentine (P) + Moxifloxacin (M)", "2HPM"],
    ]
    tbl = drug_table(new_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in new_data[1:]
    ], col_w=[2.5*cm, 2.5*cm, 9*cm, 2.5*cm])
    e.append(tbl)
    e.append(sp(6))

    e.append(info_box("4-Month Regimen — Key Changes vs. Standard", [
        "Ethambutol REPLACED by Moxifloxacin (fluoroquinolone)",
        "Rifampin REPLACED by Rifapentine (longer half-life, more potent rifamycin)",
        "Fixed doses: Rifapentine 1200 mg daily + Moxifloxacin 400 mg daily (7 days/week)",
        "Total duration: 4 months (down from 6 months)",
    ], bg=HexColor("#EBF5EB"), border=C_GREEN))
    e.append(sp(6))

    e.append(p("<b>Trial Evidence (Study 31/A5349):</b>"))
    for item in [
        "Non-inferiority demonstrated in adults + adolescents ≥12 years",
        "Cure rate: 84.5%; Retention on treatment: 99.7%; All-cause mortality: 0.4%",
        "Grade 3+ adverse events: 18.8% (4-month) vs. 19.3% (6-month) — similar safety profiles",
    ]:
        e.append(b(item))
    e.append(sp(6))

    eligible_tbl = Table([
        [
            Paragraph("<b>✓ Eligible for 4-month regimen</b>", make_style("_eg", fontSize=9, fontName="Helvetica-Bold", textColor=C_GREEN, leading=13)),
            Paragraph("<b>✗ NOT eligible — use 6-month regimen</b>", make_style("_ieg", fontSize=9, fontName="Helvetica-Bold", textColor=C_RED, leading=13)),
        ],
        [
            "\n".join([f"• {x}" for x in [
                "Adults and adolescents ≥12 years",
                "Smear and culture-positive pulmonary DS-TB",
                "PLHIV with CD4 ≥100 cells/mm³ (with caution)",
            ]]),
            "\n".join([f"• {x}" for x in [
                "PLHIV with CD4 <100 cells/mm³",
                "Children <12 years",
                "Pregnant, breastfeeding, postpartum women",
                "Does not meet S31/A5349 eligibility criteria",
            ]]),
        ]
    ], colWidths=[(W - 4*cm)/2]*2)
    eligible_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (0,0), HexColor("#EBF5EB")),
        ("BACKGROUND",    (1,0), (1,0), HexColor("#FDEDEC")),
        ("BACKGROUND",    (0,1), (0,1), HexColor("#EBF5EB")),
        ("BACKGROUND",    (1,1), (1,1), HexColor("#FDEDEC")),
        ("FONTSIZE",      (0,0), (-1,-1), 8.5),
        ("LEADING",       (0,0), (-1,-1), 13),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
        ("GRID",          (0,0), (-1,-1), 0.5, HexColor("#CCCCCC")),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    e.append(eligible_tbl)
    e.append(sp(8))

    e.append(p("<b>6.3 Drug Dosing and Side Effects</b>", sH2))
    drug_data = [
        [Paragraph("<b>Drug</b>", sLabel), Paragraph("<b>Adult Dose</b>", sLabel), Paragraph("<b>Children Dose</b>", sLabel), Paragraph("<b>Key Side Effects / Notes</b>", sLabel)],
        ["Isoniazid (H)", "5 mg/kg/day (single dose)", "10 mg/kg/day", "Peripheral neuropathy (give pyridoxine 50 mg/day prophylactically); hepatitis (esp. in alcoholics); lupus-like syndrome. Most effective single drug."],
        ["Rifampin (R)", "10 mg/kg/day", "15 mg/kg/day", "Hepatitis; orange discolouration of secretions (warn patients); potent P450 inducer (↓ many drugs including ART); flu-like syndrome"],
        ["Rifapentine (P)", "1200 mg/day (fixed)", "Weight-based", "Similar to rifampin; longer half-life; used in 4-month DS-TB regimen and weekly LTBI regimen (3HP)"],
        ["Pyrazinamide (Z)", "20–35 mg/kg/day", "Same range", "Hepatitis; hyperuricaemia (monitor uric acid); rash; GI upset; arthralgias"],
        ["Ethambutol (E)", "15 mg/kg/day", "15 mg/kg/day", "Optic neuropathy — monitor visual acuity + red-green colour discrimination regularly. Avoid doses >20 mg/kg. Risk ↑ in renal failure."],
        ["Moxifloxacin (M)", "400 mg/day", "Limited data", "QT prolongation (ECG monitoring required; avoid with other QT-prolonging drugs); tendinopathy; used in 4-month DS-TB and DR-TB regimens"],
        ["Pyridoxine (B6)", "50 mg/day (with INH)", "25 mg/day", "Prevents INH-induced peripheral neuropathy. Give to ALL patients on isoniazid (especially pregnant women, alcoholics, diabetics, elderly, malnourished)"],
        ["Ethionamide (Eto)", "15–25 mg/kg/day (divided, after meals)", "Same", "GI irritation (take after meals); optic neuropathy; hepatitis; metallic taste. Used in MDR-TB as 5th drug if needed."],
    ]
    tbl = drug_table(drug_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in drug_data[1:]
    ], col_w=[3*cm, 3*cm, 2.8*cm, 7.7*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(warn_box("INH and rifampin can be given parenterally. All other first-line drugs are oral/NG tube only. Monitor LFTs monthly — discontinue INH if symptomatic hepatitis or LFTs >3–5× ULN."))
    return e

# ── Section 7: DR-TB ─────────────────────────────────────────────────────────

def section7():
    e = []
    e.append(PageBreak())
    e.append(section_header("7. DRUG-RESISTANT TB TREATMENT — WHO 2025 GUIDELINES"))
    e.append(sp(8))

    e.append(p("<b>7.1 Definitions</b>", sH2))
    def_data = [
        [Paragraph("<b>Classification</b>", sLabel), Paragraph("<b>Resistance Pattern</b>", sLabel)],
        ["Isoniazid-resistant TB (Hr-TB)", "Resistant to isoniazid; rifampicin-susceptible"],
        ["RR-TB", "Rifampicin-resistant (any pattern including monoresistance)"],
        ["MDR-TB", "Resistant to BOTH isoniazid + rifampicin"],
        ["Pre-XDR-TB", "MDR/RR-TB + resistance to any fluoroquinolone (levofloxacin or moxifloxacin)"],
        ["XDR-TB", "MDR/RR-TB + resistance to any fluoroquinolone + ≥1 of bedaquiline OR linezolid"],
    ]
    tbl = drug_table(def_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in def_data[1:]
    ], col_w=[5.5*cm, 11*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>7.2 Recommended Regimens — Three Tiers (WHO 2025)</b>", sH2))

    e.append(p("<b>TIER 1 (Preferred): 6-Month All-Oral Regimens</b>", sH3))
    e.append(p("For MDR/RR-TB with fluoroquinolone susceptibility — two options:"))
    tier1_data = [
        [Paragraph("<b>Regimen</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Trial Basis</b>", sLabel)],
        ["BPaLM", "Bedaquiline + Pretomanid + Linezolid + Moxifloxacin", "6 months", "TB-PRACTECAL (Lancet, 2024); ZeNix trial"],
        ["BDLLfxC ★NEW 2025", "Bedaquiline + Delamanid + Linezolid + Levofloxacin + Clofazimine", "6 months", "BEAT-TB; endTB trials (2025 addition)"],
    ]
    tbl = drug_table(tier1_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in tier1_data[1:]
    ], col_w=[2.5*cm, 7.5*cm, 2.5*cm, 4*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(p("For pre-XDR-TB (fluoroquinolone-resistant):"))
    tier1b_data = [
        [Paragraph("<b>Regimen</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["BPaL", "Bedaquiline + Pretomanid + Linezolid", "6 months", "Preferred for pre-XDR-TB; ZeNix/TB-PRACTECAL"],
        ["BDLC", "Bedaquiline + Delamanid + Linezolid + Clofazimine", "6 months", "Alternative for pre-XDR-TB"],
    ]
    tbl = drug_table(tier1b_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in tier1b_data[1:]
    ], col_w=[2.5*cm, 7.5*cm, 2.5*cm, 4*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(info_box("Extension to 9 months is permitted for:", [
        "Severe or extensive disease (bilateral cavitary disease, extensive parenchymal involvement)",
        "Immunosuppression (HIV with low CD4, organ transplant, immunosuppressive therapy)",
        "Poor early response or slow culture conversion",
    ], bg=C_MINT, border=C_TEAL))
    e.append(sp(6))

    e.append(p("<b>TIER 2: 9-Month All-Oral Regimens</b>", sH3))
    e.append(p("For MDR/RR-TB when <b>fluoroquinolone resistance is excluded</b>. As of end 2024, <b>99 countries</b> were using 9-month regimens (small decrease from 103 in 2023 as 6-month adoption accelerates)."))
    e.append(sp(4))
    tier2_data = [
        [Paragraph("<b>Standard 9-month regimen (modified)</b>", sLabel), Paragraph("<b>Composition</b>", sLabel)],
        ["Modified all-oral 9-month", "Bedaquiline + Levofloxacin/Moxifloxacin + Ethionamide/Prothionamide + Pyrazinamide + Clofazimine + Isoniazid (high-dose) + Ethambutol\n(4–6 months intensive, 5 months continuation)"],
    ]
    tbl = drug_table(tier2_data[0], [
        [Paragraph(str(r[0]), sBody), Paragraph(str(r[1]), sBody)] for r in tier2_data[1:]
    ], col_w=[6*cm, 10.5*cm])
    e.append(tbl)
    e.append(sp(6))

    e.append(p("<b>TIER 3 (Last Resort): 18–20 Month Individualized Regimens</b>", sH3))
    for item in [
        "For XDR-TB or patients with intolerance to bedaquiline and/or linezolid",
        "Regimen designed by expert clinicians based on full drug susceptibility testing (DST)",
        "May include injectable agent (amikacin) — last-resort injectable",
        "Guided by WHO Group A/B/C drug classification",
        "Treatment cost: USD 200–600 per person (vs. ~USD 50 for first-line DS-TB)",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>7.3 Drug Abbreviation Key</b>", sH2))
    abbr_data = [
        [Paragraph("<b>Letter</b>", sLabel), Paragraph("<b>Drug</b>", sLabel),
         Paragraph("<b>Letter</b>", sLabel), Paragraph("<b>Drug</b>", sLabel)],
        ["B", "Bedaquiline", "Pa", "Pretomanid"],
        ["L", "Linezolid", "M", "Moxifloxacin"],
        ["D", "Delamanid", "Lfx", "Levofloxacin"],
        ["C", "Clofazimine", "H", "Isoniazid"],
        ["R", "Rifampicin", "Z", "Pyrazinamide"],
        ["E", "Ethambutol", "P", "Rifapentine"],
        ["S", "Streptomycin", "Am", "Amikacin"],
    ]
    tbl = drug_table(abbr_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in abbr_data[1:]
    ], col_w=[2*cm, 5.5*cm, 2*cm, 5.5*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>7.4 Key Trial Evidence for BPaLM</b>", sH2))
    e.append(p("<b>TB-PRACTECAL (Lancet Respir Med, 2024) — PMID 37980911:</b>"))
    e.append(p("Phase 2B-3 open-label RCT; 7 sites; Uzbekistan, Belarus, South Africa; n=552 enrolled; rifampicin-resistant pulmonary TB."))
    trial_data = [
        [Paragraph("<b>Outcome at 72 weeks</b>", sLabel), Paragraph("<b>BPaLM (n=138)</b>", sLabel), Paragraph("<b>Standard Care (n=137)</b>", sLabel), Paragraph("<b>p-value</b>", sLabel)],
        ["Unfavourable composite outcome", "12% (16/137)", "41% (56/137)", "<0.0001"],
        ["Grade 3+ or serious adverse events", "23%", "48%", "Sig. different"],
        ["Deaths by week 72", "0", "5", "—"],
        ["Early treatment discontinuation", "NNT = 8", "—", "—"],
    ]
    tbl = drug_table(trial_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in trial_data[1:]
    ], col_w=[6*cm, 3.5*cm, 3.5*cm, 3.5*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(p("<b>BPaLM Systematic Review (Silva et al., J Bras Pneumol, 2025) — PMID 39813501:</b>"))
    for item in [
        "BPaLM reduced risk of unfavourable composite outcome vs. standard of care (NNT = 7)",
        "Reduced early treatment discontinuation (NNT = 8)",
        "Reduced serious adverse events (NNT = 5)",
        "Conclusion: BPaLM is more effective AND safer than standard of care",
        "Quality of evidence: Only 1 RCT met inclusion criteria — further evidence needed",
    ]:
        e.append(b(item))
    e.append(sp(6))

    # Rapid adoption stats
    adopt_data = [
        [Paragraph("<b>Year</b>", sLabel), Paragraph("<b>Countries using 6-month MDR regimens</b>", sLabel), Paragraph("<b>People started on 6-month regimens</b>", sLabel)],
        ["2022", "41", "1,744"],
        ["2023", "60", "5,653"],
        ["2024", "97", "34,256 (~6× increase from 2023)"],
    ]
    tbl = drug_table(adopt_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in adopt_data[1:]
    ], col_w=[2.5*cm, 8*cm, 6*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(p("Source: WHO Global TB Report 2025 (data as of 30 July 2025).", sSmall))
    return e

# ── Section 8: Special Situations ───────────────────────────────────────────

def section8():
    e = []
    e.append(PageBreak())
    e.append(section_header("8. TREATMENT — SPECIAL SITUATIONS"))
    e.append(sp(8))

    e.append(p("<b>8.1 TB Meningitis Treatment</b>", sH2))
    tbm_trt_data = [
        [Paragraph("<b>Phase</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["Intensive", "2 months", "HRZE (Isoniazid + Rifampin + Pyrazinamide + Ethambutol)", "All 4 drugs; alternative: INH + PZA + high-dose RMP + Moxifloxacin"],
        ["Continuation", "7–10 months", "HR (Isoniazid + Rifampin)", "Total duration 9–12 months"],
    ]
    tbl = drug_table(tbm_trt_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in tbm_trt_data[1:]
    ], col_w=[2.5*cm, 2.5*cm, 7*cm, 4.5*cm])
    e.append(tbl)
    e.append(sp(6))
    e.append(p("<b>CNS drug penetration (best to least):</b> INH &gt; PZA &gt; Rifampin &gt; Ethambutol"))
    e.append(sp(4))
    e.append(p("<b>Adjunctive Dexamethasone (WHO-recommended for TBM):</b>"))
    for item in [
        "IV dexamethasone 0.4 mg/kg/day — taper by 0.1 mg/kg/week until week 4, then 0.1 mg/kg/day",
        "Followed by oral dexamethasone 4 mg/day — taper by 1 mg/week over 4 weeks",
        "Total: 6–8 week tapering course",
        "Evidence: Reduces mortality from 41% to 32% (Thwaites et al., Vietnam RCT) — no reduction in neurological sequelae",
        "CAUTION: A recent placebo-controlled trial showed <b>NO benefit in PLHIV</b> from adjunctive dexamethasone",
    ]:
        e.append(b(item))
    e.append(sp(4))
    e.append(warn_box("Dexamethasone is recommended for non-HIV TBM. Avoid or use with caution in HIV-infected patients based on the most recent evidence. Always use only in conjunction with anti-TB drugs."))
    e.append(sp(8))

    e.append(p("<b>8.2 TB-HIV Coinfection</b>", sH2))
    for item in [
        "Start ART in <b>ALL</b> TB-HIV patients regardless of CD4 count (2025 WHO expansion)",
        "Preferred DS-TB regimen when CD4 <100 cells/mm³: Standard 6-month 2HRZE/4HR (NOT the 4-month regimen)",
        "TB-IRIS (Immune Reconstitution Inflammatory Syndrome): occurs in 5–50% starting ART; paradoxical worsening or unmasking of TB",
        "CNS TB-IRIS is associated with high morbidity and mortality",
        "Rifampin is a potent CYP3A4 inducer — reduce lopinavir/ritonavir dose or use efavirenz-based ART; consider rifabutin as a substitute",
        "Drug-resistant TB in PLHIV: beware of pharmacokinetic interactions with bedaquiline + ART",
        "Mortality from TBM in HIV ~21% vs. ~10% overall — largely from delayed diagnosis and drug resistance",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>8.3 TB in Pregnancy</b>", sH2))
    for item in [
        "<b>4-month rifapentine-moxifloxacin regimen is CONTRAINDICATED</b> — pregnant women were excluded from S31/A5349",
        "Use standard 6-month 2HRZE/4HR",
        "Avoid: Streptomycin (ototoxic to fetus), fluoroquinolones (teratogenicity concerns), ethionamide (teratogenic in animals)",
        "Pyrazinamide: some guidelines avoid in 1st trimester; WHO recommends including it",
        "Isoniazid: safe in pregnancy; increase pyridoxine to 25–50 mg/day",
        "Rifampin: safe; may cause haemorrhagic disease of the newborn (give vitamin K at delivery)",
        "Breastfeeding: compatible with all first-line drugs at standard doses",
        "ART + anti-TB in pregnant HIV+ women: manage drug interactions carefully",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>8.4 Isoniazid-Resistant TB (Hr-TB)</b>", sH2))
    for item in [
        "Do NOT use INH-containing regimens — replace INH with a fluoroquinolone",
        "WHO-recommended: Rifampicin + Pyrazinamide + Ethambutol + Levofloxacin for 6 months (RZELfx)",
        "If fluoroquinolone resistance also present: individualized regimen",
        "DST before starting therapy: essential for all new TB patients in high-burden settings",
    ]:
        e.append(b(item))
    e.append(sp(8))

    e.append(p("<b>8.5 Latent TB Infection (LTBI) Treatment Options</b>", sH2))
    ltbi_data = [
        [Paragraph("<b>Regimen</b>", sLabel), Paragraph("<b>Drugs</b>", sLabel), Paragraph("<b>Duration</b>", sLabel), Paragraph("<b>Notes</b>", sLabel)],
        ["6H", "Isoniazid daily", "6 months", "Classic; widely used; 90% efficacy"],
        ["9H", "Isoniazid daily", "9 months", "Preferred by US CDC; highest efficacy"],
        ["3HP", "Isoniazid + Rifapentine once weekly", "3 months (12 doses)", "Directly observed; good completion rates"],
        ["4R", "Rifampin daily", "4 months", "Alternative; fewer hepatotoxic events than 9H"],
        ["3HR", "Isoniazid + Rifampin daily", "3 months", "Short course; used in some settings"],
    ]
    tbl = drug_table(ltbi_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(4)] for r in ltbi_data[1:]
    ], col_w=[2*cm, 4.5*cm, 3.5*cm, 6.5*cm])
    e.append(tbl)
    return e

# ── Section 9: Other EPTB ────────────────────────────────────────────────────

def section9():
    e = []
    e.append(PageBreak())
    e.append(section_header("9. OTHER EXTRAPULMONARY MANIFESTATIONS"))
    e.append(sp(8))

    eptb_data = [
        [Paragraph("<b>Site</b>", sLabel), Paragraph("<b>Key Features</b>", sLabel), Paragraph("<b>Specific Points</b>", sLabel)],
        ["Pott's Disease\n(Spinal TB)", "Lower thoracic + upper lumbar vertebrae most common; back or radicular pain", "Starts in subchondral anterior vertebral body; involves 2 adjacent vertebrae + disc; paravertebral 'cold abscess'; gibbus deformity; kyphosis; Pott's paraplegia from cord compression"],
        ["Pericardial TB", "Exudative pericardial effusion (serosanguineous); large volume (2–4 L possible)", "ADA: sensitivity 87%, specificity 89%; chronic constrictive pericarditis in 30–60%; 30–80% also have pulmonary TB"],
        ["Lymphadenitis", "Most common EPTB site; cervical nodes most often (scrofula)", "Painless, rubbery nodes; may soften, fluctuate, or form draining sinuses; biopsy + culture required"],
        ["Genitourinary TB", "Sterile pyuria on urinalysis (WBCs without bacteria)", "Dysuria, haematuria, flank pain; IVP/CT: calyceal distortion, strictures; urine AFB cultures ×3"],
        ["Miliary TB", "Haematogenous dissemination; acute systemic illness", "Diffuse 1–2 mm nodules on CXR; choroid tubercles on fundoscopy; meningitis in 20–30%; bone marrow biopsy may be positive"],
        ["Cutaneous TB", "Tuberculids: erythema nodosum, erythema induratum (subcutaneous nodules, lower extremities)", "Hypersensitivity reactions to mycobacterial antigens — NOT direct infection of skin; lupus vulgaris is direct skin infection"],
        ["Poncet's Disease", "Reactive arthritis + erythema nodosum", "Immune-mediated; treat underlying TB"],
    ]
    tbl = drug_table(eptb_data[0], [
        [Paragraph(str(r[i]), sBody) for i in range(3)] for r in eptb_data[1:]
    ], col_w=[3*cm, 5.5*cm, 8*cm])
    e.append(tbl)
    e.append(sp(8))

    e.append(p("<b>TB-IRIS (Immune Reconstitution Inflammatory Syndrome)</b>", sH2))
    for item in [
        "Occurs in 5–50% of HIV patients starting antiretroviral therapy (ART) with concurrent TB",
        "Exuberant inflammatory response against M. tuberculosis antigens as immune function recovers",
        "Two forms: (1) paradoxical worsening (fever, lymphadenitis) in patients already on anti-TB; (2) unmasking of previously undiagnosed TB",
        "CNS TB-IRIS: high morbidity and mortality — vigilance essential",
        "Management: NSAIDs, corticosteroids (prednisone) in moderate-severe cases; continue ART and anti-TB",
    ]:
        e.append(b(item))
    return e

# ── Section 10: 2025 WHO Nutrition Guidelines ────────────────────────────────

def section10():
    e = []
    e.append(PageBreak())
    e.append(section_header("10. WHO 2025 MODULE 6 — TB AND UNDERNUTRITION"))
    e.append(sp(8))
    e.append(p("Released <b>October 8, 2025</b>. Part of the WHO Consolidated Guidelines on Tuberculosis, Module 6: TB and Comorbidities. Undernutrition is one of the most significant drivers of the TB epidemic globally."))
    e.append(sp(6))

    e.append(info_box("New 2025 Recommendations (First-Time Formal Endorsement)", [
        "Nutritional assessment and counselling for ALL people with TB AND their household contacts",
        "Nutritional interventions for TB patients with undernutrition — regardless of age, drug resistance status, pregnancy status, or severity of undernutrition",
        "Food assistance to PREVENT TB in household contacts of TB patients in food-insecure settings (based on RATIONS trial evidence)",
        "Addresses nutrition as part of people-centred care under WHO's End TB Strategy",
    ], bg=C_MINT, border=C_TEAL))
    e.append(sp(6))
    e.append(p("These recommendations recognise that a significant proportion of people in households with TB may also be undernourished, and that addressing food insecurity can improve treatment outcomes and prevent new cases."))
    e.append(sp(8))

    # References
    e.append(hr(C_NAVY, 1))
    e.append(sp(6))
    e.append(p("<b>KEY REFERENCES</b>", sH2))
    refs = [
        "Goldman-Cecil Medicine, 26th Edition — Chapter 299 (Pulmonary TB, Intestinal TB, Peritoneal TB, Osteoarticular TB)",
        "Harrison's Principles of Internal Medicine, 22nd Edition (2025) — Extrapulmonary TB, TBM, CSF findings",
        "Adams & Victor's Principles of Neurology, 12th Edition — Chapter 31 (Tuberculous Meningitis, Tuberculoma)",
        "Murray & Nadel's Textbook of Respiratory Medicine — TB pleuritis, peritoneal TB, pericardial TB",
        "Yamada's Textbook of Gastroenterology, 7th Edition — GI TB, peritoneal TB, ADA diagnostics",
        "ROSEN's Emergency Medicine — CNS TB, GI disease, miliary TB",
        "WHO Consolidated Guidelines on TB, Module 4: Treatment and Care (2025) — WHO.int",
        "ATS/CDC/ERS/IDSA Clinical Practice Update (February 2025) — 4-month DS-TB regimen",
        "TB-PRACTECAL Trial: Nyang'wa et al. Lancet Respir Med. 2024;12(2). PMID 37980911",
        "BPaLM Systematic Review: Silva et al. J Bras Pneumol. 2025. PMID 39813501",
        "RCT Linezolid doses in BPaL: Padmapriyadarsini et al. Clin Infect Dis. 2024. PMID 39194339",
        "WHO Global TB Report 2025 (data as of 30 July 2025) — who.int",
        "WHO Module 6: TB and Undernutrition (October 2025) — who.int",
    ]
    for i, ref in enumerate(refs):
        e.append(p(f"{i+1}. {ref}", make_style("_ref",
            fontSize=8, textColor=HexColor("#444444"), fontName="Helvetica",
            leading=12, spaceAfter=3, leftIndent=14, firstLineIndent=-14)))
    e.append(sp(10))
    e.append(hr(C_TEAL, 0.5))
    e.append(p(f"This document was compiled for educational purposes. Always consult current national guidelines and specialist opinion for individual patient management. Compiled: {datetime.date.today().strftime('%B %Y')}.", sSmall))
    return e

# ── Page number canvas ────────────────────────────────────────────────────────

def add_page_number(canvas, doc):
    canvas.saveState()
    # Header bar
    canvas.setFillColor(C_NAVY)
    canvas.rect(0, H - 1.5*cm, W, 1.5*cm, fill=1, stroke=0)
    canvas.setFillColor(C_WHITE)
    canvas.setFont("Helvetica-Bold", 9)
    canvas.drawString(2*cm, H - 1.0*cm, "TUBERCULOSIS — Complete Clinical Reference")
    canvas.setFont("Helvetica", 8)
    canvas.drawRightString(W - 2*cm, H - 1.0*cm, datetime.date.today().strftime("%B %Y"))
    # Footer
    canvas.setFillColor(C_TEAL)
    canvas.rect(0, 0, W, 1*cm, fill=1, stroke=0)
    canvas.setFillColor(C_WHITE)
    canvas.setFont("Helvetica", 8)
    canvas.drawCentredString(W/2, 0.35*cm, f"Page {doc.page}")
    canvas.restoreState()

# ── Main build ────────────────────────────────────────────────────────────────

def build_pdf(output_path):
    doc = SimpleDocTemplate(
        output_path,
        pagesize=A4,
        topMargin=2*cm,
        bottomMargin=1.5*cm,
        leftMargin=2*cm,
        rightMargin=2*cm,
        title="Tuberculosis — Complete Clinical Reference",
        author="Orris AI Medical Reference",
        subject="TB: Pulmonary, Abdominal, TBM, DR-TB, 2025 Guidelines",
    )

    story = []
    story += cover_page()
    story += toc_page()
    story += section1()
    story += section2()
    story += section3()
    story += section4()
    story += section5()
    story += section6()
    story += section7()
    story += section8()
    story += section9()
    story += section10()

    doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
    print(f"PDF saved: {output_path}")

if __name__ == "__main__":
    build_pdf("/home/daytona/workspace/tb-pdf/Tuberculosis_Complete_Reference.pdf")
Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.