Diphtheria , pulmonary TB , typical and Atypical pneumonia for all these only lab diagnosis And other questions like opportunistic fungal infections , antigenic shift and drift , MMR Vaccine , satellitism ,EBV, quellung reaction - pneumococcus answer for 6 marks refer apurva sastry 4th edition and gimme a picture format explanation in pdf

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/microbiology-notes && ls /tmp/workspace/microbiology-notes/

Writing File

~/microbiology-notes/generate_pdf.py

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

# ── OUTPUT ──────────────────────────────────────────────────────────────────
OUTPUT = "/tmp/workspace/microbiology-notes/Microbiology_6mark_Notes.pdf"

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=1.5*cm, rightMargin=1.5*cm,
    topMargin=2*cm, bottomMargin=2*cm,
    title="Microbiology 6-Mark Notes",
    author="Apurva Sastry 4e Reference"
)

W = A4[0] - 3*cm  # usable width

# ── COLOUR PALETTE ───────────────────────────────────────────────────────────
C_HEAD    = colors.HexColor("#1A3C5E")   # deep navy
C_SUB     = colors.HexColor("#2E7D9B")   # teal
C_BOX_BG  = colors.HexColor("#EAF4FB")   # light blue box
C_WARN    = colors.HexColor("#FFF3CD")   # warning yellow
C_PINK    = colors.HexColor("#FCE4EC")   # pink highlight
C_GREEN   = colors.HexColor("#E8F5E9")   # green highlight
C_ORANGE  = colors.HexColor("#FFF8E1")   # orange highlight
C_PURPLE  = colors.HexColor("#F3E5F5")   # purple highlight
C_BORDER  = colors.HexColor("#2E7D9B")
C_WHITE   = colors.white
C_BLACK   = colors.HexColor("#1A1A1A")
C_RED     = colors.HexColor("#C62828")
C_GOLD    = colors.HexColor("#F57F17")

# ── STYLES ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    base = styles.get(name, styles["Normal"])
    ns = ParagraphStyle(f"custom_{id(kw)}", parent=base, **kw)
    return ns

TITLE_S  = S("Normal", fontSize=22, textColor=C_WHITE,   fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=4, leading=26)
CHAP_S   = S("Normal", fontSize=15, textColor=C_WHITE,   fontName="Helvetica-Bold", alignment=TA_LEFT,   spaceAfter=4, leading=18)
HEAD2_S  = S("Normal", fontSize=12, textColor=C_HEAD,    fontName="Helvetica-Bold", alignment=TA_LEFT,   spaceBefore=6, spaceAfter=2, leading=14)
HEAD3_S  = S("Normal", fontSize=10.5, textColor=C_SUB,   fontName="Helvetica-Bold", alignment=TA_LEFT,   spaceBefore=4, spaceAfter=2, leading=13)
BODY_S   = S("Normal", fontSize=9.5,  textColor=C_BLACK, fontName="Helvetica",      alignment=TA_JUSTIFY, spaceAfter=3, leading=13)
BULLET_S = S("Normal", fontSize=9.5,  textColor=C_BLACK, fontName="Helvetica",      leftIndent=14, spaceAfter=2, leading=13)
SMALL_S  = S("Normal", fontSize=8.5,  textColor=colors.HexColor("#555555"), fontName="Helvetica", spaceAfter=2, leading=11)
BOLD_S   = S("Normal", fontSize=9.5,  textColor=C_BLACK, fontName="Helvetica-Bold", spaceAfter=2, leading=13)
KEY_S    = S("Normal", fontSize=9,    textColor=C_RED,   fontName="Helvetica-Bold", spaceAfter=2, leading=12)
WARN_S   = S("Normal", fontSize=9,    textColor=C_GOLD,  fontName="Helvetica-Bold", spaceAfter=2, leading=12)
TABLE_HD = S("Normal", fontSize=9,    textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=11)
TABLE_BD = S("Normal", fontSize=8.5,  textColor=C_BLACK, fontName="Helvetica",      alignment=TA_LEFT,   leading=11)
CENT_S   = S("Normal", fontSize=9.5,  textColor=C_BLACK, fontName="Helvetica",      alignment=TA_CENTER, spaceAfter=2, leading=13)

# ── HELPER BUILDERS ──────────────────────────────────────────────────────────
def chapter_banner(text):
    tbl = Table([[Paragraph(text, CHAP_S)]], colWidths=[W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), C_HEAD),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return tbl

def section_header(text):
    tbl = Table([[Paragraph(text, HEAD2_S)]], colWidths=[W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_BOX_BG),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("LINEBELOW",     (0,0), (-1,-1), 1.5, C_BORDER),
    ]))
    return tbl

def info_box(title, items, bg=C_BOX_BG, title_color=C_SUB):
    rows = [[Paragraph(f"<b><font color='#{title_color.hexval()[1:]}'>🔬 {title}</font></b>", BODY_S)]]
    for it in items:
        rows.append([Paragraph(f"• {it}", BULLET_S)])
    tbl = Table(rows, colWidths=[W-2*mm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("BOX",           (0,0), (-1,-1), 1, C_BORDER),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return tbl

def two_col_table(headers, rows, col_widths=None, bg=C_HEAD):
    if col_widths is None:
        col_widths = [W*0.4, W*0.6]
    data = [[Paragraph(h, TABLE_HD) for h in headers]]
    for r in rows:
        data.append([Paragraph(str(c), TABLE_BD) for c in r])
    tbl = Table(data, colWidths=col_widths)
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0),  bg),
        ("BACKGROUND",    (0,1), (-1,-1), C_WHITE),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
        ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("RIGHTPADDING",  (0,0), (-1,-1), 6),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    return tbl

def key_point_box(text, bg=C_WARN):
    tbl = Table([[Paragraph(f"⭐ KEY POINT: {text}", KEY_S)]], colWidths=[W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("BOX",           (0,0), (-1,-1), 1, C_GOLD),
    ]))
    return tbl

def mnemonic_box(text):
    tbl = Table([[Paragraph(f"📝 MNEMONIC: {text}", WARN_S)]], colWidths=[W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), colors.HexColor("#E8F5E9")),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("BOX",           (0,0), (-1,-1), 1, colors.HexColor("#2E7D32")),
    ]))
    return tbl

def SP(n=4):
    return Spacer(1, n)

def HR():
    return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#B0BEC5"), spaceAfter=4, spaceBefore=4)

# ─────────────────────────────────────────────────────────────────────────────
# BUILD DOCUMENT
# ─────────────────────────────────────────────────────────────────────────────
story = []

# ══════════════════════════════════════════════════════════════════
# COVER PAGE
# ══════════════════════════════════════════════════════════════════
cover_bg = Table(
    [[Paragraph("MICROBIOLOGY", TITLE_S)],
     [Paragraph("6-Mark Picture Notes", TITLE_S)],
     [Paragraph("Based on Apurva Sastry 4th Edition", SMALL_S)],
     [Spacer(1,8)],
     [Paragraph("Lab Diagnosis | Fungal Infections | Virology | Bacteriology", SMALL_S)]],
    colWidths=[W]
)
cover_bg.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), C_HEAD),
    ("TOPPADDING",    (0,0), (-1,-1), 18),
    ("BOTTOMPADDING", (0,0), (-1,-1), 18),
    ("LEFTPADDING",   (0,0), (-1,-1), 20),
    ("RIGHTPADDING",  (0,0), (-1,-1), 20),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
]))
story.append(cover_bg)
story.append(SP(20))

# Topics index
topics = [
    "1. Diphtheria - Lab Diagnosis",
    "2. Pulmonary Tuberculosis - Lab Diagnosis",
    "3. Typical Pneumonia (Streptococcus pneumoniae) - Lab Diagnosis",
    "4. Atypical Pneumonia - Lab Diagnosis",
    "5. Opportunistic Fungal Infections",
    "6. Antigenic Shift and Drift (Influenza)",
    "7. MMR Vaccine",
    "8. Satellitism",
    "9. EBV (Epstein-Barr Virus) / Infectious Mononucleosis",
    "10. Quellung Reaction (Pneumococcus)",
]
idx_data = [[Paragraph(t, BODY_S)] for t in topics]
idx_tbl = Table(idx_data, colWidths=[W])
idx_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), C_BOX_BG),
    ("ROWBACKGROUNDS",(0,0), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.3, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 10),
]))
story.append(Paragraph("TOPICS COVERED", HEAD2_S))
story.append(SP(4))
story.append(idx_tbl)
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 1. DIPHTHERIA - LAB DIAGNOSIS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("1. DIPHTHERIA - LABORATORY DIAGNOSIS"))
story.append(SP(6))
story.append(Paragraph("Causative Organism: Corynebacterium diphtheriae", BOLD_S))
story.append(SP(4))

# Flowchart-style table
story.append(section_header("Step-by-Step Lab Approach"))
story.append(SP(4))

steps = [
    ["STEP 1", "Specimen Collection",
     "Throat + nasopharyngeal swabs (BOTH sites)\nAlso from membrane/pseudomembrane"],
    ["STEP 2", "Microscopy",
     "Gram stain: Gram-positive pleomorphic rods\nAlbert's stain / Ponder's stain: Metachromatic granules (Babes-Ernst bodies)\nChinese letter / cuneiform arrangement\nNOTE: Unreliable for diagnosis alone"],
    ["STEP 3", "Culture Media",
     "• Loeffler's serum slope - best for rapid growth (6-8 hrs); shows metachromatic granules\n• Tellurite media (CTBA / Tinsdale medium) - SELECTIVE; reduces tellurite → gray-black colonies\n• Blood agar - non-selective\n• Tinsdale medium: best recovery; brown halo due to cysteinase activity"],
    ["STEP 4", "Colony Morphology",
     "On Tellurite media: Gray-to-black colonies\nTinsdale: Brown halo around colonies\n3 biotypes: gravis (large, irregular), mitis (small, smooth), intermedius"],
    ["STEP 5", "Biochemical Tests",
     "Catalase: POSITIVE\nCystinase: POSITIVE\nPyrazinamidase: NEGATIVE (key differentiator)\nFerments glucose + maltose; does NOT ferment sucrose"],
    ["STEP 6", "Toxigenicity Testing",
     "ELEK TEST (Gold Standard): In vitro immunodiffusion test\n→ Filter paper strip soaked in antitoxin placed on plate\n→ Toxigenic strains: precipitation line at 45° angle\n\nPCR: Detects tox gene (faster; used directly on swab)\nVero cell cytotoxicity assay (rarely used)"],
]

step_data = []
for s in steps:
    step_data.append([
        Paragraph(f"<b>{s[0]}</b>", TABLE_HD),
        Paragraph(f"<b>{s[1]}</b>", TABLE_HD),
        Paragraph(s[2], TABLE_BD)
    ])

step_tbl = Table(step_data, colWidths=[W*0.10, W*0.25, W*0.65])
step_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), C_HEAD),
    ("BACKGROUND",    (0,0), (0,-1), colors.HexColor("#1A3C5E")),
    ("BACKGROUND",    (1,0), (1,-1), C_SUB),
    ("BACKGROUND",    (2,0), (2,-1), C_WHITE),
    ("ROWBACKGROUNDS",(2,0), (2,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TEXTCOLOR",     (0,0), (0,-1), C_WHITE),
    ("TEXTCOLOR",     (1,0), (1,-1), C_WHITE),
    ("FONTNAME",      (0,0), (1,-1), "Helvetica-Bold"),
]))
story.append(step_tbl)
story.append(SP(8))

story.append(key_point_box("ELEK TEST = Gold standard for toxigenicity. Tinsdale = Best culture medium."))
story.append(SP(4))
story.append(mnemonic_box("'TELL ELEKTRicity' → TELLurite for culture + ELEK for toxin detection"))
story.append(SP(4))

story.append(section_header("Media Comparison Chart"))
story.append(SP(4))
media_rows = [
    ["Loeffler's serum slope", "Rapid growth (6-8h)", "Metachromatic granules visible", "NOT selective"],
    ["Tellurite blood agar", "Selective (inhibits commensals)", "Gray-black colonies", "CTBA variant: long shelf life"],
    ["Tinsdale medium", "BEST recovery", "Gray-black + brown halo", "Short shelf life; needs horse serum"],
    ["Blood agar", "Non-selective", "Hemolysis seen", "Used alongside selective media"],
]
story.append(two_col_table(
    ["Medium", "Advantage", "Colony Appearance", "Note"],
    media_rows,
    col_widths=[W*0.22, W*0.25, W*0.28, W*0.25]
))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 2. PULMONARY TUBERCULOSIS - LAB DIAGNOSIS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("2. PULMONARY TUBERCULOSIS - LABORATORY DIAGNOSIS"))
story.append(SP(6))
story.append(Paragraph("Causative Organism: Mycobacterium tuberculosis (Acid Fast Bacillus - AFB)", BOLD_S))
story.append(SP(4))

story.append(section_header("Specimens"))
story.append(SP(3))
story.append(info_box("Specimen Types", [
    "Sputum (most common) - early morning, 3 consecutive days",
    "Gastric lavage / aspirate (children, unable to expectorate)",
    "Bronchial washing / BAL (bronchoscopy cases)",
    "Pleural fluid, CSF, urine, tissue biopsy as appropriate",
    "At least 2 sputum samples needed for conclusive diagnosis",
], bg=C_BOX_BG))
story.append(SP(6))

story.append(section_header("Lab Methods - Step by Step"))
story.append(SP(4))

tb_steps = [
    ["MICROSCOPY\n(Fastest)", 
     "ZN Stain (Ziehl-Neelsen): Heat-fixed AFBs stain RED on blue background\nAuramine-Rhodamine (Fluorescent): More sensitive; AFBs glow yellow-green\nGrading: 1+ to 3+ based on bacilli per HPF\n\nGRADING (WHO): Scanty = 1-9 AFBs/100 HPF; 1+ = 10-99/100 HPF; 2+ = 1-10/HPF; 3+ = >10/HPF"],
    ["CULTURE\n(Gold standard)", 
     "Solid media: Lowenstein-Jensen (LJ) medium - buff/cream colonies in 6-8 weeks\nLiquid media: BACTEC MGIT (Mycobacteria Growth Indicator Tube) - 1-3 weeks\nMBBacT system (automated)\nDecontamination before culture: NALC-NaOH or 4% H2SO4 method"],
    ["MOLECULAR\n(Rapid)", 
     "GeneXpert MTB/RIF (CBNAAT): Detects MTB + RIF resistance in 2 hours\nLine Probe Assay (LPA): Detects INH + RIF resistance; strips methodology\nWhole genome sequencing (WGS): Comprehensive DST\nIS6110-based PCR: Specific for MTB complex"],
    ["SEROLOGY &\nIMMUNOLOGY",
     "Tuberculin Skin Test (TST/Mantoux): Delayed hypersensitivity; 5 TU PPD\n→ Read at 48-72h; induration ≥10mm = positive\nIGRAs (Interferon-Gamma Release Assays): QuantiFERON-TB Gold, T-SPOT.TB\n→ Measures IFN-γ from sensitized T-cells; more specific than TST"],
    ["ANIMAL\nINOCULATION\n(Historical)",
     "Guinea pig inoculation (now obsolete)\nReplaced by molecular methods"],
]

tb_data = []
for r in tb_steps:
    tb_data.append([Paragraph(r[0], S("Normal", fontSize=9, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=11)),
                    Paragraph(r[1], TABLE_BD)])

tb_tbl = Table(tb_data, colWidths=[W*0.18, W*0.82])
tb_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (0,-1), C_HEAD),
    ("ROWBACKGROUNDS",(1,0), (1,-1), [C_WHITE, C_BOX_BG]),
    ("BACKGROUND",    (1,0), (1,-1), C_WHITE),
    ("BACKGROUND",    (1,1), (1,1), C_BOX_BG),
    ("BACKGROUND",    (1,3), (1,3), C_BOX_BG),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("VALIGN",        (1,0), (1,-1), "TOP"),
]))
story.append(tb_tbl)
story.append(SP(8))

story.append(key_point_box("GeneXpert MTB/RIF = Rapid, sensitive, detects RIF resistance simultaneously. LJ medium = Gold standard culture but slow."))
story.append(SP(4))
story.append(mnemonic_box("'ZAP-NG' → ZN stain, Auramine, PCR/GeneXpert, NALC decontamination"))
story.append(SP(4))

story.append(section_header("ZN Staining Steps"))
story.append(SP(3))
zn = [
    ["1", "Heat fix smear"],
    ["2", "Apply Carbol Fuchsin (primary stain) + heat for 3 min"],
    ["3", "Decolorize with 25% H2SO4 (acid-fast organisms RESIST)"],
    ["4", "Counterstain with Methylene blue"],
    ["5", "AFBs = RED rods on BLUE background"],
]
story.append(two_col_table(["Step", "Action"], zn, col_widths=[W*0.1, W*0.9]))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 3. TYPICAL PNEUMONIA - LAB DIAGNOSIS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("3. TYPICAL PNEUMONIA - LABORATORY DIAGNOSIS"))
story.append(SP(6))
story.append(Paragraph("Causative Organism: Streptococcus pneumoniae (Pneumococcus) - most common", BOLD_S))
story.append(SP(3))
story.append(Paragraph("Other causes: Staphylococcus aureus, Klebsiella pneumoniae, Group A Strep", SMALL_S))
story.append(SP(6))

story.append(section_header("Specimens & Lab Tests"))
story.append(SP(3))

typ_data = [
    [Paragraph("<b>Test</b>", TABLE_HD), Paragraph("<b>Findings / Notes</b>", TABLE_HD)],
    [Paragraph("Sputum Gram Stain", TABLE_BD),
     Paragraph("• >25 WBCs + <10 squamous cells per LPF = good quality sputum\n• Gram-positive diplococci (lancet-shaped) → Pneumococcus\n• Gram-positive cocci in clusters → Staph aureus\n• Gram-negative rods → Klebsiella, H. influenzae", TABLE_BD)],
    [Paragraph("Sputum Culture", TABLE_BD),
     Paragraph("• Blood agar: alpha-hemolytic (green/partial hemolysis)\n• Chocolate agar: for fastidious organisms\n• MacConkey: for Gram-negative rods\n• Optochin sensitivity: S. pneumoniae SENSITIVE (inhibition zone ≥14mm)\n• Bile solubility: Pneumococcus POSITIVE (lyses in bile/sodium deoxycholate)", TABLE_BD)],
    [Paragraph("Blood Culture", TABLE_BD),
     Paragraph("• 10% of pneumococcal pneumonia → bacteremia\n• 2 sets before antibiotic therapy\n• Bottles: aerobic + anaerobic", TABLE_BD)],
    [Paragraph("Quellung Reaction", TABLE_BD),
     Paragraph("• Mix organism + type-specific antiserum + methylene blue\n• Capsule SWELLS (appears to enlarge) = POSITIVE\n• Identifies capsular type (>90 serotypes)\n• Also called Neufeld's reaction / Capsule swelling reaction", TABLE_BD)],
    [Paragraph("Urine Antigen Test", TABLE_BD),
     Paragraph("• Binax NOW: Rapid; detects pneumococcal C-polysaccharide\n• Sensitivity ~70-80%, specificity ~90%\n• Useful when sputum culture negative", TABLE_BD)],
    [Paragraph("CBC & CRP", TABLE_BD),
     Paragraph("• WBC >15,000/mm³ → bacterial (pyogenic) pneumonia\n• Elevated CRP, procalcitonin", TABLE_BD)],
]

typ_tbl = Table(typ_data, colWidths=[W*0.25, W*0.75])
typ_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(typ_tbl)
story.append(SP(8))

story.append(key_point_box("Optochin SENSITIVE + Bile soluble = S. pneumoniae. Viridans strep: Optochin RESISTANT + Bile insoluble."))
story.append(SP(4))
story.append(mnemonic_box("'OPTICS BILE' → Optochin + Bile solubility identify Pneumococcus"))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 4. ATYPICAL PNEUMONIA - LAB DIAGNOSIS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("4. ATYPICAL PNEUMONIA - LABORATORY DIAGNOSIS"))
story.append(SP(6))

story.append(section_header("Causative Organisms"))
story.append(SP(4))

org_data = [
    [Paragraph("<b>Organism</b>", TABLE_HD), Paragraph("<b>Lab Features</b>", TABLE_HD), Paragraph("<b>Special Test</b>", TABLE_HD)],
    [Paragraph("Mycoplasma pneumoniae", TABLE_BD),
     Paragraph("• No cell wall (not visible on Gram stain)\n• Grows on Eaton's agar (contains cholesterol)\n• Colonies: 'Fried egg' appearance\n• Slow grower: 2-3 weeks", TABLE_BD),
     Paragraph("Cold agglutinin test (IgM vs I antigen on RBCs)\n→ titer >1:64 = suggestive\nComplement fixation test\nMycoplasma IgM/IgG ELISA", TABLE_BD)],
    [Paragraph("Chlamydophila pneumoniae", TABLE_BD),
     Paragraph("• Obligate intracellular; cannot be cultured on ordinary media\n• Biphasic life cycle: EB (infectious) → RB (replicating)\n• Giemsa stain: intracytoplasmic inclusions", TABLE_BD),
     Paragraph("Microimmunofluorescence (MIF) test: Gold standard\nCF antibody titers\nPCR (respiratory secretions)", TABLE_BD)],
    [Paragraph("Legionella pneumophila", TABLE_BD),
     Paragraph("• Gram-negative rod (weakly staining)\n• Grows on BCYE agar (Buffered Charcoal Yeast Extract)\n• Requires L-cysteine and iron\n• Silver stain / Dieterle stain in tissue", TABLE_BD),
     Paragraph("Urinary antigen: Rapid, specific for serogroup 1\nDFA (Direct fluorescent antibody)\nPCR\nSerology: 4-fold rise in IgG", TABLE_BD)],
    [Paragraph("Coxiella burnetii\n(Q Fever)", TABLE_BD),
     Paragraph("• Obligate intracellular; NOT transmitted by arthropod bite\n• Phase I vs Phase II antigens\n• BSL-3 organism", TABLE_BD),
     Paragraph("Weil-Felix: NEGATIVE (differentiates from rickettsia)\nIFA (Phase I & II antigens)\nPCR on blood/tissue", TABLE_BD)],
]

atyp_tbl = Table(org_data, colWidths=[W*0.22, W*0.42, W*0.36])
atyp_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(atyp_tbl)
story.append(SP(8))

story.append(key_point_box("Mycoplasma: Cold agglutinins + Eaton's agar. Legionella: Urine antigen + BCYE agar. Chlamydia: MIF test."))
story.append(SP(4))
story.append(mnemonic_box("'MAC' → Mycoplasma (Cold agglutinin), Atypical, Chlamydia (MIF), also: ML-CQ = My Legions Chill Quietly"))
story.append(SP(4))

story.append(section_header("Typical vs Atypical Pneumonia - Quick Comparison"))
story.append(SP(3))
comp_rows = [
    ["Onset", "Sudden, acute", "Gradual, insidious"],
    ["Sputum", "Purulent, rusty", "Scanty, non-purulent"],
    ["Gram stain", "Shows organism", "No organism visible"],
    ["CXR", "Lobar/segmental consolidation", "Bilateral interstitial ('walking pneumonia')"],
    ["WBC", ">15,000 (neutrophilia)", "Normal or mild lymphocytosis"],
    ["Response to beta-lactams", "YES", "NO (no cell wall in Mycoplasma)"],
    ["Treatment", "Penicillin / Amoxicillin", "Macrolides / Doxycycline / Fluoroquinolones"],
]
story.append(two_col_table(["Feature", "Typical Pneumonia", "Atypical Pneumonia"], comp_rows,
                            col_widths=[W*0.25, W*0.35, W*0.40]))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 5. OPPORTUNISTIC FUNGAL INFECTIONS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("5. OPPORTUNISTIC FUNGAL INFECTIONS"))
story.append(SP(6))

story.append(Paragraph("Definition: Fungal infections occurring in immunocompromised hosts due to organisms normally non-pathogenic in healthy individuals.", BODY_S))
story.append(SP(4))

story.append(section_header("Risk Factors (Predisposing Conditions)"))
story.append(SP(3))

rf_data = [
    [Paragraph("<b>Risk Factor</b>", TABLE_HD), Paragraph("<b>Common Opportunistic Pathogens</b>", TABLE_HD)],
    [Paragraph("AIDS / HIV (CD4 <200)", TABLE_BD), Paragraph("Candida, Cryptococcus neoformans, Pneumocystis jirovecii", TABLE_BD)],
    [Paragraph("Bone marrow / Organ transplant", TABLE_BD), Paragraph("Aspergillus, Candida, Mucor, Fusarium", TABLE_BD)],
    [Paragraph("Prolonged antibiotics / steroids", TABLE_BD), Paragraph("Candida spp. (disrupts normal flora)", TABLE_BD)],
    [Paragraph("Neutropenia (<500 ANC)", TABLE_BD), Paragraph("Aspergillus, Mucor, Candida", TABLE_BD)],
    [Paragraph("Diabetes mellitus (DKA)", TABLE_BD), Paragraph("Mucormycosis (Rhizopus, Mucor, Rhizomucor)", TABLE_BD)],
    [Paragraph("Hematologic malignancies", TABLE_BD), Paragraph("Aspergillus, Fusarium, Trichosporon", TABLE_BD)],
    [Paragraph("Premature neonates", TABLE_BD), Paragraph("Candida spp.", TABLE_BD)],
]

rf_tbl = Table(rf_data, colWidths=[W*0.40, W*0.60])
rf_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(rf_tbl)
story.append(SP(6))

story.append(section_header("Major Opportunistic Fungi - Lab Diagnosis"))
story.append(SP(4))

fungi_data = [
    [Paragraph("<b>Fungus</b>", TABLE_HD), Paragraph("<b>Morphology / Lab Features</b>", TABLE_HD), Paragraph("<b>Special Test</b>", TABLE_HD)],
    [Paragraph("Candida albicans", TABLE_BD),
     Paragraph("• Gram-positive yeast (budding)\n• Forms pseudohyphae + true hyphae\n• Germ tube test: POSITIVE at 37°C in serum (2h)\n• Chlamydoconidia on corn meal agar\n• Chrome agar: green colonies", TABLE_BD),
     Paragraph("Germ tube test (rapid ID)\nCHROMagar Candida\nBlood culture (BACTEC)\nBeta-D-glucan (serum)", TABLE_BD)],
    [Paragraph("Cryptococcus neoformans", TABLE_BD),
     Paragraph("• Encapsulated yeast\n• India ink: LARGE capsule (halo around yeast)\n• Urease POSITIVE\n• Birdseed/Niger seed agar: brown colonies\n• No pseudohyphae", TABLE_BD),
     Paragraph("India ink of CSF\nCryptococcal antigen (CrAg) - serum/CSF\nLatex agglutination test\nNiger seed agar", TABLE_BD)],
    [Paragraph("Aspergillus fumigatus", TABLE_BD),
     Paragraph("• Septate hyphae (45° angle branching)\n• Conidiophore with phialides\n• KOH mount of BAL/sputum\n• Velvety green colonies on SDA", TABLE_BD),
     Paragraph("Galactomannan (serum/BAL)\nBeta-D-glucan\nCT chest: 'Halo sign' / air crescent sign\nCulture on SDA", TABLE_BD)],
    [Paragraph("Mucor / Rhizopus\n(Mucormycosis)", TABLE_BD),
     Paragraph("• Broad ASEPTATE hyphae (90° angle branching)\n• Ribbon-like hyphae on KOH\n• Rhizopus: has rhizoids\n• Sporangiophore with sporangium\n• Very fast growing (2-3 days)", TABLE_BD),
     Paragraph("KOH mount of tissue/sputum\nHistopathology (PAS/GMS stain)\nCT: Rhino-orbital involvement\nSerology unreliable", TABLE_BD)],
    [Paragraph("Pneumocystis jirovecii\n(formerly carinii)", TABLE_BD),
     Paragraph("• Classified as FUNGUS (not protozoa)\n• Cannot be cultured in vitro\n• Cysts and trophic forms\n• CD4 <200 cells/μL", TABLE_BD),
     Paragraph("GMS (Gomori Methenamine Silver): cysts stain black\nToluidine blue O stain\nBAL or induced sputum\nPCR (most sensitive)\nLDH markedly elevated (non-specific)", TABLE_BD)],
]

fungi_tbl = Table(fungi_data, colWidths=[W*0.18, W*0.46, W*0.36])
fungi_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(fungi_tbl)
story.append(SP(6))

story.append(key_point_box("Mucor = ASEPTATE hyphae. Aspergillus = SEPTATE hyphae. India ink = Cryptococcus. Germ tube = Candida albicans."))
story.append(SP(4))
story.append(mnemonic_box("'ACMP' - Aspergillus (galactomannan), Candida (germ tube), Mucor (aseptate), Pneumocystis (GMS stain)"))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 6. ANTIGENIC SHIFT AND DRIFT
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("6. ANTIGENIC SHIFT AND DRIFT (INFLUENZA VIRUS)"))
story.append(SP(6))

story.append(Paragraph("Influenza virus surface antigens: Hemagglutinin (HA) - 18 subtypes, Neuraminidase (NA) - 11 subtypes", BOLD_S))
story.append(SP(4))

compare_data = [
    [Paragraph("<b>Feature</b>", TABLE_HD), Paragraph("<b>ANTIGENIC DRIFT</b>", TABLE_HD), Paragraph("<b>ANTIGENIC SHIFT</b>", TABLE_HD)],
    [Paragraph("Definition", TABLE_BD), Paragraph("Gradual, minor changes in HA/NA", TABLE_BD), Paragraph("Abrupt, major change in HA/NA subtype", TABLE_BD)],
    [Paragraph("Mechanism", TABLE_BD), Paragraph("Point mutations in HA/NA genes", TABLE_BD), Paragraph("Genetic REASSORTMENT between 2 different influenza strains in same host (e.g., pig)", TABLE_BD)],
    [Paragraph("Change type", TABLE_BD), Paragraph("Quantitative (incremental)", TABLE_BD), Paragraph("Qualitative (completely new subtype)", TABLE_BD)],
    [Paragraph("Result", TABLE_BD), Paragraph("EPIDEMICS (smaller outbreaks)", TABLE_BD), Paragraph("PANDEMICS (global spread)", TABLE_BD)],
    [Paragraph("Frequency", TABLE_BD), Paragraph("Occurs continuously/yearly", TABLE_BD), Paragraph("Rare (every 10-40 years)", TABLE_BD)],
    [Paragraph("Occurs in", TABLE_BD), Paragraph("ALL influenza types (A, B, C)", TABLE_BD), Paragraph("ONLY Influenza A (animal reservoir exists)", TABLE_BD)],
    [Paragraph("Immunity", TABLE_BD), Paragraph("Partial immunity (some cross-protection)", TABLE_BD), Paragraph("NO immunity in population (new subtype)", TABLE_BD)],
    [Paragraph("Example", TABLE_BD), Paragraph("Annual seasonal flu variations", TABLE_BD), Paragraph("1918 (H1N1 Spanish flu), 1957 (H2N2 Asian), 1968 (H3N2 Hong Kong), 2009 (H1N1 Swine flu)", TABLE_BD)],
    [Paragraph("Internal proteins", TABLE_BD), Paragraph("NP, M proteins relatively stable", TABLE_BD), Paragraph("NP, M proteins relatively stable (only HA/NA change)", TABLE_BD)],
]

comp_tbl = Table(compare_data, colWidths=[W*0.22, W*0.38, W*0.40])
comp_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("BACKGROUND",    (1,1), (1,-1), colors.HexColor("#E3F2FD")),
    ("BACKGROUND",    (2,1), (2,-1), colors.HexColor("#FCE4EC")),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(comp_tbl)
story.append(SP(8))

story.append(key_point_box("DRIFT = Small changes → Epidemics. SHIFT = Big reassortment → Pandemics. ONLY Influenza A undergoes both."))
story.append(SP(4))
story.append(mnemonic_box("'DRIFTing slowly (gradual/epidemic) vs SHIFTing suddenly (abrupt/pandemic)' | 'A-SHIFT = Animal reassortment'"))
story.append(SP(6))

story.append(section_header("Pandemic Examples"))
story.append(SP(3))
pandemic_rows = [
    ["1918", "H1N1", "Spanish flu", "~50 million deaths"],
    ["1957", "H2N2", "Asian flu", "~1-2 million deaths"],
    ["1968", "H3N2", "Hong Kong flu", "~1 million deaths"],
    ["1977", "H1N1", "Russian flu", "Re-emergence"],
    ["2009", "H1N1 (pdm09)", "Swine flu", "Quadruple reassortant; >18,000 deaths"],
]
story.append(two_col_table(["Year", "Subtype", "Name", "Impact"], pandemic_rows,
                            col_widths=[W*0.12, W*0.18, W*0.30, W*0.40]))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 7. MMR VACCINE
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("7. MMR VACCINE"))
story.append(SP(6))

story.append(section_header("Overview"))
story.append(SP(4))

mmr_info = [
    [Paragraph("<b>Feature</b>", TABLE_HD), Paragraph("<b>Details</b>", TABLE_HD)],
    [Paragraph("Full form", TABLE_BD), Paragraph("Measles-Mumps-Rubella combined vaccine", TABLE_BD)],
    [Paragraph("Type", TABLE_BD), Paragraph("Live attenuated vaccine", TABLE_BD)],
    [Paragraph("Route", TABLE_BD), Paragraph("Subcutaneous (SC) injection, 0.5 mL", TABLE_BD)],
    [Paragraph("Schedule (India)", TABLE_BD), Paragraph("1st dose: 9 months (as MR vaccine) or 12 months\n2nd dose: 15-18 months\nMMRV also available (adds Varicella)", TABLE_BD)],
    [Paragraph("Schedule (USA)", TABLE_BD), Paragraph("1st dose: 12-15 months\n2nd dose: 4-6 years", TABLE_BD)],
    [Paragraph("Immunity", TABLE_BD), Paragraph("~95-99% seroconversion after 2 doses", TABLE_BD)],
    [Paragraph("Duration", TABLE_BD), Paragraph("Lifelong immunity (most cases)", TABLE_BD)],
    [Paragraph("Storage", TABLE_BD), Paragraph("2-8°C; protect from light (light-sensitive)", TABLE_BD)],
]

mmr_tbl = Table(mmr_info, colWidths=[W*0.30, W*0.70])
mmr_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(mmr_tbl)
story.append(SP(6))

story.append(section_header("Individual Vaccine Components"))
story.append(SP(4))

comp_data = [
    [Paragraph("<b>Component</b>", TABLE_HD), Paragraph("<b>Virus Strain Used</b>", TABLE_HD), Paragraph("<b>Key Points</b>", TABLE_HD)],
    [Paragraph("MEASLES", TABLE_BD),
     Paragraph("Edmonston B → Schwarz strain\nMoreaten strain (Attenuvax)", TABLE_BD),
     Paragraph("Prevents rubeola; fever + maculopapular rash\nKoplik's spots pathognomonic\nMost common VPD causing death globally\nSSPE is late complication", TABLE_BD)],
    [Paragraph("MUMPS", TABLE_BD),
     Paragraph("Jeryl Lynn strain (used in MMR-II)\nUrabe strain (older; withdrawn)", TABLE_BD),
     Paragraph("Prevents parotitis, orchitis, meningitis\nJeryl Lynn = safest strain\nUrabe withdrawn due to aseptic meningitis", TABLE_BD)],
    [Paragraph("RUBELLA", TABLE_BD),
     Paragraph("RA 27/3 strain", TABLE_BD),
     Paragraph("Prevents congenital rubella syndrome (CRS)\nCRS: deafness, cataracts, cardiac defects (PDA, VSD)\nBlueberry muffin rash in neonates\nMost important to vaccinate WOMEN OF CHILDBEARING AGE", TABLE_BD)],
]

comp_tbl2 = Table(comp_data, colWidths=[W*0.15, W*0.28, W*0.57])
comp_tbl2.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(comp_tbl2)
story.append(SP(6))

story.append(section_header("Contraindications & Special Notes"))
story.append(SP(3))
story.append(info_box("Contraindications", [
    "Severe immunodeficiency (HIV with CD4 <15% / AIDS, lymphoma, leukemia)",
    "Pregnancy (live vaccine - teratogenic potential; avoid 1 month post-vaccination)",
    "Recent blood product / IG administration (defer 3 months)",
    "Known anaphylaxis to neomycin or gelatin",
    "High-dose corticosteroids (>2 mg/kg/day >14 days) - defer 1 month",
    "NOTE: Egg allergy is NOT a contraindication (grown in chick embryo, not egg white)",
], bg=C_PINK))
story.append(SP(4))
story.append(key_point_box("MMR = Live attenuated. Contraindicated in pregnancy and severe immunodeficiency. RA 27/3 strain used for Rubella."))
story.append(SP(4))
story.append(mnemonic_box("'MMR = Must give at Month 12 + Re-dose at 4-6 years' | 'Jeryl Lynn = Safe jerky Lynn strain for Mumps'"))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 8. SATELLITISM
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("8. SATELLITISM"))
story.append(SP(6))

story.append(section_header("Definition"))
story.append(SP(3))
story.append(Paragraph(
    "Satellitism is a phenomenon in which one bacterium (Haemophilus influenzae) grows only near or around colonies of another organism (Staphylococcus aureus) because it requires growth factors secreted by the latter.",
    BODY_S))
story.append(SP(6))

story.append(section_header("Key Components"))
story.append(SP(4))

sat_info = [
    [Paragraph("<b>Component</b>", TABLE_HD), Paragraph("<b>Details</b>", TABLE_HD)],
    [Paragraph("Organism showing satellitism", TABLE_BD), Paragraph("Haemophilus influenzae (small, pale colonies)", TABLE_BD)],
    [Paragraph("Helper organism", TABLE_BD), Paragraph("Staphylococcus aureus (or Staphylococcus epidermidis)", TABLE_BD)],
    [Paragraph("Medium", TABLE_BD), Paragraph("Blood agar (H. influenzae grows only NEAR Staph colonies)", TABLE_BD)],
    [Paragraph("What Staph provides", TABLE_BD), Paragraph("Factor V (NAD - nicotinamide adenine dinucleotide) released by RBC hemolysis by Staph\nAlso: Factor X present in blood agar", TABLE_BD)],
    [Paragraph("Growth factors needed", TABLE_BD), Paragraph("H. influenzae requires BOTH Factor X (hemin/protoporphyrin IX) AND Factor V (NAD)\nFactor V crosses from Staph-lysed RBCs into surrounding area", TABLE_BD)],
    [Paragraph("Appearance", TABLE_BD), Paragraph("H. influenzae colonies appear small and grow only in the SATELLITE zone around Staph aureus colonies", TABLE_BD)],
    [Paragraph("Lab significance", TABLE_BD), Paragraph("Confirms H. influenzae; differentiates from other Haemophilus species\nH. aegyptius: needs X + V; H. ducreyi: needs only X; H. parainfluenzae: needs only V", TABLE_BD)],
]

sat_tbl = Table(sat_info, colWidths=[W*0.30, W*0.70])
sat_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(sat_tbl)
story.append(SP(6))

story.append(section_header("Haemophilus Growth Factor Requirements"))
story.append(SP(3))
hfac_rows = [
    ["H. influenzae", "YES (X)", "YES (V)", "Satellitism with Staph on blood agar"],
    ["H. parainfluenzae", "NO", "YES (V)", "No satellitism; grows away from Staph"],
    ["H. ducreyi", "YES (X)", "NO", "Chancroid; only needs hemin"],
    ["H. aegyptius", "YES (X)", "YES (V)", "Pink eye / Brazilian purpuric fever"],
    ["H. haemolyticus", "YES (X)", "YES (V)", "Beta-hemolytic on blood agar"],
]
story.append(two_col_table(["Species", "Factor X", "Factor V", "Note"], hfac_rows,
                            col_widths=[W*0.28, W*0.13, W*0.13, W*0.46]))
story.append(SP(6))

story.append(key_point_box("Satellitism = H. influenzae satellite colonies around S. aureus on blood agar. Both X + V factors needed."))
story.append(SP(4))
story.append(mnemonic_box("'H. influenzae Xtra 5 (V) reasons to be near Staph' → needs Factor X + V (5 in Roman)"))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 9. EBV - EPSTEIN-BARR VIRUS
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("9. EBV - EPSTEIN-BARR VIRUS & INFECTIOUS MONONUCLEOSIS"))
story.append(SP(6))

story.append(Paragraph("Classification: Gamma-herpesvirus (HHV-4) | Envelope: dsDNA virus", BOLD_S))
story.append(SP(4))

story.append(section_header("Pathogenesis"))
story.append(SP(3))
story.append(info_box("EBV Infection Pathway", [
    "EBV infects B lymphocytes via CD21 receptor (also epithelial cells)",
    "2 pathways: Lytic destruction OR Latency within lymphocytes",
    "Expresses EBNAs (Epstein-Barr Nuclear Antigens) → B-cell immortalization",
    "CD8+ T cells expand vigorously → appear as 'Atypical lymphocytes' on smear",
    "Heterophile antibodies (IgM) produced against sheep RBC surface antigens",
    "Incubation period: 30-50 days",
    "Seroprevalence: 90-95% adults worldwide",
], bg=C_PURPLE))
story.append(SP(6))

story.append(section_header("Clinical Triad of Infectious Mononucleosis"))
story.append(SP(3))
triad_data = [
    [Paragraph("<b>FEVER</b>", S("Normal", fontSize=12, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
     Paragraph("<b>SORE THROAT</b>\n(Exudative pharyngitis)", S("Normal", fontSize=12, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
     Paragraph("<b>LYMPHADENOPATHY</b>\n(Posterior cervical)", S("Normal", fontSize=12, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER))],
]
triad_tbl = Table(triad_data, colWidths=[W*0.33, W*0.33, W*0.34])
triad_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (0,0), colors.HexColor("#E53935")),
    ("BACKGROUND",    (1,0), (1,0), colors.HexColor("#1E88E5")),
    ("BACKGROUND",    (2,0), (2,0), colors.HexColor("#43A047")),
    ("TOPPADDING",    (0,0), (-1,-1), 12),
    ("BOTTOMPADDING", (0,0), (-1,-1), 12),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("GRID",          (0,0), (-1,-1), 1, C_WHITE),
]))
story.append(triad_tbl)
story.append(SP(6))

story.append(section_header("Laboratory Diagnosis"))
story.append(SP(4))

ebv_lab = [
    [Paragraph("<b>Test</b>", TABLE_HD), Paragraph("<b>Findings / Notes</b>", TABLE_HD)],
    [Paragraph("CBC / Peripheral Smear", TABLE_BD),
     Paragraph("• Absolute lymphocytosis (>50% lymphocytes)\n• >10% atypical lymphocytes (Downey cells - activated CD8+ T cells)\n• Mild thrombocytopenia may be present\n• Atypical lymphocytes: large, irregular nucleus, abundant cytoplasm, 'skirt-like' cytoplasm", TABLE_BD)],
    [Paragraph("Monospot Test\n(Paul-Bunnell-Davidson)", TABLE_BD),
     Paragraph("• Detects HETEROPHILE antibodies (IgM) against sheep/horse RBCs\n• Rapid latex agglutination card test\n• Sensitivity ~85-90% in adolescents; FALSE NEGATIVE in <4 years\n• Positive at some point in up to 90% of cases\n• Heterophile antibodies are NOT cross-reactive with EBV antigens", TABLE_BD)],
    [Paragraph("EBV-Specific Serology", TABLE_BD),
     Paragraph("• Anti-VCA IgM: ACUTE infection (appears first)\n• Anti-VCA IgG: Past infection / persists lifelong\n• Anti-EA (Early Antigen): Active replication\n• Anti-EBNA IgG: Appears LATE (weeks-months); confirms past infection\n\nInterpretation:\n- VCA IgM +ve, EBNA -ve = ACUTE\n- VCA IgG +ve, EBNA +ve = Past/Latent", TABLE_BD)],
    [Paragraph("EBV PCR / EBER ISH", TABLE_BD),
     Paragraph("• Quantitative EBV DNA PCR: monitors viral load\n• EBER in-situ hybridization: detects EBV in tissue (lymphoma, etc.)\n• Used for EBV-associated malignancies: Burkitt's lymphoma, NPC, Hodgkin's", TABLE_BD)],
    [Paragraph("LFTs", TABLE_BD),
     Paragraph("• Elevated liver enzymes (ALT, AST) in ~80% of cases\n• Mild hepatomegaly common", TABLE_BD)],
]

ebv_tbl = Table(ebv_lab, colWidths=[W*0.25, W*0.75])
ebv_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(ebv_tbl)
story.append(SP(6))

story.append(section_header("EBV-Associated Malignancies"))
story.append(SP(3))
malig_rows = [
    ["Burkitt's Lymphoma", "EBV + translocation t(8;14) - c-MYC oncogene", "Jaw tumors; endemic Africa"],
    ["Nasopharyngeal Carcinoma (NPC)", "EBV + genetic/environmental factors", "Southeast Asia; raised anti-VCA titers"],
    ["Hodgkin's Lymphoma", "EBV in Reed-Sternberg cells (~40-50%)", "Mixed cellularity subtype most common"],
    ["Post-transplant lymphoproliferative disorder", "EBV-driven B-cell proliferation", "Immunosuppressed patients"],
    ["Hairy oral leukoplakia", "EBV replication in lateral tongue epithelium", "HIV patients", ],
]
story.append(two_col_table(["Malignancy", "EBV Link", "Note"], malig_rows,
                            col_widths=[W*0.32, W*0.38, W*0.30]))
story.append(SP(6))
story.append(key_point_box("Monospot = Heterophile antibodies. False -ve in children <4 yrs. VCA IgM = Acute EBV. Atypical lymphocytes = activated CD8+ T cells."))
story.append(SP(4))
story.append(mnemonic_box("'FENB' → Fever, Exudative pharyngitis, Nodes (posterior cervical), Blood (atypical lymphocytes)"))
story.append(PageBreak())

# ══════════════════════════════════════════════════════════════════
# 10. QUELLUNG REACTION
# ══════════════════════════════════════════════════════════════════
story.append(chapter_banner("10. QUELLUNG REACTION (PNEUMOCOCCUS)"))
story.append(SP(6))

story.append(section_header("Definition"))
story.append(SP(3))
story.append(Paragraph(
    "The Quellung reaction (German: 'Quellung' = swelling) is a serological test used to identify encapsulated bacteria - especially Streptococcus pneumoniae - by mixing organisms with type-specific anticapsular antiserum + methylene blue dye, causing the capsule to appear to SWELL.",
    BODY_S))
story.append(SP(6))

story.append(section_header("Procedure & Mechanism"))
story.append(SP(4))

quel_steps = [
    ["STEP 1", "Prepare fresh sputum / CSF / broth culture smear"],
    ["STEP 2", "Add one drop of TYPE-SPECIFIC antiserum + methylene blue dye"],
    ["STEP 3", "Mix and apply coverslip; observe under oil immersion"],
    ["STEP 4 (+)", "CAPSULE APPEARS TO SWELL (actually: Ab binds capsule → increases refractive index → appears larger)\nBackground: blue; Bacteria: dark; Capsule: large halo = POSITIVE"],
    ["STEP 4 (-)", "No capsular swelling = NEGATIVE (strain mismatch or non-capsulated)"],
    ["STEP 5", "Use to identify serotype among >90 pneumococcal capsular types"],
]
quel_data = [[Paragraph(f"<b>{r[0]}</b>", TABLE_HD), Paragraph(r[1], TABLE_BD)] for r in quel_steps]
quel_tbl = Table(quel_data, colWidths=[W*0.15, W*0.85])
quel_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (0,-1), C_HEAD),
    ("ROWBACKGROUNDS",(1,0), (1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("VALIGN",        (1,0), (1,-1), "TOP"),
]))
story.append(quel_tbl)
story.append(SP(6))

story.append(section_header("Key Facts & Applications"))
story.append(SP(3))
story.append(info_box("Important Points", [
    "Also called: Neufeld's Quellung reaction / Capsule swelling test",
    "Used for: S. pneumoniae (>90 serotypes), H. influenzae (6 serotypes: a-f), N. meningitidis",
    "Mechanism: Antibody + capsular polysaccharide → Ag-Ab complex → Increased refractivity → APPARENT swelling",
    "NOT actual swelling - it's OPTICAL change due to Ab binding",
    "Omniserum: Polyvalent pooled antiserum; tests all serotypes at once",
    "Diagnostic use: Serotyping of pneumococcal strains for epidemiology",
    "Quellung positive = ENCAPSULATED virulent strain (capsule = virulence factor)",
    "Quellung vs India ink: Both show capsule; India ink = exclusion stain; Quellung = immunological",
], bg=C_GREEN))
story.append(SP(6))

story.append(section_header("Pneumococcal Virulence & Other Tests"))
story.append(SP(4))

pneumo_data = [
    [Paragraph("<b>Test</b>", TABLE_HD), Paragraph("<b>Pneumococcus Result</b>", TABLE_HD), Paragraph("<b>Significance</b>", TABLE_HD)],
    [Paragraph("Gram stain", TABLE_BD), Paragraph("Gram-positive diplococci (lancet-shaped)", TABLE_BD), Paragraph("Morphology identification", TABLE_BD)],
    [Paragraph("Optochin test", TABLE_BD), Paragraph("SENSITIVE (inhibition ≥14mm)", TABLE_BD), Paragraph("Differentiates from viridans strep", TABLE_BD)],
    [Paragraph("Bile solubility", TABLE_BD), Paragraph("POSITIVE (lyses in bile salts)", TABLE_BD), Paragraph("Autolysin enzyme lyses own cell wall", TABLE_BD)],
    [Paragraph("Quellung reaction", TABLE_BD), Paragraph("POSITIVE (capsule swelling)", TABLE_BD), Paragraph("Gold standard for serotyping", TABLE_BD)],
    [Paragraph("Mouse virulence", TABLE_BD), Paragraph("POSITIVE (kills within 24-48 hrs)", TABLE_BD), Paragraph("Historically used; rarely done now", TABLE_BD)],
    [Paragraph("Inulin fermentation", TABLE_BD), Paragraph("POSITIVE", TABLE_BD), Paragraph("Differentiates from other strep", TABLE_BD)],
    [Paragraph("Alpha hemolysis", TABLE_BD), Paragraph("POSITIVE (green zone on blood agar)", TABLE_BD), Paragraph("Partial hemolysis by pneumolysin", TABLE_BD)],
]
pneumo_tbl = Table(pneumo_data, colWidths=[W*0.27, W*0.37, W*0.36])
pneumo_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(pneumo_tbl)
story.append(SP(6))

story.append(key_point_box("Quellung = Ab binds capsule → APPARENT swelling (refractive change). Identifies >90 serotypes of S. pneumoniae."))
story.append(SP(4))
story.append(mnemonic_box("'Quellung = Queen swells her CAPSULE when met with specific antibody (her royal guard)'"))
story.append(SP(8))

# Final summary page
story.append(PageBreak())
story.append(chapter_banner("QUICK REVISION SUMMARY"))
story.append(SP(8))

summary_data = [
    [Paragraph("<b>Topic</b>", TABLE_HD), Paragraph("<b>Gold Standard / Key Test</b>", TABLE_HD), Paragraph("<b>Remember</b>", TABLE_HD)],
    [Paragraph("Diphtheria Lab Dx", TABLE_BD), Paragraph("ELEK test (toxigenicity)", TABLE_BD), Paragraph("Tinsdale medium; gray-black + brown halo", TABLE_BD)],
    [Paragraph("TB Lab Dx", TABLE_BD), Paragraph("Culture on LJ medium / MGIT", TABLE_BD), Paragraph("ZN stain (rapid); GeneXpert (RIF resistance)", TABLE_BD)],
    [Paragraph("Typical Pneumonia", TABLE_BD), Paragraph("Sputum culture + Quellung", TABLE_BD), Paragraph("Optochin sensitive; bile soluble", TABLE_BD)],
    [Paragraph("Atypical Pneumonia", TABLE_BD), Paragraph("Mycoplasma: Cold agglutinin", TABLE_BD), Paragraph("Legionella: Urine antigen + BCYE agar", TABLE_BD)],
    [Paragraph("Opp. Fungi", TABLE_BD), Paragraph("Crypto: India ink / CrAg", TABLE_BD), Paragraph("Mucor = aseptate; Aspergillus = septate", TABLE_BD)],
    [Paragraph("Antigenic Shift", TABLE_BD), Paragraph("Reassortment → Pandemic", TABLE_BD), Paragraph("Only Influenza A; animal reservoir", TABLE_BD)],
    [Paragraph("Antigenic Drift", TABLE_BD), Paragraph("Point mutations → Epidemic", TABLE_BD), Paragraph("All Inf. A, B, C; annual seasonal flu", TABLE_BD)],
    [Paragraph("MMR Vaccine", TABLE_BD), Paragraph("Live attenuated; 2 doses", TABLE_BD), Paragraph("RA 27/3 (Rubella); Jeryl Lynn (Mumps)", TABLE_BD)],
    [Paragraph("Satellitism", TABLE_BD), Paragraph("H. influenzae + Staph aureus", TABLE_BD), Paragraph("Needs Factor X + V; grows near Staph", TABLE_BD)],
    [Paragraph("EBV / Inf. Mono", TABLE_BD), Paragraph("Monospot (heterophile Ab)", TABLE_BD), Paragraph("VCA IgM = acute; atypical lymphocytes", TABLE_BD)],
    [Paragraph("Quellung Reaction", TABLE_BD), Paragraph("Ab + Capsule → apparent swelling", TABLE_BD), Paragraph("Serotypes pneumococcus; also H. influenzae", TABLE_BD)],
]

summ_tbl = Table(summary_data, colWidths=[W*0.25, W*0.35, W*0.40])
summ_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_HEAD),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_BOX_BG]),
    ("GRID",          (0,0), (-1,-1), 0.5, colors.HexColor("#B0BEC5")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(summ_tbl)
story.append(SP(10))

story.append(Paragraph("Reference: Apurva Sastry Microbiology 4th Edition | Medical Microbiology 9e (Murray) | Sherris & Ryan 8e | Jawetz 28e", SMALL_S))

# ── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated: {OUTPUT}")
Running Command

cd /tmp/workspace/microbiology-notes && python generate_pdf.py 2>&1

Editing File

~/microbiology-notes/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/microbiology-notes/generate_pdf.py'
Editing File

~/microbiology-notes/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/microbiology-notes/generate_pdf.py'
Editing File

~/microbiology-notes/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/microbiology-notes/generate_pdf.py'
Running Command

cd /tmp/workspace/microbiology-notes && python generate_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/microbiology-notes/Microbiology_6mark_Notes.pdf

Your PDF is ready! Here's the download link:

Microbiology 6mark Notes

PDF Document · PDF


What's Inside the PDF

The PDF is formatted as a picture-format study guide with color-coded tables, step-by-step flowcharts, key point boxes, and mnemonics - 6-mark answer style throughout. Here's a summary of every topic:

1. Diphtheria - Lab Diagnosis

  • Step-by-step flowchart: Specimen → Microscopy → Culture → Biochemical → Toxigenicity
  • Media comparison table: Loeffler's vs Tinsdale vs CTBA
  • Elek test = gold standard for toxigenicity (immunodiffusion with antitoxin strip)
  • PCR for tox gene (direct on swab)
  • Key: Tinsdale = gray-black colonies + brown halo (cysteinase)

2. Pulmonary TB - Lab Diagnosis

  • ZN stain (red AFBs on blue background), Auramine-rhodamine (fluorescent)
  • Culture: LJ medium (gold standard, 6-8 weeks), MGIT (1-3 weeks)
  • GeneXpert MTB/RIF - detects MTB + RIF resistance in 2 hours
  • Mantoux / IGRAs for immune testing

3. Typical Pneumonia (Pneumococcus)

  • Sputum Gram stain, blood culture, Quellung reaction, Urine antigen (Binax NOW)
  • Optochin SENSITIVE + Bile SOLUBLE = S. pneumoniae

4. Atypical Pneumonia

  • Full comparison table: Mycoplasma (cold agglutinin + Eaton's agar), Legionella (BCYE + urine antigen), Chlamydia (MIF test), Coxiella (IFA)
  • Typical vs Atypical side-by-side comparison

5. Opportunistic Fungal Infections

  • Risk factor table + 5 major fungi table
  • Candida (germ tube), Cryptococcus (India ink + CrAg), Aspergillus (galactomannan + CT halo sign), Mucor (aseptate hyphae), PCP (GMS stain)

6. Antigenic Shift & Drift

  • Color-coded comparison: DRIFT (point mutations → epidemic) vs SHIFT (reassortment → pandemic)
  • Pandemic examples table (1918 to 2009)

7. MMR Vaccine

  • Live attenuated; strains: Edmonston B/Schwarz (Measles), Jeryl Lynn (Mumps), RA 27/3 (Rubella)
  • Schedule, contraindications, CRS features

8. Satellitism

  • H. influenzae grows as satellite colonies around S. aureus on blood agar
  • Factor X (hemin) + Factor V (NAD) both required
  • Haemophilus species comparison table

9. EBV / Infectious Mononucleosis

  • Clinical triad: Fever + Sore throat + Lymphadenopathy
  • Monospot (heterophile Ab), VCA IgM (acute), EBNA IgG (past)
  • Atypical lymphocytes = activated CD8+ T cells (Downey cells)
  • EBV-associated malignancies table

10. Quellung Reaction

  • Ab + capsule → APPARENT swelling (optical/refractive change, not actual)
  • Pneumococcal test battery table: Optochin, Bile, Quellung, Inulin, Mouse virulence
  • Quick revision summary on last page
This is a shared conversation. Sign in to Orris to start your own chat.