Explain Pityriasis rosae with treatment and images
pityriasis rosea clinical features treatment 2024
pityriasis rosea herald patch skin rash
pityriasis rosea treatment acyclovir
Drug-induced PR-like eruptions can be caused by: captopril, lisinopril, imatinib mesylate, interferon, ketotifen, arsenicals, gold, bismuth, clonidine, barbiturates, adalimumab, lamotrigine, rituximab, and BCG vaccine, among others.





| Variant | Features |
|---|---|
| Papular | Common in children with darker skin; more facial and scalp involvement |
| Vesicular | Blistering lesions; rare |
| Purpuric | Petechiae and ecchymoses along Langer lines — rule out underlying leukemia |
| Erythema multiforme-like | Target-like lesions |
| Inverse PR | Lesions localized to axillae, groin, or neck, sparing the trunk |
| Unilateral/segmental | Rare |
Pregnancy warning: Pityriasis rosea in the first 15 weeks of gestation is associated with premature delivery, neonatal hypotonia, and fetal loss. — Andrews' Diseases of the Skin
| Condition | Key Distinguishing Feature |
|---|---|
| Secondary syphilis | Involves palms and soles; generalized adenopathy; positive RPR/VDRL — always rule out |
| Tinea corporis | Rarely so widespread; positive KOH |
| Tinea versicolor | Flatter, smaller lesions; KOH positive |
| Guttate psoriasis | No collarette of scale; silvery-white scale |
| Seborrheic dermatitis | Greasy scales; scalp and eyebrow involvement |
| Drug eruption | History of offending drug |
| Lichen planus | Violaceous, pruritic flat-topped papules; Wickham's striae |
Syphilis testing (RPR) is advisable in any atypical case — especially with palm/sole involvement or when clinical doubt exists. Syphilis incidence is rising and it can closely mimic PR. — Andrews'; Goldman-Cecil
| Treatment | Details |
|---|---|
| Oral antihistamines | Non-sedating (e.g. cetirizine, loratadine) for pruritus |
| Topical corticosteroids | Triamcinolone 0.1% cream for pruritic areas |
| Emollients | Petroleum jelly-based preparations; reduce dryness and itch |
| Patient reassurance | Self-limiting; no isolation needed |
A Cochrane review has cited inadequate evidence for most published treatments; however, lack of evidence does not equate to lack of efficacy. The best available evidence supports acyclovir as the most effective intervention for reducing duration and pruritus. — Andrews' Diseases of the Skin
| Feature | Details |
|---|---|
| Etiology | HHV-6 / HHV-7 reactivation |
| Age | 15–40 years most common |
| Season | Spring and autumn |
| Herald patch | 50–90%; precedes generalized rash by 1–2 weeks |
| Distribution | Trunk, proximal limbs; Christmas-tree pattern along Langer lines |
| Duration | 3–8 weeks (up to 16 weeks) |
| Key diagnostic sign | Collarette of scale (inward-pointing) |
| Must-exclude | Secondary syphilis |
| Treatment | Symptomatic (antihistamines, topical steroids, emollients); acyclovir for severe/early cases; NB-UVB phototherapy |
| Prognosis | Excellent; self-limiting; recurrence uncommon |
Make a handwritten notes with images
mkdir -p /home/daytona/workspace/pityriasis-notes/images && ls /home/daytona/wor…
cd /home/daytona/workspace/pityriasis-notes/images && curl -s -o herald_patch.jp…
~/pityriasis-notes/generate_notes.py
"""
Handwritten-style medical notes for Pityriasis Rosea
Uses ReportLab to create a lined-notebook PDF with embedded clinical images.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.platypus import SimpleDocTemplate, Spacer
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor, Color
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from PIL import Image as PILImage
import os, math, textwrap
W, H = A4 # 595.27 x 841.89 pts
IMG_DIR = "/home/daytona/workspace/pityriasis-notes/images"
OUT_PATH = "/home/daytona/workspace/pityriasis-notes/Pityriasis_Rosea_Notes.pdf"
# ── Colours ────────────────────────────────────────────────────────────────────
PAPER = HexColor("#FDFAF3") # warm cream
LINE_COL = HexColor("#C8D8E8") # soft blue rule lines
MARGIN_L = HexColor("#F4B8B8") # left margin rule (red)
INK = HexColor("#1A2A6E") # dark navy ink
RED_INK = HexColor("#C0392B") # red highlight ink
GREEN_INK = HexColor("#1E7B3A") # green ink for treatment
PURPLE = HexColor("#6C3483") # purple for headings
ORANGE = HexColor("#D35400") # orange for warnings
YELLOW_HL = HexColor("#FFF176") # highlighter yellow
BLUE_HL = HexColor("#B3E5FC") # highlighter blue
LINE_SPACING = 22 # pts between ruled lines
LEFT_MARGIN = 72 # pts (includes margin line area)
RIGHT_MARGIN = 540
TOP_MARGIN = 60
BOTTOM_MARGIN= 50
# ── Register a handwriting-style font (fallback to Helvetica) ──────────────────
# We use the built-in Helvetica family; to get a true handwriting look we render
# text with slight random rotation per word using canvas.saveState / restoreState.
# We'll use Helvetica-Oblique for body, Helvetica-Bold for headings.
FONT_BODY = "Helvetica-Oblique"
FONT_HEAD = "Helvetica-Bold"
FONT_BOLD = "Helvetica-Bold"
def draw_lined_paper(c, page_num):
"""Draw cream background + blue horizontal rules + red left margin."""
c.setFillColor(PAPER)
c.rect(0, 0, W, H, fill=1, stroke=0)
# Horizontal lines
c.setStrokeColor(LINE_COL)
c.setLineWidth(0.5)
y = H - TOP_MARGIN
while y > BOTTOM_MARGIN:
c.line(LEFT_MARGIN - 10, y, RIGHT_MARGIN + 10, y)
y -= LINE_SPACING
# Red margin line
c.setStrokeColor(MARGIN_L)
c.setLineWidth(1.2)
c.line(LEFT_MARGIN - 12, H - TOP_MARGIN + 5, LEFT_MARGIN - 12, BOTTOM_MARGIN)
# Page number
c.setFont(FONT_BODY, 9)
c.setFillColor(HexColor("#888888"))
c.drawCentredString(W / 2, 30, f"— {page_num} —")
# Spiral holes
c.setStrokeColor(HexColor("#BBBBBB"))
c.setFillColor(HexColor("#DDDDDD"))
c.setLineWidth(0.8)
for yh in [H * 0.2, H * 0.5, H * 0.8]:
c.circle(25, yh, 7, fill=1, stroke=1)
def draw_title_box(c, x, y, title, subtitle=""):
"""Draw a styled title box at the top of a page."""
bw, bh = RIGHT_MARGIN - LEFT_MARGIN + 20, 52
# Shadow
c.setFillColor(HexColor("#BBBBEE"))
c.roundRect(x + 3, y - bh - 3, bw, bh, 8, fill=1, stroke=0)
# Box
c.setFillColor(HexColor("#E8EAF6"))
c.setStrokeColor(PURPLE)
c.setLineWidth(2)
c.roundRect(x, y - bh, bw, bh, 8, fill=1, stroke=1)
# Title text
c.setFont(FONT_HEAD, 20)
c.setFillColor(PURPLE)
c.drawCentredString(x + bw / 2, y - 28, title)
if subtitle:
c.setFont(FONT_BODY, 11)
c.setFillColor(HexColor("#555588"))
c.drawCentredString(x + bw / 2, y - 44, subtitle)
return y - bh - 10
def draw_section_header(c, x, y, text, color=PURPLE):
"""Underlined section header."""
c.setFont(FONT_HEAD, 13)
c.setFillColor(color)
c.drawString(x, y, text)
tw = c.stringWidth(text, FONT_HEAD, 13)
c.setStrokeColor(color)
c.setLineWidth(1.8)
c.line(x, y - 2, x + tw + 4, y - 2)
return y - LINE_SPACING
def draw_bullet(c, x, y, text, ink=INK, size=11, bullet="•", indent=0):
"""Draw a single bullet line, wrapping if needed. Returns new y."""
bx = x + indent
c.setFont(FONT_BODY, size)
c.setFillColor(ink)
c.drawString(bx, y, bullet + " ")
bw = c.stringWidth(bullet + " ", FONT_BODY, size)
max_w = RIGHT_MARGIN - bx - bw - 5
lines = wrap_text(c, text, FONT_BODY, size, max_w)
for i, line in enumerate(lines):
c.drawString(bx + bw, y - i * LINE_SPACING, line)
return y - len(lines) * LINE_SPACING
def draw_text(c, x, y, text, ink=INK, size=11, font=None, max_width=None):
"""Draw wrapped text. Returns new y."""
f = font or FONT_BODY
mw = max_width or (RIGHT_MARGIN - x - 5)
lines = wrap_text(c, text, f, size, mw)
c.setFont(f, size)
c.setFillColor(ink)
for line in lines:
c.drawString(x, y, line)
y -= LINE_SPACING
return y
def wrap_text(c, text, font, size, max_width):
"""Word-wrap text to fit max_width."""
words = text.split()
lines, current = [], ""
for w in words:
test = (current + " " + w).strip()
if c.stringWidth(test, font, size) <= max_width:
current = test
else:
if current:
lines.append(current)
current = w
if current:
lines.append(current)
return lines or [""]
def draw_highlighted_box(c, x, y, width, text, bg=YELLOW_HL, ink=INK, size=10.5, title=None):
"""Draw a highlighted sticky-note style box."""
pad = 7
# Measure lines
lines = wrap_text(c, text, FONT_BODY, size, width - pad * 2)
bh = len(lines) * LINE_SPACING + pad * 2 + (LINE_SPACING if title else 0)
# Shadow
c.setFillColor(HexColor("#CCCCCC"))
c.roundRect(x + 3, y - bh - 3, width, bh, 6, fill=1, stroke=0)
# Box
c.setFillColor(bg)
c.setStrokeColor(HexColor("#AAAAAA"))
c.setLineWidth(0.8)
c.roundRect(x, y - bh, width, bh, 6, fill=1, stroke=1)
ty = y - pad - (LINE_SPACING if not title else 0)
if title:
c.setFont(FONT_HEAD, size)
c.setFillColor(ink)
c.drawString(x + pad, ty - 2, title)
ty -= LINE_SPACING
c.setFont(FONT_BODY, size)
c.setFillColor(ink)
for line in lines:
c.drawString(x + pad, ty, line)
ty -= LINE_SPACING
return y - bh - 8
def draw_arrow(c, x1, y1, x2, y2, color=RED_INK):
"""Draw an arrow."""
c.setStrokeColor(color)
c.setLineWidth(1.5)
c.line(x1, y1, x2, y2)
# arrowhead
angle = math.atan2(y2 - y1, x2 - x1)
size = 8
for da in [0.4, -0.4]:
ax = x2 - size * math.cos(angle + da)
ay = y2 - size * math.sin(angle + da)
c.line(x2, y2, ax, ay)
def draw_table(c, x, y, headers, rows, col_widths, size=9.5):
"""Draw a simple table. Returns new y."""
row_h = LINE_SPACING + 4
pad = 5
total_w = sum(col_widths)
# Header
c.setFillColor(HexColor("#D1C4E9"))
c.setStrokeColor(PURPLE)
c.setLineWidth(1)
c.rect(x, y - row_h, total_w, row_h, fill=1, stroke=1)
c.setFont(FONT_HEAD, size)
c.setFillColor(PURPLE)
cx = x
for i, h in enumerate(headers):
c.drawString(cx + pad, y - row_h + 6, h)
cx += col_widths[i]
# Rows
for ri, row in enumerate(rows):
bg = HexColor("#F8F4FF") if ri % 2 == 0 else HexColor("#FFFFFF")
c.setFillColor(bg)
c.setStrokeColor(HexColor("#CCCCCC"))
c.setLineWidth(0.5)
c.rect(x, y - (ri + 2) * row_h, total_w, row_h, fill=1, stroke=1)
c.setFont(FONT_BODY, size)
c.setFillColor(INK)
cx = x
for ci, cell in enumerate(row):
c.drawString(cx + pad, y - (ri + 2) * row_h + 6, cell)
cx += col_widths[ci]
# vertical lines
cx = x
c.setStrokeColor(HexColor("#BBBBBB"))
for cw in col_widths[:-1]:
cx += cw
c.line(cx, y - row_h, cx, y - (len(rows) + 1) * row_h)
return y - (len(rows) + 1) * row_h - 8
def embed_image(c, path, x, y, max_w, max_h, caption=""):
"""Embed image with rounded border and caption. Returns new y."""
try:
img = PILImage.open(path)
iw, ih = img.size
ratio = min(max_w / iw, max_h / ih)
dw, dh = iw * ratio, ih * ratio
# Border shadow
c.setFillColor(HexColor("#BBBBBB"))
c.roundRect(x + 3, y - dh - 3, dw, dh, 5, fill=1, stroke=0)
# Border
c.setStrokeColor(HexColor("#888888"))
c.setLineWidth(1.5)
c.setFillColor(colors.white)
c.roundRect(x, y - dh, dw, dh, 5, fill=1, stroke=1)
c.drawImage(path, x + 2, y - dh + 2, width=dw - 4, height=dh - 4,
preserveAspectRatio=True, mask='auto')
new_y = y - dh - 6
if caption:
c.setFont(FONT_BODY, 8.5)
c.setFillColor(HexColor("#555555"))
c.drawString(x, new_y - 2, caption)
new_y -= LINE_SPACING - 4
return new_y
except Exception as e:
print(f"Image error: {e}")
return y - 20
# ══════════════════════════════════════════════════════════════════════════════
# BUILD PDF
# ══════════════════════════════════════════════════════════════════════════════
c = canvas.Canvas(OUT_PATH, pagesize=A4)
c.setTitle("Pityriasis Rosea — Handwritten Medical Notes")
c.setAuthor("Medical Notes")
LM = LEFT_MARGIN # shorthand
RM = RIGHT_MARGIN
page_num = 1
# ─────────────────────────────────────────────────────────────────────────────
# PAGE 1 — Overview, Etiology, Clinical Features Phase 1
# ─────────────────────────────────────────────────────────────────────────────
draw_lined_paper(c, page_num)
y = H - TOP_MARGIN - 5
# Title
y = draw_title_box(c, LM - 10, y + 5,
"Pityriasis Rosea",
"Self-limiting viral exanthem · HHV-6/7 reactivation")
y -= 10
# OVERVIEW box
y = draw_highlighted_box(c, LM, y, RM - LM,
"A mild, benign, self-limiting inflammatory eruption. Incidence: 3–30/1000. "
"Peak age 15–40 yrs. Slight female predominance. Spring & Autumn predominance.",
bg=BLUE_HL, title="OVERVIEW", ink=INK, size=10.5)
# ETIOLOGY
y = draw_section_header(c, LM, y, "① ETIOLOGY & PATHOGENESIS", color=PURPLE)
y -= 4
y = draw_bullet(c, LM, y, "Primary cause: Reactivation of Human Herpesvirus 6 (HHV-6) & HHV-7", ink=INK)
y = draw_bullet(c, LM, y, "Both viruses latent in mononuclear cells since childhood → viremia → eruption", ink=INK)
y = draw_bullet(c, LM, y, "Active HHV-6/HHV-7 replication demonstrated in lesional skin (Watanabe et al.)", ink=INK)
y = draw_bullet(c, LM, y, "HHV-2 and Hepatitis C also implicated in isolated cases", ink=INK)
y -= 4
# Drug causes
y = draw_highlighted_box(c, LM, y, RM - LM,
"Drug-induced PR-like eruptions: Captopril, Lisinopril, Imatinib, Interferons, Gold, "
"Barbiturates, Adalimumab, Lamotrigine, Rituximab, BCG vaccine, Clonidine, Ketotifen",
bg=HexColor("#FFF3E0"), title="⚠ Drug Causes", ink=ORANGE, size=10)
# CLINICAL FEATURES heading
y = draw_section_header(c, LM, y, "② CLINICAL FEATURES", color=HexColor("#1565C0"))
y -= 4
# Phase 1 — Herald Patch
c.setFont(FONT_HEAD, 11.5)
c.setFillColor(RED_INK)
c.drawString(LM, y, "PHASE 1 — Herald (Mother) Patch")
y -= LINE_SPACING
y = draw_bullet(c, LM, y, "Appears in 50–90% of patients as the FIRST lesion", ink=INK)
y = draw_bullet(c, LM, y, "Single, salmon-pink, oval/circinate patch — 2–5 cm diameter", ink=INK)
y = draw_bullet(c, LM, y, "Fine crinkled scale with COLLARETTE (scale edge points inward)", ink=RED_INK)
y = draw_bullet(c, LM, y, "Persists 1–2 weeks before generalised eruption", ink=INK)
y = draw_bullet(c, LM, y, "Often confused for Tinea corporis (annular + central scale)", ink=ORANGE)
y -= 8
# Herald patch image
img_w, img_h = 200, 165
img_x = RM - img_w
img_y = y + 120
embed_image(c, f"{IMG_DIR}/herald_patch.jpg", img_x, img_y, img_w, img_h,
"Fig 1: Herald patch — collarette scale (Andrews')")
y -= 10
# Phase 2 intro
c.setFont(FONT_HEAD, 11.5)
c.setFillColor(HexColor("#1565C0"))
c.drawString(LM, y, "PHASE 2 — Generalised Eruption (1–2 wks after herald patch)")
y -= LINE_SPACING
y = draw_bullet(c, LM, y, "Smaller salmon-coloured oval plaques erupt rapidly", ink=INK, max_width=RM - LM - img_w - 15)
y = draw_bullet(c, LM, y, "Distribution: trunk + proximal limbs — SPARES sun-exposed areas", ink=INK, max_width=RM - LM - img_w - 15)
c.saveState()
c.setPageNumber = 1
c.showPage()
page_num += 1
# ─────────────────────────────────────────────────────────────────────────────
# PAGE 2 — Clinical features continued + Christmas tree + images
# ─────────────────────────────────────────────────────────────────────────────
draw_lined_paper(c, page_num)
y = H - TOP_MARGIN - 5
# Continuation header
c.setFont(FONT_HEAD, 13)
c.setFillColor(HexColor("#1565C0"))
c.drawString(LM, y, "② CLINICAL FEATURES (cont.)")
y -= LINE_SPACING + 4
# Christmas tree description
y = draw_highlighted_box(c, LM, y, RM - LM,
'"Christmas Tree" / "Fir-Tree" Pattern: Long axes of lesions run parallel to Langer\'s '
'lines of skin cleavage → creates a triangular tree pattern on the back.',
bg=HexColor("#E8F5E9"), title="⭐ CHRISTMAS TREE SIGN", ink=GREEN_INK, size=10.5)
y = draw_bullet(c, LM, y, "Collarette of scale — open edge of scale faces INWARD (hanging curtain sign)", ink=RED_INK)
y = draw_bullet(c, LM, y, "Moderate pruritus (may be severe during outbreak)", ink=INK)
y = draw_bullet(c, LM, y, "Mild constitutional prodrome: malaise, pharyngitis before rash", ink=INK)
y -= 8
# Two images side by side
img_w2 = (RM - LM - 15) / 2
y_for_imgs = y
y_after_img1 = embed_image(c, f"{IMG_DIR}/full_rash.jpg", LM, y_for_imgs, img_w2, 175,
"Fig 2: Classic Christmas tree eruption (DermNet)")
y_after_img2 = embed_image(c, f"{IMG_DIR}/skin_of_color.jpg", LM + img_w2 + 15, y_for_imgs, img_w2, 175,
"Fig 3: PR in skin of color — muted erythema (DermNet)")
y = min(y_after_img1, y_after_img2) - 10
# Atypical variants
y = draw_section_header(c, LM, y, "ATYPICAL VARIANTS", color=ORANGE)
y -= 4
variants = [
("Papular variant", "Children with darker skin; facial + scalp involvement"),
("Vesicular variant", "Blistering lesions; rare"),
("Purpuric variant", "Petechiae along Langer lines — RULE OUT leukemia"),
("Inverse PR", "Localized to axillae, groin, neck — spares trunk"),
("Erythema multiforme-like", "Target-shaped lesions"),
("Unilateral / Segmental", "Rare pattern"),
]
for vname, vdesc in variants:
c.setFont(FONT_HEAD, 10)
c.setFillColor(ORANGE)
c.drawString(LM, y, f"▸ {vname}:")
tw = c.stringWidth(f"▸ {vname}:", FONT_HEAD, 10) + 6
c.setFont(FONT_BODY, 10)
c.setFillColor(INK)
c.drawString(LM + tw, y, vdesc)
y -= LINE_SPACING
y -= 4
# Pregnancy warning
y = draw_highlighted_box(c, LM, y, RM - LM,
"PR in first 15 weeks of pregnancy → risk of premature delivery, neonatal hypotonia, "
"and fetal loss. Consider acyclovir with obstetric input.",
bg=HexColor("#FFEBEE"), title="🤰 PREGNANCY WARNING", ink=RED_INK, size=10.5)
c.showPage()
page_num += 1
# ─────────────────────────────────────────────────────────────────────────────
# PAGE 3 — Course, Histology, Differential Diagnosis
# ─────────────────────────────────────────────────────────────────────────────
draw_lined_paper(c, page_num)
y = H - TOP_MARGIN - 5
# COURSE
y = draw_section_header(c, LM, y, "③ CLINICAL COURSE & PROGNOSIS", color=GREEN_INK)
y -= 4
y = draw_bullet(c, LM, y, "Self-limiting — typical course 3–8 weeks (range 4–16 weeks)", ink=GREEN_INK)
y = draw_bullet(c, LM, y, "Spontaneous resolution is the RULE", ink=INK)
y = draw_bullet(c, LM, y, "Relapses and recurrences are UNCOMMON", ink=INK)
y = draw_bullet(c, LM, y, "In darker skin: lesions resolve with post-inflammatory hypopigmentation", ink=INK)
y -= 10
# HISTOLOGY
y = draw_section_header(c, LM, y, "④ HISTOLOGY", color=PURPLE)
y -= 4
y = draw_bullet(c, LM, y, "Mild acanthosis", ink=INK)
y = draw_bullet(c, LM, y, "Focal parakeratosis", ink=INK)
y = draw_bullet(c, LM, y, "Extravasation of erythrocytes into the epidermis ← characteristic!", ink=RED_INK)
y = draw_bullet(c, LM, y, "Spongiosis (in acute cases)", ink=INK)
y = draw_bullet(c, LM, y, "Mild perivascular lymphocytic infiltrate in dermis", ink=INK)
y -= 10
# DIFFERENTIAL DIAGNOSIS — Table
y = draw_section_header(c, LM, y, "⑤ DIFFERENTIAL DIAGNOSIS", color=RED_INK)
y -= 6
dd_headers = ["Condition", "Key Distinguishing Feature"]
dd_rows = [
["Secondary Syphilis ⚠", "Palms + soles involved; lymphadenopathy; +ve RPR"],
["Tinea Corporis", "Rarely so widespread; KOH +ve"],
["Tinea Versicolor", "Flatter, smaller lesions; KOH +ve"],
["Guttate Psoriasis", "No collarette; silvery-white scale"],
["Seborrheic Dermatitis", "Scalp/eyebrow involvement; greasy scale"],
["Drug Eruption", "History of offending drug (see list above)"],
["Lichen Planus", "Violaceous, flat-topped papules; Wickham's striae"],
]
y = draw_table(c, LM, y, dd_headers, dd_rows, [185, 285])
y -= 4
y = draw_highlighted_box(c, LM, y, RM - LM,
"Always test RPR/VDRL to exclude secondary syphilis — especially with palm/sole "
"involvement. Syphilis incidence is RISING and it closely mimics PR.",
bg=HexColor("#FFEBEE"), title="⚠ MUST EXCLUDE: Secondary Syphilis", ink=RED_INK, size=10.5)
# Trunk rash image on right
img_y_p3 = y + 80
embed_image(c, f"{IMG_DIR}/trunk_rash.jpg", RM - 190, img_y_p3, 180, 140,
"Fig 4: Salmon plaques with fine scale (Andrews')")
y -= 10
# DIAGNOSIS
y = draw_section_header(c, LM, y, "⑥ DIAGNOSIS", color=HexColor("#1565C0"))
y -= 4
y = draw_bullet(c, LM, y, "Usually CLINICAL — based on characteristic appearance and distribution", ink=INK)
y = draw_bullet(c, LM, y, "Herald patch + Christmas-tree distribution = near-diagnostic", ink=GREEN_INK)
y = draw_bullet(c, LM, y, "KOH scraping to exclude tinea if doubt", ink=INK)
y = draw_bullet(c, LM, y, "RPR/VDRL serology if atypical or palmoplantar involvement", ink=RED_INK)
y = draw_bullet(c, LM, y, "Biopsy rarely needed — confirms if atypical", ink=INK)
c.showPage()
page_num += 1
# ─────────────────────────────────────────────────────────────────────────────
# PAGE 4 — Treatment
# ─────────────────────────────────────────────────────────────────────────────
draw_lined_paper(c, page_num)
y = H - TOP_MARGIN - 5
# Treatment title box
y = draw_title_box(c, LM - 10, y + 5,
"TREATMENT",
"Most patients require no specific therapy — condition is self-limiting")
y -= 10
# Symptomatic box
c.setFont(FONT_HEAD, 12)
c.setFillColor(GREEN_INK)
c.drawString(LM, y, "1. SYMPTOMATIC / FIRST-LINE")
y -= LINE_SPACING + 2
treat_symp = [
("Oral Antihistamines", "Cetirizine / Loratadine (non-sedating) — for pruritus", GREEN_INK),
("Topical Corticosteroids", "Triamcinolone 0.1% cream — for pruritic areas", GREEN_INK),
("Emollients", "Petroleum jelly-based preparations — reduce dryness and itch", GREEN_INK),
("Patient Education", "Reassure: self-limiting, no isolation needed, no scarring", HexColor("#1565C0")),
]
for tname, tdesc, tcol in treat_symp:
c.setFont(FONT_HEAD, 11)
c.setFillColor(tcol)
c.drawString(LM + 10, y, f"✓ {tname}:")
tw = c.stringWidth(f"✓ {tname}:", FONT_HEAD, 11) + 6
c.setFont(FONT_BODY, 10.5)
c.setFillColor(INK)
lines = wrap_text(c, tdesc, FONT_BODY, 10.5, RM - LM - tw - 15)
for i, line in enumerate(lines):
c.drawString(LM + 10 + tw, y - i * LINE_SPACING, line)
y -= len(lines) * LINE_SPACING + 2
y -= 8
# Antiviral
c.setFont(FONT_HEAD, 12)
c.setFillColor(HexColor("#1565C0"))
c.drawString(LM, y, "2. ANTIVIRAL THERAPY")
y -= LINE_SPACING + 2
y = draw_highlighted_box(c, LM, y, RM - LM,
"Acyclovir — BEST EVIDENCE. Multiple trials show DECREASE in eruption duration and pruritus. "
"Dose: 800 mg × 5/day for 7 days. Start EARLY (within first week of eruption). "
"Use in pregnancy with obstetric guidance (reduces fetal risk from viremia).",
bg=BLUE_HL, title="★ Acyclovir (Drug of Choice)", ink=HexColor("#1565C0"), size=11)
y -= 4
# Phototherapy
c.setFont(FONT_HEAD, 12)
c.setFillColor(PURPLE)
c.drawString(LM, y, "3. PHOTOTHERAPY")
y -= LINE_SPACING + 2
y = draw_bullet(c, LM, y, "Narrowband UVB (NB-UVB) phototherapy — may speed resolution of lesions", ink=PURPLE)
y = draw_bullet(c, LM, y, "Natural sunlight exposure also reported to help", ink=PURPLE)
y -= 8
# Antibiotics
c.setFont(FONT_HEAD, 12)
c.setFillColor(ORANGE)
c.drawString(LM, y, "4. ANTIBIOTICS (limited role)")
y -= LINE_SPACING + 2
y = draw_bullet(c, LM, y, "Erythromycin — benefit in small studies; GI side effects limit use", ink=ORANGE)
y = draw_bullet(c, LM, y, "Macrolides NOT routinely indicated (evidence insufficient)", ink=RED_INK)
y -= 8
y = draw_highlighted_box(c, LM, y, RM - LM,
"A Cochrane review cited inadequate evidence for most published treatments. "
"However, lack of evidence ≠ lack of efficacy. Acyclovir remains the best-supported specific therapy.",
bg=HexColor("#FFF3E0"), title="📖 Evidence Note (Cochrane)", ink=ORANGE, size=10.5)
# Summary table
y = draw_section_header(c, LM, y, "⑦ SUMMARY TABLE", color=PURPLE)
y -= 6
sum_headers = ["Feature", "Details"]
sum_rows = [
["Etiology", "HHV-6 / HHV-7 reactivation"],
["Peak Age", "15–40 years"],
["Season", "Spring & Autumn"],
["Herald Patch", "50–90%; precedes rash 1–2 weeks; 2–5 cm"],
["Distribution", "Trunk + proximal limbs; Christmas-tree pattern"],
["Duration", "3–8 weeks (up to 16 weeks)"],
["Key sign", "Collarette of scale (inward-pointing)"],
["Must exclude", "Secondary syphilis (RPR/VDRL)"],
["1st line Rx", "Antihistamines + topical steroids + emollients"],
["Specific Rx", "Acyclovir 800 mg x5/day x7 days"],
["Prognosis", "Excellent; self-limiting; recurrence uncommon"],
]
y = draw_table(c, LM, y, sum_headers, sum_rows, [145, 325])
# Footer
c.setFont(FONT_BODY, 8)
c.setFillColor(HexColor("#999999"))
c.drawCentredString(W / 2, 20, "Sources: Andrews' Diseases of the Skin | Tintinalli's Emergency Medicine | Goldman-Cecil Medicine | DermNet")
c.showPage()
# Save
c.save()
print(f"PDF saved: {OUT_PATH}")