python3 << 'PYEOF'
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_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, Image, PageBreak, HRFlowable,
KeepTogether)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.graphics.shapes import Drawing, Rect, String
import os
OUTPUT = '/tmp/workspace/pathogenic-organisms/output/Pathogenic_Organisms_Chapter.pdf'
DIAG_DIR = '/tmp/workspace/pathogenic-organisms/diagrams/'
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=2.0*cm, bottomMargin=2.0*cm,
title='Pathogenic Organisms - Full Chapter',
author='Medical Microbiology Notes'
)
W, H = A4
CONTENT_W = W - 3.6*cm
# ── Colour palette ──────────────────────────────────────────────────────────
C_NAVY = colors.HexColor('#1A3C6E')
C_RED = colors.HexColor('#922B21')
C_GREEN = colors.HexColor('#1A6E3C')
C_PURPLE = colors.HexColor('#6E1A5A')
C_ORANGE = colors.HexColor('#784212')
C_LIGHT_BLUE = colors.HexColor('#D6EAF8')
C_LIGHT_GREEN = colors.HexColor('#D5F5E3')
C_LIGHT_PURPLE = colors.HexColor('#E8DAEF')
C_LIGHT_ORANGE = colors.HexColor('#FDEBD0')
C_LIGHT_RED = colors.HexColor('#FADBD8')
C_LIGHT_GREY = colors.HexColor('#F2F3F4')
C_GOLD = colors.HexColor('#B7950B')
# ── Styles ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S('CoverTitle', fontSize=28, textColor=colors.white,
alignment=TA_CENTER, fontName='Helvetica-Bold', spaceAfter=6)
cover_sub = S('CoverSub', fontSize=14, textColor=colors.HexColor('#AED6F1'),
alignment=TA_CENTER, fontName='Helvetica', spaceAfter=4)
cover_info = S('CoverInfo', fontSize=11, textColor=colors.HexColor('#D6EAF8'),
alignment=TA_CENTER, fontName='Helvetica')
h1 = S('H1', fontSize=17, textColor=colors.white, fontName='Helvetica-Bold',
spaceBefore=14, spaceAfter=6, alignment=TA_LEFT,
backColor=C_NAVY, borderPad=6, leftIndent=-2)
h2 = S('H2', fontSize=13, textColor=C_NAVY, fontName='Helvetica-Bold',
spaceBefore=10, spaceAfter=4, borderPad=4,
borderWidth=0, leftIndent=0)
h3 = S('H3', fontSize=11, textColor=C_RED, fontName='Helvetica-Bold',
spaceBefore=8, spaceAfter=3)
h4 = S('H4', fontSize=10, textColor=C_GREEN, fontName='Helvetica-Bold',
spaceBefore=6, spaceAfter=2)
h5 = S('H5', fontSize=9.5, textColor=C_PURPLE, fontName='Helvetica-Bold',
spaceBefore=5, spaceAfter=2)
body = S('Body', fontSize=9, leading=14, alignment=TA_JUSTIFY,
spaceAfter=4, fontName='Helvetica')
bullet = S('Bullet', fontSize=9, leading=13, leftIndent=14,
bulletIndent=4, spaceAfter=2, fontName='Helvetica')
key_box = S('KeyBox', fontSize=9, leading=13, backColor=colors.HexColor('#FEF9E7'),
borderColor=C_GOLD, borderWidth=1, borderPad=6,
fontName='Helvetica', spaceAfter=6)
caption = S('Caption', fontSize=8, textColor=colors.HexColor('#555555'),
alignment=TA_CENTER, fontName='Helvetica-Oblique', spaceAfter=4)
def P(text, style=body): return Paragraph(text, style)
def SP(n=4): return Spacer(1, n)
def HR(col=C_NAVY, t=0.7): return HRFlowable(width='100%', thickness=t, color=col, spaceAfter=4, spaceBefore=4)
def IMG(fname, w=None, h=None):
path = DIAG_DIR + fname
if not os.path.exists(path): return SP(2)
if w is None: w = CONTENT_W
return Image(path, width=w, height=h or w*0.55, kind='proportional')
def section_header(text, color=C_NAVY):
tbl = Table([[Paragraph(f'<font color="white"><b>{text}</b></font>',
ParagraphStyle('sh', fontSize=12, textColor=colors.white,
fontName='Helvetica-Bold', alignment=TA_LEFT))]],
colWidths=[CONTENT_W])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('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 sub_header(text, color=C_LIGHT_BLUE, tc=C_NAVY):
tbl = Table([[Paragraph(f'<b>{text}</b>',
ParagraphStyle('subh', fontSize=10.5, textColor=tc,
fontName='Helvetica-Bold'))]],
colWidths=[CONTENT_W])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
('LINEBELOW', (0,0), (-1,-1), 1.5, tc),
]))
return tbl
def organism_table(rows, col_headers, col_widths, header_color=C_NAVY):
data = [col_headers] + rows
tbl = Table(data, colWidths=col_widths, repeatRows=1)
style = [
('BACKGROUND', (0,0), (-1,0), header_color),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, C_LIGHT_GREY]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#CCCCCC')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
('WORDWRAP', (0,0), (-1,-1), True),
]
tbl.setStyle(TableStyle(style))
return tbl
def info_card(label, items, bg_color=C_LIGHT_BLUE, label_color=C_NAVY):
"""A two-column card: label on left, items on right."""
bullets = ''.join(f'• {i}<br/>' for i in items)
data = [[
Paragraph(f'<b>{label}</b>', ParagraphStyle('lbl', fontSize=8.5, textColor=label_color,
fontName='Helvetica-Bold')),
Paragraph(bullets, ParagraphStyle('itm', fontSize=8.5, leading=12, fontName='Helvetica'))
]]
tbl = Table(data, colWidths=[2.8*cm, CONTENT_W-2.8*cm])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,0), bg_color),
('BACKGROUND', (1,0), (1,0), colors.white),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('BOX', (0,0), (-1,-1), 0.8, label_color),
('LINEAFTER', (0,0), (0,-1), 0.8, label_color),
]))
return tbl
# ════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER PAGE ──────────────────────────────────────────────────────────────
cover_bg = Table([
[Paragraph('CHAPTER', ParagraphStyle('ct', fontSize=13, textColor=colors.HexColor('#AED6F1'),
alignment=TA_CENTER, fontName='Helvetica'))],
[Paragraph('Pathogenic Organisms', ParagraphStyle('ct2', fontSize=30, textColor=colors.white,
alignment=TA_CENTER, fontName='Helvetica-Bold', leading=34))],
[SP(6)],
[Paragraph('Complete Chapter Notes', ParagraphStyle('ct3', fontSize=16, textColor=colors.HexColor('#AED6F1'),
alignment=TA_CENTER, fontName='Helvetica'))],
[SP(8)],
[HR(colors.HexColor('#5DADE2'), 1.5)],
[SP(4)],
[Paragraph('Covering: Bacteria (Cocci & Bacilli) • Viruses • Fungi • Parasites • Vectors & Rodents',
ParagraphStyle('ct4', fontSize=11, textColor=colors.HexColor('#D6EAF8'),
alignment=TA_CENTER, fontName='Helvetica', leading=16))],
[SP(4)],
[Paragraph('Characteristics • Source • Portal of Entry • Transmission • Disease Identification',
ParagraphStyle('ct5', fontSize=10, textColor=colors.HexColor('#AED6F1'),
alignment=TA_CENTER, fontName='Helvetica-Oblique'))],
[SP(16)],
[Paragraph('Medical Microbiology | Nursing & Allied Health Sciences',
ParagraphStyle('ct6', fontSize=10, textColor=colors.HexColor('#85C1E9'),
alignment=TA_CENTER, fontName='Helvetica'))],
], colWidths=[CONTENT_W])
cover_bg.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), C_NAVY),
('TOPPADDING', (0,0), (-1,-1), 10),
('BOTTOMPADDING', (0,0), (-1,-1), 10),
('BOX', (0,0), (-1,-1), 3, colors.HexColor('#5DADE2')),
('ROUNDEDCORNERS', [8,8,8,8]),
]))
story.append(SP(30))
story.append(cover_bg)
story.append(PageBreak())
# ── INTRODUCTION ─────────────────────────────────────────────────────────────
story.append(section_header('INTRODUCTION TO PATHOGENIC ORGANISMS'))
story.append(SP(6))
story.append(P('A <b>pathogenic organism</b> is any microorganism capable of causing disease in a susceptible host. The ability to cause disease (<i>pathogenicity</i>) depends on:'))
story.append(SP(3))
intro_items = [
['Virulence of the organism', 'Presence of toxins, enzymes, capsules, pili'],
['Portal of entry', 'Respiratory, GI, skin, mucosal surfaces'],
['Infective dose', 'Minimum number of organisms required to cause infection'],
['Host immune status', 'Immunocompromised hosts are more susceptible'],
]
intro_tbl = Table(intro_items, colWidths=[5.5*cm, CONTENT_W-5.5*cm])
intro_tbl.setStyle(TableStyle([
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTNAME', (1,0), (1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,0), (-1,-1), [C_LIGHT_BLUE, colors.white]),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#BBBBBB')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(intro_tbl)
story.append(SP(8))
# Classification diagram
story.append(P('<b>Overview: Classification of Pathogenic Organisms</b>', caption))
story.append(IMG('fig1_classification.png', w=CONTENT_W))
story.append(P('Figure 1: Major groups of pathogenic organisms and their sub-classifications.', caption))
story.append(SP(6))
# ── PART 1: BACTERIA ──────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('PART 1: BACTERIA', C_NAVY))
story.append(SP(6))
story.append(P('Bacteria are unicellular prokaryotes that lack a membrane-bound nucleus. They are classified by <b>Gram staining</b> into Gram-positive and Gram-negative based on cell wall differences.'))
story.append(SP(4))
story.append(IMG('fig2_gramstain.png', w=CONTENT_W))
story.append(P('Figure 2: Gram-positive vs Gram-negative cell wall structure.', caption))
story.append(SP(4))
story.append(IMG('fig3_shapes.png', w=CONTENT_W))
story.append(P('Figure 3: Bacterial shapes and cellular arrangements.', caption))
story.append(SP(8))
# Gram stain comparison table
gs_rows = [
['Peptidoglycan layer', 'Thick (20-80 nm)', 'Thin (2-7 nm)'],
['Outer membrane', 'Absent', 'Present (contains LPS/endotoxin)'],
['Teichoic acids', 'Present', 'Absent'],
['Colour after Gram stain', 'Purple/Violet', 'Pink/Red'],
['Antibiotic sensitivity', 'Penicillin, Vancomycin sensitive', 'Often resistant; Beta-lactam variable'],
['Examples', 'Staph, Strep, Bacillus, Clostridium', 'E.coli, Salmonella, Neisseria, Vibrio'],
]
story.append(organism_table(gs_rows,
[Paragraph('<b>Feature</b>', ParagraphStyle('h', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold')),
Paragraph('<b>Gram-Positive</b>', ParagraphStyle('h', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold')),
Paragraph('<b>Gram-Negative</b>', ParagraphStyle('h', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold'))],
[5.0*cm, 6.5*cm, 6.5*cm], C_NAVY))
story.append(SP(4))
story.append(P('Table 1: Comparison of Gram-positive and Gram-negative bacteria.', caption))
# ── GRAM POSITIVE COCCI ──────────────────────────────────────────────────────
story.append(PageBreak())
story.append(sub_header('A. COCCI (Spherical Bacteria)', C_LIGHT_BLUE, C_NAVY))
story.append(SP(4))
story.append(sub_header('1. GRAM-POSITIVE COCCI', colors.HexColor('#D5F5E3'), C_GREEN))
story.append(SP(6))
# Staphylococcus aureus card
story.append(P('<b>(a) Staphylococcus aureus</b>', h3))
sa_data = [
['Morphology', 'Gram+ve cocci in grape-like clusters; non-motile, non-spore forming'],
['Key Features', 'Coagulase-POSITIVE (distinguishes from CoNS); Beta-hemolytic; golden pigment on agar'],
['Virulence Factors', 'Coagulase, hyaluronidase, staphylokinase, exotoxins, TSST-1, PVL, enterotoxins'],
['Source', 'Human nose/skin (normal flora); contaminated food; hospital environment'],
['Portal of Entry', 'Skin breaks, wounds, respiratory tract, IV lines'],
['Transmission', 'Direct contact, droplet nuclei, fomites, contaminated food'],
['Diseases', 'Boils/carbuncles, impetigo, septicemia, osteomyelitis, endocarditis, food poisoning, TSS, SSSS'],
['Identification', 'Catalase+, Coagulase+; Mannitol Salt Agar (yellow); DNase+; blood agar beta-hemolysis'],
]
sa_tbl = Table(sa_data, colWidths=[3.5*cm, CONTENT_W-3.5*cm])
sa_tbl.setStyle(TableStyle([
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTNAME', (1,0), (1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,0), (-1,-1), [C_LIGHT_BLUE, colors.white]),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#BBBBBB')),
('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(sa_tbl)
story.append(SP(8))
# Streptococcus pyogenes
story.append(P('<b>(b) Streptococcus pyogenes (Group A Streptococcus)</b>', h3))
sp_data = [
['Morphology', 'Gram+ve cocci in chains; catalase-NEGATIVE; beta-hemolytic'],
['Key Features', 'Bacitracin SENSITIVE (Disc A test); M protein (antiphagocytic); produces streptolysin O & S'],
['Source', 'Human throat/skin; carriers common'],
['Portal of Entry', 'Respiratory tract (droplets), broken skin'],
['Transmission', 'Respiratory droplets, direct contact'],
['Diseases', 'Pharyngitis ("strep throat"), scarlet fever, impetigo, erysipelas, necrotizing fasciitis; Post-strep: Rheumatic fever, APSGN'],
['Identification', 'Beta-hemolysis; Bacitracin sensitive; ASO titer for post-streptococcal disease'],
]
sp_tbl = Table(sp_data, colWidths=[3.5*cm, CONTENT_W-3.5*cm])
sp_tbl.setStyle(TableStyle([
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTNAME', (1,0), (1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,0), (-1,-1), [C_LIGHT_GREEN, colors.white]),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#BBBBBB')),
('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(sp_tbl)
story.append(SP(8))
# Streptococcus pneumoniae
story.append(P('<b>(c) Streptococcus pneumoniae (Pneumococcus)</b>', h3))
pn_data = [
['Morphology', 'Gram+ve lancet-shaped diplococci; encapsulated; alpha-hemolytic (green)'],
['Key Features', 'Optochin SENSITIVE; bile SOLUBLE; Quellung reaction +ve'],
['Source', 'Normal flora of nasopharynx; carrier state common'],
['Portal of Entry', 'Respiratory tract'],
['Transmission', 'Respiratory droplets'],
['Diseases', 'Lobar pneumonia, bacterial meningitis, otitis media, sinusitis, bacteremia'],
['Identification', 'Optochin disc sensitivity; bile solubility test; Quellung (capsular swelling) reaction'],
]
pn_tbl = Table(pn_data, colWidths=[3.5*cm, CONTENT_W-3.5*cm])
pn_tbl.setStyle(TableStyle([
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTNAME', (1,0), (1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,0), (-1,-1), [C_LIGHT_PURPLE, colors.white]),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#BBBBBB')),
('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(pn_tbl)
# ── GRAM NEGATIVE COCCI ──────────────────────────────────────────────────────
story.append(PageBreak())
story.append(sub_header('2. GRAM-NEGATIVE COCCI', C_LIGHT_RED, C_RED))
story.append(SP(6))
neisseria_rows = [
[Paragraph('<b>Feature</b>', ParagraphStyle('h2', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold')),
Paragraph('<b>N. meningitidis (Meningococcus)</b>', ParagraphStyle('h2', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold')),
Paragraph('<b>N. gonorrhoeae (Gonococcus)</b>', ParagraphStyle('h2', fontSize=8, textColor=colors.white, fontName='Helvetica-Bold'))],
['Morphology', 'Gram-ve diplococci; encapsulated', 'Gram-ve diplococci; non-encapsulated'],
['Sugar fermented', 'Glucose AND Maltose', 'Glucose ONLY (not maltose)'],
['Source', 'Nasopharynx (carrier state)', 'Infected humans only (no animal reservoir)'],
['Portal of Entry', 'Respiratory tract', 'Urogenital mucosa, conjunctiva'],
['Transmission', 'Respiratory droplets; close contact', 'Sexual contact; vertical (mother to neonate)'],
['Diseases', 'Bacterial meningitis; Meningococcemia; Waterhouse-Friderichsen syndrome', 'Urethritis; Cervicitis; PID; Ophthalmia neonatorum; DGI'],
['Identification', 'Thayer-Martin medium; Oxidase+; Latex agglutination', 'Thayer-Martin medium; Gram stain of discharge; NAAT (gold standard)'],
]
n_tbl = Table([[r] if isinstance(r, Paragraph) else
[Paragraph(str(c), ParagraphStyle('cell', fontSize=8, fontName='Helvetica')) for c in r]
for r in neisseria_rows],
colWidths=[3.2*cm, 6.4*cm, 6.4*cm])
# Rebuild properly
n_data = [neisseria_rows[0]]
for row in neisseria_rows[1:]:
n_data.append([Paragraph(str(c), ParagraphStyle('cell', fontSize=8, fontName='Helvetica', leading=11)) for c in row])
n_tbl2 = Table(n_data, colWidths=[3.2*cm, 6.4*cm, 6.4*cm])
n_tbl2.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), C_RED),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS', (0,1), (-1,-1), [C_LIGHT_RED, colors.white]),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#CCCCCC')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
]))
story.append(n_tbl2)
story.append(P('Table 2: Comparison of Neisseria meningitidis and Neisseria gonorrhoeae.', caption))
story.append(SP(8))
# ── BACILLI ───────────────────────────────────────────────────────────────────
story.append(sub_header('B. BACILLI (Rod-Shaped Bacteria)', C_LIGHT_BLUE, C_NAVY))
story.append(SP(4))
story.append(sub_header('1. GRAM-POSITIVE BACILLI', colors.HexColor('#D5F5E3'), C_GREEN))
story.append(SP(6))
# Summary table for Gram-positive bacilli
gpb_rows = [
['Bacillus anthracis', 'Anthrax', 'Spores in soil/animal products', 'Skin, lungs, GI', 'Contact/inhalation/ingestion', '"Medusa head" colonies; non-motile; capsule stain'],
['Clostridium tetani', 'Tetanus', 'Soil, animal feces', 'Deep wounds', 'Wound contamination with spores', '"Drumstick" shape; clinical diagnosis; strict anaerobe'],
['Clostridium perfringens', 'Gas gangrene; Food poisoning', 'Soil, intestinal flora', 'Contaminated wounds', 'Wound contamination', 'Double zone hemolysis; alpha toxin (lecithinase); stormy fermentation'],
['Clostridium botulinum', 'Botulism', 'Soil, improperly canned food', 'GI tract (ingestion)', 'Ingestion of preformed toxin', 'Flaccid paralysis; blocks ACh release at NMJ'],
['Mycobacterium tuberculosis', 'Tuberculosis', 'Active TB patients', 'Respiratory (primary)', 'Airborne droplet nuclei', 'ZN stain (AFB); LJ medium; GeneXpert MTB/RIF'],
['Corynebacterium diphtheriae', 'Diphtheria', 'Human throat/carriers', 'Respiratory tract', 'Droplet, contact', 'Chinese letter arrangement; Albert stain (metachromatic granules); Elek test'],
]
story.append(organism_table(gpb_rows,
['Organism', 'Disease', 'Source', 'Portal of Entry', 'Transmission', 'Identification'],
[3.0*cm, 3.0*cm, 2.8*cm, 2.5*cm, 2.8*cm, 3.9*cm], C_GREEN))
story.append(P('Table 3: Important Gram-positive bacilli - diseases, transmission and identification.', caption))
story.append(SP(8))
# Mycobacterium TB - detailed box
story.append(P('<b>Note on Mycobacterium tuberculosis (Special AFB organism):</b>', h4))
tb_key = Table([
[Paragraph('• Cell wall contains mycolic acids → responsible for acid-fastness\n'
'• ZN (Ziehl-Neelsen) stain: red AFB on blue background\n'
'• Slow-growing: 3-8 weeks on LJ (Lowenstein-Jensen) medium\n'
'• Virulence factors: cord factor (trehalose dimycolate), sulfatides\n'
'• Ghon complex = primary lesion in lung + hilar lymph node\n'
'• Mantoux test (PPD): >10 mm = positive in general population\n'
'• GeneXpert MTB/RIF: rapid molecular diagnosis; also detects rifampicin resistance',
ParagraphStyle('tb', fontSize=8.5, leading=13, fontName='Helvetica'))]
], colWidths=[CONTENT_W])
tb_key.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#FEF9E7')),
('BOX', (0,0), (-1,-1), 1.5, C_GOLD),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
story.append(tb_key)
story.append(SP(8))
# ── GRAM NEGATIVE BACILLI ────────────────────────────────────────────────────
story.append(PageBreak())
story.append(sub_header('2. GRAM-NEGATIVE BACILLI', C_LIGHT_RED, C_RED))
story.append(SP(6))
gnb_rows = [
['Escherichia coli', 'UTI, diarrhea (ETEC/EPEC/EHEC), neonatal meningitis, septicemia', 'Human colon flora; contaminated food/water', 'GI, urinary tract', 'Fecal-oral', 'MacConkey agar: PINK colonies (lactose fermenter); IMViC: ++--'],
['Salmonella typhi', 'Enteric fever (Typhoid): stepladder fever, rose spots, bradycardia', 'Infected humans; chronic carriers', 'GI (oral)', 'Fecal-oral; contaminated food/water', 'Non-lactose fermenter; H2S+; Widal test; blood culture (1st week)'],
['Salmonella spp.', 'Salmonellosis (gastroenteritis)', 'Poultry, eggs, contaminated food', 'GI tract', 'Fecal-oral; food-borne', 'Non-lactose fermenter; H2S+; SS agar'],
['Shigella spp.', 'Bacillary dysentery (bloody diarrhea)', 'Human feces; contaminated food/water', 'GI tract', 'Fecal-oral (low infective dose)', 'Non-motile; non-lactose fermenter; no H2S'],
['Vibrio cholerae', 'Cholera: "rice-water" diarrhea, severe dehydration', 'Contaminated water, raw seafood', 'GI (oral)', 'Fecal-oral; waterborne', 'Comma-shaped; TCBS agar (YELLOW colonies); Oxidase+; String test+'],
['Pseudomonas aeruginosa', 'HAP, burn infections, UTI, CF lung infection, ecthyma gangrenosum', 'Soil, water, hospital environment', 'Wounds, respiratory, catheters', 'Contact; nosocomial', 'Blue-green pigment (pyocyanin); grape odor; Oxidase+; non-fermenter'],
['Klebsiella pneumoniae', 'Pneumonia ("currant jelly" sputum), UTI, hospital infections', 'Human GI; hospital environment', 'Respiratory, urinary tract', 'Nosocomial', 'Mucoid colonies; capsule; non-motile; lactose fermenter'],
['Yersinia pestis', 'Plague: bubonic, septicemic, pneumonic', 'Rodents (rats); rat fleas', 'Skin (flea bite)', 'Flea bite (Xenopsylla cheopis)', '"Safety pin" bipolar staining; non-motile; culture at 28°C'],
['Haemophilus influenzae', 'Meningitis (esp. children), epiglottitis, pneumonia', 'Nasopharynx of humans', 'Respiratory tract', 'Respiratory droplets', 'Chocolate agar; X and V factor requirements; satellite phenomenon'],
['Bordetella pertussis', 'Whooping cough (pertussis)', 'Human respiratory tract', 'Respiratory tract', 'Respiratory droplets', 'Bordet-Gengou agar; cough plate method'],
]
story.append(organism_table(gnb_rows,
['Organism', 'Diseases', 'Source', 'Portal of Entry', 'Transmission', 'Identification'],
[3.0*cm, 4.0*cm, 2.5*cm, 2.0*cm, 2.5*cm, 4.0*cm], C_RED))
story.append(P('Table 4: Important Gram-negative bacilli - summary of key features.', caption))
# ── PART 2: VIRUSES ──────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('PART 2: VIRUSES', colors.HexColor('#7B241C')))
story.append(SP(6))
story.append(P('Viruses are <b>obligate intracellular parasites</b> consisting of a nucleic acid core (DNA or RNA) surrounded by a protein coat (<i>capsid</i>). They are the smallest infectious agents (20-300 nm), visible only by electron microscopy.'))
story.append(SP(6))
story.append(IMG('fig4_virus.png', w=CONTENT_W))
story.append(P('Figure 4: Structure of non-enveloped and enveloped viruses.', caption))
story.append(SP(6))
# Virus properties table
vp_rows = [
['Size', '20-300 nm', 'Smaller than bacteria; require electron microscopy'],
['Nucleic acid', 'DNA OR RNA (never both)', 'Each virus has only one type of nucleic acid'],
['Cell wall', 'Absent', 'Some have a lipid envelope derived from host membrane'],
['Ribosomes', 'Absent', 'Cannot synthesize own proteins; depend entirely on host'],
['Reproduction', 'Intracellular only', 'Cannot replicate outside living host cells'],
['Antibiotic response', 'No effect', 'Antibiotics ineffective; antivirals required'],
['Capsid', 'Always present', 'Protects nucleic acid; determines shape'],
['Envelope', 'Present or absent', 'Enveloped viruses more susceptible to disinfectants'],
]
story.append(organism_table(vp_rows,
['Feature', 'Characteristic', 'Clinical Significance'],
[3.5*cm, 4.5*cm, 10.0*cm], colors.HexColor('#7B241C')))
story.append(P('Table 5: General properties of viruses.', caption))
story.append(SP(8))
# DNA Viruses table
story.append(sub_header('A. MEDICALLY IMPORTANT DNA VIRUSES', colors.HexColor('#FADBD8'), colors.HexColor('#7B241C')))
story.append(SP(4))
dna_rows = [
['Herpesviridae', 'HSV-1, HSV-2', 'Oral/genital herpes; cold sores; encephalitis', 'Direct contact, sexual, vertical', 'Tzanck smear; viral culture; PCR'],
['Herpesviridae', 'Varicella-zoster (VZV)', 'Chickenpox (primary); Herpes zoster/shingles (reactivation)', 'Respiratory droplets; contact', 'Clinical; DFA; PCR'],
['Herpesviridae', 'CMV', 'Congenital CMV; retinitis/pneumonia in AIDS', 'Blood, saliva, sexual, transplant', 'CMV antigenemia; PCR; shell vial culture'],
['Herpesviridae', 'EBV', 'Infectious mononucleosis ("kissing disease")', 'Saliva (oral contact)', 'Monospot test; Paul-Bunnell test; EBV serology'],
['Hepadnaviridae', 'Hepatitis B virus (HBV)', 'Hepatitis B; cirrhosis; hepatocellular carcinoma', 'Blood, sexual, vertical (perinatal)', 'HBsAg, HBeAg, HBcAb, HBV DNA (PCR)'],
['Papillomaviridae', 'HPV (16, 18)', 'Genital warts; cervical/anal cancer; laryngeal papillomatosis', 'Sexual contact; vertical', 'Pap smear; colposcopy; HPV DNA typing'],
['Adenoviridae', 'Adenovirus', 'Pharyngitis, pneumonia, conjunctivitis, gastroenteritis', 'Respiratory, fecal-oral, contact', 'Rapid antigen test; PCR; culture'],
['Poxviridae', 'Molluscum contagiosum', 'Umbilicated skin papules', 'Direct contact', 'Clinical; Henderson-Patterson bodies on biopsy'],
]
story.append(organism_table(dna_rows,
['Family', 'Virus', 'Diseases', 'Transmission', 'Identification'],
[3.0*cm, 3.5*cm, 5.5*cm, 3.5*cm, 3.5*cm], colors.HexColor('#7B241C')))
story.append(P('Table 6: Medically important DNA viruses.', caption))
story.append(SP(8))
story.append(sub_header('B. MEDICALLY IMPORTANT RNA VIRUSES', colors.HexColor('#FADBD8'), colors.HexColor('#7B241C')))
story.append(SP(4))
rna_rows = [
['Orthomyxoviridae', 'Influenza A, B, C', 'Influenza ("flu"): fever, cough, myalgia; can cause pandemics', 'Respiratory droplets', 'Rapid Ag test; RT-PCR; culture'],
['Paramyxoviridae', 'Measles (Rubeola)', 'Measles: Koplik spots, maculopapular rash (3 Cs: cough, coryza, conjunctivitis)', 'Respiratory droplets (highly contagious)', 'Clinical; serology; PCR'],
['Paramyxoviridae', 'Mumps', 'Parotitis; orchitis; meningitis', 'Respiratory droplets', 'Serology; PCR'],
['Paramyxoviridae', 'RSV', 'Bronchiolitis in infants; pneumonia in elderly/immunocompromised', 'Contact; respiratory droplets', 'Rapid Ag test; PCR'],
['Togaviridae', 'Rubella', 'German measles; Congenital rubella syndrome (CRS)', 'Respiratory droplets', 'Serology (IgM); PCR'],
['Flaviviridae', 'Dengue (DENV 1-4)', '"Breakbone fever"; DHF; DSS', 'Aedes aegypti mosquito bite', 'NS1 antigen; IgM/IgG ELISA; RT-PCR'],
['Flaviviridae', 'Hepatitis C (HCV)', 'Hepatitis C; cirrhosis; HCC', 'Blood (transfusion, IV drugs), sexual', 'Anti-HCV (ELISA); HCV RNA (PCR)'],
['Retroviridae', 'HIV-1, HIV-2', 'AIDS: CD4 count <200; opportunistic infections', 'Blood, sexual, vertical', 'ELISA (screening); Western blot (confirmation); CD4; viral load'],
['Rhabdoviridae', 'Rabies virus', 'Rabies: hydrophobia, aerophobia, encephalitis; always fatal if untreated', 'Bite of infected animal (dog, bat)', 'Negri bodies (histology); DFA; PCR'],
['Picornaviridae', 'Poliovirus', 'Poliomyelitis: flaccid paralysis; eradicated in most countries', 'Fecal-oral', 'Stool viral culture; PCR'],
['Coronaviridae', 'SARS-CoV-2', 'COVID-19: fever, cough, breathlessness, anosmia', 'Respiratory droplets; aerosol', 'RT-PCR (gold standard); Rapid Ag test'],
['Filoviridae', 'Ebola virus', 'Ebola hemorrhagic fever; high CFR', 'Direct contact with body fluids', 'PCR; ELISA; BSL-4 precautions required'],
]
story.append(organism_table(rna_rows,
['Family', 'Virus', 'Diseases', 'Transmission', 'Identification'],
[3.0*cm, 3.5*cm, 5.5*cm, 3.5*cm, 3.5*cm], colors.HexColor('#7B241C')))
story.append(P('Table 7: Medically important RNA viruses.', caption))
# ── PART 3: FUNGI ──────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('PART 3: FUNGI', C_GREEN))
story.append(SP(6))
story.append(P('Fungi are <b>eukaryotic organisms</b> with a rigid cell wall containing <b>chitin</b> (not peptidoglycan). They are heterotrophs, reproducing by spores. Pathogenic fungi are classified by the body region they infect.'))
story.append(SP(4))
story.append(IMG('fig5_fungi.png', w=CONTENT_W))
story.append(P('Figure 5: Classification of medically important fungi.', caption))
story.append(SP(6))
# Key concepts table
fc_rows = [
['Hyphae', 'Thread-like filamentous extensions of fungi; may be septate or non-septate (coenocytic)'],
['Mycelium', 'Mass of hyphae forming the vegetative body of a fungus'],
['Yeast', 'Unicellular fungi; reproduce by budding; e.g. Candida, Cryptococcus'],
['Mold', 'Multicellular fungi with hyphae; e.g. Aspergillus, Dermatophytes'],
['Dimorphic fungi', 'Exhibit YEAST form at 37°C (in body) and MOLD form at 25°C (environment); e.g. Histoplasma, Coccidioides, Blastomyces, Sporothrix'],
['Pseudohyphae', 'Chains of elongated budding cells; seen in Candida albicans'],
['Germ tube', 'Short hypha-like projection from yeast cell; POSITIVE in Candida albicans (Reynolds-Braude test)'],
]
story.append(organism_table(fc_rows,
['Term', 'Definition'],
[4.0*cm, CONTENT_W-4.0*cm], C_GREEN))
story.append(P('Table 8: Key terminology in mycology.', caption))
story.append(SP(8))
# Superficial mycoses
story.append(sub_header('A. SUPERFICIAL MYCOSES', C_LIGHT_GREEN, C_GREEN))
story.append(SP(4))
sup_rows = [
['Malassezia furfur', 'Pityriasis versicolor (Tinea versicolor)', 'Trunk, chest, back', 'Contact; endogenous (normal skin flora)', 'Hypo/hyperpigmented macules; KOH mount: "spaghetti and meatball" (short hyphae + round yeast)'],
['Piedraia hortae', 'Black piedra', 'Hair shafts (scalp)', 'Environment; contaminated water/soil', 'Hard black nodules on scalp hair; microscopy shows thick-walled asci with ascospores'],
['Trichosporon spp.', 'White piedra', 'Hair shafts (beard, axilla)', 'Direct contact', 'Soft, cream/white nodules on hair; microscopy shows arthrospores and blastospores'],
['Exophiala werneckii', 'Tinea nigra', 'Palms and soles', 'Contact with soil/plant matter', 'Brown-black non-scaly macules; KOH: brown septate hyphae and budding cells'],
]
story.append(organism_table(sup_rows,
['Organism', 'Disease', 'Site', 'Transmission', 'Identification'],
[3.0*cm, 3.5*cm, 2.5*cm, 3.0*cm, 6.0*cm], C_GREEN))
story.append(P('Table 9: Superficial mycoses.', caption))
story.append(SP(8))
# Cutaneous (Dermatophytes)
story.append(sub_header('B. CUTANEOUS MYCOSES (DERMATOPHYTOSES)', C_LIGHT_GREEN, C_GREEN))
story.append(SP(4))
cut_rows = [
['Tinea capitis', 'Scalp ringworm', 'Trichophyton tonsurans, Microsporum canis', 'Endothrix or ectothrix hair invasion; broken hair stubs'],
['Tinea corporis', 'Body ringworm', 'Trichophyton rubrum', 'Ring-shaped, scaly, pruritic lesion with central clearing'],
['Tinea pedis', "Athlete's foot", 'T. rubrum, T. interdigitale', 'Interdigital maceration, scaling; most common dermatophytosis'],
['Tinea unguium', 'Nail infection (Onychomycosis)', 'T. rubrum', 'Thickened, discolored, brittle nails; subungual debris'],
['Tinea cruris', "Jock itch", 'T. rubrum, Epidermophyton floccosum', 'Ring-shaped lesion in groin; spares scrotum'],
['Tinea barbae', 'Beard ringworm', 'Trichophyton spp.', 'Inflammatory lesion in bearded area of face/neck'],
['Tinea manuum', 'Hand ringworm', 'T. rubrum', 'Scaling of palms; often associated with tinea pedis'],
]
story.append(organism_table(cut_rows,
['Disease', 'Common Name', 'Organism', 'Key Features'],
[3.2*cm, 3.0*cm, 4.2*cm, 7.6*cm], colors.HexColor('#1A5276')))
story.append(P('Table 10: Cutaneous mycoses (dermatophytoses) - Tinea infections.', caption))
story.append(SP(4))
story.append(P('All dermatophytes are identified by: <b>KOH mount</b> (branching hyphae), <b>Wood\'s lamp</b> (green fluorescence in Microsporum), and <b>Sabouraud Dextrose Agar (SDA)</b> culture.', key_box))
story.append(SP(8))
# Deep/Systemic Mycoses
story.append(sub_header('C. DEEP (SYSTEMIC) MYCOSES', C_LIGHT_RED, C_RED))
story.append(SP(4))
deep_rows = [
['Histoplasma capsulatum', 'Histoplasmosis', 'Soil with bird/bat droppings (Ohio-Mississippi valley)', 'Inhalation of microconidia', 'Flu-like illness; pulmonary cavitation; disseminated disease in AIDS', 'Dimorphic; PAS/GMS stain shows small intracellular yeast inside macrophages; urine antigen'],
['Coccidioides immitis', 'Coccidioidomycosis ("Valley fever")', 'Soil of arid regions (SW USA, Mexico)', 'Inhalation of arthrospores', 'Flu-like; erythema nodosum; can disseminate to meninges/bones', 'Spherules with endospores in tissue; non-dimorphic; serology'],
['Blastomyces dermatitidis', 'Blastomycosis', 'Soil; endemic in North America', 'Inhalation', 'Pulmonary + skin verrucous lesions', 'Broad-based budding yeast (8-15 µm); double wall; silver stain'],
['Cryptococcus neoformans', 'Cryptococcosis', 'Pigeon/bird droppings', 'Inhalation', 'Meningitis in AIDS (CD4 <100); "soap bubble" lesions in brain', 'India ink: halo around capsule; Capsular antigen (latex agglutination); Urease+'],
['Aspergillus fumigatus', 'Aspergillosis', 'Ubiquitous in environment; soil/compost', 'Inhalation of conidia', 'Allergic (ABPA); Invasive in immunocompromised; Aspergilloma (fungus ball)', 'Septate hyphae with acute angle (45°) branching; galactomannan antigen; CT: halo sign'],
['Candida albicans', 'Candidiasis', 'Normal flora (oral, vaginal, GI)', 'Endogenous; overgrowth in immunocompromised', 'Oral thrush; vaginal candidiasis; invasive candidiasis (ICU patients)', 'Germ tube test+; pseudohyphae + blastospores; CHROMagar'],
['Pneumocystis jirovecii', 'PCP (Pneumocystis pneumonia)', 'Ubiquitous; acquired in childhood', 'Reactivation in HIV (CD4 <200)', 'Interstitial pneumonia; frothy exudate; "ground glass" on CT', 'GMS/Silver stain: "helmet-shaped" cysts; BAL PCR'],
['Sporothrix schenckii', 'Sporotrichosis ("Rose thorn disease")', 'Soil, decaying vegetation, thorns', 'Traumatic inoculation (thorn/wood prick)', 'Nodular lymphangitic lesion along lymphatics', 'Dimorphic; cigar-shaped yeast at 37°C; culture on SDA'],
]
story.append(organism_table(deep_rows,
['Organism', 'Disease', 'Source', 'Transmission', 'Diseases/Features', 'Identification'],
[3.0*cm, 2.5*cm, 2.5*cm, 2.3*cm, 3.7*cm, 4.0*cm], C_RED))
story.append(P('Table 11: Deep/systemic mycoses - comprehensive overview.', caption))
# ── PART 4: PARASITES ────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('PART 4: PARASITES', colors.HexColor('#6E4C1E')))
story.append(SP(6))
story.append(P('Parasites are organisms that live on or in a host and derive benefit at the host\'s expense. Medical parasitology encompasses protozoa (unicellular), helminths (multicellular worms), and ectoparasites (surface dwellers).'))
story.append(SP(4))
story.append(IMG('fig7_parasites.png', w=CONTENT_W))
story.append(P('Figure 6: Classification of parasites and key examples.', caption))
story.append(SP(6))
# Protozoa table
story.append(sub_header('A. PROTOZOA (Unicellular Parasites)', C_LIGHT_ORANGE, colors.HexColor('#6E4C1E')))
story.append(SP(4))
proto_rows = [
['Plasmodium falciparum\nP. vivax, P. malariae\nP. ovale', 'Malaria', 'Infected humans', 'Bite of female Anopheles mosquito', 'Periodic fever/chills/rigors; P. falciparum: cerebral malaria, blackwater fever; P. vivax/ovale: relapsing malaria', 'Thick/thin blood smear; RDT (HRP2 antigen); PCR'],
['Entamoeba histolytica', 'Amoebiasis', 'Human feces (cysts)', 'Fecal-oral (cyst ingestion in contaminated water/food)', 'Flask-shaped ulcers in colon; bloody diarrhea; amoebic liver abscess ("anchovy sauce" pus)', 'Stool microscopy (cysts/trophozoites); serology; stool Ag ELISA'],
['Giardia lamblia (intestinalis)', 'Giardiasis', 'Contaminated water/feces', 'Fecal-oral; ingestion of cysts', '"Falling leaf" motility; steatorrhea; malabsorption; no invasive disease', 'Stool microscopy (cysts); stool Ag test; string test (Enterotest)'],
['Leishmania donovani', 'Visceral leishmaniasis (Kala-azar)', 'Infected humans; sandfly vector', 'Bite of Phlebotomus sandfly', 'High fever; massive splenomegaly, hepatomegaly; pancytopenia; hyperpigmentation', 'LD bodies in bone marrow/spleen; rK39 RDT; PCR'],
['Leishmania tropica/major', 'Cutaneous leishmaniasis ("Oriental sore")', 'Sandfly; rodents', 'Sandfly bite', 'Painless ulcer with raised edges; heals with scar', 'Slit-skin smear; LD bodies; PCR'],
['Trypanosoma cruzi', "Chagas disease (American trypanosomiasis)", 'Triatoma (kissing bug); infected humans', 'Bite + fecal contamination of wound by Triatoma bug', "Cardiomyopathy; megacolon; megaesophagus; Romaña's sign (periorbital edema)", 'Blood smear; serology; xenodiagnosis; PCR'],
['Trypanosoma brucei', "African sleeping sickness", 'Tsetse fly; wild animals', 'Bite of Tsetse fly (Glossina)', 'Chancre at bite site; lymphadenopathy (Winterbottom\'s sign); CNS invasion → coma', 'Blood/CSF smear; card agglutination test'],
['Trichomonas vaginalis', 'Trichomoniasis', 'Infected humans', 'Sexual intercourse (STI)', 'Frothy yellow-green vaginal discharge; "strawberry cervix"; dysuria', 'Wet mount: motile trophozoites; NAAT (gold standard)'],
['Toxoplasma gondii', 'Toxoplasmosis', 'Cat feces (oocysts); undercooked meat (tissue cysts)', 'Ingestion of oocysts/tissue cysts; vertical (transplacental)', 'Usually asymptomatic in immunocompetent; congenital: chorioretinitis, hydrocephalus, intracranial calcifications; encephalitis in AIDS', 'Serology (IgM/IgG); PCR; Sabin-Feldman dye test; CT brain (ring-enhancing lesions)'],
['Cryptosporidium parvum', 'Cryptosporidiosis', 'Contaminated water; animals', 'Fecal-oral; waterborne', 'Profuse watery diarrhea; self-limiting in immunocompetent; life-threatening in AIDS', 'Modified ZN stain: red oocysts on blue background; stool Ag test'],
]
story.append(organism_table(proto_rows,
['Organism', 'Disease', 'Source', 'Transmission', 'Key Features/Diseases', 'Identification'],
[2.8*cm, 2.8*cm, 2.2*cm, 2.8*cm, 4.5*cm, 3.9*cm], colors.HexColor('#6E4C1E')))
story.append(P('Table 12: Important pathogenic protozoa.', caption))
story.append(SP(8))
# Helminths
story.append(sub_header('B. HELMINTHS (Multicellular Worms)', C_LIGHT_ORANGE, colors.HexColor('#6E4C1E')))
story.append(SP(4))
# Nematodes
story.append(P('<b>(i) Nematodes (Roundworms)</b>', h4))
nem_rows = [
['Ascaris lumbricoides', 'Ascariasis', 'Embryonated eggs in soil', 'Ingestion of eggs', 'Loeffler syndrome (larval migration through lungs); intestinal obstruction; malnutrition', 'Stool microscopy: thick-shelled ova; adult worm passed in stool/vomit'],
['Ancylostoma duodenale / Necator americanus', 'Hookworm infection', 'Larvae in soil', 'Skin penetration by filariform larvae (walking barefoot); Ancylostoma also oral', 'Iron-deficiency anemia; ground itch; Loeffler syndrome during migration', 'Stool: oval thin-shelled eggs; larval culture (Harada-Mori)'],
['Strongyloides stercoralis', 'Strongyloidiasis', 'Soil; larvae', 'Skin penetration', 'Autoinfection possible; hyperinfection syndrome in immunocompromised', 'Stool: rhabditiform larvae (not eggs); string test; serology'],
['Enterobius vermicularis', 'Pinworm/Threadworm', 'Human feces/perianal area', 'Fecal-oral; autoinfection; retroinfection', 'Nocturnal perianal itching; appendicitis rare', 'Scotch tape (cellophane) test: eggs collected from perianal skin in morning'],
['Trichuris trichiura', 'Whipworm', 'Contaminated soil', 'Ingestion of embryonated eggs', 'Rectal prolapse in heavy infection; dysentery', 'Stool: "lemon-shaped/barrel-shaped" eggs with polar plugs'],
['Wuchereria bancrofti', 'Lymphatic filariasis (Elephantiasis)', 'Infected humans', 'Bite of Culex mosquito', 'Lymphedema; hydrocele; elephantiasis (chronic); nocturnal periodicity of microfilariae', 'Night blood smear: microfilariae; Mf sheathed; ICT card test'],
['Trichinella spiralis', 'Trichinellosis', 'Pigs; wildlife', 'Ingestion of undercooked pork with larvae', 'Periorbital edema; myalgia; eosinophilia; larvae encyst in muscle', 'Muscle biopsy; serology; eosinophilia'],
['Loa loa', 'Loiasis', 'Chrysops fly; African rainforest', 'Chrysops (deerfly) bite', 'Calabar swelling; worm crossing conjunctiva (visible)', 'Day blood smear: sheathed microfilariae; Mf seen crossing eye'],
]
story.append(organism_table(nem_rows,
['Organism', 'Disease', 'Source', 'Transmission', 'Key Features', 'Identification'],
[3.2*cm, 2.8*cm, 2.0*cm, 2.5*cm, 3.5*cm, 4.0*cm], colors.HexColor('#784212')))
story.append(P('Table 13: Important nematodes (roundworms).', caption))
story.append(SP(6))
# Trematodes
story.append(P('<b>(ii) Trematodes (Flukes)</b>', h4))
trem_rows = [
['Schistosoma mansoni / S. japonicum / S. haematobium', 'Schistosomiasis (Bilharziasis)', 'Fresh water (with Bulinus/Biomphalaria snail as IH)', 'Skin penetration by cercariae while wading/swimming', 'Katayama fever (acute); hepatosplenic disease (mansoni/japonicum); hematuria, bladder cancer (haematobium)', 'Stool/urine microscopy for eggs; S. haematobium eggs: terminal spine; serology'],
['Fasciola hepatica', 'Liver fluke / Fascioliasis', 'Liver of sheep/cattle; metacercariae on water plants', 'Ingestion of metacercariae on raw watercress/vegetables', 'Biliary colic; hepatomegaly; eosinophilia; obstructive jaundice', 'Stool microscopy: large operculated eggs; serology; imaging'],
['Clonorchis sinensis', 'Clonorchiasis', 'Freshwater fish (second IH)', 'Ingestion of raw/undercooked freshwater fish', 'Cholangitis; biliary obstruction; cholangiocarcinoma (long-term)', 'Stool microscopy: small eggs with operculum and shoulder rim; serology'],
['Paragonimus westermani', 'Pulmonary paragonimiasis', 'Freshwater crabs/crayfish', 'Ingestion of undercooked crabs/crayfish', 'Hemoptysis; pleural effusion; mimics TB', 'Sputum/stool: operculated eggs; serology; ELISA'],
]
story.append(organism_table(trem_rows,
['Organism', 'Disease', 'Source', 'Transmission', 'Key Features', 'Identification'],
[3.0*cm, 2.5*cm, 2.5*cm, 2.8*cm, 3.7*cm, 3.5*cm], colors.HexColor('#6E4C1E')))
story.append(P('Table 14: Important trematodes (flukes).', caption))
story.append(SP(6))
# Cestodes
story.append(P('<b>(iii) Cestodes (Tapeworms)</b>', h4))
ces_rows = [
['Taenia solium', 'Taeniasis (adult worm); Cysticercosis (larval)', 'Pork (cysticerci in muscle)', 'Ingestion of undercooked pork; ingestion of eggs (cysticercosis)', 'Taeniasis: abdominal pain; cysticercosis: neurocysticercosis (seizures, hydrocephalus)', 'Stool: proglottids (uterine branches <13); CT brain: ring-enhancing calcified lesions; serology'],
['Taenia saginata', 'Taeniasis (beef tapeworm)', 'Beef (cysticerci in muscle)', 'Ingestion of undercooked beef', 'Usually asymptomatic; abdominal discomfort; proglottids passed in stool', 'Stool: proglottids (uterine branches >15); no cysticercosis in humans'],
['Echinococcus granulosus', 'Cystic echinococcosis (Hydatid disease)', 'Dog (definitive host); sheep/cattle', 'Ingestion of eggs from dog feces', 'Hydatid cysts in liver/lung; anaphylaxis if cyst ruptures', 'Ultrasound/CT: cyst with daughter cysts; Casoni test; serology (ELISA); Pathans sign'],
['Diphyllobothrium latum', 'Diphyllobothriasis (Fish tapeworm)', 'Freshwater fish (second IH)', 'Ingestion of raw/undercooked freshwater fish', 'Vitamin B12 deficiency (competes for B12); megaloblastic anemia; longest tapeworm', 'Stool: operculated eggs; proglottids wider than long'],
['Hymenolepis nana', 'Hymenolepiasis (dwarf tapeworm)', 'Grain beetles/mites; autoinfection possible', 'Fecal-oral; direct human-to-human', 'Usually asymptomatic; most common tapeworm worldwide', 'Stool: small round eggs with polar filaments; smallest tapeworm'],
]
story.append(organism_table(ces_rows,
['Organism', 'Disease', 'Source', 'Transmission', 'Key Features', 'Identification'],
[3.0*cm, 2.8*cm, 2.3*cm, 2.5*cm, 3.7*cm, 3.7*cm], colors.HexColor('#922B21')))
story.append(P('Table 15: Important cestodes (tapeworms).', caption))
# ── PART 5: RODENTS & VECTORS ────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('PART 5: RODENTS AND VECTORS', C_PURPLE))
story.append(SP(6))
story.append(IMG('fig6_vectors.png', w=CONTENT_W))
story.append(P('Figure 7: Important disease vectors and the diseases they transmit.', caption))
story.append(SP(6))
# Rodents
story.append(sub_header('A. RODENTS AS SOURCES OF INFECTION', C_LIGHT_PURPLE, C_PURPLE))
story.append(SP(4))
rod_rows = [
['Yersinia pestis', 'Plague', 'Rats are primary reservoir', 'Rat flea (Xenopsylla cheopis) bite; direct contact', 'Bubonic: bubo; Pneumonic: airborne spread; Septicemic: DIC', 'Blood/bubo culture; Giemsa/Wayson stain: bipolar "safety-pin" coccobacilli; PCR'],
['Leptospira interrogans', 'Leptospirosis ("Rat urine disease")', 'Rats excrete in urine; dogs, cattle', 'Contact with contaminated water/soil (flooded areas)', 'Weil\'s disease: jaundice, renal failure, hemorrhage; Fort Bragg fever', 'Dark-field microscopy; MAT (microscopic agglutination test); PCR; ELISA'],
['Rickettsia typhi', 'Murine (endemic) typhus', 'Rats are reservoir', 'Rat flea bite', 'Fever, headache, maculopapular rash; mild disease', 'Serology (Weil-Felix: OX-19; specific ELISA/IFA); PCR'],
['Hantavirus', 'Hantavirus Pulmonary Syndrome (HPS)', 'Deer mouse, other rodents', 'Inhalation of rodent urine/feces/saliva aerosols', 'Flu-like prodrome followed by rapid respiratory failure; high mortality', 'PCR; ELISA (IgM/IgG); RT-PCR on blood/BAL'],
['Streptobacillus moniliformis', 'Rat-bite fever', 'Rats, mice', 'Bite of rat/mouse; ingestion (Haverhill fever)', 'Fever, rash, polyarthritis; relapsing fever pattern', 'Blood/joint culture; serology'],
['LCM Virus', 'Lymphocytic choriomeningitis', 'House mice (Mus musculus)', 'Inhalation/ingestion of infected rodent material', 'Aseptic meningitis; flu-like illness; severe in immunocompromised', 'Serology (IgM/IgG); PCR on CSF'],
['Monkeypox virus', 'Mpox', 'Rodents (squirrels, rats) in Africa', 'Contact with infected animal/person; respiratory droplets', 'Rash (pustules including palms/soles); lymphadenopathy; milder than smallpox', 'PCR on skin lesion; electron microscopy'],
]
story.append(organism_table(rod_rows,
['Pathogen', 'Disease', 'Rodent Role', 'Transmission', 'Key Features', 'Identification'],
[2.8*cm, 2.5*cm, 2.5*cm, 2.8*cm, 3.5*cm, 3.9*cm], C_PURPLE))
story.append(P('Table 16: Rodent-associated diseases.', caption))
story.append(SP(8))
# Vectors
story.append(sub_header('B. ARTHROPOD VECTORS AND THEIR DISEASES', C_LIGHT_PURPLE, C_PURPLE))
story.append(SP(4))
vec_rows = [
['Anopheles mosquito\n(Female; night biter)', 'Malaria (Plasmodium spp.)\nLymphatic filariasis (Wuchereria)', 'Larvae in clean stagnant water', 'Insect repellents, bed nets, larvicides, indoor residual spraying'],
['Aedes aegypti\n(Female; day biter)', 'Dengue, Yellow fever, Zika, Chikungunya', 'Stagnant water in containers (urban)', 'Container management, larvicides, release of sterile males'],
['Culex mosquito\n(Female; night biter)', 'Japanese encephalitis, West Nile fever, Lymphatic filariasis', 'Stagnant water, rice fields, drains', 'Insecticides, biological control, drainage'],
['Phlebotomus sandfly', 'Kala-azar (Leishmania donovani)\nSandfly fever\nCutaneous leishmaniasis', 'Sandy soil, cracks in walls, animal burrows', 'DDT spraying, bed nets, sand fly proof screens'],
['Glossina (Tsetse fly)', 'African trypanosomiasis (Sleeping sickness)', 'Tropical African forests/savannahs', 'Tsetse traps, insecticides, clearing of bush'],
['Ixodes tick', 'Lyme disease (Borrelia)\nRocky Mountain spotted fever (Rickettsia)\nTick-borne encephalitis', 'Deer, mice; vegetation', 'Protective clothing, DEET repellent, tick checks'],
['Pediculus (Body louse)', 'Epidemic typhus (R. prowazekii)\nRelapsing fever (Borrelia recurrentis)\nTrench fever', 'Human body/clothing', 'Delousing (DDT/permethrin), improved hygiene'],
['Xenopsylla cheopis (Rat flea)', 'Bubonic plague (Y. pestis)\nMurine typhus (R. typhi)', 'Rats', 'Rodent control, insecticides'],
['Triatoma (Reduviid/Kissing bug)', 'Chagas disease (T. cruzi)', 'Rural houses, thatched roofs', 'House improvement, insecticides, bed nets'],
['Simulium (Blackfly)', 'Onchocerciasis/River blindness (Onchocerca volvulus)', 'Fast-flowing rivers', 'Ivermectin (mass drug administration), larviciding with temephos'],
['Sarcoptes scabiei (Mite)', 'Scabies\n(Orientia tsutsugamushi via Trombicula mite → Scrub typhus)', 'Human skin; vegetation (Trombicula)', 'Permethrin cream; clothing protection; rodent control'],
['Chrysops (Deerfly)', 'Loiasis (Loa loa)', 'African rainforest', 'Protective clothing; diethylcarbamazine prophylaxis'],
]
story.append(organism_table(vec_rows,
['Vector', 'Diseases Transmitted', 'Breeding Habitat', 'Prevention/Control'],
[3.5*cm, 5.0*cm, 3.5*cm, 6.0*cm], C_PURPLE))
story.append(P('Table 17: Arthropod vectors, diseases transmitted, and control measures.', caption))
# ── PART 6: COMPREHENSIVE SUMMARY TABLE ──────────────────────────────────────
story.append(PageBreak())
story.append(section_header('COMPREHENSIVE SUMMARY: All Pathogenic Organisms', colors.HexColor('#212F3C')))
story.append(SP(6))
story.append(P('The following table provides a quick-reference summary of all major pathogenic organisms covering characteristics, source, portal of entry, transmission, and identification methods as required by the syllabus.', body))
story.append(SP(6))
summary_rows = [
# Bacteria
['Staphylococcus aureus', 'Gram+ve Cocci (clusters)', 'Skin/nose', 'Skin breaks, wounds', 'Contact, droplet, fomites', 'Coagulase+; Mannitol salt agar; Beta-hemolysis'],
['Streptococcus pyogenes', 'Gram+ve Cocci (chains)', 'Throat/skin', 'Respiratory, skin', 'Droplets, contact', 'Beta-hemolysis; Bacitracin sensitive; ASO titer'],
['S. pneumoniae', 'Gram+ve Diplococci', 'Nasopharynx', 'Respiratory', 'Droplets', 'Optochin sensitive; Bile soluble; Quellung test'],
['N. meningitidis', 'Gram-ve Diplococci', 'Nasopharynx', 'Respiratory', 'Droplets', 'Thayer-Martin; Glucose+Maltose fermenter'],
['N. gonorrhoeae', 'Gram-ve Diplococci', 'Urogenital', 'Mucous membranes', 'Sexual, vertical', 'Thayer-Martin; Glucose only; NAAT'],
['M. tuberculosis', 'AFB (Gram+ve wall)', 'Active TB patients', 'Respiratory', 'Airborne droplet nuclei', 'ZN stain; LJ medium; GeneXpert'],
['C. tetani', 'Gram+ve Bacillus', 'Soil, feces', 'Deep wounds', 'Wound contamination', 'Drumstick shape; clinical diagnosis'],
['B. anthracis', 'Gram+ve Bacillus (spores)', 'Soil, animals', 'Skin, lungs, GI', 'Contact, inhalation, ingestion', 'Non-motile; Medusa head colony; capsule stain'],
['Salmonella typhi', 'Gram-ve Bacillus', 'Infected humans/carriers', 'GI tract', 'Fecal-oral', 'Non-lactose fermenter; Widal test; Blood culture'],
['Vibrio cholerae', 'Gram-ve Curved Bacillus', 'Water, seafood', 'GI tract', 'Fecal-oral, waterborne', 'Comma shape; TCBS (yellow); Oxidase+'],
['E. coli (pathogenic)', 'Gram-ve Bacillus', 'Human colon/food/water', 'GI, urinary', 'Fecal-oral', 'MacConkey pink; IMViC: ++--'],
['Pseudomonas aeruginosa', 'Gram-ve Bacillus', 'Hospital environment', 'Wounds, respiratory', 'Nosocomial', 'Blue-green pigment; grape odor; Oxidase+'],
# Viruses
['HIV', 'RNA Retrovirus', 'Blood, genital fluids, milk', 'Mucous membrane, blood', 'Sexual, blood, vertical', 'ELISA; Western blot; CD4 count; Viral load'],
['HBV', 'DNA Hepadnavirus', 'Blood, sexual fluids', 'Blood, mucous membrane', 'Sexual, blood, perinatal', 'HBsAg; HBeAg; HBV DNA PCR'],
['Dengue', 'RNA Flavivirus', 'Infected human (viremia)', 'Skin (mosquito bite)', 'Aedes aegypti mosquito', 'NS1 antigen; IgM ELISA; RT-PCR'],
['Influenza', 'RNA Orthomyxovirus', 'Humans, birds, pigs', 'Respiratory', 'Respiratory droplets', 'Rapid Ag test; RT-PCR; culture'],
['Rabies', 'RNA Rhabdovirus', 'Infected animal (dog, bat)', 'Skin (bite wound)', 'Animal bite', 'Negri bodies; DFA; PCR'],
# Fungi
['Candida albicans', 'Yeast (Fungi)', 'Normal flora', 'Mucous membranes', 'Endogenous/contact', 'Germ tube+; CHROMagar; pseudohyphae'],
['Aspergillus fumigatus', 'Mold (Fungi)', 'Soil, environment', 'Respiratory', 'Inhalation of conidia', 'Septate hyphae (45°); Galactomannan; CT: halo sign'],
['Cryptococcus neoformans', 'Encapsulated yeast', 'Pigeon droppings', 'Respiratory', 'Inhalation', 'India ink; Latex agglutination (capsule Ag)'],
['Histoplasma capsulatum', 'Dimorphic fungus', 'Bat/bird droppings', 'Respiratory', 'Inhalation of microconidia', 'Intracellular yeast in macrophages; Urine antigen'],
# Parasites
['Plasmodium falciparum', 'Protozoa (Intracellular)', 'Infected humans', 'Skin (mosquito)', 'Female Anopheles bite', 'Blood smear; RDT; PCR'],
['Entamoeba histolytica', 'Protozoa', 'Human feces (cysts)', 'GI tract', 'Fecal-oral', 'Stool microscopy; stool Ag ELISA'],
['Ascaris lumbricoides', 'Nematode (Roundworm)', 'Soil (embryonated eggs)', 'GI tract (oral)', 'Ingestion of eggs', 'Stool ova; adult worm passed'],
['Ancylostoma/Necator', 'Nematode (Roundworm)', 'Soil (filariform larvae)', 'Skin (feet)', 'Skin penetration', 'Stool ova; larval culture; eosinophilia'],
['Wuchereria bancrofti', 'Nematode (Filarial)', 'Infected humans', 'Skin (mosquito)', 'Culex mosquito bite', 'Night blood smear; ICT card test'],
['Taenia solium', 'Cestode (Tapeworm)', 'Infected pork', 'GI tract', 'Ingestion of undercooked pork/eggs', 'Stool proglottids; CT brain (neurocysticercosis)'],
['Schistosoma spp.', 'Trematode (Fluke)', 'Fresh water (snail)', 'Skin', 'Cercariae skin penetration', 'Stool/urine for eggs; serology'],
# Vectors & Rodents
['Yersinia pestis', 'Gram-ve Bacillus (Rodent-associated)', 'Rats (reservoir)', 'Skin (flea bite)', 'Xenopsylla cheopis flea bite', 'Bipolar staining; Culture; PCR'],
['Leptospira interrogans', 'Spirochete (Rodent-associated)', 'Rat urine; contaminated water', 'Skin/mucous membrane', 'Contact with infected water/soil', 'MAT; Dark field microscopy; PCR'],
]
summary_tbl = Table(summary_rows, colWidths=[3.0*cm, 2.5*cm, 2.5*cm, 2.5*cm, 2.5*cm, 5.0*cm],
repeatRows=0)
# Apply alternating row colors with group shading
style_cmds = [
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#CCCCCC')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 4),
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
]
# Row group shading
bacteria_end = 12
for i in range(bacteria_end):
bg = C_LIGHT_BLUE if i % 2 == 0 else colors.white
style_cmds.append(('BACKGROUND', (0,i), (-1,i), bg))
for i in range(bacteria_end, bacteria_end+5):
bg = colors.HexColor('#FDEDEC') if i % 2 == 0 else colors.HexColor('#FEF9E7')
style_cmds.append(('BACKGROUND', (0,i), (-1,i), bg))
for i in range(bacteria_end+5, bacteria_end+9):
bg = C_LIGHT_GREEN if i % 2 == 0 else colors.white
style_cmds.append(('BACKGROUND', (0,i), (-1,i), bg))
for i in range(bacteria_end+9, len(summary_rows)):
bg = C_LIGHT_ORANGE if i % 2 == 0 else colors.white
style_cmds.append(('BACKGROUND', (0,i), (-1,i), bg))
summary_tbl.setStyle(TableStyle(style_cmds))
story.append(summary_tbl)
story.append(P('Table 18: Comprehensive summary of all pathogenic organisms (Syllabus-aligned).', caption))
# ── KEY POINTS FOR EXAM ────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header('KEY POINTS FOR EXAMINATION', C_GOLD))
story.append(SP(6))
key_points = [
('Gram staining', 'Gram+ve = purple (thick peptidoglycan); Gram-ve = pink (thin peptidoglycan + outer LPS membrane). LPS = endotoxin causing fever and septic shock.'),
('Coagulase test', 'Coagulase-POSITIVE = S. aureus (pathogenic). Coagulase-NEGATIVE = CoNS (S. epidermidis, S. saprophyticus).'),
('Special stains', 'ZN stain = AFB (TB, Leprosy); India ink = Cryptococcus (capsule halo); KOH mount = Fungi (hyphae); Gram stain = Bacteria; Giemsa = Parasites (malaria), Leishmania.'),
('Fecal-oral route', 'Salmonella, Shigella, Vibrio, E. coli, HAV, Poliovirus, Entamoeba, Giardia, Ascaris, Taenia (eggs).'),
('Airborne transmission', 'Mycobacterium tuberculosis (droplet nuclei, <5µm), Measles, Varicella, Influenza (also droplet).'),
('Opportunistic infections', 'Candida, Aspergillus, Cryptococcus, PCP (Pneumocystis), CMV, MAI - occur when CD4 < threshold in HIV/AIDS.'),
('Dimorphic fungi', 'Yeast at 37°C (body temperature), Mold at 25°C (room temperature). Rule: "Mold in Cold, Yeast in Heat". Examples: Histoplasma, Coccidioides, Blastomyces, Sporothrix.'),
('Vector-borne mnemonic', 'Malaria=Anopheles; Dengue/Yellow fever/Zika=Aedes; JE=Culex; Kala-azar=Sandfly; Sleeping sickness=Tsetse; Plague=Rat flea; Chagas=Reduviid; Onchocerciasis=Blackfly.'),
('Malaria diagnosis', 'Thick blood smear (screening), thin blood smear (speciation), RDT (HRP2 antigen for P. falciparum), PCR (gold standard). P. falciparum: no true relapse (no hypnozoites).'),
('Portal of entry', 'Determines type of disease. Respiratory → pneumonia/meningitis; GI → diarrhea/enteric fever; Skin → cellulitis/wound infection; Urogenital → STIs/UTI.'),
('Tetanus toxin', 'Tetanospasmin: blocks INHIBITORY neurons (glycine/GABA) at spinal cord → spastic paralysis. Botulinum toxin: blocks EXCITATORY ACh release at NMJ → flaccid paralysis.'),
('Plague forms', 'Bubonic (flea bite → bubo in groin); Pneumonic (airborne → most contagious, can cause pandemic); Septicemic (DIC, black skin → "Black Death").'),
]
for label, text in key_points:
row_data = [[
Paragraph(f'<b>{label}</b>', ParagraphStyle('kpl', fontSize=8.5, fontName='Helvetica-Bold', textColor=C_NAVY)),
Paragraph(text, ParagraphStyle('kpt', fontSize=8.5, fontName='Helvetica', leading=12))
]]
kp_tbl = Table(row_data, colWidths=[3.5*cm, CONTENT_W-3.5*cm])
kp_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,0), C_LIGHT_BLUE),
('BACKGROUND', (1,0), (1,0), colors.white),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('BOX', (0,0), (-1,-1), 0.5, C_NAVY),
('LINEAFTER', (0,0), (0,-1), 1, C_NAVY),
]))
story.append(kp_tbl)
story.append(SP(3))
story.append(SP(10))
story.append(HR(C_NAVY))
story.append(P('<i>Sources: Jawetz, Melnick & Adelberg\'s Medical Microbiology 28th Ed; Sherris & Ryan\'s Medical Microbiology 8th Ed; Medical Microbiology 9th Ed (Murray et al.)</i>',
ParagraphStyle('ref', fontSize=7.5, textColor=colors.grey, alignment=TA_CENTER, fontName='Helvetica-Oblique')))
# ════════════════════════════════════════════════════════════════════════════
# PAGE NUMBERS
# ════════════════════════════════════════════════════════════════════════════
def on_page(canvas, doc):
canvas.saveState()
canvas.setFont('Helvetica', 8)
canvas.setFillColor(colors.HexColor('#888888'))
canvas.drawString(1.8*cm, 1.2*cm, 'Pathogenic Organisms - Medical Microbiology Chapter')
canvas.drawRightString(W - 1.8*cm, 1.2*cm, f'Page {doc.page}')
canvas.restoreState()
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF created: {OUTPUT}")
PYEOF
show command