Malaria symptoms, diagnosis, treatment flow chart diagram

Reading File
Finding Sources
Searching the Web

malaria symptoms diagnosis treatment flowchart WHO guidelines 2024

Finding Sources
Reading File
Reading File
Generating Image

A clean, professional medical flowchart diagram titled "Malaria: Symptoms, Diagnosis & Treatment" with the following flow structure: START BOX at top: "Patient presents with Fever + Travel/Residence in endemic area" Arrow down to SYMPTOMS BOX (light orange background): Title: "SYMPTOMS" • Fever (irregular early, then periodic every 2-3 days) • Chills and rigors • Headache • Myalgia / arthralgia • Nausea, vomiting, diarrhea • Sweating episodes • Fatigue / malaise • Splenomegaly (classic triad: fever + splenomegaly + thrombocytopenia) Arrow down to CLINICAL ASSESSMENT BOX (light yellow background): Title: "INITIAL ASSESSMENT" • Travel history to malaria-endemic region? • Fever >38.5°C of unclear origin? • Chemoprophylaxis taken? • Altered mental status? (suspect cerebral malaria) • Assess for severe vs. uncomplicated malaria Arrow splits into two paths: LEFT = "SEVERE MALARIA signs present" RIGHT = "No severe signs" SEVERE MALARIA indicators (red border box, left side): • Altered consciousness / cerebral malaria • Respiratory distress • Severe anemia (Hb <7 g/dL) • Renal failure / hemoglobinuria • Shock / circulatory collapse • Spontaneous bleeding • Hyperparasitemia (>5% RBCs) UNCOMPLICATED MALARIA (green border box, right side): • Fever + parasitemia • No organ dysfunction • Can tolerate oral medications Arrow down from both boxes to DIAGNOSIS BOX (light blue background): Title: "DIAGNOSIS" • Blood smear (thick & thin) - Gold standard • Rapid Diagnostic Test (RDT) - antigen detection • PCR - for low parasitemia / species confirmation • CBC: thrombocytopenia, anemia • LFTs, renal function, blood glucose • Species identification: P. falciparum, P. vivax, P. ovale, P. malariae, P. knowlesi Arrow down to TREATMENT BOX splitting into two branches: LEFT BRANCH - SEVERE MALARIA (red header): "HOSPITALIZE - IV Treatment" • IV Artesunate (first-line) - preferred over quinine • If artesunate unavailable: IV Quinine + doxycycline/clindamycin • Supportive care: fluids, antipyretics, manage complications • Monitor blood glucose (risk of hypoglycemia) • Blood transfusion if severe anemia RIGHT BRANCH - UNCOMPLICATED MALARIA (green header): "Outpatient Oral Treatment" • P. falciparum / mixed: Artemisinin-based Combination Therapy (ACT) (Artemether-lumefantrine OR Artesunate-amodiaquine) • Chloroquine-sensitive species (P. vivax, P. ovale, P. malariae): Oral Chloroquine 3-day course • P. vivax / P. ovale: add Primaquine (after G6PD testing) to prevent relapse • Treat fever with paracetamol Arrow down to FOLLOW-UP BOX (light purple background): Title: "FOLLOW-UP & MONITORING" • Repeat blood smears at 48-72 hrs, Day 7, Day 14, Day 28 • Monitor for treatment failure / drug resistance • Assess for complications • Primaquine for radical cure (P. vivax/P. ovale) • Educate on prevention: bed nets, repellents, chemoprophylaxis for future travel Use a clean white background, medical blue color scheme, clear directional arrows, bold section headers, and professional typography suitable for medical education.

Malaria Symptoms, Diagnosis & Treatment Flowchart
Here is a complete Malaria: Symptoms, Diagnosis & Treatment flowchart based on authoritative clinical sources (Tintinalli's Emergency Medicine, Rosen's Emergency Medicine, and WHO guidelines). Key points summarized below:

Symptoms (Classic Triad)
  • Fever + Splenomegaly + Thrombocytopenia
  • Fever may be irregular early, then periodic every 2-3 days
  • Associated: chills, rigors, headache, myalgia, nausea, fatigue
Diagnosis
  • Gold standard: Thick & thin blood smear - identifies species and parasite density
  • Rapid Diagnostic Test (RDT): Fast antigen detection at point-of-care
  • PCR: For species confirmation or low parasitemia
  • CBC shows thrombocytopenia and anemia in most cases
Treatment - Uncomplicated Malaria (oral)
  • P. falciparum: Artemisinin-based Combination Therapy (ACT) - artemether-lumefantrine is first-line
  • P. vivax / P. ovale: Chloroquine (where sensitive) + Primaquine for radical cure (after G6PD testing)
Treatment - Severe Malaria (IV, hospitalize)
  • IV Artesunate is the WHO preferred first-line agent
  • Supportive care for complications (cerebral malaria, severe anemia, renal failure, hypoglycemia)
Follow-up
  • Repeat blood smears at Day 3, 7, 14, 28 to detect treatment failure
  • Prevention counseling: bed nets, insect repellents, chemoprophylaxis
Sources: Tintinalli's Emergency Medicine; Rosen's Emergency Medicine; WHO Guidelines for Malaria (Nov 2024)

Create a detailed reference PDF of this flowchart for clinical use

Reading File
Running Command

mkdir -p /home/daytona/workspace/malaria-pdf && ls /home/daytona/workspace/malar…

Writing File

~/malaria-pdf/generate_malaria_pdf.py

#!/usr/bin/env python3
"""
Malaria Clinical Reference PDF Generator
Detailed flowchart-style reference for clinical use
"""

import urllib.request
import io
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
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,
    HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus import Image as RLImage
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon
from reportlab.graphics.charts.flowchart import (
    FlowChart
)
from reportlab.graphics import renderPDF
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor

OUTPUT_PATH = "/home/daytona/workspace/malaria-pdf/Malaria_Clinical_Reference.pdf"

# --- Color Palette ---
C_BLUE_DARK   = HexColor("#1A3C5E")
C_BLUE_MED    = HexColor("#2C6FAC")
C_BLUE_LIGHT  = HexColor("#D6E8FA")
C_ORANGE      = HexColor("#E8790C")
C_ORANGE_LIGHT= HexColor("#FEF0DC")
C_GREEN       = HexColor("#1F7A3E")
C_GREEN_LIGHT = HexColor("#D4EDDA")
C_RED         = HexColor("#B22222")
C_RED_LIGHT   = HexColor("#FDECEA")
C_YELLOW_LIGHT= HexColor("#FFFDE7")
C_PURPLE      = HexColor("#5B2C8D")
C_PURPLE_LIGHT= HexColor("#EDE7F6")
C_GREY_LIGHT  = HexColor("#F5F5F5")
C_GREY        = HexColor("#CCCCCC")
C_BLACK       = colors.black
C_WHITE       = colors.white

# --- Page Setup ---
W, H = A4  # 595 x 842 pts


def header_footer(canvas_obj, doc):
    """Draw header and footer on every page."""
    canvas_obj.saveState()
    # Top header bar
    canvas_obj.setFillColor(C_BLUE_DARK)
    canvas_obj.rect(0, H - 28*mm, W, 28*mm, fill=1, stroke=0)
    canvas_obj.setFillColor(C_WHITE)
    canvas_obj.setFont("Helvetica-Bold", 14)
    canvas_obj.drawString(15*mm, H - 14*mm, "MALARIA  –  Clinical Reference Guide")
    canvas_obj.setFont("Helvetica", 9)
    canvas_obj.drawRightString(W - 15*mm, H - 10*mm, "Symptoms · Diagnosis · Treatment")
    canvas_obj.drawRightString(W - 15*mm, H - 18*mm, "Based on WHO Guidelines (2024) | Tintinalli's EM | Rosen's EM")

    # Orange accent line under header
    canvas_obj.setFillColor(C_ORANGE)
    canvas_obj.rect(0, H - 30*mm, W, 2*mm, fill=1, stroke=0)

    # Footer
    canvas_obj.setFillColor(C_GREY_LIGHT)
    canvas_obj.rect(0, 0, W, 12*mm, fill=1, stroke=0)
    canvas_obj.setFillColor(C_BLUE_DARK)
    canvas_obj.setFont("Helvetica", 8)
    canvas_obj.drawString(15*mm, 4*mm,
        "Sources: WHO Guidelines for Malaria (Nov 2024) | Tintinalli's Emergency Medicine | Rosen's Emergency Medicine | Harrison's Principles of Internal Medicine 22E")
    canvas_obj.drawRightString(W - 15*mm, 4*mm, f"Page {doc.page}")
    canvas_obj.restoreState()


def build_section_title(text, bg_color=C_BLUE_DARK, fg_color=C_WHITE, size=12):
    style = ParagraphStyle(
        "sectiontitle",
        fontName="Helvetica-Bold",
        fontSize=size,
        textColor=fg_color,
        backColor=bg_color,
        spaceAfter=2,
        spaceBefore=6,
        leftIndent=6,
        rightIndent=6,
        leading=size + 6,
        borderPad=4,
    )
    return Paragraph(f"  {text}", style)


def build_body(text, bold=False, size=9, color=C_BLACK, indent=0):
    style = ParagraphStyle(
        "body",
        fontName="Helvetica-Bold" if bold else "Helvetica",
        fontSize=size,
        textColor=color,
        leftIndent=indent,
        leading=size + 4,
        spaceAfter=1,
    )
    return Paragraph(text, style)


def bullet(text, color=C_BLUE_MED, size=9):
    style = ParagraphStyle(
        "bullet",
        fontName="Helvetica",
        fontSize=size,
        textColor=C_BLACK,
        leftIndent=12,
        bulletIndent=2,
        leading=size + 4,
        spaceAfter=1,
    )
    return Paragraph(f"<bullet>&bull;</bullet> {text}", style)


def colored_table(data, col_widths, header_bg=C_BLUE_DARK, row_bg_alt=C_BLUE_LIGHT, font_size=8):
    """Build a styled table."""
    style = TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), header_bg),
        ("TEXTCOLOR", (0, 0), (-1, 0), C_WHITE),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("FONTSIZE", (0, 0), (-1, 0), font_size),
        ("FONTNAME", (0, 1), (-1, -1), "Helvetica"),
        ("FONTSIZE", (0, 1), (-1, -1), font_size - 1),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [C_WHITE, row_bg_alt]),
        ("GRID", (0, 0), (-1, -1), 0.5, C_GREY),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("LEFTPADDING", (0, 0), (-1, -1), 5),
        ("RIGHTPADDING", (0, 0), (-1, -1), 5),
        ("TOPPADDING", (0, 0), (-1, -1), 4),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
        ("WORDWRAP", (0, 0), (-1, -1), True),
    ])
    t = Table(data, colWidths=col_widths)
    t.setStyle(style)
    return t


def flowchart_box(canvas_obj, x, y, w, h, title, lines,
                  bg=C_BLUE_LIGHT, border=C_BLUE_MED, title_bg=C_BLUE_MED,
                  title_fg=C_WHITE, font_size=8, title_size=9):
    """Draw a styled flowchart box directly on canvas."""
    canvas_obj.setFillColor(bg)
    canvas_obj.setStrokeColor(border)
    canvas_obj.setLineWidth(1.2)
    canvas_obj.roundRect(x, y, w, h, 5, fill=1, stroke=1)
    # Title bar
    canvas_obj.setFillColor(title_bg)
    canvas_obj.roundRect(x, y + h - 18, w, 18, 4, fill=1, stroke=0)
    canvas_obj.setFillColor(title_fg)
    canvas_obj.setFont("Helvetica-Bold", title_size)
    canvas_obj.drawCentredString(x + w / 2, y + h - 13, title)
    # Content lines
    canvas_obj.setFillColor(C_BLACK)
    canvas_obj.setFont("Helvetica", font_size)
    line_h = font_size + 3
    cy = y + h - 24
    for line in lines:
        if cy < y + 4:
            break
        canvas_obj.drawString(x + 7, cy, line)
        cy -= line_h


def draw_arrow(canvas_obj, x1, y1, x2, y2, color=C_BLUE_MED):
    """Draw an arrow from (x1,y1) to (x2,y2)."""
    canvas_obj.setStrokeColor(color)
    canvas_obj.setFillColor(color)
    canvas_obj.setLineWidth(1.5)
    canvas_obj.line(x1, y1, x2, y2)
    # arrowhead
    canvas_obj.setFillColor(color)
    p = canvas_obj.beginPath()
    p.moveTo(x2, y2)
    p.lineTo(x2 - 5, y2 + 8)
    p.lineTo(x2 + 5, y2 + 8)
    p.close()
    canvas_obj.drawPath(p, fill=1, stroke=0)


def draw_diamond(canvas_obj, cx, cy, w, h, text, bg=C_YELLOW_LIGHT, border=C_ORANGE, font_size=8):
    """Draw a diamond decision shape."""
    pts = [cx, cy + h/2, cx + w/2, cy, cx, cy - h/2, cx - w/2, cy]
    canvas_obj.setFillColor(bg)
    canvas_obj.setStrokeColor(border)
    canvas_obj.setLineWidth(1.5)
    p = canvas_obj.beginPath()
    p.moveTo(pts[0], pts[1])
    for i in range(2, len(pts), 2):
        p.lineTo(pts[i], pts[i+1])
    p.close()
    canvas_obj.drawPath(p, fill=1, stroke=1)
    canvas_obj.setFillColor(C_BLACK)
    canvas_obj.setFont("Helvetica-Bold", font_size)
    canvas_obj.drawCentredString(cx, cy - 3, text)


# ============================================================
# PAGE 1 – FLOWCHART (drawn with canvas)
# ============================================================
class FlowChartPage:
    """Custom canvas-based page 1 flowchart."""

    def draw(self, canvas_obj):
        cw = W
        ch = H

        # --- Title already handled by header/footer ---

        # ---- START box ----
        start_x = cw/2 - 80; start_y = ch - 80*mm
        start_w = 160; start_h = 22
        canvas_obj.setFillColor(C_BLUE_DARK)
        canvas_obj.roundRect(start_x, start_y, start_w, start_h, 8, fill=1, stroke=0)
        canvas_obj.setFillColor(C_WHITE)
        canvas_obj.setFont("Helvetica-Bold", 9)
        canvas_obj.drawCentredString(cw/2, start_y + 7, "PATIENT PRESENTS WITH FEVER  +  TRAVEL / RESIDENCE IN ENDEMIC AREA")

        # Arrow down
        draw_arrow(canvas_obj, cw/2, start_y, cw/2, start_y - 10)

        # ---- SYMPTOMS box ----
        sym_y = start_y - 10 - 90
        sym_x = cw/2 - 120; sym_w = 240; sym_h = 90
        flowchart_box(canvas_obj, sym_x, sym_y, sym_w, sym_h,
                      "SYMPTOMS",
                      ["• Fever (irregular early → periodic every 2-3 days)",
                       "• Chills and rigors  |  • Profuse sweating",
                       "• Headache  |  • Myalgia / arthralgia",
                       "• Nausea, vomiting, diarrhea",
                       "• Fatigue / malaise  |  • Splenomegaly",
                       "Classic triad: Fever + Splenomegaly + Thrombocytopenia"],
                      bg=C_ORANGE_LIGHT, border=C_ORANGE, title_bg=C_ORANGE,
                      title_fg=C_WHITE, font_size=7.5)

        draw_arrow(canvas_obj, cw/2, sym_y, cw/2, sym_y - 10)

        # ---- ASSESSMENT diamond ----
        assess_cy = sym_y - 10 - 28
        draw_diamond(canvas_obj, cw/2, assess_cy, 220, 52,
                     "Severe malaria signs?", bg=C_YELLOW_LIGHT, border=C_ORANGE, font_size=8.5)

        # YES / NO labels
        canvas_obj.setFont("Helvetica-Bold", 8)
        canvas_obj.setFillColor(C_RED)
        canvas_obj.drawString(cw/2 - 105 - 22, assess_cy - 3, "YES")
        canvas_obj.setFillColor(C_GREEN)
        canvas_obj.drawString(cw/2 + 105 + 5, assess_cy - 3, "NO")

        # ---- SEVERE branch (left) ----
        sev_x = 15*mm; sev_w = 130; sev_h = 105
        sev_y = assess_cy - 28 - sev_h
        # Arrow from diamond left
        draw_arrow(canvas_obj, cw/2 - 110, assess_cy, sev_x + sev_w/2, sev_y + sev_h + 10)
        draw_arrow(canvas_obj, sev_x + sev_w/2, sev_y + sev_h + 10, sev_x + sev_w/2, sev_y + sev_h)
        flowchart_box(canvas_obj, sev_x, sev_y, sev_w, sev_h,
                      "SEVERE MALARIA",
                      ["• Altered consciousness",
                       "• Cerebral malaria / seizures",
                       "• Respiratory distress / ARDS",
                       "• Severe anemia (Hb <7 g/dL)",
                       "• Acute renal failure",
                       "• Circulatory shock",
                       "• Haemoglobinuria",
                       "• Hyperparasitaemia (>5% RBCs)",
                       "• Spontaneous bleeding",
                       "• Repeated vomiting"],
                      bg=C_RED_LIGHT, border=C_RED, title_bg=C_RED,
                      title_fg=C_WHITE, font_size=7.5)

        # ---- UNCOMPLICATED branch (right) ----
        unc_x = W - 15*mm - 130; unc_w = 130; unc_h = 105
        unc_y = sev_y
        # Arrow from diamond right
        draw_arrow(canvas_obj, cw/2 + 110, assess_cy, unc_x + unc_w/2, unc_y + unc_h + 10)
        draw_arrow(canvas_obj, unc_x + unc_w/2, unc_y + unc_h + 10, unc_x + unc_w/2, unc_y + unc_h)
        flowchart_box(canvas_obj, unc_x, unc_y, unc_w, unc_h,
                      "UNCOMPLICATED MALARIA",
                      ["• Fever + parasitaemia confirmed",
                       "• No organ dysfunction",
                       "• Able to tolerate oral meds",
                       "• Outpatient management",
                       "",
                       "Species: P. falciparum,",
                       "P. vivax, P. ovale,",
                       "P. malariae, P. knowlesi"],
                      bg=C_GREEN_LIGHT, border=C_GREEN, title_bg=C_GREEN,
                      title_fg=C_WHITE, font_size=7.5)

        # ---- DIAGNOSIS box (centre, below both branches) ----
        diag_y = sev_y - 15 - 95
        diag_x = cw/2 - 130; diag_w = 260; diag_h = 95
        # Arrows from both branches down to diagnosis
        draw_arrow(canvas_obj, sev_x + sev_w/2, sev_y, sev_x + sev_w/2, diag_y + diag_h + 8)
        draw_arrow(canvas_obj, sev_x + sev_w/2, diag_y + diag_h + 8, cw/2, diag_y + diag_h + 8)
        draw_arrow(canvas_obj, unc_x + unc_w/2, unc_y, unc_x + unc_w/2, diag_y + diag_h + 8)
        draw_arrow(canvas_obj, unc_x + unc_w/2, diag_y + diag_h + 8, cw/2, diag_y + diag_h + 8)
        draw_arrow(canvas_obj, cw/2, diag_y + diag_h + 8, cw/2, diag_y + diag_h)
        flowchart_box(canvas_obj, diag_x, diag_y, diag_w, diag_h,
                      "DIAGNOSIS",
                      ["• Thick & thin blood smear  [GOLD STANDARD] – species ID + parasite density",
                       "• Rapid Diagnostic Test (RDT) – antigen detection (HRP2, pLDH)",
                       "• PCR – species confirmation, low parasitaemia, mixed infections",
                       "• CBC: thrombocytopenia, anaemia, leukopenia",
                       "• LFTs, renal function, blood glucose, lactate",
                       "• Repeat smears if initial negative + high suspicion"],
                      bg=C_BLUE_LIGHT, border=C_BLUE_MED, title_bg=C_BLUE_MED,
                      title_fg=C_WHITE, font_size=7.5)

        draw_arrow(canvas_obj, cw/2, diag_y, cw/2, diag_y - 10)

        # ---- TREATMENT split ----
        treat_y = diag_y - 10 - 110
        # Severe treatment (left)
        st_x = 15*mm; st_w = 145; st_h = 110
        draw_arrow(canvas_obj, cw/2, diag_y - 10, cw/2 - st_w/2 - 15, diag_y - 10)
        draw_arrow(canvas_obj, st_x + st_w/2, diag_y - 10, st_x + st_w/2, treat_y + st_h)
        flowchart_box(canvas_obj, st_x, treat_y, st_w, st_h,
                      "SEVERE MALARIA TREATMENT",
                      ["HOSPITALISE – IV Treatment",
                       "• IV Artesunate (1st line, WHO preferred)",
                       "  2.4 mg/kg at 0, 12, 24h then daily",
                       "• Alt: IV Quinine + Doxycycline/Clindamycin",
                       "• Supportive: IV fluids, antipyretics",
                       "• Blood glucose monitoring (hypoglycaemia risk)",
                       "• Transfusion if Hb <7 g/dL",
                       "• Manage seizures, respiratory support",
                       "• ICU if cerebral malaria"],
                      bg=C_RED_LIGHT, border=C_RED, title_bg=C_RED,
                      title_fg=C_WHITE, font_size=7.2)
        canvas_obj.setFont("Helvetica-Bold", 8); canvas_obj.setFillColor(C_RED)
        canvas_obj.drawCentredString(st_x + st_w/2, treat_y - 8, "HOSPITALISE")

        # Uncomplicated treatment (right)
        ut_x = W - 15*mm - 150; ut_w = 150; ut_h = 110
        draw_arrow(canvas_obj, cw/2, diag_y - 10, cw/2 + ut_w/2 + 15, diag_y - 10)
        draw_arrow(canvas_obj, ut_x + ut_w/2, diag_y - 10, ut_x + ut_w/2, treat_y + ut_h)
        flowchart_box(canvas_obj, ut_x, treat_y, ut_w, ut_h,
                      "UNCOMPLICATED TREATMENT",
                      ["Oral Treatment – Outpatient",
                       "P. falciparum / mixed (ACT):",
                       "• Artemether-lumefantrine (1st line)",
                       "• Artesunate-amodiaquine",
                       "• Artesunate-mefloquine",
                       "P. vivax / P. ovale (chloroquine-sensitive):",
                       "• Chloroquine 3-day course",
                       "+ Primaquine (after G6PD test) for radical cure",
                       "Antipyretic: Paracetamol"],
                      bg=C_GREEN_LIGHT, border=C_GREEN, title_bg=C_GREEN,
                      title_fg=C_WHITE, font_size=7.2)
        canvas_obj.setFont("Helvetica-Bold", 8); canvas_obj.setFillColor(C_GREEN)
        canvas_obj.drawCentredString(ut_x + ut_w/2, treat_y - 8, "OUTPATIENT")

        # ---- FOLLOW-UP box ----
        fu_y = treat_y - 18 - 60
        fu_x = cw/2 - 130; fu_w = 260; fu_h = 60
        draw_arrow(canvas_obj, st_x + st_w/2, treat_y, st_x + st_w/2, fu_y + fu_h + 10)
        draw_arrow(canvas_obj, st_x + st_w/2, fu_y + fu_h + 10, cw/2, fu_y + fu_h + 10)
        draw_arrow(canvas_obj, ut_x + ut_w/2, treat_y, ut_x + ut_w/2, fu_y + fu_h + 10)
        draw_arrow(canvas_obj, ut_x + ut_w/2, fu_y + fu_h + 10, cw/2, fu_y + fu_h + 10)
        draw_arrow(canvas_obj, cw/2, fu_y + fu_h + 10, cw/2, fu_y + fu_h)
        flowchart_box(canvas_obj, fu_x, fu_y, fu_w, fu_h,
                      "FOLLOW-UP & MONITORING",
                      ["• Repeat blood smears at 48-72h, Day 7, 14, 28",
                       "• Monitor for treatment failure / drug resistance",
                       "• Primaquine for P. vivax/P. ovale radical cure (check G6PD first)",
                       "• Prevention: insecticide-treated nets, repellents, chemoprophylaxis"],
                      bg=C_PURPLE_LIGHT, border=C_PURPLE, title_bg=C_PURPLE,
                      title_fg=C_WHITE, font_size=7.5)


# ============================================================
# PAGE 2 – DETAILED REFERENCE TABLES
# ============================================================

def build_reference_content():
    styles = getSampleStyleSheet()
    story = []

    TOP = 32*mm   # reserve top for header
    story.append(Spacer(1, TOP))

    # ---- Section 1: Species Overview ----
    story.append(build_section_title("1.  MALARIA SPECIES COMPARISON", bg_color=C_BLUE_DARK))
    story.append(Spacer(1, 3))

    species_data = [
        ["Feature", "P. falciparum", "P. vivax", "P. ovale", "P. malariae", "P. knowlesi"],
        ["Distribution", "Sub-Saharan Africa\nS/SE Asia, Americas", "Widespread\n(temperate/tropical)", "West Africa\nPacific", "Worldwide\n(low endemic)", "SE Asia\n(Borneo)"],
        ["Fever cycle", "Irregular / quotidian", "Tertian (48h)", "Tertian (48h)", "Quartan (72h)", "Quotidian (24h)"],
        ["Severe disease", "YES – high risk", "Rare", "Rare", "Nephrotic syndrome", "YES – rapid course"],
        ["Relapse", "No", "YES (hypnozoites)", "YES (hypnozoites)", "Recrudesence", "No"],
        ["Radical cure", "Not needed", "Primaquine required", "Primaquine required", "Not needed", "Not needed"],
        ["Chloroquine Rx", "Usually resistant", "Sensitive*", "Sensitive", "Sensitive", "Sensitive"],
    ]
    t1 = colored_table(species_data,
                       col_widths=[3.2*cm, 3.2*cm, 3.2*cm, 2.8*cm, 3*cm, 3*cm],
                       header_bg=C_BLUE_DARK, row_bg_alt=C_BLUE_LIGHT, font_size=7)
    story.append(t1)
    story.append(build_body("* P. vivax chloroquine resistance emerging in parts of PNG, Indonesia, and South America.", size=7, color=HexColor("#666666")))
    story.append(Spacer(1, 6))

    # ---- Section 2: Severe Malaria Criteria ----
    story.append(build_section_title("2.  WHO CRITERIA FOR SEVERE MALARIA (Any one criterion = Severe)", bg_color=C_RED))
    story.append(Spacer(1, 3))

    severe_data = [
        ["Clinical Criteria", "Laboratory Criteria"],
        ["Impaired consciousness / coma (cerebral malaria)", "Hyperparasitaemia: >5% parasitised RBCs"],
        ["Respiratory distress (deep breathing / ARDS)", "Severe anaemia: Hb <7 g/dL (child) or <8 g/dL (adult)"],
        ["Multiple convulsions (≥2 in 24h)", "Hypoglycaemia: blood glucose <2.2 mmol/L"],
        ["Circulatory collapse / shock (SBP <70 mmHg adult)", "Acute renal failure: creatinine >265 µmol/L"],
        ["Pulmonary oedema / ARDS", "Metabolic acidosis: bicarbonate <15 mmol/L"],
        ["Abnormal bleeding / DIC", "Elevated lactate: >5 mmol/L"],
        ["Jaundice (bilirubin >50 µmol/L + >2 other criteria)", "Haemoglobinuria (blackwater fever)"],
        ["Hyperparasitaemia with deterioration", ""],
    ]
    t2 = colored_table(severe_data, col_widths=[9*cm, 9*cm],
                       header_bg=C_RED, row_bg_alt=C_RED_LIGHT, font_size=7.5)
    story.append(t2)
    story.append(Spacer(1, 6))

    # ---- Section 3: Treatment Protocols ----
    story.append(build_section_title("3.  TREATMENT PROTOCOLS (WHO Guidelines 2024)", bg_color=C_BLUE_MED))
    story.append(Spacer(1, 3))

    # Severe treatment
    story.append(build_body("SEVERE MALARIA – IV Treatment (Hospitalise)", bold=True, color=C_RED, size=9))
    severe_tx_data = [
        ["Drug", "Dose", "Route", "Notes"],
        ["IV Artesunate\n(1st line – WHO preferred)", "2.4 mg/kg at 0h, 12h, 24h;\nthen once daily", "IV (or IM)", "Switch to oral ACT once patient can tolerate;\ncomplete 3-day ACT course after IV artesunate"],
        ["IV Quinine\n(if artesunate unavailable)", "20 mg/kg loading, then\n10 mg/kg every 8h", "IV infusion", "Add doxycycline 100mg BD or clindamycin\n(pregnant/children); monitor for hypoglycaemia"],
        ["Artemether IM\n(if IV access not possible)", "3.2 mg/kg stat, then\n1.6 mg/kg daily", "IM", "Use until IV access available;\nswitch to oral when possible"],
    ]
    t3a = colored_table(severe_tx_data, col_widths=[4.5*cm, 5*cm, 2.5*cm, 6.5*cm],
                        header_bg=C_RED, row_bg_alt=C_RED_LIGHT, font_size=7)
    story.append(t3a)
    story.append(Spacer(1, 5))

    # Uncomplicated treatment
    story.append(build_body("UNCOMPLICATED MALARIA – Oral ACT Treatment", bold=True, color=C_GREEN, size=9))
    unc_tx_data = [
        ["Regimen", "Dose (Adult)", "Duration", "Notes"],
        ["Artemether-lumefantrine\n(AL) – 1st line P. falciparum", "4 tabs at 0h, 8h;\nthen BD for 2 days\n(6 doses total)", "3 days", "Take with food (fat increases bioavailability);\navoid in 1st trimester of pregnancy"],
        ["Artesunate-amodiaquine\n(ASAQ)", "As per weight-based\nfixed-dose combination", "3 days", "Monitor for amodiaquine toxicity;\nalternative to AL"],
        ["Artesunate-mefloquine\n(AS-MQ)", "Artesunate 4 mg/kg/day\n+ mefloquine 25 mg/kg split", "3 days", "SE Asia preference;\navoid in psychiatric history"],
        ["Dihydroartemisinin-\npiperaquine (DHP)", "3 tablets (40/320mg)\nonce daily", "3 days", "Preferred in some SE Asia regions;\nonce daily improves adherence"],
        ["Chloroquine\n(P. vivax / P. ovale)", "620mg base stat, 310mg\nat 6h, 12h, 24h", "3 days", "Only where chloroquine-sensitive;\ncombine with primaquine for radical cure"],
        ["Primaquine\n(radical cure – hypnozoites)", "0.25 mg/kg/day (P. vivax)\n0.5 mg/kg/day (P. ovale)", "14 days", "TEST G6PD FIRST – haemolysis risk;\ncontraindicated in pregnancy"],
    ]
    t3b = colored_table(unc_tx_data, col_widths=[4.5*cm, 4.5*cm, 2*cm, 7.5*cm],
                        header_bg=C_GREEN, row_bg_alt=C_GREEN_LIGHT, font_size=7)
    story.append(t3b)
    story.append(Spacer(1, 6))

    # ---- Section 4: Special Populations ----
    story.append(build_section_title("4.  TREATMENT IN SPECIAL POPULATIONS", bg_color=C_PURPLE))
    story.append(Spacer(1, 3))
    sp_data = [
        ["Population", "First-Line Treatment", "Key Cautions"],
        ["Pregnant – 1st trimester", "Quinine + clindamycin × 7 days", "ACTs avoided in 1st trimester (limited data); artesunate if life-threatening severe malaria"],
        ["Pregnant – 2nd/3rd trimester", "AL or ASAQ (uncomplicated);\nIV artesunate (severe)", "Primaquine CONTRAINDICATED in pregnancy; increased risk of hypoglycaemia"],
        ["Children <5 years", "Weight-based ACT dosing;\nIV artesunate for severe", "Higher mortality risk; monitor glucose; rectal artesunate if referral delayed"],
        ["G6PD deficiency", "ACT for P. falciparum;\nWeekly primaquine 0.75 mg/kg × 8 wks\n(P. vivax radical cure)", "Daily primaquine CONTRAINDICATED;\nTest G6PD before any primaquine use"],
        ["HIV / immunocompromised", "Standard ACT;\nIV artesunate (severe)", "Drug interactions: artemether-lumefantrine + efavirenz/lopinavir;\nMonitor closely"],
        ["Returning traveller", "As per species + resistance\npattern of country visited", "Assume P. falciparum until excluded;\nseek infectious disease specialist input"],
    ]
    t4 = colored_table(sp_data, col_widths=[4*cm, 6*cm, 8.5*cm],
                       header_bg=C_PURPLE, row_bg_alt=C_PURPLE_LIGHT, font_size=7)
    story.append(t4)
    story.append(Spacer(1, 6))

    # ---- Section 5: Monitoring ----
    story.append(build_section_title("5.  MONITORING & TREATMENT RESPONSE", bg_color=C_BLUE_DARK))
    story.append(Spacer(1, 3))

    mon_data = [
        ["Timepoint", "Action", "Treatment Failure Criteria"],
        ["48–72h", "Repeat thick blood smear;\ncheck parasite density", "Parasite count not falling or clinical deterioration"],
        ["Day 3", "Clinical review;\nparasite count <25% baseline = adequate", "Parasite count >25% baseline on Day 3 suggests resistance"],
        ["Day 7", "Blood smear + clinical review", "Persistent parasitaemia = likely treatment failure"],
        ["Day 14", "Blood smear;\nsymptom check", "Reappearance of parasitaemia = recrudescence or re-infection"],
        ["Day 28", "Final smear + clinical review", "WHO standard endpoint for treatment efficacy assessment"],
    ]
    t5 = colored_table(mon_data, col_widths=[3*cm, 7*cm, 8.5*cm],
                       header_bg=C_BLUE_DARK, row_bg_alt=C_BLUE_LIGHT, font_size=7)
    story.append(t5)
    story.append(Spacer(1, 6))

    # ---- Section 6: Prevention ----
    story.append(build_section_title("6.  PREVENTION & CHEMOPROPHYLAXIS", bg_color=C_ORANGE))
    story.append(Spacer(1, 3))
    prev_data = [
        ["Agent", "Dosing", "Indication / Region", "Notes"],
        ["Atovaquone-proguanil\n(Malarone)", "1 adult tab daily;\nstart 1–2 days before,\ncontinue 7 days after", "All regions incl. resistant\nP. falciparum areas", "Well tolerated; no G6PD issue;\nhigh cost"],
        ["Doxycycline", "100 mg daily;\nstart 1–2 days before,\ncontinue 4 weeks after", "SE Asia (mefloquine\nresistance), sub-Saharan Africa", "Photosensitivity; GI side effects;\ncontraindicated in pregnancy + <8 yrs"],
        ["Mefloquine (Lariam)", "250 mg weekly;\nstart 3 weeks before,\ncontinue 4 weeks after", "Most endemic areas\n(check local resistance)", "Neuropsychiatric side effects;\ncontraindicated in seizure disorders"],
        ["Chloroquine", "500 mg (base 300mg)\nweekly", "Areas with only\nchloroquine-sensitive malaria", "Limited use due to widespread resistance"],
        ["Primaquine", "30 mg base daily\n(start day before travel)", "G6PD-normal individuals;\nVivax-endemic areas", "Test G6PD; terminal prophylaxis for\nP. vivax/ovale exposure"],
    ]
    t6 = colored_table(prev_data, col_widths=[3.8*cm, 4*cm, 5.2*cm, 5.5*cm],
                       header_bg=C_ORANGE, row_bg_alt=C_ORANGE_LIGHT, font_size=7)
    story.append(t6)
    story.append(Spacer(1, 5))

    # Personal protection reminder
    prot_data = [["Personal Protection Measures"],
                 ["• Insecticide-treated bed nets (ITNs) / Long-Lasting Insecticidal Nets (LLINs)"],
                 ["• DEET-based repellents (20-50% DEET) applied to exposed skin"],
                 ["• Permethrin-treated clothing"],
                 ["• Indoor Residual Spraying (IRS) in endemic households"],
                 ["• Wear long sleeves/trousers from dusk to dawn (peak Anopheles biting time)"],
                 ["• RTS,S/AS01 (Mosquirix) vaccine – recommended for children in sub-Saharan Africa"]]
    t_prot = Table(prot_data, colWidths=[18.5*cm])
    t_prot.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), C_ORANGE),
        ("TEXTCOLOR", (0, 0), (-1, 0), C_WHITE),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("FONTSIZE", (0, 0), (-1, 0), 8),
        ("FONTNAME", (0, 1), (-1, -1), "Helvetica"),
        ("FONTSIZE", (0, 1), (-1, -1), 7.5),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [C_WHITE, C_ORANGE_LIGHT]),
        ("GRID", (0, 0), (-1, -1), 0.4, C_GREY),
        ("LEFTPADDING", (0, 0), (-1, -1), 8),
        ("TOPPADDING", (0, 0), (-1, -1), 3),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 3),
    ]))
    story.append(t_prot)
    story.append(Spacer(1, 8))

    # ---- Section 7: Key Drug Interactions / Cautions ----
    story.append(build_section_title("7.  KEY DRUG INTERACTIONS & CAUTIONS", bg_color=C_RED))
    story.append(Spacer(1, 3))
    int_data = [
        ["Drug", "Interaction / Caution", "Clinical Impact"],
        ["Artemether-lumefantrine", "CYP3A4 inducers (rifampicin, efavirenz)", "Reduced lumefantrine levels → treatment failure"],
        ["Artemether-lumefantrine", "QT-prolonging drugs (halofantrine, amiodarone)", "Additive QT prolongation → arrhythmia risk"],
        ["Quinine (IV)", "Mefloquine", "Increased quinine toxicity; avoid combination"],
        ["Quinine (IV)", "Digoxin", "Elevated digoxin levels; monitor closely"],
        ["Primaquine", "G6PD-deficient individuals", "Haemolytic anaemia – ALWAYS test G6PD before prescribing"],
        ["Doxycycline (prophylaxis)", "Antacids, dairy, iron supplements", "Reduced absorption – take on empty stomach"],
        ["Mefloquine", "Beta-blockers, calcium channel blockers", "Cardiac conduction disturbances"],
        ["Atovaquone-proguanil", "Rifampicin, tetracycline", "Reduced atovaquone levels → prophylaxis failure"],
    ]
    t7 = colored_table(int_data, col_widths=[4.5*cm, 7*cm, 7*cm],
                       header_bg=C_RED, row_bg_alt=C_RED_LIGHT, font_size=7)
    story.append(t7)

    story.append(Spacer(1, 10))
    # References
    story.append(HRFlowable(width="100%", thickness=0.5, color=C_GREY_LIGHT))
    story.append(Spacer(1, 3))
    ref_style = ParagraphStyle("ref", fontName="Helvetica", fontSize=6.5,
                               textColor=HexColor("#555555"), leading=9)
    story.append(Paragraph(
        "<b>References:</b> "
        "1. WHO Guidelines for Malaria, 30 November 2024 (WHO/UCN/GMP/2024.01 Rev.1). "
        "2. Tintinalli JE et al. Tintinalli's Emergency Medicine: A Comprehensive Study Guide, 9th ed. McGraw-Hill, 2020. "
        "3. Walls RM et al. Rosen's Emergency Medicine: Concepts and Clinical Practice, 9th ed. Elsevier, 2022. "
        "4. Loscalzo J et al. Harrison's Principles of Internal Medicine, 22nd ed. McGraw-Hill, 2025. "
        "5. CDC Malaria Diagnosis and Treatment Guidelines, 2024.",
        ref_style))

    return story


# ============================================================
# MAIN BUILD
# ============================================================
def build_pdf():
    doc = SimpleDocTemplate(
        OUTPUT_PATH,
        pagesize=A4,
        leftMargin=15*mm,
        rightMargin=15*mm,
        topMargin=32*mm,
        bottomMargin=15*mm,
        title="Malaria Clinical Reference Guide",
        author="Orris Medical Reference",
        subject="Malaria Symptoms, Diagnosis, and Treatment",
    )

    # --- Page 1: flowchart via canvas ---
    class FlowChartDrawing:
        def __init__(self):
            self.width = W - 30*mm
            self.height = H - 50*mm

        def drawOn(self, canvas_obj, x, y):
            fc = FlowChartPage()
            fc.draw(canvas_obj)

        def wrap(self, aw, ah):
            return self.width, self.height

    # We'll use a two-pass approach: first build reference pages, then prepend flowchart page

    # Build reference tables content
    story = build_reference_content()

    # Custom first page (flowchart) using onFirstPage / onLaterPages
    def on_first_page(canvas_obj, doc):
        header_footer(canvas_obj, doc)
        fc = FlowChartPage()
        fc.draw(canvas_obj)

    def on_later_pages(canvas_obj, doc):
        header_footer(canvas_obj, doc)

    # Insert a PageBreak at beginning so first page is blank (handled by canvas)
    final_story = [Spacer(1, H - 50*mm), PageBreak()] + story

    doc.build(final_story,
              onFirstPage=on_first_page,
              onLaterPages=on_later_pages)

    print(f"PDF created: {OUTPUT_PATH}")


if __name__ == "__main__":
    build_pdf()
Running Command

cd /home/daytona/workspace/malaria-pdf && python generate_malaria_pdf.py 2>&1

Editing File

~/malaria-pdf/generate_malaria_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/malaria-pdf/generate_malaria_pdf.py'
Editing File

~/malaria-pdf/generate_malaria_pdf.py

Error: String not found in file: 'from reportlab.platypus import Image as RLImage
from reportlab.platypus import ('
Running Command

cd /home/daytona/workspace/malaria-pdf && python generate_malaria_pdf.py 2>&1

Editing File

~/malaria-pdf/generate_malaria_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/malaria-pdf/generate_malaria_pdf.py'
Running Command

cd /home/daytona/workspace/malaria-pdf && python generate_malaria_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/malaria-pdf/Malaria_Clinical_Reference.pdf

Your clinical reference PDF is ready for download:

Malaria Clinical Reference

PDF Document · PDF


What's inside the PDF (2 pages, A4):
Page 1 - Visual Flowchart
  • Full canvas-drawn diagnostic flowchart from "Patient presents with fever" through Symptoms → Assessment Diamond (Severe vs. Uncomplicated) → Diagnosis → Treatment (IV vs. oral) → Follow-up
  • Color-coded by clinical pathway: red for severe, green for uncomplicated, blue for diagnosis, purple for follow-up
Page 2 - Detailed Reference Tables (7 sections)
SectionContent
1Species Comparison - P. falciparum, vivax, ovale, malariae, knowlesi
2WHO Severe Malaria Criteria (clinical + laboratory)
3Full Treatment Protocols with doses - IV artesunate, ACTs, chloroquine, primaquine
4Special Populations - pregnancy, children, G6PD deficiency, HIV
5Monitoring schedule - Day 3, 7, 14, 28 with treatment failure criteria
6Chemoprophylaxis - atovaquone-proguanil, doxycycline, mefloquine, primaquine
7Key Drug Interactions & Cautions
Sources cited throughout: WHO Guidelines (Nov 2024), Tintinalli's EM, Rosen's EM, Harrison's 22nd edition, CDC guidelines.

Generate a quick reference card (PDF poster) for point-of-care use

Writing File

~/malaria-pdf/generate_poc_card.py

#!/usr/bin/env python3
"""
Malaria Point-of-Care Quick Reference Card
Single A4 page – designed for wall/desk use at clinical settings
"""

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.colors import HexColor, white, black

OUTPUT = "/home/daytona/workspace/malaria-pdf/Malaria_POC_QuickRef.pdf"

W, H = A4  # 595.28 x 841.89 pts

# ── Palette ──────────────────────────────────────────────────
BG          = HexColor("#F0F4F8")
NAVY        = HexColor("#0D2B4E")
BLUE        = HexColor("#1A5EA8")
BLUE_LIGHT  = HexColor("#C8DEFA")
BLUE_PALE   = HexColor("#E8F2FF")
ORANGE      = HexColor("#D4680A")
ORANGE_LITE = HexColor("#FEF0DC")
RED         = HexColor("#B01C1C")
RED_LITE    = HexColor("#FDECEA")
GREEN       = HexColor("#1A6B38")
GREEN_LITE  = HexColor("#D4EDDA")
PURPLE      = HexColor("#5B2C8D")
PURPLE_LITE = HexColor("#EDE7F6")
GOLD        = HexColor("#E8A020")
GREY        = HexColor("#BBBBBB")
GREY_DARK   = HexColor("#555555")
WHITE       = white
BLACK       = black

# ── Helpers ──────────────────────────────────────────────────

def filled_rect(c, x, y, w, h, fill, stroke=None, radius=3):
    c.setFillColor(fill)
    if stroke:
        c.setStrokeColor(stroke)
        c.setLineWidth(0.6)
        c.roundRect(x, y, w, h, radius, fill=1, stroke=1)
    else:
        c.roundRect(x, y, w, h, radius, fill=1, stroke=0)


def section_header(c, x, y, w, h, text, bg=NAVY, fg=WHITE, fsize=8.5):
    filled_rect(c, x, y, w, h, bg, radius=3)
    c.setFillColor(fg)
    c.setFont("Helvetica-Bold", fsize)
    c.drawCentredString(x + w / 2, y + h / 2 - fsize * 0.35, text)


def txt(c, x, y, text, font="Helvetica", size=7.5, color=BLACK, align="left"):
    c.setFont(font, size)
    c.setFillColor(color)
    if align == "center":
        c.drawCentredString(x, y, text)
    elif align == "right":
        c.drawRightString(x, y, text)
    else:
        c.drawString(x, y, text)


def bullet_lines(c, x, y, lines, size=7, lead=10, color=BLACK, bullet_color=BLUE, indent=8):
    """Draw bulleted lines, return final y."""
    for line in lines:
        c.setFillColor(bullet_color)
        c.setFont("Helvetica-Bold", size + 1)
        c.drawString(x, y, "•")
        c.setFillColor(color)
        c.setFont("Helvetica", size)
        c.drawString(x + indent, y, line)
        y -= lead
    return y


def mini_table(c, x, y, rows, col_widths, row_h=11,
               header_bg=NAVY, header_fg=WHITE,
               alt_bg=None, font_size=7):
    """Draw a compact table. rows[0] = header."""
    for ri, row in enumerate(rows):
        cx = x
        bg = header_bg if ri == 0 else (alt_bg if (alt_bg and ri % 2 == 0) else WHITE)
        fg = header_fg if ri == 0 else BLACK
        fn = "Helvetica-Bold" if ri == 0 else "Helvetica"
        for ci, (cell, cw) in enumerate(zip(row, col_widths)):
            filled_rect(c, cx, y - row_h, cw, row_h, bg)
            c.setStrokeColor(GREY)
            c.setLineWidth(0.3)
            c.rect(cx, y - row_h, cw, row_h, fill=0, stroke=1)
            c.setFillColor(fg)
            c.setFont(fn, font_size)
            c.drawString(cx + 3, y - row_h + 3, str(cell))
            cx += cw
        y -= row_h
    return y


def arrow_down(c, x, y1, y2, color=BLUE):
    c.setStrokeColor(color)
    c.setFillColor(color)
    c.setLineWidth(1.2)
    c.line(x, y1, x, y2 + 5)
    p = c.beginPath()
    p.moveTo(x, y2); p.lineTo(x - 4, y2 + 7); p.lineTo(x + 4, y2 + 7)
    p.close(); c.drawPath(p, fill=1, stroke=0)


def badge(c, x, y, w, h, text, bg=RED, fg=WHITE, fsize=7):
    filled_rect(c, x, y, w, h, bg, radius=4)
    c.setFillColor(fg)
    c.setFont("Helvetica-Bold", fsize)
    c.drawCentredString(x + w / 2, y + h / 2 - fsize * 0.35, text)


# ══════════════════════════════════════════════════════════════
# MAIN DRAW
# ══════════════════════════════════════════════════════════════
def draw(c):
    M = 6 * mm   # margin
    IW = W - 2 * M  # inner width = ~183mm

    # ── Background ──
    c.setFillColor(BG)
    c.rect(0, 0, W, H, fill=1, stroke=0)

    # ── TOP HEADER BAR ──
    hdr_h = 18 * mm
    filled_rect(c, 0, H - hdr_h, W, hdr_h, NAVY, radius=0)

    # Red accent stripe
    filled_rect(c, 0, H - hdr_h - 2.5*mm, W, 2.5*mm, ORANGE, radius=0)

    # Title
    c.setFillColor(WHITE)
    c.setFont("Helvetica-Bold", 16)
    c.drawCentredString(W / 2, H - 11 * mm, "MALARIA  QUICK REFERENCE CARD")
    c.setFont("Helvetica", 8)
    c.setFillColor(GOLD)
    c.drawCentredString(W / 2, H - 16 * mm,
        "Point-of-Care  |  Symptoms · Diagnosis · Treatment  |  WHO Guidelines 2024")

    # ── LAYOUT: 3 columns ──
    top_y = H - hdr_h - 2.5*mm - 3*mm  # just below orange stripe
    col_w = (IW - 4 * mm) / 3
    c1x = M
    c2x = M + col_w + 2 * mm
    c3x = M + 2 * (col_w + 2 * mm)
    cy = top_y  # current y (top of content)

    # ━━━━━━━━━━━━━━━━━━━━━━━
    # COLUMN 1
    # ━━━━━━━━━━━━━━━━━━━━━━━
    y = cy

    # ── SUSPECT MALARIA ──
    section_header(c, c1x, y - 9, col_w, 9, "▶  SUSPECT MALARIA WHEN…", bg=NAVY)
    y -= 9
    filled_rect(c, c1x, y - 55, col_w, 55, BLUE_PALE, radius=3)
    y2 = y - 7
    items = [
        "Fever ≥38.5°C of unclear origin",
        "Travel/residence in endemic area",
        "Periodic chills + rigors + sweating",
        "Headache + myalgia + fatigue",
        "Thrombocytopenia on CBC",
        "Altered mental status + fever → cerebral malaria",
    ]
    for line in items:
        txt(c, c1x + 10, y2, "•", size=7.5, color=BLUE); txt(c, c1x + 16, y2, line, size=7)
        y2 -= 9
    y -= 55

    # ── SYMPTOMS box ──
    y -= 3
    section_header(c, c1x, y - 9, col_w, 9, "SYMPTOMS", bg=ORANGE)
    y -= 9
    sym_h = 70
    filled_rect(c, c1x, y - sym_h, col_w, sym_h, ORANGE_LITE, stroke=ORANGE, radius=3)
    y2 = y - 8
    sym_lines = [
        ("Fever", "irregular early → periodic 48-72h"),
        ("Chills/rigors", "abrupt onset"),
        ("Profuse sweating", "after fever breaks"),
        ("Headache", "frontal / diffuse"),
        ("Myalgia", "arthralgia, backache"),
        ("Nausea/vomiting", "± diarrhea"),
        ("Splenomegaly", "chronic cases"),
    ]
    for k, v in sym_lines:
        c.setFont("Helvetica-Bold", 6.8); c.setFillColor(ORANGE)
        c.drawString(c1x + 4, y2, k)
        kw = c.stringWidth(k, "Helvetica-Bold", 6.8)
        c.setFont("Helvetica", 6.8); c.setFillColor(BLACK)
        c.drawString(c1x + 4 + kw + 2, y2, f"– {v}")
        y2 -= 9.5
    y -= sym_h

    # ── CLASSIC TRIAD callout ──
    y -= 3
    filled_rect(c, c1x, y - 14, col_w, 14, GOLD, radius=4)
    c.setFillColor(NAVY); c.setFont("Helvetica-Bold", 7.5)
    c.drawCentredString(c1x + col_w / 2, y - 9.5, "CLASSIC TRIAD")
    c.setFont("Helvetica", 6.8)
    c.drawCentredString(c1x + col_w / 2, y - 3, "Fever  +  Splenomegaly  +  Thrombocytopenia")
    y -= 14

    # ── SPECIES quick-ref ──
    y -= 4
    section_header(c, c1x, y - 9, col_w, 9, "SPECIES AT A GLANCE", bg=PURPLE)
    y -= 9
    sp_rows = [
        ["Species", "Cycle", "Relapse", "Severity"],
        ["P. falciparum", "Irreg.", "No", "★★★"],
        ["P. vivax",      "48h",   "Yes", "★★"],
        ["P. ovale",      "48h",   "Yes", "★"],
        ["P. malariae",   "72h",   "No",  "★"],
        ["P. knowlesi",   "24h",   "No",  "★★★"],
    ]
    cws = [col_w * 0.38, col_w * 0.18, col_w * 0.22, col_w * 0.22]
    mini_table(c, c1x, y, sp_rows, cws, row_h=10,
               header_bg=PURPLE, alt_bg=PURPLE_LITE, font_size=6.5)
    y -= 10 * len(sp_rows)

    # ━━━━━━━━━━━━━━━━━━━━━━━
    # COLUMN 2
    # ━━━━━━━━━━━━━━━━━━━━━━━
    y = cy

    # ── DIAGNOSIS ──
    section_header(c, c2x, y - 9, col_w, 9, "DIAGNOSIS", bg=BLUE)
    y -= 9
    diag_h = 68
    filled_rect(c, c2x, y - diag_h, col_w, diag_h, BLUE_PALE, stroke=BLUE, radius=3)
    y2 = y - 8
    diag = [
        ("Thick + thin smear", "GOLD STANDARD"),
        ("  → Species ID", "+ parasite density"),
        ("Rapid Diag. Test", "(RDT) – HRP2/pLDH"),
        ("PCR", "species confirm / low parasit."),
        ("CBC", "↓platelets, ↓Hb, leukopenia"),
        ("Glucose", "hypoglycaemia (severe)"),
        ("LFTs / Cr", "organ dysfunction screen"),
    ]
    for k, v in diag:
        c.setFont("Helvetica-Bold", 6.8); c.setFillColor(BLUE)
        c.drawString(c2x + 4, y2, k)
        kw = c.stringWidth(k, "Helvetica-Bold", 6.8)
        c.setFont("Helvetica", 6.8); c.setFillColor(BLACK)
        c.drawString(c2x + 4 + kw + 2, y2, v)
        y2 -= 9.5
    y -= diag_h

    # ── SEVERITY ASSESSMENT ──
    y -= 3
    section_header(c, c2x, y - 9, col_w, 9, "SEVERE MALARIA – ANY ONE CRITERION", bg=RED)
    y -= 9
    sev_h = 90
    filled_rect(c, c2x, y - sev_h, col_w, sev_h, RED_LITE, stroke=RED, radius=3)
    y2 = y - 8
    sev = [
        "Impaired consciousness / coma",
        "Respiratory distress / ARDS",
        "Convulsions (≥2 in 24h)",
        "Circulatory shock (SBP <70 mmHg)",
        "Severe anaemia (Hb <7 g/dL)",
        "Hyperparasitaemia (>5% RBCs)",
        "Acute renal failure",
        "Hypoglycaemia (<2.2 mmol/L)",
        "Haemoglobinuria / jaundice",
    ]
    for line in sev:
        c.setFillColor(RED); c.setFont("Helvetica-Bold", 7.5)
        c.drawString(c2x + 4, y2, "!")
        c.setFillColor(BLACK); c.setFont("Helvetica", 6.8)
        c.drawString(c2x + 11, y2, line)
        y2 -= 9.5
    y -= sev_h

    # ── FOLLOW-UP ──
    y -= 3
    section_header(c, c2x, y - 9, col_w, 9, "MONITORING / FOLLOW-UP", bg=PURPLE)
    y -= 9
    fu_h = 52
    filled_rect(c, c2x, y - fu_h, col_w, fu_h, PURPLE_LITE, stroke=PURPLE, radius=3)
    y2 = y - 8
    fu = [
        "Day 1-3: repeat smear; density falling?",
        "Day 3: count <25% baseline = adequate",
        "Day 7, 14, 28: smear + clinical review",
        "Treatment failure → switch ACT / IV art.",
        "Primaquine: P. vivax/ovale radical cure",
        "  CHECK G6PD BEFORE PRESCRIBING",
    ]
    for line in fu:
        col = RED if "CHECK" in line else BLACK
        fn  = "Helvetica-Bold" if "CHECK" in line else "Helvetica"
        c.setFillColor(PURPLE if "CHECK" not in line else RED)
        c.setFont("Helvetica-Bold", 7.5)
        if "CHECK" not in line:
            c.drawString(c2x + 4, y2, "›")
        c.setFillColor(col); c.setFont(fn, 6.8)
        c.drawString(c2x + 11, y2, line)
        y2 -= 9
    y -= fu_h

    # ━━━━━━━━━━━━━━━━━━━━━━━
    # COLUMN 3
    # ━━━━━━━━━━━━━━━━━━━━━━━
    y = cy

    # ── SEVERE Tx ──
    section_header(c, c3x, y - 9, col_w, 9, "SEVERE MALARIA – TX  (HOSPITALISE)", bg=RED)
    y -= 9
    sev_tx_h = 70
    filled_rect(c, c3x, y - sev_tx_h, col_w, sev_tx_h, RED_LITE, stroke=RED, radius=3)
    y2 = y - 8

    badge(c, c3x + 4, y2 - 7, col_w - 8, 9, "1st LINE: IV ARTESUNATE", bg=RED)
    y2 -= 11
    rows_st = [
        ("IV Artesunate", "2.4 mg/kg @ 0h, 12h, 24h; then daily"),
        ("→ Switch to oral ACT", "when tolerating PO"),
        ("Alt: IV Quinine", "20 mg/kg load → 10 mg/kg q8h"),
        ("+ Doxycycline", "100 mg BD (or clindamycin in pregnancy)"),
        ("Artemether IM", "if no IV access: 3.2 mg/kg stat"),
    ]
    for k, v in rows_st:
        c.setFont("Helvetica-Bold", 6.8); c.setFillColor(RED)
        c.drawString(c3x + 4, y2, k)
        kw = c.stringWidth(k, "Helvetica-Bold", 6.8)
        c.setFont("Helvetica", 6.5); c.setFillColor(BLACK)
        c.drawString(c3x + 4 + kw + 2, y2, v)
        y2 -= 9
    y -= sev_tx_h

    # Supportive care badge
    y -= 2
    filled_rect(c, c3x, y - 28, col_w, 28, RED_LITE, stroke=RED, radius=3)
    y2 = y - 7
    supp = ["Supportive: IV fluids, paracetamol",
            "Monitor blood glucose (hypoglycaemia!)",
            "Transfuse if Hb <7 g/dL",
            "ICU: cerebral malaria / ARDS"]
    for line in supp:
        c.setFillColor(RED); c.setFont("Helvetica-Bold", 7)
        c.drawString(c3x + 4, y2, "▸")
        c.setFillColor(BLACK); c.setFont("Helvetica", 6.5)
        c.drawString(c3x + 11, y2, line)
        y2 -= 7
    y -= 28

    # ── UNCOMPLICATED Tx ──
    y -= 4
    section_header(c, c3x, y - 9, col_w, 9, "UNCOMPLICATED MALARIA – TX (ORAL)", bg=GREEN)
    y -= 9
    unc_h = 82
    filled_rect(c, c3x, y - unc_h, col_w, unc_h, GREEN_LITE, stroke=GREEN, radius=3)
    y2 = y - 7

    # P. falciparum
    c.setFillColor(GREEN); c.setFont("Helvetica-Bold", 7)
    c.drawString(c3x + 3, y2, "P. falciparum / mixed  →  ACT  (3-day course)")
    y2 -= 9
    act_lines = [
        "Artemether-lumefantrine (AL) ← TAKE WITH FOOD",
        "Artesunate-amodiaquine (ASAQ)",
        "Dihydroartemisinin-piperaquine (DHP)",
        "Artesunate-mefloquine (SE Asia)",
    ]
    for line in act_lines:
        c.setFillColor(GREY_DARK if "←" not in line else RED)
        c.setFont("Helvetica-Bold" if "←" in line else "Helvetica", 6.5)
        c.drawString(c3x + 8, y2, f"• {line}")
        y2 -= 8

    # P. vivax / ovale
    y2 -= 2
    c.setFillColor(GREEN); c.setFont("Helvetica-Bold", 7)
    c.drawString(c3x + 3, y2, "P. vivax / P. ovale  →  Chloroquine (3 days)")
    y2 -= 9
    viv_lines = [
        "Chloroquine 620mg → 310mg at 6h, 12h, 24h",
        "+ PRIMAQUINE 0.25 mg/kg/day × 14 days",
        "  ⚠ CHECK G6PD BEFORE PRIMAQUINE",
    ]
    for line in viv_lines:
        col = RED if "⚠" in line else GREY_DARK
        fn  = "Helvetica-Bold" if "⚠" in line else "Helvetica"
        c.setFillColor(col); c.setFont(fn, 6.5)
        c.drawString(c3x + 8, y2, line)
        y2 -= 8

    # Antipyretic line
    y2 -= 2
    c.setFillColor(BLUE); c.setFont("Helvetica-Bold", 6.5)
    c.drawString(c3x + 3, y2, "Antipyretic:"); c.setFont("Helvetica", 6.5); c.setFillColor(BLACK)
    c.drawString(c3x + 40, y2, "Paracetamol (avoid aspirin)")
    y -= unc_h

    # ── PROPHYLAXIS ──
    y -= 4
    section_header(c, c3x, y - 9, col_w, 9, "CHEMOPROPHYLAXIS", bg=ORANGE)
    y -= 9
    proph_rows = [
        ["Drug",           "Start",    "After"],
        ["Atovaquone-\nproguanil", "1-2d pre","7d post"],
        ["Doxycycline",   "1-2d pre", "4wk post"],
        ["Mefloquine",    "3wk pre",  "4wk post"],
        ["Chloroquine",   "1wk pre",  "4wk post"],
    ]
    cws3 = [col_w * 0.44, col_w * 0.28, col_w * 0.28]
    mini_table(c, c3x, y, proph_rows, cws3, row_h=10,
               header_bg=ORANGE, alt_bg=ORANGE_LITE, font_size=6.5)
    y -= 10 * len(proph_rows)

    # ── SPECIAL POPULATIONS strip ──
    y_sp = 32 * mm   # fixed y position above footer
    section_header(c, M, y_sp, IW, 9, "SPECIAL POPULATIONS", bg=PURPLE)
    sp_y = y_sp - 9
    sp_entries = [
        ("Pregnancy T1",   "Quinine + clindamycin × 7d; artesunate only if life-threatening"),
        ("Pregnancy T2/T3","AL or ASAQ (uncomplicated); IV artesunate (severe); NO primaquine"),
        ("Children",       "Weight-based ACT; IV artesunate severe; rectal artesunate if IV delayed"),
        ("G6PD deficiency","Weekly primaquine 0.75 mg/kg × 8 wks for radical cure; NEVER daily primaquine"),
        ("HIV (ART)",      "AL + efavirenz/lopinavir → reduced lumefantrine; monitor for treatment failure"),
    ]
    sp_col_w = IW / len(sp_entries)
    for i, (title, note) in enumerate(sp_entries):
        sx = M + i * sp_col_w
        filled_rect(c, sx, sp_y - 22, sp_col_w, 22, PURPLE_LITE if i % 2 == 0 else WHITE,
                    stroke=GREY, radius=0)
        c.setFillColor(PURPLE); c.setFont("Helvetica-Bold", 6.5)
        c.drawCentredString(sx + sp_col_w / 2, sp_y - 8, title)
        # wrap text
        words = note.split()
        lines_out = []; line_cur = ""
        for w in words:
            test = (line_cur + " " + w).strip()
            if c.stringWidth(test, "Helvetica", 6) < sp_col_w - 6:
                line_cur = test
            else:
                lines_out.append(line_cur); line_cur = w
        lines_out.append(line_cur)
        yy = sp_y - 15
        for ln in lines_out[:2]:
            c.setFillColor(BLACK); c.setFont("Helvetica", 6)
            c.drawCentredString(sx + sp_col_w / 2, yy, ln)
            yy -= 7

    # ── FOOTER ──
    filled_rect(c, 0, 0, W, 10 * mm, NAVY, radius=0)
    c.setFillColor(GOLD); c.setFont("Helvetica-Bold", 7)
    c.drawCentredString(W / 2, 6 * mm, "⚠  Always confirm with blood smear + RDT before treatment. "
                        "Treat suspected severe malaria IMMEDIATELY without waiting for results.")
    c.setFillColor(HexColor("#99AABB")); c.setFont("Helvetica", 6)
    c.drawCentredString(W / 2, 2.5 * mm,
        "Sources: WHO Guidelines for Malaria (Nov 2024)  |  Tintinalli's EM 9e  |  "
        "Rosen's EM 9e  |  Harrison's Principles 22e  |  CDC 2024")


def main():
    c = canvas.Canvas(OUTPUT, pagesize=A4)
    c.setTitle("Malaria Point-of-Care Quick Reference Card")
    c.setAuthor("Orris Medical Reference")
    c.setSubject("Malaria POC Quick Reference – Symptoms, Diagnosis, Treatment")
    draw(c)
    c.save()
    print(f"Saved: {OUTPUT}")


if __name__ == "__main__":
    main()
Running Command

cd /home/daytona/workspace/malaria-pdf && python generate_poc_card.py 2>&1

Running Command

ls -lh /home/daytona/workspace/malaria-pdf/Malaria_POC_QuickRef.pdf

Your POC quick reference card is ready:

Malaria POC QuickRef

PDF Document · PDF


What's on the single A4 page (3-column layout, print-ready):
Column 1 - Recognition
  • "Suspect malaria when..." checklist (6 triggers)
  • Full symptom list with descriptors
  • Classic Triad callout (gold highlight bar)
  • Species at a glance mini-table (P. falciparum through P. knowlesi - cycle, relapse risk, severity)
Column 2 - Workup & Assessment
  • Diagnosis panel: smear (gold standard), RDT, PCR, CBC, glucose, LFTs
  • Severe malaria criteria - all 9 WHO criteria with red "!" markers
  • Monitoring/follow-up schedule (Day 1-3, 7, 14, 28) with G6PD warning
Column 3 - Treatment
  • Severe malaria: IV artesunate dosing, quinine alternative, IM artemether, supportive care checklist
  • Uncomplicated malaria: ACT options for P. falciparum, chloroquine + primaquine protocol for P. vivax/ovale
  • Chemoprophylaxis table (atovaquone-proguanil, doxycycline, mefloquine, chloroquine)
Bottom band - Special populations strip (pregnancy T1/T2-T3, children, G6PD deficiency, HIV/ART)
Footer - Prominent clinical warning ("treat severe malaria immediately without waiting for results") + sources
Designed for wall or desk mounting, desk lamination, or digital display at point of care.

Dengue symptoms, diagnosis, treatment flow chart diagram

Finding Sources
Searching the Web

dengue fever symptoms diagnosis treatment WHO classification 2024 guidelines

Reading File
Reading File
Reading File
Generating Image

A clean, professional medical flowchart diagram titled "Dengue Fever: Symptoms, Diagnosis & Treatment" with the following detailed flow structure: START BOX at top (dark teal background, white text): "Patient presents with ACUTE FEVER (2-7 days) + Travel/Residence in dengue-endemic area" Arrow down to SYMPTOMS BOX (light amber/yellow background, amber border): Title: "SYMPTOMS – Febrile Phase (Days 1-3)" • Sudden high fever (39-40°C) • Severe headache + retro-orbital pain • Myalgia / arthralgia / bone pain ("breakbone fever") • Nausea and vomiting • Facial flushing / facial erythema • Maculopapular rash (trunk spreading to extremities) • Leukopenia (characteristic) • Petechiae / minor bleeding • Positive tourniquet test Arrow down to WHO CLASSIFICATION DIAMOND (decision diamond, amber border): "Apply WHO 2009 Classification" Three branches emerging: LEFT BRANCH - "Dengue WITHOUT Warning Signs" (blue-green box): Fever + ≥2 of: • Nausea/vomiting • Rash • Aches and pains • Leukopenia • Positive tourniquet test → Group A: Outpatient management CENTRE BRANCH - "Dengue WITH Warning Signs" (orange box): Any of the following (Days 3-7, Critical Phase): • Abdominal pain or tenderness • Persistent vomiting • Clinical fluid accumulation (ascites, pleural effusion) • Mucosal bleeding • Lethargy / restlessness • Liver enlargement >2 cm • ↑ Hematocrit + rapid ↓ platelet count → Group B: Hospitalise RIGHT BRANCH - "SEVERE Dengue" (red box): Any ONE of: • Severe plasma leakage → shock (DSS) • Fluid accumulation + respiratory distress • Severe bleeding (clinician assessed) • Severe organ involvement: - Liver: AST/ALT ≥1000 IU/L - CNS: impaired consciousness - Heart failure / other organ failure → Group C: Emergency/ICU Arrow down from all branches to DIAGNOSIS BOX (blue background): Title: "DIAGNOSIS" Time-based testing: • Days 1-5 (Febrile Phase): RT-PCR (dengue RNA) OR NS1 antigen test • Days 5-10 (Late febrile/Critical): IgM antibody (EIA) – detectable from Day 3-5 • Combined NS1 + IgM on single specimen: identifies ≥90% of cases • CBC: thrombocytopenia (platelets <100,000) + ↑ hematocrit (hemoconcentration) • Note: IgG may cross-react with Zika, West Nile, Yellow Fever, JE Arrow down to TREATMENT section splitting into THREE columns: LEFT COLUMN - Group A: Dengue WITHOUT Warning Signs (teal/green header): "OUTPATIENT MANAGEMENT" • Adequate oral hydration (ORS, fluids, coconut water) • Paracetamol for fever (max 4g/day adult) • AVOID: NSAIDs, aspirin, ibuprofen (bleeding risk) • Monitor daily: platelet count + hematocrit from Day 3 • Return immediately if warning signs develop • Rest and mosquito bite prevention (prevent spread) CENTRE COLUMN - Group B: Dengue WITH Warning Signs (orange header): "HOSPITALISE – IV Fluid Therapy" • IV crystalloid (0.9% NaCl or Ringer's lactate) • Fluid bolus 5-10 mL/kg over 1 hour if compensated shock • Monitor vital signs every 1-4 hours • CBC every 4-6 hours • Maintain urine output 0.5-1 mL/kg/hr • Observe during critical phase (24-48 hours) • Platelet transfusion only if <20,000 + active bleeding • Transition to oral fluids when improving RIGHT COLUMN - Group C: SEVERE Dengue (red header): "ICU / EMERGENCY MANAGEMENT" • Aggressive IV fluid resuscitation (10-20 mL/kg bolus) • Blood products: packed RBCs if Hb <7 g/dL • Platelet transfusion: <10,000 or active bleed • Fresh frozen plasma (FFP) for coagulopathy • Vasopressors if fluid-refractory shock • Mechanical ventilation if respiratory failure • Treat underlying organ dysfunction • Avoid excessive fluids (pulmonary oedema risk) Arrow down to MONITORING & DISCHARGE BOX (purple background): Title: "MONITORING PARAMETERS & DISCHARGE CRITERIA" • Platelet count + hematocrit monitoring: daily from Day 3 • Defervescence (Day 3-7): CRITICAL PHASE – increased risk of complications • Discharge criteria: afebrile ≥24h, improving appetite, stable hematocrit, platelets >50,000, no respiratory distress • Convalescent phase: bradypulse rash, fatigue may persist 2-4 weeks Bottom note box (light yellow): "NO specific antiviral therapy exists for dengue. Management is entirely supportive." Color scheme: teal/dark green header, amber/orange for warning signs, red for severe, blue for diagnosis, purple for monitoring. Clean white background, medical professional style with clear directional arrows.

Dengue Fever: Symptoms, Diagnosis & Treatment Flowchart
Here is the complete Dengue Fever: Symptoms, Diagnosis & Treatment flowchart based on WHO 2009 classification, Red Book 2021, Harrison's Principles 22e, and PAHO guidelines. Key points:

Symptoms (Febrile Phase Days 1-3)
  • Sudden high fever (39-40°C), severe headache, retro-orbital pain
  • "Breakbone fever" - myalgia/arthralgia/bone pain
  • Maculopapular rash, facial flushing, leukopenia, petechiae
  • Positive tourniquet test is a useful bedside marker
WHO 2009 Three-Tier Classification
GroupClassificationManagement
ADengue WITHOUT warning signsOutpatient, oral hydration
BDengue WITH warning signsHospitalise, IV fluids
CSevere dengue (shock/bleeding/organ failure)ICU, emergency Tx
Diagnosis - Time-sensitive testing
  • Days 1-5: NS1 antigen or RT-PCR (virus detectable)
  • Days 3-10: IgM antibody (EIA) - detectable from Day 3-5
  • NS1 + IgM combined on one specimen identifies ≥90% of cases
  • CBC: thrombocytopenia + rising hematocrit = hallmark of plasma leakage
Treatment - Supportive only (no antiviral exists)
  • AVOID aspirin, NSAIDs, ibuprofen - bleeding risk
  • Paracetamol only for fever control
  • IV crystalloids for Groups B and C; aggressive resuscitation for shock
Critical Phase: Days 3-7 (around defervescence)
  • Highest risk of plasma leakage, shock (DSS), and haemorrhage
  • Monitor platelet count + hematocrit every 4-6 hours
Sources: Red Book 2021 (AAP); Harrison's Principles of Internal Medicine 22E; WHO Dengue Guidelines; PAHO Clinical Management Algorithms 2024

Poc and refrence card pdf

Writing File

~/dengue-pdf/generate_dengue_reference.py

#!/usr/bin/env python3
"""
Dengue Fever – Detailed Clinical Reference PDF (2 pages)
Page 1: Canvas flowchart  |  Page 2: Reference tables
"""

from reportlab.pdfgen import canvas as rl_canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.colors import HexColor, white, black
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT

OUTPUT = "/home/daytona/workspace/dengue-pdf/Dengue_Clinical_Reference.pdf"
W, H = A4

# ── Palette ──────────────────────────────────────────────────
TEAL        = HexColor("#0D6B6E")
TEAL_LIGHT  = HexColor("#D0ECEC")
TEAL_PALE   = HexColor("#E8F7F7")
AMBER       = HexColor("#C96A00")
AMBER_LIGHT = HexColor("#FEF0DC")
AMBER_PALE  = HexColor("#FFFBF5")
ORANGE      = HexColor("#D45A00")
ORANGE_LITE = HexColor("#FDECEA")
RED         = HexColor("#B01C1C")
RED_LITE    = HexColor("#FDECEA")
BLUE        = HexColor("#1A5EA8")
BLUE_LIGHT  = HexColor("#D6E8FA")
BLUE_PALE   = HexColor("#EEF6FF")
PURPLE      = HexColor("#5B2C8D")
PURPLE_LITE = HexColor("#EDE7F6")
NAVY        = HexColor("#0D2B4E")
GOLD        = HexColor("#E8A020")
GREY        = HexColor("#BBBBBB")
GREY_DARK   = HexColor("#555555")
GREY_LIGHT  = HexColor("#F5F5F5")
WHITE       = white
BLACK       = black

# ── Canvas helpers ────────────────────────────────────────────

def rr(c, x, y, w, h, fill, stroke=None, lw=0.7, r=4):
    c.setFillColor(fill)
    if stroke:
        c.setStrokeColor(stroke); c.setLineWidth(lw)
        c.roundRect(x, y, w, h, r, fill=1, stroke=1)
    else:
        c.roundRect(x, y, w, h, r, fill=1, stroke=0)

def box_title(c, x, y, w, h, title, bg=NAVY, fg=WHITE, fsize=9):
    rr(c, x, y, w, h, bg, r=3)
    c.setFillColor(fg); c.setFont("Helvetica-Bold", fsize)
    c.drawCentredString(x + w/2, y + h/2 - fsize*0.35, title)

def arrow_v(c, x, y1, y2, col=TEAL):
    c.setStrokeColor(col); c.setFillColor(col); c.setLineWidth(1.4)
    c.line(x, y1, x, y2+5)
    p = c.beginPath()
    p.moveTo(x, y2); p.lineTo(x-4, y2+7); p.lineTo(x+4, y2+7)
    p.close(); c.drawPath(p, fill=1, stroke=0)

def arrow_h(c, x1, x2, y, col=TEAL):
    c.setStrokeColor(col); c.setFillColor(col); c.setLineWidth(1.4)
    dx = 1 if x2 > x1 else -1
    c.line(x1, y, x2 - dx*5, y)
    p = c.beginPath()
    p.moveTo(x2, y); p.lineTo(x2 - dx*7, y+4); p.lineTo(x2 - dx*7, y-4)
    p.close(); c.drawPath(p, fill=1, stroke=0)

def text_lines(c, x, y, lines, size=7.5, lead=10, font="Helvetica",
               color=BLACK, bullet_color=None, indent=0):
    for line in lines:
        if bullet_color:
            c.setFillColor(bullet_color); c.setFont("Helvetica-Bold", size+1)
            c.drawString(x, y, "•")
            c.setFillColor(color); c.setFont(font, size)
            c.drawString(x + 9, y, line)
        else:
            c.setFillColor(color); c.setFont(font, size)
            c.drawString(x + indent, y, line)
        y -= lead
    return y

def flowbox(c, x, y, w, h, title, lines, bg, border, tbg, tfg=WHITE,
            fsize=7.5, tsize=8.5, lead=9):
    rr(c, x, y, w, h, bg, stroke=border, lw=1.2, r=4)
    rr(c, x, y+h-16, w, 16, tbg, r=3)
    c.setFillColor(tfg); c.setFont("Helvetica-Bold", tsize)
    c.drawCentredString(x+w/2, y+h-11, title)
    cy = y+h-22
    for line in lines:
        if cy < y+3: break
        if line.startswith("**"):
            c.setFont("Helvetica-Bold", fsize); c.setFillColor(border)
            c.drawString(x+5, cy, line[2:])
        else:
            c.setFont("Helvetica", fsize); c.setFillColor(BLACK)
            c.drawString(x+5, cy, line)
        cy -= lead

def draw_diamond(c, cx, cy, w, h, lines, bg=AMBER_LIGHT, border=AMBER, fsize=8):
    pts = [cx, cy+h/2, cx+w/2, cy, cx, cy-h/2, cx-w/2, cy]
    c.setFillColor(bg); c.setStrokeColor(border); c.setLineWidth(1.5)
    p = c.beginPath()
    p.moveTo(pts[0], pts[1])
    for i in range(2, len(pts), 2): p.lineTo(pts[i], pts[i+1])
    p.close(); c.drawPath(p, fill=1, stroke=1)
    c.setFillColor(NAVY); c.setFont("Helvetica-Bold", fsize)
    for i, ln in enumerate(lines):
        c.drawCentredString(cx, cy + (len(lines)-1)*5 - i*10, ln)

# ── Header / Footer ───────────────────────────────────────────

def header_footer(cv, doc):
    cv.saveState()
    cv.setFillColor(TEAL)
    cv.rect(0, H-26*mm, W, 26*mm, fill=1, stroke=0)
    cv.setFillColor(AMBER)
    cv.rect(0, H-28*mm, W, 2*mm, fill=1, stroke=0)
    cv.setFillColor(WHITE); cv.setFont("Helvetica-Bold", 14)
    cv.drawString(14*mm, H-13*mm, "DENGUE FEVER  –  Clinical Reference Guide")
    cv.setFont("Helvetica", 8.5); cv.setFillColor(TEAL_LIGHT)
    cv.drawRightString(W-14*mm, H-10*mm, "Symptoms · WHO Classification · Diagnosis · Treatment")
    cv.drawRightString(W-14*mm, H-17*mm, "WHO 2009 | Red Book 2021 | Harrison's 22E | PAHO 2024")
    cv.setFillColor(GREY_LIGHT); cv.rect(0, 0, W, 11*mm, fill=1, stroke=0)
    cv.setFillColor(GREY_DARK); cv.setFont("Helvetica", 7)
    cv.drawString(14*mm, 4*mm,
        "Sources: WHO Dengue Guidelines 2009 | AAP Red Book 2021 | Harrison's Principles of Internal Medicine 22E | PAHO Algorithms 2024")
    cv.drawRightString(W-14*mm, 4*mm, f"Page {doc.page}")
    cv.restoreState()

# ══════════════════════════════════════════════════════════════
# PAGE 1  –  FLOWCHART
# ══════════════════════════════════════════════════════════════

class DengueFlowchart:
    def draw(self, cv):
        # start box
        sx = W/2-120; sy = H-78*mm; sw=240; sh=20
        rr(cv, sx, sy, sw, sh, TEAL, r=6)
        cv.setFillColor(WHITE); cv.setFont("Helvetica-Bold", 8.5)
        cv.drawCentredString(W/2, sy+6,
            "ACUTE FEVER (2-7 days)  +  Travel / Residence in Dengue-Endemic Area")

        arrow_v(cv, W/2, sy, sy-10)

        # incubation note
        cv.setFillColor(GREY_DARK); cv.setFont("Helvetica-Oblique", 6.8)
        cv.drawCentredString(W/2, sy-17, "Incubation: 3-14 days  |  Transmitted by Aedes aegypti (day-biting)")

        # SYMPTOMS box
        sym_y = sy-14-80; sym_x=W/2-120; sym_w=240; sym_h=80
        flowbox(cv, sym_x, sym_y, sym_w, sym_h,
                "SYMPTOMS  (Febrile Phase  Days 1–3)",
                ["Sudden high fever 39-40°C",
                 "Severe headache + retro-orbital pain",
                 'Myalgia / arthralgia / bone pain ("breakbone fever")',
                 "Nausea, vomiting  |  Facial flushing",
                 "Maculopapular rash (trunk → extremities)",
                 "Leukopenia (characteristic finding)",
                 "Petechiae / minor bleeding  |  Positive tourniquet test"],
                bg=AMBER_LIGHT, border=AMBER, tbg=AMBER, tsize=9)
        arrow_v(cv, W/2, sym_y, sym_y-10)

        # WHO classification diamond
        dia_cy = sym_y - 10 - 28
        draw_diamond(cv, W/2, dia_cy, 220, 52,
                     ["Apply WHO 2009 Classification", "(Days 3-7: Critical Phase)"],
                     bg=AMBER_LIGHT, border=AMBER, fsize=8)

        # Branch labels
        cv.setFont("Helvetica-Bold", 7.5)
        cv.setFillColor(BLUE); cv.drawString(14*mm, dia_cy+2, "Group A")
        cv.setFillColor(ORANGE); cv.drawCentredString(W/2, dia_cy-32, "Group B")
        cv.setFillColor(RED); cv.drawRightString(W-14*mm, dia_cy+2, "Group C")

        # Three branch boxes
        bx_h = 90
        # Group A – no warning signs (left)
        ax = 13*mm; aw = 120
        ay = dia_cy - 30 - bx_h
        arrow_h(cv, W/2-110, ax+aw, dia_cy, col=BLUE)
        arrow_v(cv, ax+aw/2, dia_cy, ay+bx_h, col=BLUE)
        flowbox(cv, ax, ay, aw, bx_h,
                "WITHOUT Warning Signs",
                ["Fever + ≥2 of:",
                 "• Nausea/vomiting",
                 "• Rash",
                 "• Aches and pains",
                 "• Leukopenia",
                 "• +ve tourniquet test",
                 "",
                 "→ OUTPATIENT (Group A)"],
                bg=TEAL_PALE, border=TEAL, tbg=TEAL, tsize=8)

        # Group B – with warning signs (centre)
        bx = W/2-65; bw = 130
        bby = dia_cy-30-bx_h
        arrow_v(cv, W/2, dia_cy-26, bby+bx_h, col=ORANGE)
        flowbox(cv, bx, bby, bw, bx_h,
                "WITH Warning Signs",
                ["• Abdominal pain/tenderness",
                 "• Persistent vomiting",
                 "• Fluid accumulation",
                 "• Mucosal bleeding",
                 "• Lethargy/restlessness",
                 "• Liver >2 cm",
                 "• ↑HCT + rapid ↓platelets",
                 "→ HOSPITALISE (Group B)"],
                bg=AMBER_LIGHT, border=ORANGE, tbg=ORANGE, tsize=8)

        # Group C – severe (right)
        cx2 = W-13*mm-120; cw2 = 120
        cy2 = dia_cy-30-bx_h
        arrow_h(cv, W/2+110, cx2, dia_cy, col=RED)
        arrow_v(cv, cx2+cw2/2, dia_cy, cy2+bx_h, col=RED)
        flowbox(cv, cx2, cy2, cw2, bx_h,
                "SEVERE Dengue",
                ["Severe plasma leakage:",
                 "• Shock (DSS)",
                 "• Resp. distress",
                 "Severe bleeding",
                 "Organ involvement:",
                 "• AST/ALT ≥1000",
                 "• Impaired consciousness",
                 "→ ICU (Group C)"],
                bg=RED_LITE, border=RED, tbg=RED, tsize=8)

        # DIAGNOSIS box
        diag_y = ay - 12 - 80; diag_x = W/2-145; diag_w = 290; diag_h = 80
        # arrows converging
        arrow_v(cv, ax+aw/2, ay, ay-6, col=BLUE)
        arrow_h(cv, ax+aw/2, W/2, ay-6, col=TEAL)
        arrow_v(cv, cx2+cw2/2, cy2, cy2-6, col=RED)
        arrow_h(cv, cx2+cw2/2, W/2, cy2-6, col=TEAL)
        arrow_v(cv, W/2, bby, bby-6, col=ORANGE)
        # horizontal merge line
        cv.setStrokeColor(TEAL); cv.setLineWidth(1.4)
        merge_y = min(ay, cy2, bby)-6
        cv.line(ax+aw/2, merge_y, cx2+cw2/2, merge_y)
        arrow_v(cv, W/2, merge_y, diag_y+diag_h)

        flowbox(cv, diag_x, diag_y, diag_w, diag_h,
                "DIAGNOSIS  (Time-Based Testing)",
                ["Days 1-5 (Febrile): RT-PCR (dengue RNA)  OR  NS1 antigen test",
                 "Days 3-10 (Late febrile/Critical): IgM antibody (EIA) – 99% by Day 10",
                 "Combined NS1 + IgM on single specimen → identifies ≥90% of cases",
                 "CBC: thrombocytopenia (plt <100,000) + rising haematocrit (haemoconcentration)",
                 "⚠ IgM cross-reacts with Zika, West Nile, Yellow Fever, Japanese Encephalitis",
                 "IgG elevated lifelong – use acute+convalescent paired sera (≥4× rise = confirmed)"],
                bg=BLUE_PALE, border=BLUE, tbg=BLUE, tsize=9)
        arrow_v(cv, W/2, diag_y, diag_y-10)

        # TREATMENT boxes – 3 columns
        tx_h = 95
        tx_y = diag_y - 12 - tx_h
        tw = (W - 30*mm) / 3 - 2*mm
        t1x = 14*mm; t2x = t1x+tw+3*mm; t3x = t2x+tw+3*mm

        # Split arrow
        cv.setStrokeColor(TEAL); cv.setLineWidth(1.2)
        cv.line(W/2, diag_y-10, W/2, tx_y+tx_h+8)
        # horizontal split
        cv.line(t1x+tw/2, tx_y+tx_h+8, t3x+tw/2, tx_y+tx_h+8)
        for tx in [t1x+tw/2, t2x+tw/2, t3x+tw/2]:
            arrow_v(cv, tx, tx_y+tx_h+8, tx_y+tx_h, col=TEAL)

        flowbox(cv, t1x, tx_y, tw, tx_h,
                "Group A – Outpatient",
                ["• Adequate oral hydration",
                 "  (ORS, water, coconut water)",
                 "• Paracetamol for fever",
                 "  (max 4 g/day adult)",
                 "• AVOID NSAIDs/aspirin!",
                 "• Daily platelet + HCT",
                 "  from Day 3",
                 "• Return if warning signs",
                 "• Mosquito bite prevention"],
                bg=TEAL_PALE, border=TEAL, tbg=TEAL, tsize=8)

        flowbox(cv, t2x, tx_y, tw, tx_h,
                "Group B – Hospitalise",
                ["• IV crystalloid (0.9% NaCl",
                 "  or Ringer's lactate)",
                 "• 5-10 mL/kg/hr bolus",
                 "  if compensated shock",
                 "• Vitals every 1-4 hrs",
                 "• CBC every 4-6 hrs",
                 "• Urine output 0.5-1 mL/kg/hr",
                 "• Plt transfusion only if",
                 "  <20,000 + active bleeding"],
                bg=AMBER_LIGHT, border=ORANGE, tbg=ORANGE, tsize=8)

        flowbox(cv, t3x, tx_y, tw, tx_h,
                "Group C – ICU/Emergency",
                ["• Aggressive IV resus.",
                 "  10-20 mL/kg bolus",
                 "• pRBCs if Hb <7 g/dL",
                 "• Plt transfusion <10,000",
                 "  or active bleeding",
                 "• FFP for coagulopathy",
                 "• Vasopressors if refractory",
                 "• Mechanical ventilation",
                 "  if respiratory failure"],
                bg=RED_LITE, border=RED, tbg=RED, tsize=8)

        # Follow-up box
        fu_y = tx_y - 12 - 48; fu_x = 14*mm; fu_w = W-28*mm; fu_h = 48
        cv.setStrokeColor(TEAL); cv.setLineWidth(1.2)
        cv.line(t1x+tw/2, tx_y, t1x+tw/2, fu_y+fu_h+6)
        cv.line(t3x+tw/2, tx_y, t3x+tw/2, fu_y+fu_h+6)
        cv.line(t1x+tw/2, fu_y+fu_h+6, t3x+tw/2, fu_y+fu_h+6)
        arrow_v(cv, W/2, fu_y+fu_h+6, fu_y+fu_h)

        flowbox(cv, fu_x, fu_y, fu_w, fu_h,
                "MONITORING & DISCHARGE CRITERIA",
                ["• Critical phase (Days 3-7 / defervescence): highest risk of plasma leakage, shock, haemorrhage – monitor hourly",
                 "• Discharge criteria: afebrile ≥24h, no warning signs, improving appetite, stable HCT, platelets >50,000, adequate urine output",
                 "• Convalescent phase: bradycardia, convalescent rash (isles of white in sea of red), fatigue may persist 2-4 weeks",
                 "• NO specific antiviral exists – management is entirely SUPPORTIVE"],
                bg=PURPLE_LITE, border=PURPLE, tbg=PURPLE, tsize=9, lead=10)

# ══════════════════════════════════════════════════════════════
# PAGE 2 – REFERENCE TABLES
# ══════════════════════════════════════════════════════════════

def build_reference(story):
    def sec(text, bg=TEAL):
        return Paragraph(f"  {text}", ParagraphStyle("sh", fontName="Helvetica-Bold",
            fontSize=9, textColor=white, backColor=bg, leading=15,
            leftIndent=4, spaceAfter=2, spaceBefore=6, borderPad=3))

    def body(text, bold=False, size=8, color=BLACK, indent=0):
        return Paragraph(text, ParagraphStyle("b", fontName="Helvetica-Bold" if bold else "Helvetica",
            fontSize=size, textColor=color, leftIndent=indent, leading=size+4, spaceAfter=1))

    def tbl(data, cws, hbg=TEAL, altbg=TEAL_LIGHT, fs=7.5):
        t = Table(data, colWidths=cws)
        t.setStyle(TableStyle([
            ("BACKGROUND", (0,0), (-1,0), hbg),
            ("TEXTCOLOR",  (0,0), (-1,0), white),
            ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
            ("FONTSIZE",   (0,0), (-1,0), fs),
            ("FONTNAME",   (0,1), (-1,-1), "Helvetica"),
            ("FONTSIZE",   (0,1), (-1,-1), fs-0.5),
            ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, altbg]),
            ("GRID",       (0,0), (-1,-1), 0.4, GREY),
            ("VALIGN",     (0,0), (-1,-1), "MIDDLE"),
            ("LEFTPADDING",(0,0), (-1,-1), 5),
            ("RIGHTPADDING",(0,0), (-1,-1), 5),
            ("TOPPADDING", (0,0), (-1,-1), 3),
            ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ]))
        return t

    story.append(Spacer(1, 31*mm))

    # 1. WHO Classification
    story.append(sec("1.  WHO 2009 DENGUE CLASSIFICATION & MANAGEMENT GROUPS", bg=TEAL))
    story.append(Spacer(1,3))
    d1 = [
        ["Group","Classification","Key Features","Setting","Action"],
        ["A","Dengue WITHOUT\nWarning Signs",
         "Fever + ≥2: nausea/vomiting, rash, aches/pains,\nleukopenia, +ve tourniquet test",
         "Outpatient","Oral fluids, paracetamol, daily CBC"],
        ["B","Dengue WITH\nWarning Signs",
         "Abdominal pain, persistent vomiting, fluid accumulation,\nmucosal bleed, lethargy, liver >2 cm, ↑HCT+↓plt",
         "Hospital ward","IV fluids, close monitoring"],
        ["C","SEVERE Dengue",
         "Severe plasma leakage → shock (DSS); severe bleeding;\norgan impairment (AST/ALT ≥1000, coma, heart failure)",
         "ICU","Emergency resuscitation"],
    ]
    story.append(tbl(d1, [1.2*mm*10, 3*mm*10, 6.5*mm*10, 2.5*mm*10, 4.3*mm*10], hbg=TEAL))
    story.append(Spacer(1,6))

    # 2. Warning Signs detail
    story.append(sec("2.  WARNING SIGNS IN DETAIL (Group B – Hospitalise)", bg=ORANGE))
    story.append(Spacer(1,3))
    d2 = [
        ["Warning Sign","Clinical Significance"],
        ["Abdominal pain or tenderness","Ascites or hepatic congestion – plasma leakage imminent"],
        ["Persistent vomiting (≥3× in 1h)","Prevents oral hydration; fluid depletion risk"],
        ["Clinical fluid accumulation","Pleural effusion, ascites – confirms plasma leakage"],
        ["Mucosal bleed (nose, gums, vagina)","Coagulopathy or thrombocytopenia-related"],
        ["Lethargy / restlessness","Early CNS compromise or haemodynamic instability"],
        ["Liver enlargement >2 cm","Hepatitis / dengue hepatopathy"],
        ["Rapid ↑HCT concurrent with rapid ↓platelets","Hallmark of significant plasma leakage"],
    ]
    story.append(tbl(d2, [6*mm*10, 12.5*mm*10], hbg=ORANGE, altbg=AMBER_LIGHT))
    story.append(Spacer(1,6))

    # 3. Diagnosis
    story.append(sec("3.  DIAGNOSTIC TESTS – TIME-BASED GUIDE", bg=BLUE))
    story.append(Spacer(1,3))
    d3 = [
        ["Test","Window","Detects","Sensitivity","Notes"],
        ["RT-PCR","Days 1-7","Dengue RNA","High (early)","Gold standard for early phase; also serotypes 1-4"],
        ["NS1 Antigen (EIA/RDT)","Days 1-9","Viral NS1 protein","80-90%","Positive from day 1; combined NS1+IgM ≥90%"],
        ["IgM Antibody (EIA)","Day 3-5 onset;\npeak 2 weeks","Anti-dengue IgM","99% by Day 10","Cross-reacts with Zika, WNV, JE, YFV"],
        ["IgG Antibody","Lifetime","Anti-dengue IgG","High (convalescent)","≥4× rise acute vs. convalescent = confirmed"],
        ["CBC","Any time","Thrombocytopenia\n+ haemoconcentration","—","Platelets <100,000 + ↑HCT = plasma leakage"],
        ["Tourniquet test","Any time","Capillary fragility","Supportive","Inflate BP cuff mid-systolic/diastolic × 5 min; ≥10 petechiae/in² = positive"],
    ]
    story.append(tbl(d3, [3.8*mm*10, 3*mm*10, 3.5*mm*10, 2.8*mm*10, 5.4*mm*10], hbg=BLUE, altbg=BLUE_LIGHT))
    story.append(Spacer(1,6))

    # 4. Treatment
    story.append(sec("4.  TREATMENT PROTOCOLS BY GROUP", bg=TEAL))
    story.append(Spacer(1,3))
    d4 = [
        ["Parameter","Group A (Outpatient)","Group B (Hospital)","Group C (ICU)"],
        ["Fluids","Oral hydration (ORS)\n≥5 glasses/day","IV crystalloid (0.9% NaCl or\nRL) 5-10 mL/kg/hr",
         "Aggressive bolus 10-20 mL/kg;\nthen titrate to response"],
        ["Fever","Paracetamol 500-1000 mg\nq6h (max 4 g/day)","Paracetamol; tepid sponging",
         "Paracetamol; temperature\nmanagement"],
        ["Avoid","NSAIDs, aspirin,\nibuprofen (bleed risk)","NSAIDs, aspirin",
         "Excessive IV fluids\n(pulmonary oedema risk)"],
        ["Platelet transfusion","Not indicated","Only if <20,000\n+ active bleeding",
         "If <10,000 or\nclinically significant bleed"],
        ["Blood transfusion","Not indicated","If Hb <7 g/dL\n+ haemodynamic instability",
         "pRBCs if Hb <7 g/dL;\nFFP for coagulopathy"],
        ["Monitoring","Daily CBC (Day 3 onwards)\nUntil 1-2 days post-defervescence",
         "Vitals q1-4h; CBC q4-6h;\nurine output q1h",
         "Continuous monitoring;\nICU-level care"],
        ["Antivirals","NONE – no approved antiviral","NONE","NONE"],
    ]
    story.append(tbl(d4, [3.5*mm*10, 5*mm*10, 5*mm*10, 5*mm*10], hbg=TEAL, altbg=TEAL_LIGHT))
    story.append(Spacer(1,6))

    # 5. Disease Phases
    story.append(sec("5.  THREE CLINICAL PHASES OF DENGUE", bg=PURPLE))
    story.append(Spacer(1,3))
    d5 = [
        ["Phase","Duration","Key Features","Clinical Action"],
        ["FEBRILE","Days 1-3",
         "High fever, facial flushing, rash, myalgia, headache,\nretro-orbital pain; minor bleeding possible",
         "Oral hydration; paracetamol; monitor for warning signs;\nNSAIDs CONTRAINDICATED"],
        ["CRITICAL","Days 3-7\n(defervescence)",
         "Plasma leakage (↑HCT), thrombocytopenia; risk of\nshock (DSS), severe bleeding, organ damage",
         "HIGHEST RISK PERIOD – intensive monitoring;\nIV fluids for Groups B/C; hourly vitals"],
        ["CONVALESCENT","Days 7-10+",
         "Reabsorption of leaked fluids; bradycardia common;\nconvalescent rash (isles of white); gradual recovery",
         "Beware fluid overload during reabsorption;\nmonitor for pulmonary oedema"],
    ]
    story.append(tbl(d5, [3*mm*10, 2.8*mm*10, 6.7*mm*10, 6*mm*10], hbg=PURPLE, altbg=PURPLE_LITE))
    story.append(Spacer(1,6))

    # 6. Special populations
    story.append(sec("6.  SPECIAL POPULATIONS & RISK FACTORS", bg=RED))
    story.append(Spacer(1,3))
    d6 = [
        ["Population","Risk","Management"],
        ["Second dengue infection (different serotype)",
         "Antibody-dependent enhancement → severe dengue (DHF/DSS)",
         "High index of suspicion; early hospitalisation"],
        ["Infants (<1 year)","Higher mortality; atypical presentation",
         "Lower threshold for hospitalisation; weight-based fluid management"],
        ["Pregnant women","Vertical transmission ~20%; severe complications",
         "Close fetal monitoring; avoid NSAIDs; manage post-partum haemorrhage risk"],
        ["Chronic disease (asthma, sickle cell, diabetes)",
         "Increased severe disease risk","Hospitalise early; tighter glycaemic control"],
        ["Dengue vaccine (Dengvaxia / CYD-TDV)",
         "Increases risk of severe dengue in seronegative individuals",
         "Vaccinate only if pre-vaccination serostatus confirmed positive; not for naive individuals"],
        ["Returning travellers","May present outside endemic area; clinicians unfamiliar",
         "CBC, NS1+IgM testing; consider dengue in any febrile returning traveller"],
    ]
    story.append(tbl(d6, [5*mm*10, 5.5*mm*10, 8*mm*10], hbg=RED, altbg=RED_LITE))
    story.append(Spacer(1,6))

    # 7. Discharge
    story.append(sec("7.  DISCHARGE CRITERIA", bg=TEAL))
    story.append(Spacer(1,3))
    d7 = [["Criterion","Target / Definition"],
          ["Afebrile","≥24 hours without antipyretics"],
          ["No warning signs","No abdominal pain, vomiting, bleeding, restlessness"],
          ["Improving appetite","Able to tolerate oral fluids and diet"],
          ["Haematocrit","Stable (not rising)"],
          ["Platelet count",">50,000 per µL and rising"],
          ["Urine output","Adequate (>1 mL/kg/hr for previous 24 hours)"],
          ["No respiratory distress","No pleural effusion causing distress"],
    ]
    story.append(tbl(d7, [8*mm*10, 10.5*mm*10], hbg=TEAL, altbg=TEAL_LIGHT))
    story.append(Spacer(1,8))

    story.append(HRFlowable(width="100%", thickness=0.5, color=GREY))
    story.append(Spacer(1,3))
    story.append(Paragraph(
        "<b>References:</b> "
        "1. WHO. Dengue: Guidelines for Diagnosis, Treatment, Prevention and Control. WHO/TDR, 2009. "
        "2. AAP Red Book 2021 – Report of the Committee on Infectious Diseases, 32nd Edition. "
        "3. Loscalzo J et al. Harrison's Principles of Internal Medicine, 22nd ed. McGraw-Hill, 2025. "
        "4. PAHO. Algorithms for the Clinical Management of Dengue Patients. June 2024. "
        "5. CDC. Guidelines for Classifying Dengue. cdc.gov/dengue, 2024.",
        ParagraphStyle("ref", fontName="Helvetica", fontSize=6.5, textColor=GREY_DARK, leading=9)))
    return story


# ══════════════════════════════════════════════════════════════
# BUILD
# ══════════════════════════════════════════════════════════════
def build():
    import os; os.makedirs("/home/daytona/workspace/dengue-pdf", exist_ok=True)

    doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
        leftMargin=14*mm, rightMargin=14*mm,
        topMargin=30*mm, bottomMargin=13*mm,
        title="Dengue Fever Clinical Reference Guide",
        author="Orris Medical Reference",
        subject="Dengue Symptoms, Diagnosis, Treatment – WHO 2009 Classification")

    def on_first(cv, doc):
        header_footer(cv, doc)
        DengueFlowchart().draw(cv)

    def on_later(cv, doc):
        header_footer(cv, doc)

    story = [Spacer(1, 1), PageBreak()]
    build_reference(story)

    doc.build(story, onFirstPage=on_first, onLaterPages=on_later)
    print(f"Saved: {OUTPUT}")

if __name__ == "__main__":
    build()
Writing File

~/dengue-pdf/generate_dengue_poc.py

#!/usr/bin/env python3
"""
Dengue Fever – Point-of-Care Quick Reference Card
Single A4 page – 3 column layout for clinical wall/desk use
"""

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.colors import HexColor, white, black

OUTPUT = "/home/daytona/workspace/dengue-pdf/Dengue_POC_QuickRef.pdf"
W, H = A4

TEAL        = HexColor("#0D6B6E")
TEAL_LIGHT  = HexColor("#D0ECEC")
TEAL_PALE   = HexColor("#E8F7F7")
AMBER       = HexColor("#C96A00")
AMBER_LIGHT = HexColor("#FEF0DC")
ORANGE      = HexColor("#D45A00")
ORANGE_LITE = HexColor("#FDECEA")
RED         = HexColor("#B01C1C")
RED_LITE    = HexColor("#FDECEA")
BLUE        = HexColor("#1A5EA8")
BLUE_LIGHT  = HexColor("#D6E8FA")
BLUE_PALE   = HexColor("#EEF6FF")
PURPLE      = HexColor("#5B2C8D")
PURPLE_LITE = HexColor("#EDE7F6")
NAVY        = HexColor("#0D2B4E")
GOLD        = HexColor("#E8A020")
GREY        = HexColor("#BBBBBB")
GREY_DARK   = HexColor("#444444")
WHITE       = white
BLACK       = black


def rr(c, x, y, w, h, fill, stroke=None, lw=0.6, r=3):
    c.setFillColor(fill)
    if stroke:
        c.setStrokeColor(stroke); c.setLineWidth(lw)
        c.roundRect(x, y, w, h, r, fill=1, stroke=1)
    else:
        c.roundRect(x, y, w, h, r, fill=1, stroke=0)

def sec_hdr(c, x, y, w, h, text, bg=TEAL, fg=WHITE, fsize=8.5):
    rr(c, x, y, w, h, bg, r=3)
    c.setFillColor(fg); c.setFont("Helvetica-Bold", fsize)
    c.drawCentredString(x+w/2, y+h/2-fsize*0.35, text)

def txt(c, x, y, t, font="Helvetica", size=7.5, color=BLACK):
    c.setFont(font, size); c.setFillColor(color); c.drawString(x, y, t)

def ctxt(c, x, y, t, font="Helvetica", size=7.5, color=BLACK):
    c.setFont(font, size); c.setFillColor(color); c.drawCentredString(x, y, t)

def mini_tbl(c, x, y, rows, cws, rh=10.5, hbg=TEAL, hfg=WHITE, altbg=None, fs=7):
    for ri, row in enumerate(rows):
        cx = x
        is_hdr = ri == 0
        for ci, (cell, cw) in enumerate(zip(row, cws)):
            bg = hbg if is_hdr else (altbg if altbg and ri%2==0 else WHITE)
            fg = hfg if is_hdr else BLACK
            fn = "Helvetica-Bold" if is_hdr else "Helvetica"
            rr(c, cx, y-rh, cw, rh, bg)
            c.setStrokeColor(GREY); c.setLineWidth(0.3)
            c.rect(cx, y-rh, cw, rh, fill=0, stroke=1)
            c.setFillColor(fg); c.setFont(fn, fs)
            # wrap if needed
            words = str(cell).split('\n')
            line_y = y - rh + 3 + (len(words)-1)*7
            for ln in words:
                c.drawString(cx+3, line_y, ln)
                line_y -= 7
            cx += cw
        y -= rh
    return y

def draw(c):
    M = 6*mm
    IW = W - 2*M

    # BG
    c.setFillColor(HexColor("#F2F7F7")); c.rect(0,0,W,H,fill=1,stroke=0)

    # Header
    hh = 19*mm
    rr(c, 0, H-hh, W, hh, TEAL, r=0)
    rr(c, 0, H-hh-2.5*mm, W, 2.5*mm, AMBER, r=0)

    c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 16)
    c.drawCentredString(W/2, H-11.5*mm, "DENGUE FEVER  QUICK REFERENCE CARD")
    c.setFont("Helvetica", 8); c.setFillColor(TEAL_LIGHT)
    c.drawCentredString(W/2, H-17*mm,
        "Point-of-Care  |  WHO 2009 Classification  |  Symptoms · Diagnosis · Treatment")

    TOP = H - hh - 2.5*mm - 3*mm
    col_w = (IW - 4*mm) / 3
    c1x = M
    c2x = M + col_w + 2*mm
    c3x = M + 2*(col_w+2*mm)

    # ── COLUMN 1 ─────────────────────────────────────────────
    y = TOP

    # Suspect dengue
    sec_hdr(c, c1x, y-9, col_w, 9, "▶  SUSPECT DENGUE WHEN…", bg=NAVY)
    y -= 9
    rr(c, c1x, y-44, col_w, 44, TEAL_PALE, stroke=TEAL, r=3)
    y2 = y-7
    for ln in ["Fever ≥38°C + endemic area travel (14 days)",
               "Severe headache + retro-orbital pain",
               "Myalgia/arthralgia – 'breakbone fever'",
               "Rash + flushing + leukopenia",
               "Positive tourniquet test"]:
        c.setFillColor(TEAL); c.setFont("Helvetica-Bold",8); c.drawString(c1x+4,y2,"•")
        c.setFillColor(BLACK); c.setFont("Helvetica",7); c.drawString(c1x+11,y2,ln)
        y2 -= 8.5
    y -= 44

    # Incubation
    y -= 2
    rr(c, c1x, y-12, col_w, 12, GOLD, r=3)
    c.setFillColor(NAVY); c.setFont("Helvetica-Bold",7)
    c.drawCentredString(c1x+col_w/2, y-4.5, "Incubation: 3-14 days  |  Vector: Aedes aegypti (day-biting)")
    c.setFont("Helvetica",6.5)
    c.drawCentredString(c1x+col_w/2, y-10, "Serotypes: DENV-1, 2, 3, 4  |  2nd infection → severe disease risk")
    y -= 12

    # SYMPTOMS
    y -= 3
    sec_hdr(c, c1x, y-9, col_w, 9, "SYMPTOMS  (Febrile Phase  Days 1–3)", bg=AMBER)
    y -= 9
    sym_h = 78
    rr(c, c1x, y-sym_h, col_w, sym_h, AMBER_LIGHT, stroke=AMBER, r=3)
    y2 = y-8
    sym = [("Fever","39-40°C, abrupt onset"),
           ("Headache","severe, frontal + retro-orbital"),
           ("Myalgia/Arthralgia","bone pain – 'breakbone fever'"),
           ("Rash","maculopapular, trunk → extremities"),
           ("Flushing","facial erythema, conjunctival injection"),
           ("Leukopenia","characteristic CBC finding"),
           ("Bleeding","petechiae, gum bleed, +ve tourniquet"),
           ("Nausea/Vomiting","early, non-specific")]
    for k,v in sym:
        c.setFont("Helvetica-Bold",6.8); c.setFillColor(AMBER)
        c.drawString(c1x+4, y2, k)
        kw = c.stringWidth(k,"Helvetica-Bold",6.8)
        c.setFont("Helvetica",6.8); c.setFillColor(BLACK)
        c.drawString(c1x+4+kw+2, y2, f"– {v}")
        y2 -= 9.2
    y -= sym_h

    # Three phases
    y -= 3
    sec_hdr(c, c1x, y-9, col_w, 9, "THREE CLINICAL PHASES", bg=PURPLE)
    y -= 9
    ph_h = 54
    rr(c, c1x, y-ph_h, col_w, ph_h, PURPLE_LITE, stroke=PURPLE, r=3)
    y2 = y-7
    phases = [
        ("FEBRILE","Days 1-3","Fever, myalgia, rash"),
        ("CRITICAL","Days 3-7","Plasma leakage, shock, bleed ⚠"),
        ("CONVALESC.","Days 7+","Fluid reabsorption, recovery"),
    ]
    for ph,days,desc in phases:
        c.setFont("Helvetica-Bold",7); c.setFillColor(PURPLE)
        c.drawString(c1x+4,y2,ph)
        pw = c.stringWidth(ph,"Helvetica-Bold",7)
        c.setFont("Helvetica-Bold",6.5); c.setFillColor(GREY_DARK)
        c.drawString(c1x+4+pw+3,y2,days)
        y2 -= 7.5
        c.setFont("Helvetica",6.8); c.setFillColor(BLACK)
        c.drawString(c1x+10,y2,desc)
        y2 -= 10
    y -= ph_h

    # ── COLUMN 2 ─────────────────────────────────────────────
    y = TOP

    # WHO Classification
    sec_hdr(c, c2x, y-9, col_w, 9, "WHO 2009 CLASSIFICATION", bg=TEAL)
    y -= 9
    rr(c, c2x, y-82, col_w, 82, TEAL_PALE, stroke=TEAL, r=3)
    y2 = y-8

    groups = [
        (TEAL,  "GROUP A","No Warning Signs",
         ["Fever + ≥2: nausea, rash,","aches, leukopenia, +ve TT","→ OUTPATIENT"]),
        (ORANGE,"GROUP B","With Warning Signs",
         ["Abd. pain, persistent vomit,","fluid accumulation, mucosal","bleed, lethargy, liver >2cm","→ HOSPITALISE"]),
        (RED,   "GROUP C","SEVERE Dengue",
         ["Shock (DSS), severe bleeding,","AST/ALT ≥1000, coma, organ","failure → ICU"]),
    ]
    for grp_col, grp, sub, lines in groups:
        rr(c, c2x+3, y2-8, col_w-6, 8, grp_col, r=2)
        c.setFillColor(WHITE); c.setFont("Helvetica-Bold",7)
        c.drawString(c2x+6, y2-5.5, f"{grp}:  {sub}")
        y2 -= 9
        for ln in lines:
            col = RED if "→" in ln else BLACK
            fn = "Helvetica-Bold" if "→" in ln else "Helvetica"
            c.setFillColor(col); c.setFont(fn,6.5)
            c.drawString(c2x+8,y2,ln)
            y2 -= 7.5
        y2 -= 2
    y -= 82

    # Warning signs
    y -= 3
    sec_hdr(c, c2x, y-9, col_w, 9, "WARNING SIGNS  (Admit if ANY)", bg=ORANGE)
    y -= 9
    ws_h = 72
    rr(c, c2x, y-ws_h, col_w, ws_h, AMBER_LIGHT, stroke=ORANGE, r=3)
    y2 = y-8
    ws = ["! Abdominal pain or tenderness",
          "! Persistent vomiting (≥3×/hr)",
          "! Fluid accumulation (effusion/ascites)",
          "! Mucosal bleeding",
          "! Lethargy / restlessness",
          "! Liver enlargement >2 cm",
          "! ↑Haematocrit + rapid ↓platelets"]
    for ln in ws:
        c.setFillColor(RED); c.setFont("Helvetica-Bold",8); c.drawString(c2x+4,y2,ln[0])
        c.setFillColor(BLACK); c.setFont("Helvetica",6.8); c.drawString(c2x+11,y2,ln[2:])
        y2 -= 9.5
    y -= ws_h

    # Diagnosis
    y -= 3
    sec_hdr(c, c2x, y-9, col_w, 9, "DIAGNOSIS  (Time-Based)", bg=BLUE)
    y -= 9
    diag_h = 60
    rr(c, c2x, y-diag_h, col_w, diag_h, BLUE_PALE, stroke=BLUE, r=3)
    y2 = y-8
    diag = [
        ("Days 1-7","RT-PCR  or  NS1 antigen test"),
        ("Day 3-10","IgM antibody (EIA)"),
        ("Combined","NS1 + IgM → ≥90% detection"),
        ("CBC","Plt <100k + ↑HCT = plasma leakage"),
        ("Tourniquet","≥10 petechiae/in² = positive"),
        ("Note","IgM cross-reacts: Zika, WNV, JE, YFV"),
    ]
    for k,v in diag:
        c.setFont("Helvetica-Bold",6.8); c.setFillColor(BLUE); c.drawString(c2x+4,y2,k)
        kw = c.stringWidth(k,"Helvetica-Bold",6.8)
        c.setFont("Helvetica",6.8); c.setFillColor(BLACK); c.drawString(c2x+4+kw+2,y2,v)
        y2 -= 9.2
    y -= diag_h

    # ── COLUMN 3 ─────────────────────────────────────────────
    y = TOP

    # Group A treatment
    sec_hdr(c, c3x, y-9, col_w, 9, "GROUP A – OUTPATIENT Tx", bg=TEAL)
    y -= 9
    rr(c, c3x, y-62, col_w, 62, TEAL_PALE, stroke=TEAL, r=3)
    y2 = y-8
    for ln in ["Oral hydration (ORS, water, coconut water)",
               "Paracetamol fever (max 4g/day adult)",
               "⛔ NO NSAIDs / aspirin / ibuprofen",
               "Daily CBC from Day 3",
               "Until 1-2 days post-defervescence",
               "Return IMMEDIATELY if warning signs",
               "Mosquito nets to prevent spread"]:
        is_warn = "⛔" in ln
        c.setFillColor(RED if is_warn else TEAL); c.setFont("Helvetica-Bold",8)
        c.drawString(c3x+4,y2,"▸" if not is_warn else "")
        c.setFillColor(RED if is_warn else BLACK); c.setFont("Helvetica-Bold" if is_warn else "Helvetica",6.8)
        c.drawString(c3x+11,y2,ln)
        y2 -= 8.5
    y -= 62

    # Group B treatment
    y -= 3
    sec_hdr(c, c3x, y-9, col_w, 9, "GROUP B – HOSPITALISE", bg=ORANGE)
    y -= 9
    rr(c, c3x, y-62, col_w, 62, AMBER_LIGHT, stroke=ORANGE, r=3)
    y2 = y-8
    for ln in ["IV crystalloid (0.9% NaCl or Ringer's)",
               "5-10 mL/kg bolus if compensated shock",
               "Vitals every 1-4 hours",
               "CBC every 4-6 hours",
               "Urine output 0.5-1 mL/kg/hr",
               "Plt transfusion: <20,000 + active bleed",
               "Transition oral when improving"]:
        c.setFillColor(ORANGE); c.setFont("Helvetica-Bold",8); c.drawString(c3x+4,y2,"▸")
        c.setFillColor(BLACK); c.setFont("Helvetica",6.8); c.drawString(c3x+11,y2,ln)
        y2 -= 8.5
    y -= 62

    # Group C treatment
    y -= 3
    sec_hdr(c, c3x, y-9, col_w, 9, "GROUP C – ICU / EMERGENCY", bg=RED)
    y -= 9
    rr(c, c3x, y-68, col_w, 68, RED_LITE, stroke=RED, r=3)
    y2 = y-8
    for ln in ["Aggressive bolus: 10-20 mL/kg IV",
               "pRBCs if Hb <7 g/dL",
               "Platelet transfusion <10,000",
               "or clinically significant bleeding",
               "FFP for coagulopathy",
               "Vasopressors: fluid-refractory shock",
               "Mechanical ventilation if resp. failure",
               "⚠ Avoid excessive fluids (pulm. oedema)"]:
        is_w = "⚠" in ln
        c.setFillColor(RED); c.setFont("Helvetica-Bold",8)
        c.drawString(c3x+4,y2,"⚠" if is_w else "▸")
        c.setFillColor(RED if is_w else BLACK)
        c.setFont("Helvetica-Bold" if is_w else "Helvetica",6.8)
        c.drawString(c3x+11,y2,ln)
        y2 -= 8.2
    y -= 68

    # Discharge criteria
    y -= 3
    sec_hdr(c, c3x, y-9, col_w, 9, "DISCHARGE CRITERIA (ALL must be met)", bg=PURPLE)
    y -= 9
    rr(c, c3x, y-54, col_w, 54, PURPLE_LITE, stroke=PURPLE, r=3)
    y2 = y-8
    for ln in ["Afebrile ≥24h (no antipyretics)",
               "No warning signs",
               "Improving appetite + oral intake",
               "Platelets >50,000 and rising",
               "Stable haematocrit",
               "No respiratory distress"]:
        c.setFillColor(PURPLE); c.setFont("Helvetica-Bold",8); c.drawString(c3x+4,y2,"✓")
        c.setFillColor(BLACK); c.setFont("Helvetica",6.8); c.drawString(c3x+11,y2,ln)
        y2 -= 8.5
    y -= 54

    # ── BOTTOM BAND: Monitoring strip ────────────────────────
    y_sp = 32*mm
    sec_hdr(c, M, y_sp, IW, 9, "MONITORING SCHEDULE  &  CRITICAL PHASE ALERT", bg=NAVY)
    sp_y = y_sp - 9
    entries = [
        ("Day 3 onwards","CBC daily (PLT+HCT)\nUntil 1-2d post-defervescence"),
        ("CRITICAL PHASE\n(Days 3-7)","⚠ HIGHEST RISK: plasma leakage,\nshock, haemorrhage – hourly vitals"),
        ("Shock (DSS)","Fluid bolus + close monitoring;\npressor if fluid-refractory"),
        ("Haematocrit","↑HCT = haemoconcentration;\nmarker of plasma leakage"),
        ("Platelet nadirs","Usually Day 4-6;\nrebound in convalescence"),
    ]
    ew = IW / len(entries)
    for i,(title,note) in enumerate(entries):
        sx = M + i*ew
        is_warn = "⚠" in note
        bg = RED_LITE if is_warn else (TEAL_PALE if i%2==0 else WHITE)
        rr(c, sx, sp_y-22, ew, 22, bg, stroke=GREY, lw=0.3, r=0)
        c.setFillColor(RED if is_warn else TEAL); c.setFont("Helvetica-Bold",6.5)
        c.drawCentredString(sx+ew/2, sp_y-8, title)
        words = note.split('\n')
        yy = sp_y-15
        for ln in words:
            c.setFillColor(RED if is_warn else BLACK); c.setFont("Helvetica",6)
            c.drawCentredString(sx+ew/2, yy, ln)
            yy -= 7

    # ── FOOTER ─────────────────────────────────────────────
    rr(c, 0, 0, W, 10*mm, NAVY, r=0)
    c.setFillColor(GOLD); c.setFont("Helvetica-Bold",7)
    c.drawCentredString(W/2, 6*mm,
        "⚠  NO antiviral therapy exists – management is SUPPORTIVE.  "
        "NSAIDs / aspirin CONTRAINDICATED.  Critical phase (Days 3-7) is highest risk.")
    c.setFillColor(HexColor("#99AABB")); c.setFont("Helvetica",6)
    c.drawCentredString(W/2, 2.5*mm,
        "Sources: WHO Dengue Guidelines 2009  |  AAP Red Book 2021  |  "
        "Harrison's Principles 22E  |  PAHO Clinical Algorithms 2024  |  CDC 2024")


def main():
    import os; os.makedirs("/home/daytona/workspace/dengue-pdf", exist_ok=True)
    c = canvas.Canvas(OUTPUT, pagesize=A4)
    c.setTitle("Dengue Fever Point-of-Care Quick Reference Card")
    c.setAuthor("Orris Medical Reference")
    c.setSubject("Dengue POC Quick Reference – WHO 2009 Classification")
    draw(c)
    c.save()
    print(f"Saved: {OUTPUT}")

if __name__ == "__main__":
    main()
Running Command

cd /home/daytona/workspace/dengue-pdf && python generate_dengue_reference.py 2>&…

Running Command

ls -lh /home/daytona/workspace/dengue-pdf/

Both Dengue PDFs are ready:
POC Quick Reference Card (single A4):

Dengue POC QuickRef

PDF Document · PDF

Detailed Clinical Reference (2-page):

Dengue Clinical Reference

PDF Document · PDF


POC Card layout (single A4, 3-column, wall/desk ready):
Column 1 - RecognitionColumn 2 - Classify & DiagnoseColumn 3 - Treat
"Suspect dengue when..." checklistWHO 2009 Groups A / B / CGroup A outpatient protocol
Symptom list with descriptorsWarning signs (admit if ANY)Group B IV fluid protocol
Three clinical phases (Febrile/Critical/Convalescent)Time-based diagnosis guideGroup C ICU/emergency protocol
Incubation + vector noteNS1/RT-PCR/IgM windowsDischarge criteria (all 6 must be met)
Bottom monitoring strip: daily CBC schedule, critical phase alert (Days 3-7), DSS management cue
Footer warning: No antiviral exists - NSAIDs contraindicated - Critical phase Days 3-7 is highest risk

Reference PDF tables (7 sections):
  1. WHO 2009 Classification table (Groups A/B/C with features + settings)
  2. Warning signs with clinical significance
  3. Diagnostic tests - time windows, sensitivities, cross-reactivity notes
  4. Treatment protocols by group (fluids, monitoring, transfusion thresholds)
  5. Three clinical phases (febrile/critical/convalescent) with actions
  6. Special populations (2nd infection, pregnancy, infants, vaccine caution)
  7. Discharge criteria
Sources: WHO Dengue Guidelines 2009 | AAP Red Book 2021 | Harrison's 22E | PAHO Algorithms 2024 | CDC 2024
This is a shared conversation. Sign in to Orris to start your own chat.