Is it normal
| Parameter | Result | Reference Range | Status |
|---|---|---|---|
| WBC | 2.41 | 4.00-10.00 × 10⁹/L | 🔴 LOW |
| Lym# | 0.32 | 0.80-4.00 × 10⁹/L | 🔴 LOW |
| Mid# | 0.06 | 0.10-1.80 × 10⁹/L | 🔴 LOW |
| Lym% | 0.131 | 0.200-0.400 | 🔴 LOW |
| Gran% | 0.856 | 0.500-0.700 | 🟡 HIGH |
| MCH | 25.1 pg | 27.0-34.0 pg | 🔴 LOW |
| MCHC | 273 g/L | 320-360 g/L | 🔴 LOW |
| PDW-CV | 0.136 | 0.150-0.170 | 🔴 LOW |
| Test | Result | Significance |
|---|---|---|
| Widal - S. Typhi O | 1:160 | 🔴 SIGNIFICANT |
| Widal - S. Typhi H | 1:160 | 🔴 SIGNIFICANT |
| Widal - Para Typhi AH | 1:80 | Borderline |
| Widal - Para Typhi B | 1:40 | Low/borderline |
| Blood Sugar (Random) | 132 mg% | ✅ Normal (80-160) |
| Malaria (MP) | Negative | ✅ |
| Dengue NS1Ag, IgG, IgM | Non-Reactive | ✅ |
Important: This report should be reviewed promptly with the treating doctor. Do not self-medicate. Typhoid can worsen quickly without proper treatment.
Create a quick reference PDF on typhoid diagnosis and management
mkdir -p /tmp/workspace/typhoid-pdf && ls /tmp/workspace/typhoid-pdf/
~/typhoid-pdf/generate_typhoid_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
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_PATH = "/tmp/workspace/typhoid-pdf/Typhoid_Quick_Reference.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────────
DARK_RED = colors.HexColor("#B71C1C")
RED = colors.HexColor("#D32F2F")
LIGHT_RED = colors.HexColor("#FFCDD2")
ORANGE = colors.HexColor("#E65100")
AMBER = colors.HexColor("#FFF8E1")
DARK_BLUE = colors.HexColor("#1A237E")
BLUE = colors.HexColor("#1565C0")
LIGHT_BLUE = colors.HexColor("#E3F2FD")
TEAL = colors.HexColor("#00695C")
LIGHT_TEAL = colors.HexColor("#E0F2F1")
GREEN = colors.HexColor("#2E7D32")
LIGHT_GREEN= colors.HexColor("#E8F5E9")
YELLOW_BG = colors.HexColor("#FFFDE7")
GREY_DARK = colors.HexColor("#212121")
GREY_MED = colors.HexColor("#757575")
GREY_LIGHT = colors.HexColor("#F5F5F5")
WHITE = colors.white
# ── Styles ──────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("DocTitle",
fontSize=26, leading=32, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER)
subtitle_style = S("DocSubtitle",
fontSize=13, leading=17, textColor=colors.HexColor("#FFCDD2"),
fontName="Helvetica", alignment=TA_CENTER)
section_header_style = S("SectionHeader",
fontSize=13, leading=17, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_LEFT,
leftIndent=6)
sub_header_style = S("SubHeader",
fontSize=10, leading=13, textColor=DARK_BLUE,
fontName="Helvetica-Bold", alignment=TA_LEFT)
body_style = S("Body",
fontSize=9, leading=13, textColor=GREY_DARK,
fontName="Helvetica", alignment=TA_JUSTIFY)
bullet_style = S("Bullet",
fontSize=9, leading=13, textColor=GREY_DARK,
fontName="Helvetica", leftIndent=12, bulletIndent=4,
alignment=TA_LEFT)
small_style = S("Small",
fontSize=8, leading=11, textColor=GREY_MED,
fontName="Helvetica", alignment=TA_CENTER)
alert_style = S("Alert",
fontSize=9.5, leading=13, textColor=DARK_RED,
fontName="Helvetica-Bold", alignment=TA_LEFT)
green_style = S("Green",
fontSize=9, leading=13, textColor=GREEN,
fontName="Helvetica-Bold", alignment=TA_LEFT)
table_header_style = S("TableHeader",
fontSize=9, leading=12, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER)
table_cell_style = S("TableCell",
fontSize=8.5, leading=12, textColor=GREY_DARK,
fontName="Helvetica", alignment=TA_LEFT)
table_cell_bold = S("TableCellBold",
fontSize=8.5, leading=12, textColor=GREY_DARK,
fontName="Helvetica-Bold", alignment=TA_LEFT)
# ── Helper builders ─────────────────────────────────────────────────────────────
def section_block(title, bg_color, text_color=WHITE):
"""A coloured section header row."""
data = [[Paragraph(title, section_header_style)]]
t = Table(data, colWidths=[17.5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4]),
]))
return t
def bp(text):
return Paragraph(f"<bullet>•</bullet> {text}", bullet_style)
def body(text):
return Paragraph(text, body_style)
def bold_body(text):
return Paragraph(f"<b>{text}</b>", body_style)
def sp(h=4):
return Spacer(1, h)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#E0E0E0"))
# ── Two-column helper ────────────────────────────────────────────────────────────
def two_col(left_items, right_items, col_widths=(8.5*cm, 8.5*cm), valign="TOP"):
"""Wrap two lists of flowables into a 2-column table."""
from reportlab.platypus import KeepInFrame
# We use nested tables via KeepInFrame trick - just use normal Table cells
left_frame = [i for i in left_items]
right_frame = [i for i in right_items]
data = [[left_frame, right_frame]]
t = Table(data, colWidths=list(col_widths))
t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), valign),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
# ── Box wrapper ──────────────────────────────────────────────────────────────────
def box(items, bg=GREY_LIGHT, border_color=colors.HexColor("#BDBDBD"), col_w=17.5*cm):
t = Table([[items]], colWidths=[col_w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 0.75, border_color),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return t
# ── Page template with header/footer ────────────────────────────────────────────
def on_first_page(canvas, doc):
pass # header drawn inline
def on_later_pages(canvas, doc):
canvas.saveState()
canvas.setFont("Helvetica", 7.5)
canvas.setFillColor(GREY_MED)
canvas.drawString(2*cm, 1.2*cm, "Typhoid Fever - Quick Reference Guide")
canvas.drawRightString(19*cm, 1.2*cm, f"Page {doc.page}")
canvas.restoreState()
# ── BUILD PDF ────────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=1.5*cm, bottomMargin=2*cm,
)
story = []
# ════════════════════════════════════════════════════════════
# TITLE BANNER
# ════════════════════════════════════════════════════════════
banner_data = [[
Paragraph("TYPHOID FEVER", title_style),
Paragraph("Quick Reference Guide", subtitle_style),
Paragraph("Diagnosis & Management", subtitle_style),
]]
banner = Table(banner_data, colWidths=[17.5*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_RED),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (-1,-1), 16),
("RIGHTPADDING", (0,0), (-1,-1), 16),
("ROUNDEDCORNERS", [6]),
]))
story.append(banner)
story.append(sp(10))
# ════════════════════════════════════════════════════════════
# AT A GLANCE strip
# ════════════════════════════════════════════════════════════
glance_items = [
["Causative\nOrganism", "Salmonella\ntyphi/paratyphi"],
["Transmission", "Faeco-oral\n(food/water)"],
["Incubation", "10-20 days\n(range 1-3 wk)"],
["Mortality\n(untreated)", "10-20%"],
["Endemic\nRegions", "South Asia,\nAfrica, S.E. Asia"],
]
glance_data = [[Paragraph(k, S("glk", fontSize=7.5, fontName="Helvetica-Bold", textColor=GREY_MED, alignment=TA_CENTER)) for k,v in glance_items],
[Paragraph(v, S("glv", fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_BLUE, alignment=TA_CENTER)) for k,v in glance_items]]
glance_t = Table(glance_data, colWidths=[3.5*cm]*5)
glance_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), LIGHT_BLUE),
("BACKGROUND", (0,1), (-1,1), WHITE),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#90CAF9")),
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#90CAF9")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("ALIGN", (0,0), (-1,-1), "CENTER"),
]))
story.append(glance_t)
story.append(sp(10))
# ════════════════════════════════════════════════════════════
# SECTION 1 - PATHOPHYSIOLOGY (compact)
# ════════════════════════════════════════════════════════════
story.append(section_block("1. PATHOPHYSIOLOGY", BLUE))
story.append(sp(4))
patho_items = [
bp("Oral ingestion of S. typhi (infective dose ~10<super>3</super>-10<super>5</super> organisms)"),
bp("Organisms penetrate small bowel mucosa → lymphatics → systemic bacteraemia"),
bp("Reticuloendothelial hyperplasia: lymph nodes, liver, spleen"),
bp("Peyer's patches in terminal ileum become hyperplastic → ulcerate → risk of perforation/haemorrhage"),
bp("Endotoxin release drives systemic inflammation and fever"),
]
story.append(box(patho_items, bg=LIGHT_BLUE, border_color=colors.HexColor("#90CAF9")))
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 2 - CLINICAL FEATURES
# ════════════════════════════════════════════════════════════
story.append(section_block("2. CLINICAL FEATURES BY WEEK", BLUE))
story.append(sp(4))
weeks_data = [
[Paragraph("Week", table_header_style),
Paragraph("Symptoms & Signs", table_header_style),
Paragraph("Key Features", table_header_style)],
[Paragraph("Week 1\n(Bacteraemia)", table_cell_bold),
Paragraph("Fever (stepwise rise), headache, malaise, dry cough, constipation", table_cell_style),
Paragraph("Relative bradycardia (Faget sign)", table_cell_bold)],
[Paragraph("Week 2\n(Enteric phase)", table_cell_bold),
Paragraph("High fever, abdominal distension, splenomegaly, diarrhoea OR constipation (30%)", table_cell_style),
Paragraph("Rose spots (trunk) - pink macules, fair skin only", table_cell_bold)],
[Paragraph("Week 3\n(Complications)", table_cell_bold),
Paragraph("Prostration, delirium; risk of perforation/haemorrhage", table_cell_style),
Paragraph("Most dangerous period", table_cell_bold)],
[Paragraph("Week 4+\n(Recovery)", table_cell_bold),
Paragraph("Slow defervescence, fatigue; 10% relapse", table_cell_style),
Paragraph("Carrier state may develop", table_cell_bold)],
]
weeks_t = Table(weeks_data, colWidths=[3.2*cm, 9*cm, 5.3*cm])
weeks_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), BLUE),
("BACKGROUND", (0,1), (-1,1), LIGHT_BLUE),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), LIGHT_RED),
("BACKGROUND", (0,4), (-1,4), LIGHT_GREEN),
("ROWBACKGROUNDS", (0,0), (-1,-1), []),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#BDBDBD")),
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#E0E0E0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(weeks_t)
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 3 - DIAGNOSIS
# ════════════════════════════════════════════════════════════
story.append(section_block("3. DIAGNOSIS", TEAL))
story.append(sp(4))
# Left: lab tests | Right: Widal interpretation
left_diag = [
Paragraph("<b>Culture (Gold Standard)</b>", sub_header_style),
sp(2),
bp("<b>Blood culture</b> - Week 1 (yield ~60-80%)"),
bp("<b>Bone marrow culture</b> - Most sensitive (90%), positive even after antibiotics"),
bp("<b>Stool/urine culture</b> - Week 2 onwards"),
sp(6),
Paragraph("<b>Serology</b>", sub_header_style),
sp(2),
bp("Widal test: O ≥1:160 and H ≥1:160 significant"),
bp("Rapid antigen tests (NS1-type): used in endemic areas"),
bp("IgM/IgG ELISA: useful for confirmation"),
sp(6),
Paragraph("<b>Other Tests</b>", sub_header_style),
sp(2),
bp("PCR: high specificity but costly; unpredictable sensitivity"),
bp("CBC: <b>leukopenia</b> is classic (as seen in this case)"),
bp("LFTs: mildly elevated transaminases common"),
bp("Anaemia, thrombocytopenia in severe cases"),
]
right_diag = [
Paragraph("<b>Widal Interpretation</b>", sub_header_style),
sp(2),
box([
Paragraph("<b>Titre</b> | <b>Interpretation</b>", S("h", fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_BLUE)),
sp(3),
Paragraph("< 1:80 | Insignificant", table_cell_style),
Paragraph("1:80-1:160 | Borderline / possible", table_cell_style),
Paragraph("<b>≥ 1:160</b> | <b>Significant - typhoid likely</b>", S("w", fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_RED)),
], bg=YELLOW_BG, border_color=ORANGE, col_w=7.5*cm),
sp(6),
Paragraph("<b>Limitations of Widal Test</b>", sub_header_style),
sp(2),
bp("Cross-reactivity with other Salmonella species"),
bp("Prior vaccination or infection elevates baseline titres"),
bp("Single titre less reliable than paired titres (4x rise)"),
bp("Now considered <b>non-specific</b> per current guidelines"),
sp(6),
Paragraph("<b>Recommended Approach</b>", sub_header_style),
sp(2),
box([
Paragraph("Culture + clinical picture is preferred over Widal alone. In resource-limited settings, Widal at ≥1:160 with compatible symptoms justifies empirical treatment.",
S("rec", fontSize=8.5, fontName="Helvetica", textColor=DARK_BLUE)),
], bg=LIGHT_BLUE, border_color=BLUE, col_w=7.5*cm),
]
story.append(two_col(left_diag, right_diag, col_widths=(9*cm, 8.5*cm)))
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 4 - MANAGEMENT
# ════════════════════════════════════════════════════════════
story.append(section_block("4. MANAGEMENT", GREEN))
story.append(sp(4))
# Antibiotics table
abx_data = [
[Paragraph("Antibiotic", table_header_style),
Paragraph("Dose (Adult)", table_header_style),
Paragraph("Duration", table_header_style),
Paragraph("Notes", table_header_style)],
[Paragraph("Azithromycin\n(1st line, uncomplicated)", table_cell_bold),
Paragraph("500 mg OD orally", table_cell_style),
Paragraph("7 days", table_cell_style),
Paragraph("Preferred in areas with fluoroquinolone resistance (S. Asia). Safe in pregnancy.", table_cell_style)],
[Paragraph("Ceftriaxone\n(severe/hospitalised)", table_cell_bold),
Paragraph("2-3 g IV once daily", table_cell_style),
Paragraph("10-14 days", table_cell_style),
Paragraph("Drug of choice for severe typhoid. Use when oral not tolerated.", table_cell_style)],
[Paragraph("Ciprofloxacin\n(if susceptible)", table_cell_bold),
Paragraph("500 mg BD orally\nor 400 mg IV BD", table_cell_style),
Paragraph("10-14 days", table_cell_style),
Paragraph("Increasing resistance (S. Asia). Check nalidixic acid sensitivity as proxy.", table_cell_style)],
[Paragraph("Cefixime\n(oral, uncomplicated)", table_cell_bold),
Paragraph("200 mg BD orally", table_cell_style),
Paragraph("7-14 days", table_cell_style),
Paragraph("Good for outpatient management. 3rd-gen cephalosporin.", table_cell_style)],
[Paragraph("Chloramphenicol\n(historical)", table_cell_bold),
Paragraph("500 mg QID orally", table_cell_style),
Paragraph("14 days", table_cell_style),
Paragraph("Widely resistant. Avoid as first-line. May still be used where resistance not common.", table_cell_style)],
]
abx_t = Table(abx_data, colWidths=[3.8*cm, 3.5*cm, 2.3*cm, 7.9*cm])
abx_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), GREEN),
("BACKGROUND", (0,1), (-1,1), LIGHT_GREEN),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), LIGHT_GREEN),
("BACKGROUND", (0,4), (-1,4), WHITE),
("BACKGROUND", (0,5), (-1,5), LIGHT_GREEN),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#BDBDBD")),
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#E0E0E0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(abx_t)
story.append(sp(6))
# Supportive care
story.append(Paragraph("<b>Supportive Care</b>", sub_header_style))
story.append(sp(3))
supportive = [
bp("IV rehydration - correct electrolyte imbalances (especially Na, K)"),
bp("Antipyretics - paracetamol preferred; avoid NSAIDs (bleeding risk)"),
bp("Blood transfusion if significant GI haemorrhage"),
bp("Nutritional support - soft diet; resume normal diet as tolerated"),
bp("Dexamethasone 3 mg/kg loading + 1 mg/kg 6-hourly x 8 doses - for severe typhoid with shock or meningitis/encephalitis"),
bp("Strict enteric precautions: hand hygiene, isolation, decontamination of excreta"),
]
story.append(box(supportive, bg=LIGHT_GREEN, border_color=GREEN))
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 5 - COMPLICATIONS
# ════════════════════════════════════════════════════════════
story.append(section_block("5. COMPLICATIONS & SURGICAL EMERGENCIES", RED))
story.append(sp(4))
comp_left = [
Paragraph("<b>GI Complications (Surgical)</b>", sub_header_style),
sp(3),
bp("<b>Intestinal perforation</b> (~2%) - typically single perforation in terminal ileum; occurs Week 3"),
bp("Signs: sudden abdominal pain, peritonism, free gas on AXR/CT"),
bp("Management: emergency laparotomy - simple closure (single) OR resection (multiple)"),
sp(4),
bp("<b>GI Haemorrhage</b> (~5-10%) - from ulcerated Peyer's patches"),
bp("Management: transfusion usually sufficient; laparotomy rarely needed"),
sp(4),
bp("<b>Paralytic ileus</b> - bowel rest, NG decompression"),
bp("<b>Cholecystitis</b> - may become chronic carrier"),
]
comp_right = [
Paragraph("<b>Systemic Complications</b>", sub_header_style),
sp(3),
bp("<b>Toxic encephalopathy / meningitis</b>"),
bp("<b>Myocarditis</b> - arrhythmias, CCF"),
bp("<b>Pneumonia</b>"),
bp("<b>Septic arthritis / osteomyelitis</b>"),
bp("<b>DIC</b> - haemorrhagic manifestations"),
bp("<b>Renal failure</b>"),
bp("<b>Mycotic aneurysm</b>"),
sp(4),
Paragraph("<b>Sequelae</b>", sub_header_style),
sp(2),
bp("Deafness, psychosis, ataxia, seizures"),
bp("<b>Chronic carrier state</b> - organisms shed >1 yr (gallbladder reservoir); cholecystectomy may be required"),
]
story.append(two_col(comp_left, comp_right))
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 6 - WIDAL TEST REFERENCE (quick box)
# ════════════════════════════════════════════════════════════
story.append(section_block("6. LAB PATTERNS & WIDAL QUICK REFERENCE", TEAL))
story.append(sp(4))
lab_data = [
[Paragraph("Test", table_header_style),
Paragraph("Typical Finding in Typhoid", table_header_style),
Paragraph("Significance", table_header_style)],
[Paragraph("WBC", table_cell_bold),
Paragraph("LOW - Leukopenia (2-4 × 10⁹/L)", table_cell_style),
Paragraph("Classic feature; helps exclude pyogenic infection", table_cell_style)],
[Paragraph("Neutrophils", table_cell_bold),
Paragraph("Elevated % (Gran% high, absolute count normal-low)", table_cell_style),
Paragraph("Relative neutrophilia despite overall leukopenia", table_cell_style)],
[Paragraph("Lymphocytes", table_cell_bold),
Paragraph("Absolute lymphopenia", table_cell_style),
Paragraph("Consistent with systemic bacterial infection", table_cell_style)],
[Paragraph("Haemoglobin", table_cell_bold),
Paragraph("Mild-moderate anaemia possible", table_cell_style),
Paragraph("From haemolysis or GI loss", table_cell_style)],
[Paragraph("Platelets", table_cell_bold),
Paragraph("Usually normal; thrombocytopenia in severe disease", table_cell_style),
Paragraph("Thrombocytopenia signals severity", table_cell_style)],
[Paragraph("Liver enzymes", table_cell_bold),
Paragraph("Mildly elevated ALT/AST (2-3x ULN)", table_cell_style),
Paragraph("Typhoid hepatitis; not always present", table_cell_style)],
[Paragraph("CRP/ESR", table_cell_bold),
Paragraph("Elevated", table_cell_style),
Paragraph("Non-specific acute phase response", table_cell_style)],
[Paragraph("Widal O titre", table_cell_bold),
Paragraph("≥1:160 significant (rising 4x more specific)", table_cell_style),
Paragraph("O antigen - earlier response, shorter duration", table_cell_style)],
[Paragraph("Widal H titre", table_cell_bold),
Paragraph("≥1:160 significant", table_cell_style),
Paragraph("H antigen - persists longer (vaccination also raises)", table_cell_style)],
]
lab_t = Table(lab_data, colWidths=[3.5*cm, 7*cm, 7*cm])
lab_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_TEAL, WHITE]),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#BDBDBD")),
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#E0E0E0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(lab_t)
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 7 - PREVENTION & PUBLIC HEALTH
# ════════════════════════════════════════════════════════════
story.append(section_block("7. PREVENTION & PUBLIC HEALTH", colors.HexColor("#5E35B1")))
story.append(sp(4))
prev_left = [
Paragraph("<b>Vaccination</b>", sub_header_style),
sp(3),
bp("<b>Vi polysaccharide vaccine</b> (ViPS): IM, single dose, ≥2 years, ~60-70% efficacy, revaccinate every 2-3 years"),
bp("<b>Ty21a (Vivotif)</b>: oral live attenuated, 3-4 capsules on alternate days, ≥6 years; good for travellers"),
bp("<b>Vi-TT conjugate vaccine (Typhoid Conjugate Vaccine)</b>: preferred for children >6 months; longer lasting immunity"),
bp("Vaccination does not replace food/water precautions"),
]
prev_right = [
Paragraph("<b>Notification & Isolation</b>", sub_header_style),
sp(3),
bp("Notifiable disease in most countries"),
bp("Hospitalise where possible - prolonged infectious course"),
bp("Stool/urine precautions until 3 consecutive negative stool cultures"),
sp(4),
Paragraph("<b>Carrier Management</b>", sub_header_style),
sp(2),
bp("Treat chronic carriers with ciprofloxacin 750 mg BD x 4 weeks OR ampicillin"),
bp("Cholecystectomy if gallstones present with carrier state"),
bp("Food handlers must not work until declared free of infection"),
]
story.append(two_col(prev_left, prev_right))
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 8 - RED FLAGS
# ════════════════════════════════════════════════════════════
story.append(section_block("8. RED FLAGS - ADMIT & ESCALATE", DARK_RED))
story.append(sp(4))
red_flag_data = [
[
[
Paragraph("⚠ IMMEDIATE CONCERN", alert_style),
sp(3),
bp("Sudden severe abdominal pain (perforation)"),
bp("Haematemesis or melaena"),
bp("Altered consciousness / delirium"),
bp("Hypotension / shock"),
bp("WBC < 2.0 × 10⁹/L (severe leukopenia)"),
],
[
Paragraph("⚠ HIGH RISK FEATURES", alert_style),
sp(3),
bp("Fever persisting >10 days"),
bp("Abdominal distension + rigidity"),
bp("Splenomegaly (risk of rupture)"),
bp("Jaundice (typhoid hepatitis/cholangitis)"),
bp("Respiratory compromise (pneumonia)"),
],
[
Paragraph("⚠ RESISTANT TYPHOID", S("rt", fontSize=9.5, fontName="Helvetica-Bold", textColor=ORANGE)),
sp(3),
bp("Nalidixic acid resistant = likely fluoroquinolone reduced susceptibility"),
bp("MDR typhoid: resistant to chloramphenicol + ampicillin + TMP-SMX"),
bp("XDR typhoid: MDR + fluoroquinolone + cephalosporin resistant"),
bp("XDR: use <b>azithromycin</b> or <b>carbapenems</b>"),
],
]
]
rf_t = Table(red_flag_data, colWidths=[5.8*cm, 5.8*cm, 5.9*cm])
rf_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), colors.HexColor("#FFEBEE")),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#FFF8E1")),
("BACKGROUND", (2,0), (2,0), colors.HexColor("#FFF3E0")),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#BDBDBD")),
("INNERGRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDBDBD")),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(rf_t)
story.append(sp(8))
# ════════════════════════════════════════════════════════════
# SECTION 9 - DIFFERENTIAL DIAGNOSIS
# ════════════════════════════════════════════════════════════
story.append(section_block("9. DIFFERENTIAL DIAGNOSIS", colors.HexColor("#6A1B9A")))
story.append(sp(4))
diff_data = [
[Paragraph("Condition", table_header_style),
Paragraph("Distinguishing Features", table_header_style),
Paragraph("Key Test", table_header_style)],
[Paragraph("Malaria", table_cell_bold),
Paragraph("Cyclic fever, rigors; travel to endemic area; splenomegaly", table_cell_style),
Paragraph("Thick/thin blood film, RDT", table_cell_style)],
[Paragraph("Dengue", table_cell_bold),
Paragraph("Thrombocytopenia, petechiae, rash, bone pain, positive tourniquet test", table_cell_style),
Paragraph("NS1Ag, IgM/IgG serology", table_cell_style)],
[Paragraph("Viral hepatitis", table_cell_bold),
Paragraph("Jaundice, very elevated LFTs, dark urine", table_cell_style),
Paragraph("Hepatitis serology (HBsAg, anti-HCV)", table_cell_style)],
[Paragraph("Brucellosis", table_cell_bold),
Paragraph("Animal exposure, undulant fever, joint pain, lymphadenopathy", table_cell_style),
Paragraph("Brucella serology, blood culture", table_cell_style)],
[Paragraph("Tuberculosis", table_cell_bold),
Paragraph("Prolonged cough, weight loss, night sweats; slower course", table_cell_style),
Paragraph("CXR, sputum AFB, Gene Xpert", table_cell_style)],
[Paragraph("Infective endocarditis", table_cell_bold),
Paragraph("Heart murmur, Osler nodes, Janeway lesions, embolic phenomena", table_cell_style),
Paragraph("Blood cultures x3, echocardiogram", table_cell_style)],
]
diff_t = Table(diff_data, colWidths=[4*cm, 9*cm, 4.5*cm])
diff_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#6A1B9A")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.HexColor("#F3E5F5"), WHITE]),
("BOX", (0,0), (-1,-1), 0.75, colors.HexColor("#BDBDBD")),
("INNERGRID", (0,0), (-1,-1), 0.4, colors.HexColor("#E0E0E0")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(diff_t)
story.append(sp(10))
# ════════════════════════════════════════════════════════════
# FOOTER DISCLAIMER
# ════════════════════════════════════════════════════════════
disclaimer = Table([[
Paragraph(
"<b>Clinical Disclaimer:</b> This quick reference is for educational purposes only. "
"All clinical decisions must be made by a qualified healthcare professional based on individual "
"patient assessment, local antibiogram data, and current institutional guidelines. "
"Drug doses shown are for average adults; adjust for renal/hepatic impairment, pregnancy, and paediatric patients. "
"Sources: Tintinalli's Emergency Medicine, Sabiston Textbook of Surgery, Bailey & Love's Surgery, Goldman-Cecil Medicine.",
S("disc", fontSize=7.5, fontName="Helvetica", textColor=GREY_MED, alignment=TA_JUSTIFY)
)
]], colWidths=[17.5*cm])
disclaimer.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GREY_LIGHT),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
story.append(disclaimer)
# ── Build ────────────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=on_later_pages, onLaterPages=on_later_pages)
print(f"PDF saved: {OUTPUT_PATH}")
cd /tmp/workspace/typhoid-pdf && python generate_typhoid_pdf.py 2>&1
~/typhoid-pdf/generate_typhoid_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/typhoid-pdf/generate_typhoid_pdf.py'
"ROWBACKGROUNDS" in ~/typhoid-pdf
~/typhoid-pdf/generate_typhoid_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/typhoid-pdf/generate_typhoid_pdf.py'
~/typhoid-pdf/generate_typhoid_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/typhoid-pdf/generate_typhoid_pdf.py'
cd /tmp/workspace/typhoid-pdf && python generate_typhoid_pdf.py 2>&1
ls -lh /tmp/workspace/typhoid-pdf/Typhoid_Quick_Reference.pdf
Typhoid Quick Reference
PDF Document · PDF
| Section | Content |
|---|---|
| At a Glance | Organism, transmission, incubation, mortality, endemic regions |
| Pathophysiology | Step-by-step from ingestion to Peyer's patch ulceration |
| Clinical Features by Week | Color-coded week-by-week progression table (rose spots, bradycardia, perforation risk) |
| Diagnosis | Blood/bone marrow/stool cultures, Widal interpretation table (with titer cutoffs), PCR, rapid tests - and their limitations |
| Management | Antibiotic table: azithromycin, ceftriaxone, ciprofloxacin, cefixime with doses, duration, and resistance notes; supportive care including dexamethasone indications |
| Complications | GI (perforation, haemorrhage) and systemic; surgical management criteria |
| Lab Patterns | WBC, lymphocytes, Hb, platelets, LFTs, Widal O vs H - what to expect |
| Red Flags | Three-column alert box: immediate danger signs, high-risk features, and MDR/XDR typhoid |
| Differential Diagnosis | Malaria, dengue, hepatitis, brucellosis, TB, endocarditis - distinguishing features and key tests |
| Prevention | ViPS, Ty21a, Vi-TT conjugate vaccines; carrier management |