Can you suggest me good points in the form of ppt about systemic mastocytosis
mkdir -p /home/daytona/workspace/systemic-mastocytosis-ppt && ls /home/daytona/w…
~/systemic-mastocytosis-ppt/create_ppt.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Systemic Mastocytosis";
pres.author = "Medical Education";
// Color palette: Deep navy dominates, crimson-maroon accent, light slate for content
const C = {
navy: "0D1B3E",
maroon: "8B1A2E",
crimson: "C0392B",
gold: "D4A843",
slate: "2C3E6B",
lightBlue: "EAF1FB",
white: "FFFFFF",
offWhite: "F5F7FA",
textDark: "1A1A2E",
textGray: "4A5568",
accent: "3A7BD5",
};
// ── Helper ──────────────────────────────────────────────────────────────────
function addSlideTitle(slide, text, subtitle) {
// Dark header bar
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: 10, h: 0.9,
fill: { color: C.navy }, line: { color: C.navy }
});
// Gold accent bar
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0.9, w: 10, h: 0.06,
fill: { color: C.gold }, line: { color: C.gold }
});
slide.addText(text, {
x: 0.3, y: 0.1, w: 9.4, h: 0.7,
fontSize: 22, bold: true, color: C.white, fontFace: "Calibri",
valign: "middle", margin: 0
});
if (subtitle) {
slide.addText(subtitle, {
x: 0.3, y: 0.96, w: 9.4, h: 0.28,
fontSize: 11, color: C.gold, fontFace: "Calibri", italic: true, margin: 0
});
}
}
function addBullets(slide, items, opts) {
const defaults = { x: 0.35, y: 1.3, w: 9.3, h: 3.8, fontSize: 15.5, color: C.textDark, fontFace: "Calibri" };
const o = Object.assign({}, defaults, opts);
const textArr = items.map((item, i) => ({
text: item.text || item,
options: {
bullet: item.indent ? { indent: 20 } : true,
fontSize: item.sub ? 13 : (item.big ? 17 : o.fontSize),
bold: item.bold || false,
color: item.color || o.color,
breakLine: i < items.length - 1
}
}));
slide.addText(textArr, { x: o.x, y: o.y, w: o.w, h: o.h, fontFace: o.fontFace, valign: "top" });
}
// ── SLIDE 1: Title ───────────────────────────────────────────────────────────
{
const s = pres.addSlide();
// Full dark background
s.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: 10, h: 5.625,
fill: { color: C.navy }, line: { color: C.navy }
});
// Decorative geometric shape – right panel
s.addShape(pres.shapes.RECTANGLE, {
x: 6.8, y: 0, w: 3.2, h: 5.625,
fill: { color: C.maroon }, line: { color: C.maroon }
});
// Gold diagonal accent
s.addShape(pres.shapes.RIGHT_TRIANGLE, {
x: 5.7, y: 0, w: 1.4, h: 5.625,
fill: { color: C.slate }, line: { color: C.slate }, flipH: true
});
// Gold top bar
s.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: 6.8, h: 0.08,
fill: { color: C.gold }, line: { color: C.gold }
});
s.addText("SYSTEMIC", {
x: 0.6, y: 1.05, w: 5.8, h: 0.75,
fontSize: 44, bold: true, color: C.white, fontFace: "Calibri", charSpacing: 6, margin: 0
});
s.addText("MASTOCYTOSIS", {
x: 0.6, y: 1.75, w: 5.8, h: 0.9,
fontSize: 38, bold: true, color: C.gold, fontFace: "Calibri", charSpacing: 3, margin: 0
});
s.addText("A Comprehensive Clinical Overview", {
x: 0.6, y: 2.75, w: 5.8, h: 0.5,
fontSize: 15, color: "A0AEC0", fontFace: "Calibri", italic: true, margin: 0
});
s.addShape(pres.shapes.RECTANGLE, {
x: 0.6, y: 3.4, w: 2.5, h: 0.05,
fill: { color: C.gold }, line: { color: C.gold }
});
s.addText("Based on Harrison's & Goldman-Cecil Medicine", {
x: 0.6, y: 3.6, w: 5.8, h: 0.4,
fontSize: 11.5, color: "718096", fontFace: "Calibri", italic: true, margin: 0
});
// Right panel text
s.addText([
{ text: "KIT D816V", options: { bold: true, breakLine: true } },
{ text: "Mast cell neoplasm", options: { breakLine: true } },
{ text: "WHO 2022", options: { bold: true, breakLine: true } },
{ text: "Classification", options: {} }
], {
x: 7.1, y: 1.8, w: 2.6, h: 2.0,
fontSize: 14, color: C.white, fontFace: "Calibri", align: "center"
});
}
// ── SLIDE 2: Overview / Agenda ───────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Presentation Overview");
const topics = [
"1. Definition & Epidemiology",
"2. Pathobiology & KIT Mutations",
"3. WHO Classification",
"4. Clinical Manifestations",
"5. Diagnosis & WHO Criteria",
"6. Investigations",
"7. Treatment Approach",
"8. Prognosis & Summary",
];
// Two-column cards
const colors = [C.navy, C.maroon, C.slate, C.accent];
topics.forEach((t, i) => {
const col = i < 4 ? 0 : 1;
const row = i % 4;
const cx = col === 0 ? 0.3 : 5.2;
const cy = 1.25 + row * 0.95;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: cy, w: 4.6, h: 0.78,
fill: { color: colors[row] }, line: { color: colors[row] }, rectRadius: 0.08
});
s.addText(t, {
x: cx + 0.15, y: cy + 0.05, w: 4.3, h: 0.68,
fontSize: 14.5, bold: true, color: C.white, fontFace: "Calibri", valign: "middle", margin: 0
});
});
}
// ── SLIDE 3: Definition & Epidemiology ──────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Definition & Epidemiology", "WHO 5th Edition Classification Framework");
// Definition box
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 1.25, w: 9.4, h: 1.1,
fill: { color: C.navy }, line: { color: C.navy }, rectRadius: 0.08
});
s.addText("Mastocytosis is a heterogeneous group of disorders characterized by pathologic accumulation of clonally expanded mast cells in tissues, including skin and bone marrow.", {
x: 0.5, y: 1.3, w: 9.0, h: 1.0,
fontSize: 14, color: C.white, fontFace: "Calibri", valign: "middle", italic: true, margin: 0
});
// Key facts in colored cards
const facts = [
{ label: "Prevalence", val: "~1 in 10,000\nin general population" },
{ label: "Age of Onset", val: "Any age; peak in\ninfancy & young adulthood" },
{ label: "KIT D816V", val: ">90% of adults\n~40% of children" },
{ label: "Familial", val: "Rare; mostly\nsporadic occurrence" },
];
facts.forEach((f, i) => {
const cx = 0.3 + i * 2.38;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: 2.55, w: 2.2, h: 1.55,
fill: { color: C.white }, line: { color: C.navy, pt: 1.5 }, rectRadius: 0.08,
shadow: { type: "outer", color: "000000", blur: 5, offset: 2, angle: 135, opacity: 0.12 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: cx, y: 2.55, w: 2.2, h: 0.38,
fill: { color: C.maroon }, line: { color: C.maroon }
});
s.addText(f.label, {
x: cx + 0.05, y: 2.56, w: 2.1, h: 0.36,
fontSize: 11, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addText(f.val, {
x: cx + 0.05, y: 2.96, w: 2.1, h: 1.1,
fontSize: 12, color: C.textDark, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
});
s.addText("Source: Harrison's Principles of Internal Medicine 22E; Goldman-Cecil Medicine", {
x: 0.3, y: 5.2, w: 9.4, h: 0.3,
fontSize: 9, color: C.textGray, italic: true, fontFace: "Calibri"
});
}
// ── SLIDE 4: Pathobiology ────────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Pathobiology & KIT Mutations", "Molecular drivers of mast cell proliferation");
// Left column
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 1.25, w: 4.4, h: 3.8,
fill: { color: C.navy }, line: { color: C.navy }, rectRadius: 0.1
});
s.addText("KIT Receptor Pathway", {
x: 0.4, y: 1.3, w: 4.2, h: 0.45,
fontSize: 14.5, bold: true, color: C.gold, fontFace: "Calibri", align: "center", margin: 0
});
addBullets(s, [
{ text: "KIT = transmembrane tyrosine kinase receptor", bold: false },
{ text: "Extracellular domain binds stem cell factor (SCF)" },
{ text: "SCF–KIT interaction drives mast cell growth & differentiation" },
{ text: "D816V mutation → ligand-independent autophosphorylation" },
{ text: "Net result: defective apoptosis → mast cell accumulation" },
{ text: "Advanced SM: co-mutations in TET2, SRSF2, ASXL1, RUNX1", bold: false },
], { x: 0.45, y: 1.8, w: 4.15, h: 3.1, fontSize: 13, color: C.white });
// Right column
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 5.1, y: 1.25, w: 4.6, h: 3.8,
fill: { color: C.white }, line: { color: C.navy, pt: 1.5 }, rectRadius: 0.1,
shadow: { type: "outer", color: "000000", blur: 5, offset: 2, angle: 135, opacity: 0.12 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: 5.1, y: 1.25, w: 4.6, h: 0.48,
fill: { color: C.maroon }, line: { color: C.maroon }
});
s.addText("Mediators Released by Mast Cells", {
x: 5.15, y: 1.26, w: 4.5, h: 0.46,
fontSize: 13, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
addBullets(s, [
{ text: "Preformed (granule-stored):", bold: true },
{ text: "Histamine, Tryptase, Chymase, Carboxypeptidase A, Heparin", indent: true },
{ text: "De novo synthesized:", bold: true },
{ text: "Prostaglandin D2, Leukotriene C4 (LTC4)", indent: true },
{ text: "Cytokines:", bold: true },
{ text: "TNF-α, IL-6 → fatigue, osteoporosis", indent: true },
{ text: "Serum tryptase: marker of mast cell burden", bold: false, color: C.crimson },
], { x: 5.2, y: 1.82, w: 4.4, h: 3.15, fontSize: 13, color: C.textDark });
}
// ── SLIDE 5: WHO Classification ──────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "WHO Classification of Mastocytosis (2022)", "5th Edition – Myeloid Neoplasms");
const cats = [
{ name: "Cutaneous Mastocytosis (CM)", note: "Skin only; no internal organs", color: "3A7BD5" },
{ name: "Indolent SM (ISM)", note: ">70% of adult SM; normal life expectancy", color: "27AE60" },
{ name: "Bone Marrow Mastocytosis", note: "BM involved; no skin lesions", color: "8E44AD" },
{ name: "Smoldering SM (SSM)", note: "BM infiltration >30%; tryptase >200 ng/mL", color: C.gold },
{ name: "SM with Assoc. Hematologic Neoplasm (SM-AHN)", note: "Previously SM-AHNMD", color: C.maroon },
{ name: "Aggressive SM (ASM)", note: "Organ dysfunction (C-findings)", color: "E67E22" },
{ name: "Mast Cell Leukemia (MCL)", note: "≥20% mast cells in BM aspirate", color: C.crimson },
{ name: "Mast Cell Sarcoma (MCS)", note: "Rare; destructive extracutaneous tumor", color: "2C3E50" },
];
cats.forEach((c, i) => {
const col = i < 4 ? 0 : 1;
const row = i % 4;
const cx = col === 0 ? 0.25 : 5.15;
const cy = 1.2 + row * 1.05;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: cy, w: 4.7, h: 0.9,
fill: { color: C.white }, line: { color: c.color, pt: 2 }, rectRadius: 0.07,
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.1 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: cx, y: cy, w: 0.12, h: 0.9,
fill: { color: c.color }, line: { color: c.color }
});
s.addText(c.name, {
x: cx + 0.2, y: cy + 0.06, w: 4.4, h: 0.38,
fontSize: 12.5, bold: true, color: C.textDark, fontFace: "Calibri", valign: "top", margin: 0
});
s.addText(c.note, {
x: cx + 0.2, y: cy + 0.48, w: 4.4, h: 0.35,
fontSize: 11, color: C.textGray, fontFace: "Calibri", italic: true, valign: "top", margin: 0
});
});
}
// ── SLIDE 6: Clinical Manifestations ─────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Clinical Manifestations", "Driven by mediator release AND tissue infiltration");
const systems = [
{ sys: "Skin", items: "Urticaria pigmentosa (MPCM)\nDarier sign (urtication on stroking)\nFlushing, pruritus", color: C.maroon },
{ sys: "Cardiovascular", items: "Vasodilation → flushing\nTachycardia, hypotension\nPresyncope/syncope, anaphylaxis", color: C.accent },
{ sys: "GI Tract", items: "Gastric acid hypersecretion (peptic ulcers)\nDiarrhea, abdominal pain\nMalabsorption (advanced SM)", color: "27AE60" },
{ sys: "Musculoskeletal", items: "Osteoporosis (TNF-α, IL-6)\nOsteosclerosis or osteolysis\nBone pain, pathologic fractures", color: "8E44AD" },
{ sys: "Neuropsychiatric", items: "Fatigue, cognitive impairment\nHeadache, irritability\nDepression (mediator-related)", color: "E67E22" },
{ sys: "Hematologic (Advanced)", items: "Splenomegaly, hepatomegaly\nCytopenias, leukocytosis\nAscites (portal hypertension)", color: C.crimson },
];
systems.forEach((sys, i) => {
const col = i % 3;
const row = Math.floor(i / 3);
const cx = 0.2 + col * 3.27;
const cy = 1.2 + row * 2.1;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: cy, w: 3.1, h: 1.92,
fill: { color: C.white }, line: { color: sys.color, pt: 2 }, rectRadius: 0.08,
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.1 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: cx, y: cy, w: 3.1, h: 0.45,
fill: { color: sys.color }, line: { color: sys.color }
});
s.addText(sys.sys, {
x: cx + 0.1, y: cy + 0.05, w: 2.9, h: 0.38,
fontSize: 13, bold: true, color: C.white, fontFace: "Calibri", valign: "middle", align: "center", margin: 0
});
s.addText(sys.items, {
x: cx + 0.1, y: cy + 0.5, w: 2.9, h: 1.38,
fontSize: 11.5, color: C.textDark, fontFace: "Calibri", valign: "top", margin: 0
});
});
s.addText("Key trigger: NSAIDs, opioids, alcohol, contrast media, insect stings → mast cell degranulation → anaphylaxis", {
x: 0.3, y: 5.25, w: 9.4, h: 0.28,
fontSize: 10.5, color: C.maroon, bold: true, fontFace: "Calibri", italic: true
});
}
// ── SLIDE 7: Diagnosis & WHO Criteria ────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Diagnosis of Systemic Mastocytosis", "WHO Diagnostic Criteria — 1 Major + 1 Minor OR 3 Minor");
// Major criterion
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 1.2, w: 9.4, h: 1.05,
fill: { color: C.navy }, line: { color: C.navy }, rectRadius: 0.08
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 1.2, w: 1.2, h: 1.05,
fill: { color: C.gold }, line: { color: C.gold }, rectRadius: 0.08
});
s.addText("MAJOR", {
x: 0.35, y: 1.2, w: 1.1, h: 1.05,
fontSize: 16, bold: true, color: C.navy, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addText("Multifocal dense mast cell infiltrates (≥15 mast cells) in bone marrow and/or extracutaneous organs, confirmed on tryptase-immunostaining", {
x: 1.65, y: 1.28, w: 7.8, h: 0.9,
fontSize: 13.5, color: C.white, fontFace: "Calibri", valign: "middle", margin: 0
});
// Minor criteria
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 2.42, w: 0.85, h: 2.6,
fill: { color: C.maroon }, line: { color: C.maroon }, rectRadius: 0.08
});
s.addText("MINOR\nCriteria", {
x: 0.3, y: 2.42, w: 0.85, h: 2.6,
fontSize: 11, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
const minors = [
{ label: "1", text: "≥25% of mast cells in BM biopsy are spindle-shaped or atypical morphology in smears" },
{ label: "2", text: "KIT D816V mutation in blood, BM, or other extracutaneous organs" },
{ label: "3", text: "Mast cells co-express CD117 with CD2 and/or CD25 (aberrant immunophenotype)" },
{ label: "4", text: "Baseline serum tryptase persistently >20 ng/mL (not applicable if SM-AHN present)" },
];
minors.forEach((m, i) => {
const cy = 2.42 + i * 0.63;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 1.3, y: cy + 0.05, w: 8.4, h: 0.55,
fill: { color: C.white }, line: { color: C.maroon, pt: 1.5 }, rectRadius: 0.06
});
s.addText(m.label, {
x: 1.3, y: cy + 0.05, w: 0.38, h: 0.55,
fontSize: 14, bold: true, color: C.maroon, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addText(m.text, {
x: 1.72, y: cy + 0.08, w: 7.9, h: 0.48,
fontSize: 12, color: C.textDark, fontFace: "Calibri", valign: "middle", margin: 0
});
});
}
// ── SLIDE 8: B and C Findings ─────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "B & C Findings — Staging Advanced SM", "Critical for distinguishing ISM/SSM from ASM");
// B-findings
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: 1.18, w: 4.6, h: 3.75,
fill: { color: C.white }, line: { color: C.accent, pt: 2 }, rectRadius: 0.1,
shadow: { type: "outer", color: "000000", blur: 5, offset: 2, angle: 135, opacity: 0.12 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: 0.25, y: 1.18, w: 4.6, h: 0.5,
fill: { color: C.accent }, line: { color: C.accent }
});
s.addText("B FINDINGS (High Mast Cell Burden)", {
x: 0.3, y: 1.19, w: 4.5, h: 0.48,
fontSize: 13, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addText("≥2 = Smoldering SM", {
x: 0.3, y: 1.72, w: 4.5, h: 0.3,
fontSize: 11.5, color: C.accent, fontFace: "Calibri", bold: true, italic: true, margin: 0
});
addBullets(s, [
"BM biopsy: >30% mast cell infiltration + serum tryptase >200 ng/mL",
"Hypercellular BM ± loss of fat cells; discrete mast cell clusters in BM",
"Hepatomegaly (no impairment), splenomegaly, lymphadenopathy",
"Blood dyscrasia: e.g. dysplastic features, not meeting AHN criteria",
], { x: 0.4, y: 2.05, w: 4.3, h: 2.8, fontSize: 12.5, color: C.textDark });
// C-findings
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 5.15, y: 1.18, w: 4.6, h: 3.75,
fill: { color: C.white }, line: { color: C.crimson, pt: 2 }, rectRadius: 0.1,
shadow: { type: "outer", color: "000000", blur: 5, offset: 2, angle: 135, opacity: 0.12 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: 5.15, y: 1.18, w: 4.6, h: 0.5,
fill: { color: C.crimson }, line: { color: C.crimson }
});
s.addText("C FINDINGS (Organ Dysfunction)", {
x: 5.2, y: 1.19, w: 4.5, h: 0.48,
fontSize: 13, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addText("≥1 = Aggressive SM", {
x: 5.2, y: 1.72, w: 4.5, h: 0.3,
fontSize: 11.5, color: C.crimson, fontFace: "Calibri", bold: true, italic: true, margin: 0
});
addBullets(s, [
"BM dysfunction: ANC <1000/μL, Hgb <10 g/dL, or platelets <100,000/μL",
"Palpable hepatomegaly with impaired liver function, ascites, portal hypertension",
"Palpable splenomegaly with hypersplenism",
"Malabsorption with weight loss and hypoalbuminemia",
"Skeletal: large osteolytic lesions and/or pathologic fractures",
], { x: 5.25, y: 2.05, w: 4.35, h: 2.8, fontSize: 12.5, color: C.textDark });
}
// ── SLIDE 9: Investigations ───────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Investigations", "Laboratory, Imaging & Pathology Workup");
const groups = [
{ title: "Laboratory Tests", color: C.navy, items: [
"Serum tryptase (baseline) — >20 ng/mL is minor criterion",
"CBC with differential — cytopenia in advanced SM",
"24-h urine: 5-HIAA (exclude carcinoid), metanephrines (pheo)",
"LFTs, alkaline phosphatase, serum albumin",
"Histamine metabolites (N-methylhistamine in urine)",
]},
{ title: "Molecular / Genetic", color: C.maroon, items: [
"KIT D816V mutation — BM or peripheral blood (allele-specific PCR preferred)",
"Flow cytometry: CD2/CD25 co-expression on mast cells",
"NGS: additional mutations (TET2, SRSF2, ASXL1, RUNX1) in advanced SM",
"Hereditary alpha-tryptasemia: TPSAB1 copy number",
]},
{ title: "Bone Marrow Studies", color: "8E44AD", items: [
"Core biopsy: tryptase + CD117 immunostaining (gold standard)",
"Aspirate smear: spindle-shaped / atypical mast cells",
"% mast cell infiltration (critical for B & C findings)",
]},
{ title: "Imaging", color: "27AE60", items: [
"DEXA scan: bone density (osteoporosis assessment)",
"Skeletal survey or CT: osteolytic/osteosclerotic lesions",
"Abdominal CT/ultrasound: hepatosplenomegaly, lymphadenopathy",
"PET-CT in suspected mast cell leukemia",
]},
];
groups.forEach((g, i) => {
const col = i % 2;
const row = Math.floor(i / 2);
const cx = col === 0 ? 0.25 : 5.15;
const cy = 1.18 + row * 2.1;
const h = row === 0 ? 1.95 : 1.9;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: cy, w: 4.65, h: h,
fill: { color: C.white }, line: { color: g.color, pt: 1.5 }, rectRadius: 0.08,
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.1 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: cx, y: cy, w: 4.65, h: 0.42,
fill: { color: g.color }, line: { color: g.color }
});
s.addText(g.title, {
x: cx + 0.1, y: cy + 0.04, w: 4.45, h: 0.38,
fontSize: 13, bold: true, color: C.white, fontFace: "Calibri", valign: "middle", align: "center", margin: 0
});
const textArr = g.items.map((it, idx) => ({
text: it,
options: { bullet: true, fontSize: 11.5, color: C.textDark, breakLine: idx < g.items.length - 1 }
}));
s.addText(textArr, {
x: cx + 0.1, y: cy + 0.46, w: 4.45, h: h - 0.52,
fontFace: "Calibri", valign: "top"
});
});
}
// ── SLIDE 10: Treatment ───────────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Treatment Approach", "Stepwise Symptom-Directed + Targeted Therapy");
// Step ladder for symptom control
const steps = [
{ step: "Step 1", text: "H1 antihistamines — flushing, pruritus, urticaria", color: "3A7BD5" },
{ step: "Step 2", text: "H2 antihistamines / PPI — gastric acid hypersecretion, peptic disease", color: "27AE60" },
{ step: "Step 3", text: "Oral cromolyn sodium — diarrhea, abdominal pain, malabsorption", color: "8E44AD" },
{ step: "Step 4", text: "Aspirin (NSAID-tolerant patients only) — severe flushing; blocks PGD2 synthesis", color: "E67E22" },
{ step: "Step 5", text: "Systemic glucocorticoids — malabsorption in advanced disease", color: C.maroon },
];
steps.forEach((st, i) => {
const cy = 1.2 + i * 0.72;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: cy, w: 1.0, h: 0.6,
fill: { color: st.color }, line: { color: st.color }, rectRadius: 0.06
});
s.addText(st.step, {
x: 0.25, y: cy, w: 1.0, h: 0.6,
fontSize: 12, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle", margin: 0
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 1.38, y: cy + 0.04, w: 6.1, h: 0.52,
fill: { color: C.white }, line: { color: st.color, pt: 1.5 }, rectRadius: 0.06
});
s.addText(st.text, {
x: 1.5, y: cy + 0.04, w: 5.95, h: 0.52,
fontSize: 12.5, color: C.textDark, fontFace: "Calibri", valign: "middle", margin: 0
});
});
// Advanced therapy box
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: 4.82, w: 7.62, h: 0.0 // will be defined below properly
});
// Epinephrine box
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 7.65, y: 1.18, w: 2.1, h: 3.62,
fill: { color: C.navy }, line: { color: C.navy }, rectRadius: 0.1
});
s.addText("Emergency\nPreparedness", {
x: 7.7, y: 1.22, w: 2.0, h: 0.7,
fontSize: 12.5, bold: true, color: C.gold, fontFace: "Calibri", align: "center", margin: 0
});
addBullets(s, [
{ text: "Self-injectable epinephrine (EpiPen) — ALL patients" },
{ text: "Venom immunotherapy if Hymenoptera sensitivity" },
{ text: "Avoid triggers: opioids, contrast dye, NSAIDs (if intolerant), alcohol" },
], { x: 7.7, y: 1.95, w: 1.95, h: 2.7, fontSize: 11, color: C.white });
// Advanced therapy
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: 4.85, w: 9.5, h: 0.65,
fill: { color: C.maroon }, line: { color: C.maroon }, rectRadius: 0.08
});
s.addText("Advanced SM: Avapritinib (KIT D816V inhibitor — 1st-line for ASM/MCL & refractory ISM) | Midostaurin | Cladribine | IFN-α | Stem cell transplantation", {
x: 0.35, y: 4.88, w: 9.3, h: 0.6,
fontSize: 12, bold: true, color: C.white, fontFace: "Calibri", valign: "middle", margin: 0
});
}
// ── SLIDE 11: Prognosis ───────────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite }, line: { color: C.offWhite } });
addSlideTitle(s, "Prognosis & Disease Variants", "Spectrum from benign to aggressive disease");
const variants = [
{ type: "ISM", prog: "Normal life expectancy", note: "Most common (>70% adults). Rare transformation to advanced SM.", color: "27AE60", icon: "●●●●●" },
{ type: "SSM", prog: "Intermediate prognosis", note: "High mast cell burden; monitor for progression.", color: "F39C12", icon: "●●●●○" },
{ type: "BM Mastocytosis", prog: "Good prognosis", note: "Bone marrow involved, no skin lesions, no organ dysfunction.", color: "3A7BD5", icon: "●●●●●" },
{ type: "SM-AHN", prog: "Determined by AHN type", note: "Prognosis driven by the associated hematologic neoplasm.", color: "8E44AD", icon: "●●●○○" },
{ type: "ASM", prog: "Poor; median survival years", note: "Organ dysfunction (C-findings). Requires cytoreduction.", color: "E67E22", icon: "●●○○○" },
{ type: "MCL", prog: "Very poor; months", note: "≥20% mast cells in BM aspirate. Leukemic transformation.", color: C.crimson, icon: "●○○○○" },
];
variants.forEach((v, i) => {
const col = i % 2;
const row = Math.floor(i / 2);
const cx = col === 0 ? 0.25 : 5.15;
const cy = 1.18 + row * 1.44;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: cx, y: cy, w: 4.65, h: 1.28,
fill: { color: C.white }, line: { color: v.color, pt: 2 }, rectRadius: 0.08,
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.1 }
});
s.addShape(pres.shapes.RECTANGLE, {
x: cx, y: cy, w: 0.12, h: 1.28,
fill: { color: v.color }, line: { color: v.color }
});
s.addText(v.type, {
x: cx + 0.2, y: cy + 0.08, w: 2.5, h: 0.35,
fontSize: 14, bold: true, color: v.color, fontFace: "Calibri", margin: 0
});
s.addText(v.icon, {
x: cx + 2.75, y: cy + 0.08, w: 1.75, h: 0.35,
fontSize: 11, color: v.color, fontFace: "Calibri", align: "right", margin: 0
});
s.addText(v.prog, {
x: cx + 0.2, y: cy + 0.46, w: 4.3, h: 0.32,
fontSize: 12.5, bold: true, color: C.textDark, fontFace: "Calibri", margin: 0
});
s.addText(v.note, {
x: cx + 0.2, y: cy + 0.8, w: 4.3, h: 0.4,
fontSize: 11, color: C.textGray, fontFace: "Calibri", italic: true, margin: 0
});
});
}
// ── SLIDE 12: Summary / Closing ───────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy }, line: { color: C.navy } });
s.addShape(pres.shapes.RECTANGLE, { x: 6.5, y: 0, w: 3.5, h: 5.625, fill: { color: C.maroon }, line: { color: C.maroon } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 5.35, w: 6.5, h: 0.275, fill: { color: C.gold }, line: { color: C.gold } });
s.addText("Key Takeaways", {
x: 0.5, y: 0.3, w: 5.7, h: 0.65,
fontSize: 28, bold: true, color: C.white, fontFace: "Calibri", charSpacing: 2, margin: 0
});
s.addShape(pres.shapes.RECTANGLE, { x: 0.5, y: 0.95, w: 1.8, h: 0.05, fill: { color: C.gold }, line: { color: C.gold } });
const pts = [
"SM = clonal mast cell neoplasm driven by KIT D816V mutation (>90% adults)",
"WHO 2022 classifies 8 types: from cutaneous to mast cell leukemia",
"Diagnosis: 1 major OR 3 minor WHO criteria confirmed on bone marrow biopsy",
"Serum tryptase is the primary biomarker for mast cell burden",
"ISM (most common) carries normal life expectancy; ASM and MCL are aggressive",
"Symptom control: H1/H2 antihistamines, PPI, cromolyn, epinephrine (all patients)",
"Advanced SM: Avapritinib (KIT D816V inhibitor) is now 1st-line targeted therapy",
];
pts.forEach((p, i) => {
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.35, y: 1.1 + i * 0.6, w: 5.9, h: 0.52,
fill: { color: "FFFFFF", transparency: 88 }, line: { color: C.gold, pt: 0.8 }, rectRadius: 0.05
});
s.addText(`${i + 1}. ${p}`, {
x: 0.45, y: 1.12 + i * 0.6, w: 5.7, h: 0.48,
fontSize: 11.5, color: C.white, fontFace: "Calibri", valign: "middle", margin: 0
});
});
s.addText("Systemic\nMastocytosis", {
x: 6.65, y: 1.2, w: 3.1, h: 1.0,
fontSize: 22, bold: true, color: C.white, fontFace: "Calibri", align: "center", charSpacing: 1
});
s.addText("KIT D816V", {
x: 6.65, y: 2.35, w: 3.1, h: 0.55,
fontSize: 32, bold: true, color: C.gold, fontFace: "Calibri", align: "center", margin: 0
});
s.addText("Targeted Therapy\nEra", {
x: 6.65, y: 3.05, w: 3.1, h: 0.8,
fontSize: 18, color: C.white, fontFace: "Calibri", align: "center", italic: true
});
s.addText("Harrison's 22E | Goldman-Cecil Medicine", {
x: 6.65, y: 4.5, w: 3.1, h: 0.4,
fontSize: 9.5, color: "A0AEC0", fontFace: "Calibri", align: "center", italic: true
});
}
// ── Write file ────────────────────────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/systemic-mastocytosis-ppt/Systemic_Mastocytosis.pptx" })
.then(() => console.log("✅ Done: Systemic_Mastocytosis.pptx created successfully"))
.catch(e => { console.error("Error:", e); process.exit(1); });
cd /home/daytona/workspace/systemic-mastocytosis-ppt && node create_ppt.js
ls -lh /home/daytona/workspace/systemic-mastocytosis-ppt/
Systemic Mastocytosis
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide — bold visual design |
| 2 | Overview / Agenda — 8-topic roadmap cards |
| 3 | Definition & Epidemiology — prevalence, age, KIT D816V stats |
| 4 | Pathobiology & KIT Mutations — receptor pathway, D816V, co-mutations (TET2, SRSF2), mediator release table |
| 5 | WHO 2022 Classification — all 8 categories (ISM through MCS) with color-coded cards |
| 6 | Clinical Manifestations — 6 organ system cards (skin, CV, GI, MSK, neuropsychiatric, hematologic) |
| 7 | Diagnosis & WHO Criteria — 1 major + 4 minor criteria clearly formatted |
| 8 | B & C Findings — distinguishing Smoldering SM vs Aggressive SM |
| 9 | Investigations — lab tests, molecular/genetic testing, bone marrow studies, imaging |
| 10 | Treatment — 5-step symptom ladder + emergency preparedness + advanced therapy (avapritinib, midostaurin) |
| 11 | Prognosis by Variant — 6-card comparison from ISM (normal life expectancy) to MCL (very poor) |
| 12 | Summary / Key Takeaways — 7 high-yield points on dark background |
Can you make pdf with attachment of picture
~/systemic-mastocytosis-ppt/create_pdf.py
#!/usr/bin/env python3
"""
Systemic Mastocytosis - Comprehensive PDF with Medical Images
Sources: Harrison's 22E, Goldman-Cecil Medicine, Fitzpatrick's Dermatology
"""
import urllib.request
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
Image, HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from io import BytesIO
# ── Colors ───────────────────────────────────────────────────────────────────
NAVY = colors.HexColor("#0D1B3E")
MAROON = colors.HexColor("#8B1A2E")
GOLD = colors.HexColor("#D4A843")
SLATE = colors.HexColor("#2C3E6B")
ACCENT = colors.HexColor("#3A7BD5")
GREEN = colors.HexColor("#27AE60")
ORANGE = colors.HexColor("#E67E22")
CRIMSON = colors.HexColor("#C0392B")
LTBLUE = colors.HexColor("#EAF1FB")
LTGOLD = colors.HexColor("#FFF8E7")
WHITE = colors.white
LGRAY = colors.HexColor("#F5F7FA")
DGRAY = colors.HexColor("#4A5568")
DARK = colors.HexColor("#1A1A2E")
W, H = A4
MARGIN = 1.8 * cm
# ── Download images ───────────────────────────────────────────────────────────
IMAGES = {
"urticaria": "https://cdn.orris.care/cdss_images/61441e0536d7b9e7288260bc00c28a77227375e75b31d02ab087a1577c25d74c.png",
"bm_biopsy": "https://cdn.orris.care/cdss_images/58c585de8ecd96f854e1fdebf8df2638be7d91df51d8de930459a8387c1246e0.png",
"tryptase_stain": "https://cdn.orris.care/cdss_images/ce35910c82ae313d1592856e41dd76db168f8e060a6c0acaa01a9d5e4495ed26.png",
"flowchart": "https://cdn.orris.care/cdss_images/8b397c638c375ac634909fbcda3e7372670ccced25da09464cf8f0cb52cfa278.png",
}
img_paths = {}
os.makedirs("/home/daytona/workspace/systemic-mastocytosis-ppt/img_cache", exist_ok=True)
for key, url in IMAGES.items():
dest = f"/home/daytona/workspace/systemic-mastocytosis-ppt/img_cache/{key}.png"
if not os.path.exists(dest):
try:
urllib.request.urlretrieve(url, dest)
print(f" Downloaded {key}")
except Exception as e:
print(f" WARN: Could not download {key}: {e}")
dest = None
if dest and os.path.exists(dest):
img_paths[key] = dest
print("Images ready:", list(img_paths.keys()))
# ── Style sheet ───────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def make_style(name, parent="Normal", **kw):
s = ParagraphStyle(name, parent=styles[parent], **kw)
return s
S_title = make_style("S_title", fontSize=28, textColor=WHITE, fontName="Helvetica-Bold",
leading=34, spaceAfter=4, alignment=TA_CENTER)
S_subtitle = make_style("S_subtitle", fontSize=13, textColor=GOLD, fontName="Helvetica-Oblique",
leading=18, alignment=TA_CENTER)
S_h1 = make_style("S_h1", fontSize=15, textColor=WHITE, fontName="Helvetica-Bold",
leading=20, spaceBefore=6, spaceAfter=4)
S_h2 = make_style("S_h2", fontSize=12, textColor=NAVY, fontName="Helvetica-Bold",
leading=16, spaceBefore=8, spaceAfter=3)
S_body = make_style("S_body", fontSize=10, textColor=DARK, fontName="Helvetica",
leading=15, spaceAfter=4, alignment=TA_JUSTIFY)
S_bullet = make_style("S_bullet", fontSize=10, textColor=DARK, fontName="Helvetica",
leading=14, spaceAfter=2, leftIndent=14, firstLineIndent=-10)
S_caption = make_style("S_caption", fontSize=8.5, textColor=DGRAY, fontName="Helvetica-Oblique",
leading=12, alignment=TA_CENTER, spaceAfter=4)
S_ref = make_style("S_ref", fontSize=8, textColor=DGRAY, fontName="Helvetica",
leading=11, spaceAfter=2)
S_badge = make_style("S_badge", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
leading=12, alignment=TA_CENTER)
S_key = make_style("S_key", fontSize=10.5, textColor=DARK, fontName="Helvetica-Bold",
leading=14, spaceAfter=3)
S_val = make_style("S_val", fontSize=10, textColor=DARK, fontName="Helvetica",
leading=14, spaceAfter=3)
# ── Helpers ───────────────────────────────────────────────────────────────────
def bullet(text, color=NAVY):
return Paragraph(f'<font color="#{color.hexval()[2:]}">•</font> {text}', S_bullet)
def hline(c=GOLD, thickness=1.5):
return HRFlowable(width="100%", thickness=thickness, color=c, spaceAfter=6, spaceBefore=2)
def spacer(h=0.3):
return Spacer(1, h * cm)
def section_header(title, bg=NAVY):
"""A colored bar with white title text."""
data = [[Paragraph(title, S_h1)]]
t = Table(data, colWidths=[W - 2 * MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0), (-1,-1), 6),
("ROUNDEDCORNERS", [4]),
]))
return t
def colored_box(content_rows, bg=LTBLUE, border=NAVY):
t = Table([[r] for r in content_rows], colWidths=[W - 2 * MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1.2, border),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
]))
return t
def two_col_table(rows, col_colors=None):
"""Two-column key-value table."""
data = []
for k, v in rows:
data.append([Paragraph(k, S_key), Paragraph(v, S_val)])
cw = [(W - 2*MARGIN) * 0.38, (W - 2*MARGIN) * 0.62]
t = Table(data, colWidths=cw)
style = [
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("ROWBACKGROUNDS", (0,0), (-1,-1), [LGRAY, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, colors.HexColor("#CBD5E0")),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#E2E8F0")),
]
t.setStyle(TableStyle(style))
return t
def criteria_table(major, minors):
"""WHO criteria table with major + minor rows."""
data = [
[Paragraph("CRITERION", make_style("_ch", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("DETAILS", make_style("_cd", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12))],
[Paragraph("MAJOR", make_style("_cm", fontSize=10, textColor=WHITE,
fontName="Helvetica-Bold", leading=13, alignment=TA_CENTER)),
Paragraph(major, S_body)],
]
for i, m in enumerate(minors, 1):
data.append([
Paragraph(f"Minor {i}", make_style(f"_mn{i}", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=13, alignment=TA_CENTER)),
Paragraph(m, S_body),
])
cw = [2.5*cm, W - 2*MARGIN - 2.5*cm]
t = Table(data, colWidths=cw)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), SLATE),
("BACKGROUND", (0,1), (0,1), MAROON),
("BACKGROUND", (0,2), (0,-1), colors.HexColor("#6B4C5A")),
("BACKGROUND", (1,1), (1,-1), WHITE),
("ROWBACKGROUNDS", (1,2), (1,-1), [WHITE, LGRAY]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (0,-1), "CENTER"),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0), (-1,-1), 6),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#CBD5E0")),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
]))
return t
def who_class_table():
headers = ["WHO Category", "Key Features", "Prognosis"]
rows = [
["Cutaneous Mastocytosis (CM)", "Skin only; no internal organ involvement", "Excellent"],
["Indolent SM (ISM)", ">70% adults; no organ dysfunction or AHN", "Normal life expectancy"],
["Bone Marrow Mastocytosis", "BM involved; no skin lesions; no C findings", "Good"],
["Smoldering SM (SSM)", "BM >30%, tryptase >200 ng/mL (B findings ≥2)", "Intermediate"],
["SM with AHN (SM-AHN)", "Associated hematologic neoplasm (MDS, MPN)", "Per AHN type"],
["Aggressive SM (ASM)", "C findings (organ dysfunction present)", "Poor"],
["Mast Cell Leukemia (MCL)", "≥20% mast cells in BM aspirate smears", "Very poor"],
["Mast Cell Sarcoma (MCS)", "Rare; invasive extracutaneous tumor", "Very poor"],
]
row_colors = [NAVY, LTBLUE, LGRAY, LTBLUE, LGRAY, LTBLUE, LGRAY, LTBLUE]
data = [[Paragraph(h, make_style("_wh", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)) for h in headers]]
for r in rows:
data.append([Paragraph(c, S_body) for c in r])
cw_total = W - 2*MARGIN
cw = [cw_total*0.32, cw_total*0.46, cw_total*0.22]
t = Table(data, colWidths=cw)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LTBLUE, WHITE]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
return t
def treatment_table():
rows = [
("H1 Antihistamines", "Flushing, pruritus, urticaria", "Cetirizine, fexofenadine, hydroxyzine", ACCENT),
("H2 Antihistamines / PPI", "Gastric acid hypersecretion, peptic symptoms", "Ranitidine, famotidine, omeprazole", GREEN),
("Oral Cromolyn Sodium", "Diarrhea, abdominal pain, malabsorption", "Oral cromolyn 200 mg QID", colors.HexColor("#8E44AD")),
("Aspirin (if NSAID-tolerant)", "Severe flushing (blocks PGD2)", "Low-dose ASA; confirm NSAID tolerance first", ORANGE),
("Systemic Corticosteroids", "Severe malabsorption (advanced SM)", "Short courses; monitor bone density", MAROON),
("Self-Injectable Epinephrine", "Anaphylaxis prevention (ALL patients)", "EpiPen/Auvi-Q — carry at all times", CRIMSON),
]
header = ["Drug Class", "Indication", "Notes"]
data = [[Paragraph(h, make_style("_th", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)) for h in header]]
for drug, ind, note, col in rows:
data.append([
Paragraph(f'<font color="#{col.hexval()[2:]}"><b>{drug}</b></font>', S_body),
Paragraph(ind, S_body),
Paragraph(note, S_body),
])
cw_total = W - 2*MARGIN
cw = [cw_total*0.28, cw_total*0.36, cw_total*0.36]
t = Table(data, colWidths=cw)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), SLATE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGRAY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
return t
def add_image(path, width_cm=13.5, caption=None):
items = []
try:
img = Image(path, width=width_cm*cm, height=None)
img.hAlign = "CENTER"
items.append(img)
if caption:
items.append(Paragraph(caption, S_caption))
except Exception as e:
items.append(Paragraph(f"[Image: {caption or path}]", S_caption))
return items
def add_image_pair(path1, cap1, path2, cap2, each_width_cm=7.5):
"""Two images side by side."""
def make_img(path, cap, w):
try:
img = Image(path, width=w*cm, height=None)
return [img, Paragraph(cap, S_caption)]
except:
return [Paragraph(f"[Image unavailable]", S_caption)]
c1 = make_img(path1, cap1, each_width_cm)
c2 = make_img(path2, cap2, each_width_cm)
# Wrap in a 2-column table
data = [[c1, c2]]
# Flatten inner lists to single cells using nested tables
def wrap_col(items):
d = [[it] for it in items]
inner = Table(d, colWidths=[each_width_cm*cm])
inner.setStyle(TableStyle([
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN",(0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 2),
("RIGHTPADDING", (0,0), (-1,-1), 2),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING",(0,0), (-1,-1), 2),
]))
return inner
outer = Table([[wrap_col(c1), wrap_col(c2)]],
colWidths=[(W-2*MARGIN)*0.5, (W-2*MARGIN)*0.5])
outer.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
return outer
# ── Page background/header ────────────────────────────────────────────────────
def on_page(canvas, doc):
canvas.saveState()
# Bottom footer
canvas.setFillColor(NAVY)
canvas.rect(0, 0, W, 0.8*cm, fill=1, stroke=0)
canvas.setFillColor(GOLD)
canvas.setFont("Helvetica-Bold", 7)
canvas.drawString(MARGIN, 0.28*cm, "Systemic Mastocytosis — Clinical Reference")
canvas.setFont("Helvetica", 7)
canvas.drawRightString(W - MARGIN, 0.28*cm,
f"Sources: Harrison's 22E · Goldman-Cecil Medicine · Fitzpatrick's Dermatology | Page {doc.page}")
# Top accent line
canvas.setFillColor(GOLD)
canvas.rect(0, H - 0.15*cm, W, 0.15*cm, fill=1, stroke=0)
canvas.restoreState()
def on_first_page(canvas, doc):
"""Title page — full dark bg."""
canvas.saveState()
canvas.setFillColor(NAVY)
canvas.rect(0, 0, W, H, fill=1, stroke=0)
# Maroon right bar
canvas.setFillColor(MAROON)
canvas.rect(W*0.68, 0, W*0.32, H, fill=1, stroke=0)
# Gold bottom strip
canvas.setFillColor(GOLD)
canvas.rect(0, 0, W*0.68, 0.5*cm, fill=1, stroke=0)
canvas.restoreState()
# ── Build content ─────────────────────────────────────────────────────────────
story = []
# ========== TITLE PAGE ==========
title_pg_style = make_style("tpg", fontSize=36, textColor=WHITE, fontName="Helvetica-Bold",
leading=44, alignment=TA_LEFT, spaceAfter=6)
sub_pg_style = make_style("spg", fontSize=16, textColor=GOLD, fontName="Helvetica-Oblique",
leading=22, alignment=TA_LEFT, spaceAfter=8)
meta_style = make_style("meta", fontSize=10, textColor=colors.HexColor("#A0AEC0"),
fontName="Helvetica", leading=14, alignment=TA_LEFT)
story.append(spacer(4.5))
story.append(Paragraph("SYSTEMIC", title_pg_style))
story.append(Paragraph("MASTOCYTOSIS", make_style("t2", fontSize=36, textColor=GOLD,
fontName="Helvetica-Bold", leading=44, alignment=TA_LEFT)))
story.append(spacer(0.4))
story.append(Paragraph("A Comprehensive Clinical Reference", sub_pg_style))
story.append(HRFlowable(width="42%", thickness=2, color=GOLD, spaceAfter=10, spaceBefore=4))
story.append(Paragraph("Definition · Pathobiology · Classification · Diagnosis · Treatment", meta_style))
story.append(spacer(0.5))
story.append(Paragraph("Sources: Harrison's Principles of Internal Medicine 22E (2025) ·<br/>Goldman-Cecil Medicine (International Edition) · Fitzpatrick's Dermatology", meta_style))
story.append(PageBreak())
# ========== SECTION 1: Definition & Epidemiology ==========
story.append(section_header("1. Definition & Epidemiology"))
story.append(spacer(0.25))
story.append(colored_box([
Paragraph("Definition", S_h2),
Paragraph(
"Mastocytosis is a heterogeneous group of disorders characterized by pathologic accumulation of "
"<b>clonally expanded mast cells</b> in tissues, including skin and bone marrow. "
"<i>Systemic mastocytosis (SM)</i> refers to involvement of internal organs — most commonly bone marrow — "
"with or without skin disease.",
S_body),
], bg=LTBLUE, border=NAVY))
story.append(spacer(0.3))
story.append(two_col_table([
("<b>Prevalence</b>", "~1 in 10,000 in the general population; likely underdiagnosed"),
("<b>Age of onset</b>", "Any age; most commonly diagnosed in infancy and young adulthood"),
("<b>Ethnicity</b>", "Described in all ethnic populations; disease is predominantly sporadic"),
("<b>Familial occurrence</b>", "Rare; atopy is not increased compared with the general population"),
("<b>KIT D816V mutation</b>","Present in >90% of adults and ~40% of pediatric patients with mastocytosis"),
]))
story.append(spacer(0.4))
# ========== SECTION 2: Pathobiology ==========
story.append(section_header("2. Pathobiology & KIT Mutations", bg=SLATE))
story.append(spacer(0.25))
story.append(Paragraph("KIT Receptor & D816V Mutation", S_h2))
story.append(Paragraph(
"KIT encodes a transmembrane receptor tyrosine kinase. Binding of <b>stem cell factor (SCF)</b> to the "
"extracellular domain normally drives mast cell growth and differentiation. In mastocytosis, a somatic "
"<b>gain-of-function point mutation — KIT D816V (exon 17)</b> — leads to ligand-independent "
"autophosphorylation of the receptor, causing <b>defective apoptosis</b> and clonal mast cell accumulation.",
S_body))
story.append(spacer(0.2))
story.append(Paragraph("Co-mutations in Advanced SM", S_h2))
story.append(Paragraph(
"Advanced SM typically carries 3 or more mutations. Additional molecular aberrations include:",
S_body))
for gene in ["TET2", "SRSF2", "ASXL1", "CBL", "RUNX1", "DNMT3A"]:
story.append(bullet(f"<b>{gene}</b> — commonly identified in aggressive variants of SM"))
story.append(spacer(0.3))
story.append(Paragraph("Mast Cell Mediators Released", S_h2))
med_data = [
[Paragraph("Mediator Type", make_style("_mh", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("Examples", make_style("_mh2", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("Clinical Effects", make_style("_mh3", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12))],
[Paragraph("Preformed (granule-stored)", S_body),
Paragraph("Histamine, Tryptase, Chymase, Carboxypeptidase A, Heparin", S_body),
Paragraph("Pruritus, flushing, gastric acid hypersecretion, vasodilation", S_body)],
[Paragraph("De novo synthesized", S_body),
Paragraph("Prostaglandin D2, Leukotriene C4 (LTC4)", S_body),
Paragraph("Flushing, bronchoconstriction, vasodilation", S_body)],
[Paragraph("Cytokines", S_body),
Paragraph("TNF-α, IL-6", S_body),
Paragraph("Fatigue, accelerated osteoporosis", S_body)],
]
cw_total = W - 2*MARGIN
med_t = Table(med_data, colWidths=[cw_total*0.26, cw_total*0.38, cw_total*0.36])
med_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MAROON),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LGRAY, WHITE]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
story.append(med_t)
story.append(spacer(0.4))
# ========== SECTION 3: WHO Classification ==========
story.append(section_header("3. WHO Classification (2022)", bg=MAROON))
story.append(spacer(0.25))
story.append(Paragraph(
"The WHO 5th Edition (2022) classifies mastocytosis into <b>8 distinct categories</b>. The two broad "
"groups are <i>cutaneous mastocytosis</i> (skin only) and <i>systemic mastocytosis</i> (internal organs "
"involved). Mast cell sarcoma is classified separately.",
S_body))
story.append(spacer(0.2))
story.append(who_class_table())
story.append(spacer(0.4))
# ========== SECTION 4: Clinical Manifestations ==========
story.append(section_header("4. Clinical Manifestations"))
story.append(spacer(0.25))
story.append(Paragraph(
"Clinical features result from two mechanisms: <b>(1) mast cell mediator release</b> and "
"<b>(2) direct tissue infiltration</b>. Symptoms may be triggered by temperature changes, exercise, "
"alcohol, spicy foods, emotional stress, insect stings, opioids, NSAIDs, or contrast media.",
S_body))
story.append(spacer(0.25))
# Skin manifestations + image
story.append(Paragraph("Cutaneous Manifestations", S_h2))
story.append(Paragraph(
"<b>Urticaria pigmentosa (maculopapular cutaneous mastocytosis)</b> is the most common presentation. "
"Lesions are fixed, tan- to salmon-colored macules/papules on the trunk and extremities. "
"The <b>Darier sign</b> — urtication of lesional skin within minutes after rubbing — is pathognomonic. "
"Blistering can occur in children under 3 years.",
S_body))
story.append(spacer(0.2))
if "urticaria" in img_paths:
for item in add_image(img_paths["urticaria"], width_cm=9,
caption="Fig 1. Urticaria pigmentosa (maculopapular cutaneous mastocytosis) — "
"scattered reddish-brown macules on the trunk. (Source: Goldman-Cecil Medicine)"):
story.append(item)
story.append(spacer(0.3))
story.append(Paragraph("Systemic Manifestations by Organ", S_h2))
sys_data = [
[Paragraph("System", make_style("_sh", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("Manifestations", make_style("_sm", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", leading=12))],
[Paragraph("Cardiovascular", S_body),
Paragraph("Flushing, tachycardia, hypotension, presyncope/syncope, <b>anaphylaxis</b>", S_body)],
[Paragraph("Gastrointestinal", S_body),
Paragraph("Gastric acid hypersecretion (peptic ulcers), diarrhea, abdominal pain, malabsorption (advanced SM)", S_body)],
[Paragraph("Musculoskeletal", S_body),
Paragraph("Osteoporosis (TNF-α, IL-6 mediated), osteosclerosis/osteolysis, bone pain, pathologic fractures", S_body)],
[Paragraph("Neuropsychiatric", S_body),
Paragraph("Fatigue, headache, cognitive impairment, irritability, depression", S_body)],
[Paragraph("Hematologic\n(Advanced SM)", S_body),
Paragraph("Splenomegaly, hepatomegaly, cytopenias, leukocytosis, portal hypertension, ascites", S_body)],
]
sys_t = Table(sys_data, colWidths=[cw_total*0.22, cw_total*0.78])
sys_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), SLATE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGRAY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
story.append(sys_t)
story.append(spacer(0.4))
# ========== SECTION 5: Diagnosis ==========
story.append(section_header("5. Diagnosis — WHO Criteria", bg=MAROON))
story.append(spacer(0.25))
story.append(colored_box([
Paragraph(
"<b>Diagnostic rule:</b> Diagnosis of SM requires <b>1 Major criterion + 1 Minor criterion</b>, "
"OR <b>3 Minor criteria</b> (in the absence of the major criterion).",
S_body)
], bg=LTGOLD, border=GOLD))
story.append(spacer(0.2))
story.append(criteria_table(
major="Multifocal dense infiltrates of <b>≥15 mast cells</b> in bone marrow and/or extracutaneous organs on "
"biopsy sections, confirmed by tryptase immunohistochemistry or CD117 staining.",
minors=[
">25% of mast cells in BM biopsy sections or aspirate smears show <b>spindle-shaped or atypical morphology</b>.",
"Detection of a <b>KIT-activating mutation (D816V</b> or other) in bone marrow, blood, or extracutaneous organs.",
"Mast cells co-express CD117 with <b>CD2 and/or CD25</b> (aberrant immunophenotype).",
"<b>Persistent baseline serum tryptase >20 ng/mL</b> (not applicable if an associated hematologic neoplasm is present).",
]
))
story.append(spacer(0.35))
# BM biopsy image pair
if "bm_biopsy" in img_paths and "tryptase_stain" in img_paths:
story.append(Paragraph("Pathological Findings", S_h2))
story.append(add_image_pair(
img_paths["bm_biopsy"],
"Fig 2. Bone marrow biopsy: mast cell aggregates (tryptase stain, major criterion — A) "
"and spindle-shaped atypical mast cells in aspirate smear (minor criterion — B). "
"(Source: Goldman-Cecil Medicine)",
img_paths["tryptase_stain"],
"Fig 3. Classic mastocytosis bone marrow lesion (×100, tryptase stain) — dense brown-staining "
"mast cell clusters. (Source: Fitzpatrick's Dermatology)",
each_width_cm=7.8
))
story.append(spacer(0.3))
# Diagnostic flowchart
if "flowchart" in img_paths:
story.append(Paragraph("Diagnostic Algorithm", S_h2))
for item in add_image(img_paths["flowchart"], width_cm=13,
caption="Fig 4. Diagnostic algorithm for systemic mastocytosis "
"— branching pathways from B/C findings to disease category. "
"(Source: Goldman-Cecil Medicine)"):
story.append(item)
story.append(spacer(0.3))
# ========== SECTION 6: B and C Findings ==========
story.append(section_header("6. B & C Findings — Staging", bg=SLATE))
story.append(spacer(0.25))
bc_data = [
[Paragraph("Finding", make_style("_bch", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("B Findings (≥2 = Smoldering SM)", make_style("_bfh", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("C Findings (≥1 = Aggressive SM)", make_style("_cfh", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12))],
[Paragraph("Bone Marrow", S_body),
Paragraph(">30% BM infiltration + tryptase >200 ng/mL; D816V VAF ≥10%", S_body),
Paragraph("ANC <1000/μL OR Hb <10 g/dL OR Platelets <100,000/μL", S_body)],
[Paragraph("Liver", S_body),
Paragraph("Palpable hepatomegaly WITHOUT impaired liver function", S_body),
Paragraph("Hepatomegaly WITH ascites + impaired liver function", S_body)],
[Paragraph("Spleen", S_body),
Paragraph("Palpable splenomegaly WITHOUT hypersplenism", S_body),
Paragraph("Palpable splenomegaly WITH hypersplenism", S_body)],
[Paragraph("GI", S_body),
Paragraph("Hypercellular BM with signs of dysplasia (no criteria for MDS/MPN)", S_body),
Paragraph("Malabsorption + hypoalbuminemia + weight loss", S_body)],
[Paragraph("Skeleton", S_body),
Paragraph("Lymphadenopathy (>2 cm on CT/US) without organ dysfunction", S_body),
Paragraph("Large osteolytic lesions and/or pathologic fractures", S_body)],
]
bc_t = Table(bc_data, colWidths=[cw_total*0.15, cw_total*0.425, cw_total*0.425])
bc_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("BACKGROUND", (1,0), (1,0), ACCENT),
("BACKGROUND", (2,0), (2,0), CRIMSON),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGRAY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
story.append(bc_t)
story.append(spacer(0.4))
# ========== SECTION 7: Investigations ==========
story.append(section_header("7. Investigations"))
story.append(spacer(0.25))
inv_groups = [
("Laboratory Tests", NAVY, [
"<b>Serum tryptase</b> (baseline) — >20 ng/mL is a minor WHO criterion; correlates with mast cell burden",
"<b>CBC with differential</b> — cytopenias indicate advanced SM (C finding)",
"<b>24-h urine 5-HIAA</b> — exclude carcinoid tumor",
"<b>24-h urine metanephrines</b> — exclude pheochromocytoma",
"<b>LFTs, alkaline phosphatase, serum albumin</b>",
"<b>N-methylhistamine (urine)</b> — histamine metabolite",
]),
("Molecular & Genetic Testing", MAROON, [
"<b>KIT D816V mutation</b> — bone marrow or peripheral blood; allele-specific PCR preferred for sensitivity",
"<b>Flow cytometry</b>: CD2/CD25 co-expression on mast cells (aberrant phenotype)",
"<b>NGS panel</b>: TET2, SRSF2, ASXL1, RUNX1 in advanced SM",
"<b>TPSAB1 copy number</b> — if hereditary alpha-tryptasemia suspected",
]),
("Bone Marrow Studies", SLATE, [
"<b>Core biopsy</b>: tryptase + CD117 immunostaining (gold standard for major criterion)",
"<b>Aspirate smear</b>: look for spindle-shaped / atypical mast cells (minor criterion)",
"<b>% mast cell infiltration</b> — critical for B and C finding assessment",
]),
("Imaging", colors.HexColor("#27AE60"), [
"<b>DEXA scan</b> — bone mineral density (osteoporosis assessment in all patients)",
"<b>Skeletal survey or CT</b> — osteolytic/osteosclerotic lesions in advanced SM",
"<b>Abdominal CT/ultrasound</b> — hepatosplenomegaly, lymphadenopathy",
"<b>PET-CT</b> — in suspected mast cell leukemia or mast cell sarcoma",
]),
]
for grp_title, grp_color, items in inv_groups:
story.append(Paragraph(grp_title, make_style(f"_igh{grp_title}", fontSize=11.5,
textColor=grp_color, fontName="Helvetica-Bold", leading=16, spaceBefore=4, spaceAfter=2)))
for itm in items:
story.append(bullet(itm, color=grp_color))
story.append(spacer(0.15))
story.append(spacer(0.3))
# ========== SECTION 8: Treatment ==========
story.append(section_header("8. Treatment", bg=MAROON))
story.append(spacer(0.25))
story.append(Paragraph("Symptom-Directed Pharmacotherapy", S_h2))
story.append(Paragraph(
"Management of SM is <b>stepwise and symptom/sign-directed</b>. For indolent SM (ISM), "
"the focus is on controlling mediator-related symptoms. Cytoreductive therapy is reserved "
"for advanced or refractory disease.",
S_body))
story.append(spacer(0.2))
story.append(treatment_table())
story.append(spacer(0.3))
story.append(Paragraph("Cytoreductive Therapy (Advanced SM)", S_h2))
story.append(colored_box([
Paragraph(
"<b>Avapritinib</b> — KIT D816V-specific tyrosine kinase inhibitor; now considered "
"<b>first-line for ASM, MCL, and refractory ISM</b>. Reduces BM mast cell burden and improves symptoms.",
S_body),
Paragraph(
"<b>Midostaurin</b> — multikinase inhibitor; approved for advanced SM. "
"<b>Imatinib is NOT effective</b> in most cases (D816V mutation mediates resistance).",
S_body),
Paragraph(
"<b>Cladribine</b> — purine analog; used in advanced SM.",
S_body),
Paragraph(
"<b>IFN-α</b> — immunomodulatory; used in refractory cases.",
S_body),
Paragraph(
"<b>Combination chemotherapy</b> — for frank MCL.",
S_body),
Paragraph(
"<b>Stem cell transplantation</b> — effective in a small subset of advanced SM patients.",
S_body),
], bg=LTGOLD, border=GOLD))
story.append(spacer(0.3))
story.append(Paragraph("Additional Management Points", S_h2))
for pt in [
"Prescribe <b>self-injectable epinephrine (EpiPen)</b> to ALL patients — increased anaphylaxis risk",
"Evaluate for Hymenoptera venom-specific IgE — place on <b>lifelong venom immunotherapy</b> if positive",
"Educate patients on <b>trigger avoidance</b>: opioids, NSAIDs (if intolerant), contrast media, alcohol",
"Monitor bone density with <b>DEXA scans</b> and treat osteoporosis",
"Systemic glucocorticoids may alleviate <b>malabsorption</b>",
]:
story.append(bullet(pt, color=MAROON))
story.append(spacer(0.4))
# ========== SECTION 9: Prognosis ==========
story.append(section_header("9. Prognosis", bg=SLATE))
story.append(spacer(0.25))
prog_data = [
[Paragraph("Variant", make_style("_prh", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("Prognosis", make_style("_prp", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12)),
Paragraph("Notes", make_style("_prn", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=12))],
[Paragraph("ISM", S_body), Paragraph("Normal life expectancy", S_body),
Paragraph("Most common adult form (>70%). Rare transformation to advanced SM.", S_body)],
[Paragraph("BM Mastocytosis", S_body), Paragraph("Good", S_body),
Paragraph("BM involved without skin lesions or organ dysfunction.", S_body)],
[Paragraph("SSM", S_body), Paragraph("Intermediate", S_body),
Paragraph("High mast cell burden; monitor closely for progression.", S_body)],
[Paragraph("SM-AHN", S_body), Paragraph("Determined by associated neoplasm", S_body),
Paragraph("Prognosis driven by the hematologic component.", S_body)],
[Paragraph("ASM", S_body), Paragraph("Poor", S_body),
Paragraph("Organ dysfunction (C findings). Requires cytoreductive therapy.", S_body)],
[Paragraph("MCL", S_body), Paragraph("Very poor (months)", S_body),
Paragraph("≥20% mast cells in BM aspirate. Often rapidly fatal.", S_body)],
]
prog_t = Table(prog_data, colWidths=[cw_total*0.22, cw_total*0.28, cw_total*0.50])
prog_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGRAY]),
("BACKGROUND", (0,5), (-1,5), colors.HexColor("#FFF0EB")),
("BACKGROUND", (0,6), (-1,6), colors.HexColor("#FFE4E4")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 1, NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CBD5E0")),
]))
story.append(prog_t)
story.append(spacer(0.4))
# ========== SECTION 10: Key Takeaways ==========
story.append(section_header("10. Key Takeaways", bg=MAROON))
story.append(spacer(0.2))
for i, pt in enumerate([
"Systemic mastocytosis is a <b>clonal mast cell neoplasm</b> driven by the KIT D816V gain-of-function mutation (>90% of adults).",
"WHO 2022 classifies <b>8 categories</b> — from cutaneous mastocytosis to mast cell leukemia.",
"Diagnosis requires <b>1 major + 1 minor</b> (or 3 minor) WHO criteria confirmed by bone marrow biopsy.",
"<b>Serum tryptase</b> is the primary biomarker for mast cell burden (>20 ng/mL = minor criterion).",
"ISM accounts for >70% of adult cases and carries a <b>normal life expectancy</b>; ASM and MCL are aggressive.",
"All patients need <b>self-injectable epinephrine</b> and should be educated on trigger avoidance.",
"<b>Avapritinib</b> (KIT D816V inhibitor) is now first-line targeted therapy for advanced SM and refractory ISM.",
"Imatinib is <b>NOT effective</b> in KIT D816V-positive mastocytosis (mutation mediates resistance).",
], 1):
story.append(colored_box([
Paragraph(f"<font color='#{MAROON.hexval()[2:]}'><b>{i}.</b></font> {pt}", S_body)
], bg=LGRAY if i % 2 == 0 else WHITE, border=colors.HexColor("#CBD5E0")))
story.append(spacer(0.08))
story.append(spacer(0.4))
story.append(hline(GOLD))
story.append(Paragraph("References", S_h2))
for ref in [
"Harrison TC et al. Harrison's Principles of Internal Medicine, 22nd Edition. McGraw Hill, 2025.",
"Goldman L, Cooney KA. Goldman-Cecil Medicine, International Edition. Elsevier, 2024.",
"Khoury JD et al. The 5th edition WHO classification of haematolymphoid tumours. Leukemia, 2022;36:1703-1719.",
"Gotlib J et al. Avapritinib versus placebo in indolent systemic mastocytosis. NEJM Evid 2:6, 2023.",
"Valent P et al. Proposed diagnostic algorithm for patients with suspected mastocytosis. Allergy, 2014;69:1267.",
]:
story.append(Paragraph(f"• {ref}", S_ref))
# ── Build PDF ─────────────────────────────────────────────────────────────────
OUT = "/home/daytona/workspace/systemic-mastocytosis-ppt/Systemic_Mastocytosis.pdf"
doc = SimpleDocTemplate(
OUT,
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=1.4*cm, bottomMargin=1.4*cm,
title="Systemic Mastocytosis — Clinical Reference",
author="Medical Education",
subject="Mastocytosis",
)
doc.build(story, onFirstPage=on_first_page, onLaterPages=on_page)
print(f"✅ PDF created: {OUT}")
import os
size = os.path.getsize(OUT)
print(f" Size: {size/1024:.1f} KB")
cd /home/daytona/workspace/systemic-mastocytosis-ppt && python3 create_pdf.py 2>…
python3 -c " from PIL import Image import os for k in ['urticaria','bm_biopsy','…
~/systemic-mastocytosis-ppt/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/systemic-mastocytosis-ppt/create_pdf.py'
~/systemic-mastocytosis-ppt/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/systemic-mastocytosis-ppt/create_pdf.py'
~/systemic-mastocytosis-ppt/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/systemic-mastocytosis-ppt/create_pdf.py'
cd /home/daytona/workspace/systemic-mastocytosis-ppt && python3 create_pdf.py 2>…
Systemic Mastocytosis
PDF Document · PDF
| Section | Content |
|---|---|
| 1 | Definition & Epidemiology (prevalence, genetics stats) |
| 2 | Pathobiology — KIT D816V pathway + mediator table |
| 3 | WHO 2022 Classification — all 8 categories table |
| 4 | Clinical Manifestations — skin + systemic organ table + Fig 1: Urticaria pigmentosa photo |
| 5 | Diagnosis — WHO criteria table + Fig 2: Bone marrow biopsy (tryptase stain + spindle cells) + Fig 3: Classic BM tryptase stain + Fig 4: Diagnostic flowchart |
| 6 | B & C Findings (Smoldering vs Aggressive SM) |
| 7 | Investigations — labs, molecular, BM, imaging |
| 8 | Treatment — stepwise drug table + cytoreductive therapy box |
| 9 | Prognosis by variant |
| 10 | Key Takeaways + References |
Make it
ls -lh /home/daytona/workspace/systemic-mastocytosis-ppt/Systemic_Mastocytosis.p…
Systemic Mastocytosis
PDF Document · PDF