Diagnosis of typhoid
typhoid AND diagnosis
WHO typhoid fever diagnosis blood culture rapid diagnostic tests guidance
| Test | Role and key points |
|---|---|
| Blood culture | First-line and preferred test. Take blood cultures before antibiotics where possible. A single culture detects only about half of cases, so obtain multiple cultures if suspicion remains high. |
| Bone-marrow culture | Most sensitive, around 80% in some studies, and may remain positive even after antibiotics. It is invasive, so used when blood cultures are negative but suspicion is strong. |
| Stool culture | Can confirm infection and helps identify shedding/carriage, but is less sensitive early in illness. |
| Culture identification and susceptibility testing | Once Salmonella Typhi or S. Paratyphi is isolated, antimicrobial susceptibility testing should guide antibiotic choice. |
| PCR / molecular assays | May help where validated and available, but are not a substitute for culture and susceptibility testing in many settings. |
Create a quick-reference PDF on typhoid diagnosis
typhoid AND diagnosis
CDC clinical guidance typhoid diagnosis blood culture Widal 2026
~/
mkdir -p "/tmp/workspace/typhoid-diagnosis-pdf/src" "/tmp/workspace/typhoid-diagnosis-pdf/output" && python - <<'PY' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_LEFT, TA_CENTER from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, KeepTogether from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics from reportlab.lib.colors import HexColor from reportlab.pdfbase.pdfmetrics import registerFontFamily from reportlab.pdfgen import canvas from reportlab.lib.utils import simpleSplit from reportlab.platypus import Flowable from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics import os base='/tmp/workspace/typhoid-diagnosis-pdf' out=base+'/output/Typhoid_Diagnosis_Quick_Reference.pdf' NAVY=HexColor('#103A5C'); TEAL=HexColor('#007C83'); PALE=HexColor('#EAF5F5'); LIGHT=HexColor('#F4F7F9'); AMBER=HexColor('#FFF3D6'); RED=HexColor('#B3261E'); DARK=HexColor('#1D2939'); GREY=HexColor('#5B6673'); LINE=HexColor('#C9D4DC') styles=getSampleStyleSheet() styles.add(ParagraphStyle(name='TitleX', fontName='Helvetica-Bold', fontSize=22, leading=26, textColor=NAVY, spaceAfter=3)) styles.add(ParagraphStyle(name='Sub', fontName='Helvetica', fontSize=9.3, leading=12, textColor=GREY, spaceAfter=9)) styles.add(ParagraphStyle(name='H', fontName='Helvetica-Bold', fontSize=11, leading=13, textColor=NAVY, spaceBefore=7, spaceAfter=4)) styles.add(ParagraphStyle(name='BodyX', fontName='Helvetica', fontSize=8.7, leading=11.3, textColor=DARK)) styles.add(ParagraphStyle(name='Small', fontName='Helvetica', fontSize=7.3, leading=9, textColor=GREY)) styles.add(ParagraphStyle(name='BoxHead', fontName='Helvetica-Bold', fontSize=9.3, leading=11.5, textColor=NAVY)) styles.add(ParagraphStyle(name='BoxBody', fontName='Helvetica', fontSize=8.3, leading=10.4, textColor=DARK)) styles.add(ParagraphStyle(name='WhiteHead', fontName='Helvetica-Bold', fontSize=8.7, leading=10.4, textColor=colors.white)) styles.add(ParagraphStyle(name='WhiteBody', fontName='Helvetica', fontSize=8.1, leading=10.2, textColor=colors.white)) class HeaderRule(Flowable): def __init__(self,w): Flowable.__init__(self); self.width=w; self.height=4 def draw(self): self.canv.setFillColor(TEAL); self.canv.rect(0,1,self.width,3,stroke=0,fill=1) def P(text, style='BodyX'): return Paragraph(text, styles[style]) def section_box(title, body, bg=LIGHT, title_color=NAVY): t=Table([[P(title,'BoxHead'), P(body,'BoxBody')]], colWidths=[37*mm, 132*mm]) t.setStyle(TableStyle([ ('BACKGROUND',(0,0),(-1,-1),bg),('BOX',(0,0),(-1,-1),0.45,LINE), ('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),5),('BOTTOMPADDING',(0,0),(-1,-1),5), ('LINEAFTER',(0,0),(0,0),0.45,LINE) ])) return t def footer(canvas, doc): canvas.saveState(); w,h=A4 canvas.setStrokeColor(LINE); canvas.setLineWidth(.4); canvas.line(20*mm, 13*mm, w-20*mm,13*mm) canvas.setFont('Helvetica',7.2); canvas.setFillColor(GREY) canvas.drawString(20*mm,8.7*mm,'Typhoid diagnosis quick reference | For trained healthcare professionals') canvas.drawRightString(w-20*mm,8.7*mm,f'Page {doc.page}') canvas.restoreState() doc=SimpleDocTemplate(out,pagesize=A4,rightMargin=20*mm,leftMargin=20*mm,topMargin=15*mm,bottomMargin=18*mm) story=[] story += [P('TYPHOID FEVER: DIAGNOSIS','TitleX'), P('Quick reference for suspected enteric fever caused by <i>Salmonella</i> Typhi or Paratyphi. This aid supports, but does not replace, local laboratory and public-health guidance.','Sub'), HeaderRule(170*mm), Spacer(1,5)] # suspicion story += [P('1. WHEN TO SUSPECT ENTERIC FEVER','H')] susp=Table([[P('<b>Exposure risk</b><br/>Residence in or travel to an endemic setting; unsafe food or water; outbreak/contact history.','BoxBody'), P('<b>Typical pattern</b><br/>Insidious, progressive fever over several days with headache, malaise, abdominal pain, constipation or diarrhea. Rose spots and splenomegaly may occur.','BoxBody'), P('<b>Key limitation</b><br/>Symptoms overlap with malaria, dengue, leptospirosis, rickettsioses, viral hepatitis, acute bacterial sepsis, and other infections.','BoxBody')]], colWidths=[56.5*mm,56.5*mm,56.5*mm]) susp.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),PALE),('BOX',(0,0),(-1,-1),.45,LINE),('INNERGRID',(0,0),(-1,-1),.45,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),6),('RIGHTPADDING',(0,0),(-1,-1),6),('TOPPADDING',(0,0),(-1,-1),6),('BOTTOMPADDING',(0,0),(-1,-1),6)])) story += [susp, Spacer(1,5)] story += [P('2. DIAGNOSTIC ALGORITHM','H')] algo=[ [P('<b>1. BEFORE ANTIBIOTICS, IF FEASIBLE</b><br/>Obtain blood cultures promptly. Do not delay resuscitation or necessary empiric treatment in a clinically unwell patient.','WhiteBody')], [P('<b>2. CULTURE-BASED CONFIRMATION</b><br/>Blood culture is the preferred first-line test. Send multiple cultures if initial culture is negative and clinical suspicion remains high. Request organism identification and antimicrobial susceptibility testing.','WhiteBody')], [P('<b>3. IF CULTURES ARE NEGATIVE BUT SUSPICION IS HIGH</b><br/>Review prior antibiotic exposure and specimen volume/timing. Repeat blood cultures; seek infectious-diseases or microbiology advice. Bone-marrow culture is more sensitive and may remain positive after antibiotics, but is invasive.','WhiteBody')], [P('<b>4. CONCURRENTLY EVALUATE ALTERNATIVES</b><br/>Tailor testing to geography and presentation, including malaria testing where relevant, plus dengue, leptospirosis, rickettsial disease, hepatitis, and sepsis evaluation.','WhiteBody')] ] at=Table(algo,colWidths=[170*mm]) at.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),NAVY),('BOX',(0,0),(-1,-1),.5,NAVY),('INNERGRID',(0,0),(-1,-1),.55,colors.white),('LEFTPADDING',(0,0),(-1,-1),7),('RIGHTPADDING',(0,0),(-1,-1),7),('TOPPADDING',(0,0),(-1,-1),5),('BOTTOMPADDING',(0,0),(-1,-1),5)])) story += [at, Spacer(1,5)] story += [P('3. TEST SELECTION AT A GLANCE','H')] data=[ [P('<b>Test</b>','WhiteHead'),P('<b>Use and interpretation</b>','WhiteHead'),P('<b>Limitations</b>','WhiteHead')], [P('<b>Blood culture</b>','BoxBody'),P('Mainstay and preferred diagnostic test for acute infection. A positive culture confirms enteric fever and enables susceptibility testing.','BoxBody'),P('Sensitivity is imperfect. A single culture may be positive in only about 50% of cases; prior antibiotics and low blood volume reduce yield.','BoxBody')], [P('<b>Bone-marrow culture</b>','BoxBody'),P('Consider with persistent high clinical suspicion and negative blood cultures. Sensitivity is about 80% in some studies and it can remain positive after antibiotics.','BoxBody'),P('Invasive and less routinely available.','BoxBody')], [P('<b>Stool culture</b>','BoxBody'),P('May support diagnosis and is useful in assessing shedding/carriage.','BoxBody'),P('Less sensitive early in illness and generally less sensitive than blood culture.','BoxBody')], [P('<b>PCR / molecular tests</b>','BoxBody'),P('Potential adjunct only where a locally validated assay is available.','BoxBody'),P('Availability and performance vary. Culture remains needed for susceptibility testing.','BoxBody')], [P('<b>Widal / antibody rapid tests</b>','BoxBody'),P('<b>Do not use as stand-alone confirmation.</b>','BoxBody'),P('False positives and poor discrimination between acute infection, prior infection, and vaccination. CDC does not recommend Widal testing for acute diagnosis.','BoxBody')], ] t=Table(data,colWidths=[35*mm,75*mm,60*mm],repeatRows=1) t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),TEAL),('TEXTCOLOR',(0,0),(-1,0),colors.white),('BOX',(0,0),(-1,-1),.45,LINE),('INNERGRID',(0,0),(-1,-1),.35,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),('BACKGROUND',(0,1),(-1,-1),colors.white),('BACKGROUND',(0,5),(-1,5),HexColor('#FFF7E8'))])) story += [t, Spacer(1,5)] story += [P('4. SUPPORTIVE FINDINGS AND ESCALATION','H')] left=P('<b>Supportive, not confirmatory</b><br/>CBC may show leukopenia, anemia, or thrombocytopenia. Mild liver-enzyme elevation, relative bradycardia, rose spots, hepatomegaly, or splenomegaly can occur. None establishes the diagnosis.','BoxBody') right=P('<b>Urgent assessment / escalation</b><br/><font color="#B3261E">Severe abdominal pain, GI bleeding, persistent vomiting, confusion/encephalopathy, shock, oliguria, or signs of peritonitis.</font> Consider complications including intestinal bleeding or perforation and manage urgently.','BoxBody') t2=Table([[left,right]],colWidths=[85*mm,85*mm]) t2.setStyle(TableStyle([('BACKGROUND',(0,0),(0,0),LIGHT),('BACKGROUND',(1,0),(1,0),AMBER),('BOX',(0,0),(-1,-1),.45,LINE),('INNERGRID',(0,0),(-1,-1),.45,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),6),('RIGHTPADDING',(0,0),(-1,-1),6),('TOPPADDING',(0,0),(-1,-1),6),('BOTTOMPADDING',(0,0),(-1,-1),6)])) story += [t2, Spacer(1,6)] story += [P('KEY TAKEAWAY: Suspect from epidemiology plus a compatible febrile illness. Confirm by isolating <i>Salmonella</i> Typhi or Paratyphi, preferably from blood culture. Obtain cultures before antibiotics when feasible, but do not delay urgent treatment in a clinically ill patient.','BoxHead'), Spacer(1,5)] story += [P('<b>Sources</b>: CDC Clinical Guidance for Typhoid and Paratyphoid Fever (accessed 24 Sep 2026); CDC Yellow Book, “Typhoid and Paratyphoid Fever” (accessed 24 Sep 2026); <i>Sabiston Textbook of Surgery</i>, 22nd ed., p. 1966; <i>Sleisenger and Fordtran’s Gastrointestinal and Liver Disease</i>, “Typhoid Fever,” diagnosis section.','Small')] doc.build(story,onFirstPage=footer,onLaterPages=footer) print(out) PY python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/typhoid-diagnosis-pdf/output/Typhoid_Diagnosis_Quick_Reference.pdf' r=PdfReader(p) print('pages',len(r.pages),'bytes',__import__('os').path.getsize(p)) for i,page in enumerate(r.pages): txt=page.extract_text() print(i+1, len(txt), txt[:130].replace('\n',' | ')) PY
python - <<'PY' from reportlab.lib.pagesizes import A4, landscape from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Flowable from reportlab.lib.units import mm from pypdf import PdfReader import os out='/tmp/workspace/typhoid-diagnosis-pdf/output/Typhoid_Diagnosis_Quick_Reference.pdf' W,H=landscape(A4) NAVY=HexColor('#103A5C'); TEAL=HexColor('#007C83'); PALE=HexColor('#EAF5F5'); LIGHT=HexColor('#F4F7F9'); AMBER=HexColor('#FFF3D6'); RED=HexColor('#B3261E'); DARK=HexColor('#1D2939'); GREY=HexColor('#5B6673'); LINE=HexColor('#C9D4DC') s=getSampleStyleSheet() s.add(ParagraphStyle(name='title',fontName='Helvetica-Bold',fontSize=20,leading=23,textColor=NAVY,spaceAfter=1)) s.add(ParagraphStyle(name='sub',fontName='Helvetica',fontSize=8.3,leading=10,textColor=GREY,spaceAfter=3)) s.add(ParagraphStyle(name='h',fontName='Helvetica-Bold',fontSize=10,leading=12,textColor=NAVY,spaceBefore=4,spaceAfter=3)) s.add(ParagraphStyle(name='body',fontName='Helvetica',fontSize=7.4,leading=9.1,textColor=DARK)) s.add(ParagraphStyle(name='head',fontName='Helvetica-Bold',fontSize=7.5,leading=9.2,textColor=colors.white)) s.add(ParagraphStyle(name='white',fontName='Helvetica',fontSize=7.25,leading=8.8,textColor=colors.white)) s.add(ParagraphStyle(name='small',fontName='Helvetica',fontSize=6.3,leading=7.5,textColor=GREY)) def p(txt,st='body'): return Paragraph(txt,s[st]) def footer(c,d): c.saveState();c.setStrokeColor(LINE);c.setLineWidth(.4);c.line(14*mm,10*mm,W-14*mm,10*mm);c.setFillColor(GREY);c.setFont('Helvetica',6.4);c.drawString(14*mm,6.1*mm,'Typhoid diagnosis quick reference | For trained healthcare professionals');c.drawRightString(W-14*mm,6.1*mm,'24 Sep 2026');c.restoreState() doc=SimpleDocTemplate(out,pagesize=landscape(A4),leftMargin=14*mm,rightMargin=14*mm,topMargin=10*mm,bottomMargin=14*mm) story=[p('TYPHOID FEVER: DIAGNOSIS','title'),p('A clinician quick reference for suspected enteric fever due to <i>Salmonella</i> Typhi or Paratyphi. Use alongside local laboratory, infectious-diseases, and public-health guidance.','sub')] # three trigger cards cards=[[p('<b>Suspect when</b><br/>Insidious, progressive fever plus headache, malaise, abdominal pain, constipation or diarrhea.','body'),p('<b>Exposure clues</b><br/>Travel or residence in an endemic setting; unsafe food/water; outbreak or contact exposure.','body'),p('<b>Do not diagnose clinically alone</b><br/>Presentation overlaps malaria, dengue, leptospirosis, rickettsioses, viral hepatitis, and sepsis.','body')]] t=Table(cards,colWidths=[88*mm]*3);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),PALE),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.4,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4)]));story += [t,p('DIAGNOSTIC ACTIONS','h')] steps=[[p('<b>1. CULTURE FIRST, IF FEASIBLE</b><br/>Obtain blood cultures promptly and before antibiotics when this does not delay urgent care.','white')],[p('<b>2. CONFIRMATION</b><br/>Blood culture is the preferred first-line test. Identification of <i>S.</i> Typhi or Paratyphi from blood, bone marrow, or stool confirms the diagnosis. Request antimicrobial susceptibility testing.','white')],[p('<b>3. PERSISTENT SUSPICION</b><br/>If initial culture is negative, review antibiotic exposure, specimen volume, and timing; repeat blood cultures. Seek microbiology/ID advice. Bone-marrow culture is more sensitive but invasive.','white')],[p('<b>4. TEST ALTERNATIVES IN PARALLEL</b><br/>Tailor tests to setting and presentation, including malaria testing where relevant, and dengue, leptospirosis, rickettsial infection, hepatitis, and sepsis evaluation.','white')]] t=Table(steps,colWidths=[264*mm]);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),NAVY),('BOX',(0,0),(-1,-1),.4,NAVY),('INNERGRID',(0,0),(-1,-1),.45,colors.white),('LEFTPADDING',(0,0),(-1,-1),6),('RIGHTPADDING',(0,0),(-1,-1),6),('TOPPADDING',(0,0),(-1,-1),3.5),('BOTTOMPADDING',(0,0),(-1,-1),3.5)]));story += [t,p('TEST SELECTION','h')] data=[[p('<b>Test</b>','head'),p('<b>Role</b>','head'),p('<b>Important caveat</b>','head')], [p('<b>Blood culture</b>'),p('Mainstay and preferred test for acute infection. Positive culture confirms disease and enables susceptibility testing.'),p('Sensitivity is imperfect: a single culture can be positive in only about 50% of cases. Prior antibiotics and low blood volume reduce yield.')], [p('<b>Bone-marrow culture</b>'),p('Consider when blood cultures are negative but clinical suspicion remains high.'),p('About 80% sensitivity in some studies; can remain positive after antibiotics. Invasive and less available.')], [p('<b>Stool culture</b>'),p('May support diagnosis and help assess shedding/carriage.'),p('Less sensitive early in illness and generally less sensitive than blood culture.')], [p('<b>PCR / molecular</b>'),p('Possible adjunct where a validated local assay is available.'),p('Performance and availability vary. Culture is still needed for susceptibility testing.')], [p('<b>Widal / antibody RDT</b>'),p('<b>Do not use as stand-alone confirmation.</b>'),p('False positives and inability to reliably separate acute infection from past infection or vaccination. CDC does not recommend Widal for acute diagnosis.')]] t=Table(data,colWidths=[45*mm,106*mm,113*mm],repeatRows=1);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),TEAL),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.3,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),4),('RIGHTPADDING',(0,0),(-1,-1),4),('TOPPADDING',(0,0),(-1,-1),2.8),('BOTTOMPADDING',(0,0),(-1,-1),2.8),('BACKGROUND',(0,5),(-1,5),HexColor('#FFF7E8'))]));story += [t,p('SUPPORTIVE FINDINGS AND RED FLAGS','h')] red=[[p('<b>Supportive, not diagnostic</b><br/>Leukopenia, anemia, thrombocytopenia, mildly raised liver enzymes, relative bradycardia, rose spots, hepatomegaly, or splenomegaly may occur.','body'),p('<b>Urgent assessment</b><br/><font color="#B3261E">Severe abdominal pain, GI bleeding, persistent vomiting, confusion, shock, oliguria, or peritonitis.</font> Evaluate urgently for complications such as bleeding or intestinal perforation.','body')]] t=Table(red,colWidths=[132*mm,132*mm]);t.setStyle(TableStyle([('BACKGROUND',(0,0),(0,0),LIGHT),('BACKGROUND',(1,0),(1,0),AMBER),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.4,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),3.5),('BOTTOMPADDING',(0,0),(-1,-1),3.5)]));story += [t,Spacer(1,3),p('<b>Bottom line:</b> Suspect from epidemiology plus compatible fever, but confirm with culture. Obtain cultures before antibiotics when feasible, without delaying essential treatment of an ill patient.','body'),Spacer(1,2),p('<b>Sources:</b> CDC Clinical Guidance for Typhoid and Paratyphoid Fever; CDC Yellow Book, “Typhoid and Paratyphoid Fever”; <i>Sabiston Textbook of Surgery</i>, 22nd ed., p. 1966; <i>Sleisenger and Fordtran’s Gastrointestinal and Liver Disease</i>, “Typhoid Fever” diagnosis section.','small')] doc.build(story,onFirstPage=footer,onLaterPages=footer) r=PdfReader(out);print('pages',len(r.pages),'size',os.path.getsize(out),'text',len(r.pages[0].extract_text())) PY
python - <<'PY' p='/tmp/workspace/typhoid-diagnosis-pdf/src/create_quick_reference.py' # Previous creation was inline. Build an efficient one-page landscape version. from reportlab.lib.pagesizes import A4, landscape from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle from reportlab.lib.units import mm from pypdf import PdfReader import os out='/tmp/workspace/typhoid-diagnosis-pdf/output/Typhoid_Diagnosis_Quick_Reference.pdf' W,H=landscape(A4) NAVY=HexColor('#103A5C'); TEAL=HexColor('#007C83'); PALE=HexColor('#EAF5F5'); LIGHT=HexColor('#F4F7F9'); AMBER=HexColor('#FFF3D6'); DARK=HexColor('#1D2939'); GREY=HexColor('#5B6673'); LINE=HexColor('#C9D4DC') s=getSampleStyleSheet() s.add(ParagraphStyle(name='QTitle',fontName='Helvetica-Bold',fontSize=20,leading=23,textColor=NAVY,spaceAfter=1)) s.add(ParagraphStyle(name='QSub',fontName='Helvetica',fontSize=8.3,leading=10,textColor=GREY,spaceAfter=3)) s.add(ParagraphStyle(name='QH',fontName='Helvetica-Bold',fontSize=10,leading=12,textColor=NAVY,spaceBefore=4,spaceAfter=3)) s.add(ParagraphStyle(name='QBody',fontName='Helvetica',fontSize=7.4,leading=9.1,textColor=DARK)) s.add(ParagraphStyle(name='QHead',fontName='Helvetica-Bold',fontSize=7.5,leading=9.2,textColor=colors.white)) s.add(ParagraphStyle(name='QWhite',fontName='Helvetica',fontSize=7.25,leading=8.8,textColor=colors.white)) s.add(ParagraphStyle(name='QSmall',fontName='Helvetica',fontSize=6.3,leading=7.5,textColor=GREY)) def p(txt,st='QBody'): return Paragraph(txt,s[st]) def footer(c,d): c.saveState();c.setStrokeColor(LINE);c.setLineWidth(.4);c.line(14*mm,10*mm,W-14*mm,10*mm);c.setFillColor(GREY);c.setFont('Helvetica',6.4);c.drawString(14*mm,6.1*mm,'Typhoid diagnosis quick reference | For trained healthcare professionals');c.drawRightString(W-14*mm,6.1*mm,'24 Sep 2026');c.restoreState() doc=SimpleDocTemplate(out,pagesize=landscape(A4),leftMargin=14*mm,rightMargin=14*mm,topMargin=10*mm,bottomMargin=14*mm) story=[p('TYPHOID FEVER: DIAGNOSIS','QTitle'),p('A clinician quick reference for suspected enteric fever due to <i>Salmonella</i> Typhi or Paratyphi. Use alongside local laboratory, infectious-diseases, and public-health guidance.','QSub')] cards=[[p('<b>Suspect when</b><br/>Insidious, progressive fever plus headache, malaise, abdominal pain, constipation or diarrhea.'),p('<b>Exposure clues</b><br/>Travel or residence in an endemic setting; unsafe food/water; outbreak or contact exposure.'),p('<b>Do not diagnose clinically alone</b><br/>Presentation overlaps malaria, dengue, leptospirosis, rickettsioses, viral hepatitis, and sepsis.')]] t=Table(cards,colWidths=[88*mm]*3);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),PALE),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.4,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4)]));story += [t,p('DIAGNOSTIC ACTIONS','QH')] steps=[[p('<b>1. CULTURE FIRST, IF FEASIBLE</b><br/>Obtain blood cultures promptly and before antibiotics when this does not delay urgent care.','QWhite')],[p('<b>2. CONFIRMATION</b><br/>Blood culture is the preferred first-line test. Identification of <i>S.</i> Typhi or Paratyphi from blood, bone marrow, or stool confirms the diagnosis. Request antimicrobial susceptibility testing.','QWhite')],[p('<b>3. PERSISTENT SUSPICION</b><br/>If initial culture is negative, review antibiotic exposure, specimen volume, and timing; repeat blood cultures. Seek microbiology/ID advice. Bone-marrow culture is more sensitive but invasive.','QWhite')],[p('<b>4. TEST ALTERNATIVES IN PARALLEL</b><br/>Tailor tests to setting and presentation, including malaria testing where relevant, and dengue, leptospirosis, rickettsial infection, hepatitis, and sepsis evaluation.','QWhite')]] t=Table(steps,colWidths=[264*mm]);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),NAVY),('BOX',(0,0),(-1,-1),.4,NAVY),('INNERGRID',(0,0),(-1,-1),.45,colors.white),('LEFTPADDING',(0,0),(-1,-1),6),('RIGHTPADDING',(0,0),(-1,-1),6),('TOPPADDING',(0,0),(-1,-1),3.5),('BOTTOMPADDING',(0,0),(-1,-1),3.5)]));story += [t,p('TEST SELECTION','QH')] data=[[p('<b>Test</b>','QHead'),p('<b>Role</b>','QHead'),p('<b>Important caveat</b>','QHead')],[p('<b>Blood culture</b>'),p('Mainstay and preferred test for acute infection. Positive culture confirms disease and enables susceptibility testing.'),p('Sensitivity is imperfect: a single culture can be positive in only about 50% of cases. Prior antibiotics and low blood volume reduce yield.')],[p('<b>Bone-marrow culture</b>'),p('Consider when blood cultures are negative but clinical suspicion remains high.'),p('About 80% sensitivity in some studies; can remain positive after antibiotics. Invasive and less available.')],[p('<b>Stool culture</b>'),p('May support diagnosis and help assess shedding/carriage.'),p('Less sensitive early in illness and generally less sensitive than blood culture.')],[p('<b>PCR / molecular</b>'),p('Possible adjunct where a validated local assay is available.'),p('Performance and availability vary. Culture is still needed for susceptibility testing.')],[p('<b>Widal / antibody RDT</b>'),p('<b>Do not use as stand-alone confirmation.</b>'),p('False positives and inability to reliably separate acute infection from past infection or vaccination. CDC does not recommend Widal for acute diagnosis.')]] t=Table(data,colWidths=[45*mm,106*mm,113*mm],repeatRows=1);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),TEAL),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.3,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),4),('RIGHTPADDING',(0,0),(-1,-1),4),('TOPPADDING',(0,0),(-1,-1),2.8),('BOTTOMPADDING',(0,0),(-1,-1),2.8),('BACKGROUND',(0,5),(-1,5),HexColor('#FFF7E8'))]));story += [t,p('SUPPORTIVE FINDINGS AND RED FLAGS','QH')] red=[[p('<b>Supportive, not diagnostic</b><br/>Leukopenia, anemia, thrombocytopenia, mildly raised liver enzymes, relative bradycardia, rose spots, hepatomegaly, or splenomegaly may occur.'),p('<b>Urgent assessment</b><br/><font color="#B3261E">Severe abdominal pain, GI bleeding, persistent vomiting, confusion, shock, oliguria, or peritonitis.</font> Evaluate urgently for complications such as bleeding or intestinal perforation.')]] t=Table(red,colWidths=[132*mm,132*mm]);t.setStyle(TableStyle([('BACKGROUND',(0,0),(0,0),LIGHT),('BACKGROUND',(1,0),(1,0),AMBER),('BOX',(0,0),(-1,-1),.4,LINE),('INNERGRID',(0,0),(-1,-1),.4,LINE),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),('TOPPADDING',(0,0),(-1,-1),3.5),('BOTTOMPADDING',(0,0),(-1,-1),3.5)]));story += [t,Spacer(1,3),p('<b>Bottom line:</b> Suspect from epidemiology plus compatible fever, but confirm with culture. Obtain cultures before antibiotics when feasible, without delaying essential treatment of an ill patient.'),Spacer(1,2),p('<b>Sources:</b> CDC Clinical Guidance for Typhoid and Paratyphoid Fever; CDC Yellow Book, “Typhoid and Paratyphoid Fever”; <i>Sabiston Textbook of Surgery</i>, 22nd ed., p. 1966; <i>Sleisenger and Fordtran’s Gastrointestinal and Liver Disease</i>, “Typhoid Fever” diagnosis section.','QSmall')] doc.build(story,onFirstPage=footer,onLaterPages=footer) r=PdfReader(out); assert len(r.pages)==1, len(r.pages); txt=r.pages[0].extract_text(); assert 'Blood culture' in txt and 'Widal' in txt print('verified',len(r.pages),os.path.getsize(out),len(txt)) PY
Typhoid Diagnosis Quick Reference
PDF Document · PDF