Make me pdf on pagets disease and ewings sarcoma for orthopedics pg examination with emphasis on management

Reading File
Now let me search the medical library and PubMed in parallel for both conditions.
Finding Sources
Finding Sources
Searching PubMed

"Paget disease"[MeSH Terms] AND "bisphosphonates" AND treatment

Searching PubMed

"Ewing sarcoma"[MeSH Terms] AND treatment AND chemotherapy

Excellent - found great orthopedic sources. Now let me read the key sections from Campbell's Operative Orthopaedics for Ewing's and Harrison's/Rockwood for Paget's in parallel.
Reading File
Reading File
Reading File
Good data coming in. Now let me read more Ewing's sarcoma content (management sections) and more Paget's content from Harrison's in parallel.
Reading File
Reading File
Getting great content. Let me read the management/treatment sections more deeply - the Ewing's management from Campbell's block 11 (around line 2133) and more Paget's treatment from Harrison's.
Reading File
Reading File
Excellent - found the treatment section for Paget's. Now let me read the full treatment details for both conditions in parallel.
Reading File
Finding Sources
Let me get the Ewing's management section directly from Campbell's and also the Miller's Review for concise exam points.
Finding Sources
Reading File
Now let me read the Campbell's TREATMENT section for Ewing's sarcoma (line 237):
Reading File
Finding Sources
Reading File
I now have comprehensive content for both conditions. Let me read the PDF skill and then generate the PDF.
Reading File
Now let me generate the comprehensive PDF using reportlab:
Running Command

mkdir -p /tmp/workspace/ortho-pg-pdf && ls /tmp/workspace/ortho-pg-pdf/

Writing File

~/ortho-pg-pdf/generate_pdf.py

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,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.lib.colors import HexColor
import os

OUTPUT_PATH = "/tmp/workspace/ortho-pg-pdf/Pagets_Ewings_Ortho_PG.pdf"

# ─── Color Palette ────────────────────────────────────────────────────────────
DARK_BLUE   = HexColor("#1A3A5C")   # headings
MID_BLUE    = HexColor("#2B6CB0")   # sub-headings
TEAL        = HexColor("#2C7A7B")   # section accent
GOLD        = HexColor("#D69E2E")   # highlight / exam tips
LIGHT_BLUE  = HexColor("#EBF4FF")   # table header bg
LIGHT_GREY  = HexColor("#F7FAFC")   # alt row
RED_ACCENT  = HexColor("#C53030")   # warnings / important
GREEN_ACCENT= HexColor("#276749")   # prognosis / good outcomes
WHITE       = colors.white
BLACK       = colors.black

# ─── Document ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT_PATH,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2.5*cm, bottomMargin=2.5*cm,
    title="Paget's Disease & Ewing's Sarcoma – Ortho PG Notes",
    author="Orris Medical Education"
)

W, H = A4
TEXT_W = W - 4*cm

# ─── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()

def style(name, parent="Normal", **kw):
    s = ParagraphStyle(name, parent=base[parent], **kw)
    return s

S_cover_title   = style("CoverTitle",   fontSize=28, textColor=WHITE,
                        fontName="Helvetica-Bold", leading=34, alignment=TA_CENTER)
S_cover_sub     = style("CoverSub",     fontSize=16, textColor=HexColor("#BEE3F8"),
                        fontName="Helvetica", leading=22, alignment=TA_CENTER)
S_cover_tag     = style("CoverTag",     fontSize=11, textColor=HexColor("#FED7AA"),
                        fontName="Helvetica-Oblique", alignment=TA_CENTER)

S_chapter       = style("Chapter",      fontSize=20, textColor=WHITE,
                        fontName="Helvetica-Bold", leading=26, alignment=TA_CENTER,
                        spaceAfter=4)
S_h1            = style("H1",           fontSize=16, textColor=DARK_BLUE,
                        fontName="Helvetica-Bold", leading=20,
                        spaceBefore=12, spaceAfter=4)
S_h2            = style("H2",           fontSize=13, textColor=MID_BLUE,
                        fontName="Helvetica-Bold", leading=17,
                        spaceBefore=8, spaceAfter=3)
S_h3            = style("H3",           fontSize=11, textColor=TEAL,
                        fontName="Helvetica-Bold", leading=14,
                        spaceBefore=6, spaceAfter=2)
S_body          = style("Body",         fontSize=10, textColor=BLACK,
                        fontName="Helvetica", leading=14, alignment=TA_JUSTIFY,
                        spaceAfter=4)
S_bullet        = style("Bullet",       fontSize=10, textColor=BLACK,
                        fontName="Helvetica", leading=14, leftIndent=14,
                        bulletIndent=4, spaceAfter=2,
                        bulletText="\u2022")
S_bullet2       = style("Bullet2",      fontSize=10, textColor=BLACK,
                        fontName="Helvetica", leading=13, leftIndent=28,
                        bulletIndent=14, spaceAfter=1,
                        bulletText="\u25e6")
S_exam_tip      = style("ExamTip",      fontSize=10, textColor=HexColor("#7B341E"),
                        fontName="Helvetica-Bold", leading=14, leftIndent=10,
                        rightIndent=10, spaceAfter=4)
S_important     = style("Important",    fontSize=10, textColor=RED_ACCENT,
                        fontName="Helvetica-Bold", leading=14, leftIndent=10)
S_table_hdr     = style("TblHdr",       fontSize=9,  textColor=WHITE,
                        fontName="Helvetica-Bold", leading=12, alignment=TA_CENTER)
S_table_body    = style("TblBody",      fontSize=9,  textColor=BLACK,
                        fontName="Helvetica", leading=12, alignment=TA_LEFT)
S_table_body_c  = style("TblBodyC",     fontSize=9,  textColor=BLACK,
                        fontName="Helvetica", leading=12, alignment=TA_CENTER)
S_caption       = style("Caption",      fontSize=8,  textColor=HexColor("#4A5568"),
                        fontName="Helvetica-Oblique", leading=11, alignment=TA_CENTER,
                        spaceAfter=4)
S_footer_note   = style("FootNote",     fontSize=8,  textColor=HexColor("#718096"),
                        fontName="Helvetica-Oblique", leading=11, alignment=TA_CENTER)

# ─── Helper Flowables ─────────────────────────────────────────────────────────
def hr(color=MID_BLUE, width=1):
    return HRFlowable(width="100%", thickness=width, color=color, spaceAfter=4, spaceBefore=4)

def chapter_banner(text, color=DARK_BLUE):
    tbl = Table([[Paragraph(text, S_chapter)]], colWidths=[TEXT_W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",  (0,0), (-1,-1), color),
        ("TOPPADDING",  (0,0), (-1,-1), 14),
        ("BOTTOMPADDING",(0,0),(-1,-1), 14),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING",(0,0), (-1,-1), 10),
        ("ROUNDEDCORNERS", [8]),
    ]))
    return tbl

def section_box(title, content_para, bg=LIGHT_BLUE, border=MID_BLUE):
    """A bordered coloured box for highlighted content."""
    rows = [[Paragraph(title, S_h3)], [content_para]]
    tbl = Table(rows, colWidths=[TEXT_W - 10])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",  (0,0), (-1,0), bg),
        ("BACKGROUND",  (0,1), (-1,-1), HexColor("#FEFEFE")),
        ("BOX",         (0,0), (-1,-1), 1.2, border),
        ("LINEBELOW",   (0,0), (-1,0), 1, border),
        ("TOPPADDING",  (0,0), (-1,-1), 6),
        ("BOTTOMPADDING",(0,0),(-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 8),
        ("RIGHTPADDING",(0,0), (-1,-1), 8),
    ]))
    return tbl

def exam_box(text):
    tbl = Table([[Paragraph("★  EXAM TIP: " + text, S_exam_tip)]], colWidths=[TEXT_W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",  (0,0), (-1,-1), HexColor("#FFFBEB")),
        ("BOX",         (0,0), (-1,-1), 1.5, GOLD),
        ("TOPPADDING",  (0,0), (-1,-1), 6),
        ("BOTTOMPADDING",(0,0),(-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING",(0,0), (-1,-1), 10),
    ]))
    return tbl

def warning_box(text):
    tbl = Table([[Paragraph("⚠  " + text, S_important)]], colWidths=[TEXT_W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",  (0,0), (-1,-1), HexColor("#FFF5F5")),
        ("BOX",         (0,0), (-1,-1), 1.5, RED_ACCENT),
        ("TOPPADDING",  (0,0), (-1,-1), 6),
        ("BOTTOMPADDING",(0,0),(-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING",(0,0), (-1,-1), 10),
    ]))
    return tbl

def b(text, para=None):
    """Bullet paragraph"""
    p = para or S_bullet
    return Paragraph(text, p)

def h1(t): return Paragraph(t, S_h1)
def h2(t): return Paragraph(t, S_h2)
def h3(t): return Paragraph(t, S_h3)
def p(t):  return Paragraph(t, S_body)
def sp(n=6): return Spacer(1, n)

def simple_table(header_row, data_rows, col_widths=None, alt=True):
    """Create a styled table."""
    all_rows = [[Paragraph(str(c), S_table_hdr) for c in header_row]]
    for row in data_rows:
        all_rows.append([Paragraph(str(c), S_table_body) for c in row])
    col_w = col_widths or [TEXT_W / len(header_row)] * len(header_row)
    tbl = Table(all_rows, colWidths=col_w, repeatRows=1)
    style_cmds = [
        ("BACKGROUND",   (0,0), (-1,0),  DARK_BLUE),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, LIGHT_GREY] if alt else [WHITE]),
        ("BOX",          (0,0), (-1,-1), 0.8, MID_BLUE),
        ("INNERGRID",    (0,0), (-1,-1), 0.5, HexColor("#BEE3F8")),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("LEFTPADDING",  (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ]
    tbl.setStyle(TableStyle(style_cmds))
    return tbl

# ═══════════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ═══════════════════════════════════════════════════════════════════════════════
story = []

# ─────────────────────────── COVER PAGE ──────────────────────────────────────
cover_bg = Table(
    [[Paragraph("ORTHOPAEDICS PG EXAMINATION NOTES", S_cover_sub)],
     [Spacer(1, 10)],
     [Paragraph("Paget's Disease of Bone", S_cover_title)],
     [Paragraph("&", style("Amp", fontSize=22, textColor=HexColor("#90CDF4"),
                               fontName="Helvetica-Bold", alignment=TA_CENTER))],
     [Paragraph("Ewing's Sarcoma", S_cover_title)],
     [Spacer(1, 20)],
     [Paragraph("With Emphasis on Management | Based on Campbell's, Harrison's, Rockwood & Green's", S_cover_tag)],
     [Spacer(1, 8)],
     [Paragraph("July 2026", S_cover_tag)],
    ],
    colWidths=[TEXT_W]
)
cover_bg.setStyle(TableStyle([
    ("BACKGROUND",   (0,0), (-1,-1), DARK_BLUE),
    ("TOPPADDING",   (0,0), (-1,-1), 14),
    ("BOTTOMPADDING",(0,0), (-1,-1), 14),
    ("LEFTPADDING",  (0,0), (-1,-1), 30),
    ("RIGHTPADDING", (0,0), (-1,-1), 30),
    ("BOX",          (0,0), (-1,-1), 3, GOLD),
]))
story.append(cover_bg)
story.append(Spacer(1, 1*cm))
story.append(Paragraph(
    "Sources: Campbell's Operative Orthopaedics 15th Ed 2026 | Harrison's 22E 2025 | "
    "Rockwood & Green's 10th Ed 2025 | Miller's Review of Orthopaedics 9th Ed | "
    "Katzung Pharmacology 16th Ed | Firestein & Kelley's Rheumatology",
    S_footer_note))
story.append(PageBreak())

# ──────────────────────────── TABLE OF CONTENTS ───────────────────────────────
story.append(h1("Table of Contents"))
story.append(hr())
toc_data = [
    ["Section", "Topic", "Page"],
    ["PART 1", "Paget's Disease of Bone", "3"],
    ["", "1.1  Epidemiology & Aetiology", "3"],
    ["", "1.2  Pathophysiology", "3"],
    ["", "1.3  Clinical Features", "4"],
    ["", "1.4  Investigations & Diagnosis", "4"],
    ["", "1.5  Complications", "5"],
    ["", "1.6  Management (Emphasis)", "5"],
    ["", "1.7  Orthopaedic Surgical Management", "7"],
    ["", "1.8  Prognosis & Follow-up", "7"],
    ["", "1.9  High-Yield Summary Table", "8"],
    ["PART 2", "Ewing's Sarcoma", "9"],
    ["", "2.1  Epidemiology & Molecular Biology", "9"],
    ["", "2.2  Pathology & Classification", "9"],
    ["", "2.3  Clinical Features", "10"],
    ["", "2.4  Imaging", "10"],
    ["", "2.5  Staging (Enneking)", "11"],
    ["", "2.6  Management (Emphasis)", "11"],
    ["", "2.7  Radiation Therapy", "13"],
    ["", "2.8  Prognosis & Prognostic Factors", "13"],
    ["", "2.9  Recurrence & Salvage", "14"],
    ["", "2.10 High-Yield Summary Table", "14"],
    ["PART 3", "Quick Comparison Table", "15"],
]
toc_col_w = [2.5*cm, 10*cm, 2.5*cm]
toc_rows = [[Paragraph(r[0], S_table_body_c),
             Paragraph(r[1], S_table_body),
             Paragraph(r[2], S_table_body_c)] for r in toc_data[1:]]
toc_hdr  = [Paragraph(c, S_table_hdr) for c in toc_data[0]]
toc_tbl  = Table([toc_hdr] + toc_rows, colWidths=toc_col_w)
toc_tbl.setStyle(TableStyle([
    ("BACKGROUND",   (0,0),(-1,0), DARK_BLUE),
    ("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE, LIGHT_GREY]),
    ("BOX",          (0,0),(-1,-1), 0.8, MID_BLUE),
    ("INNERGRID",    (0,0),(-1,-1), 0.4, HexColor("#BEE3F8")),
    ("TOPPADDING",   (0,0),(-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1), 4),
    ("LEFTPADDING",  (0,0),(-1,-1), 6),
    ("RIGHTPADDING", (0,0),(-1,-1), 6),
    ("VALIGN",       (0,0),(-1,-1),"MIDDLE"),
]))
story.append(toc_tbl)
story.append(PageBreak())

# ═══════════════════════════════════════════════════════════════════════════════
# PART 1  ──  PAGET'S DISEASE OF BONE
# ═══════════════════════════════════════════════════════════════════════════════
story.append(chapter_banner("PART 1: PAGET'S DISEASE OF BONE", DARK_BLUE))
story.append(sp(10))

# 1.1 EPIDEMIOLOGY & AETIOLOGY
story.append(h1("1.1  Epidemiology & Aetiology"))
story.append(hr())
story.append(p(
    "Paget's disease (osteitis deformans) is the second most common metabolic bone disease after osteoporosis. "
    "It is a <b>localised bone-remodeling disorder</b> affecting non-contiguous areas of the skeleton, "
    "characterised by overactive osteoclastic resorption followed by disorganised osteoblastic new bone formation. "
    "The resulting mosaic of woven and lamellar bone is expanded, less compact, more vascular, and prone to "
    "deformity and fracture."
))
cols_epi = [
    [b("<b>Prevalence:</b> ~3% autopsy series over age 40"),
     b("<b>Sex:</b> Males > Females"),
     b("<b>Age:</b> Rarely before 40; rises sharply with age"),
     b("<b>Geography:</b> UK, France, Germany, Australia, NZ, S. Africa; rare in Asia, Africa, Americas (native)"),
     b("<b>Trend:</b> Declining prevalence and severity over recent decades"),
    ],
    [b("<b>Positive family history:</b> 15-25% of patients; 7-10× risk in 1st-degree relatives"),
     b("<b>TNFRSF11B gene</b> (OPG): juvenile Paget's / familial idiopathic hyperphosphatasia"),
     b("<b>TNFRSF11A gene</b> (RANK): familial expansile osteolysis, early-onset Paget's"),
     b("<b>Paramyxovirus</b> (measles, respiratory syncytial): intranuclear inclusions in osteoclasts"),
     b("<b>VCP gene</b> mutation: Inclusion body myopathy + Paget's + frontotemporal dementia"),
    ]
]
epi_tbl = Table([cols_epi], colWidths=[TEXT_W/2, TEXT_W/2])
epi_tbl.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"), ("LEFTPADDING",(0,0),(-1,-1),0)]))
story.append(epi_tbl)
story.append(sp(6))
story.append(exam_box(
    "Paget's is the SECOND most common metabolic bone disease. "
    "RANK/OPG pathway mutations are key genetics to know. "
    "Paramyxoviral etiology is debated but frequently asked."
))

# 1.2 PATHOPHYSIOLOGY
story.append(sp(8))
story.append(h1("1.2  Pathophysiology"))
story.append(hr())
story.append(p("Three histological phases (may coexist in different areas of same bone):"))
phases_data = [
    ["Phase", "Predominant Activity", "Histology / Feature", "Radiograph"],
    ["1. Osteolytic\n(Hot/Active)", "Osteoclastic resorption", "Giant multinucleated osteoclasts; "
     "\"Osteoporosis circumscripta\" in skull\n\"Blade of grass\" in long bones", "Lytic lesion advancing"],
    ["2. Mixed\n(Active)", "Both active", "Mosaic woven + lamellar bone\n\"Mosaic pattern\" cement lines",
     "Mixed lytic-sclerotic"],
    ["3. Osteosclerotic\n(Burnt-out/Quiescent)", "Osteoblastic formation dominant",
     "Dense, disorganised sclerotic bone\nMarrow replaced by fibrovascular tissue",
     "Dense, enlarged, deformed bone"],
]
story.append(simple_table(
    phases_data[0], phases_data[1:],
    col_widths=[3*cm, 3.5*cm, 5.5*cm, 3*cm]
))
story.append(sp(6))
story.append(p(
    "The coupling of osteoclast and osteoblast activity leads to <b>elevated Alkaline Phosphatase (ALP)</b> "
    "– the hallmark biochemical marker. Pagetic bone is hypervascular, leading to increased local blood flow."
))
story.append(exam_box(
    "Classic ALP elevation in Paget's with NORMAL serum calcium and phosphate. "
    "\"Mosaic pattern\" or \"jigsaw puzzle\" cement lines are pathognomonic on histology."
))

# 1.3 CLINICAL FEATURES
story.append(sp(8))
story.append(h1("1.3  Clinical Features"))
story.append(hr())
story.append(p(
    "<b>Most patients (up to 70%) are asymptomatic</b>, diagnosed incidentally. "
    "Symptomatic disease depends on site involved."
))
cf_data = [
    ["System / Site", "Feature"],
    ["Bone pain (most common)", "Dull, aching, deep, worse at rest and night; from vascularity, lytic lesions, "
     "microfractures"],
    ["Long bones (femur, tibia)", "Bowing deformity (sabre tibia), warmth; fractures "
     "(\"chalk stick\" or transverse) – femoral shaft, subtrochanteric region"],
    ["Skull (most common site)", "Enlarged hat size, frontal bossing, cranial nerve palsies, "
     "hearing loss (cochlear nerve), platybasia, brainstem compression"],
    ["Vertebrae", "Back pain, spinal stenosis, nerve root compression, \"ivory vertebra\" / "
     "\"picture frame\" vertebra, rarely cord compression (vascular steal)"],
    ["Pelvis", "Brim sign (thickened iliopectineal line), protrusio acetabuli, secondary OA hip"],
    ["Face", "Facial deformity, dental problems, lion face (leontiasis ossea in severe cases)"],
    ["Cardiovascular", "High-output cardiac failure (>15-35% skeleton involved); AV shunting; "
     "calcific aortic stenosis"],
    ["Neurological", "Hearing loss most common; cranial nerve palsies; compression syndromes"],
]
story.append(simple_table(
    cf_data[0], cf_data[1:],
    col_widths=[4.5*cm, 10.5*cm]
))

# 1.4 INVESTIGATIONS
story.append(sp(8))
story.append(h1("1.4  Investigations & Diagnosis"))
story.append(hr())

inv_data = [
    ["Investigation", "Finding / Significance"],
    ["Serum ALP (TOTAL)", "ELEVATED – best single marker; reflects disease activity and extent; "
     "used to monitor therapy response. First-line test."],
    ["PINP (bone formation marker)", "Elevated; useful when ALP normal (single-site disease). "
     "Can be used in place of ALP."],
    ["Serum N-/C-telopeptide", "Elevated bone resorption markers; fall faster than ALP with treatment. "
     "Useful early treatment monitor."],
    ["Serum Ca, PO4", "Usually NORMAL. Hypercalcemia may occur with immobilization."],
    ["Urine Ca/creatinine", "Elevated in active disease; monitor renal complications."],
    ["Bone-specific ALP", "Useful when single-site disease with normal total ALP"],
    ["Serum osteocalcin", "NOT reliable – not recommended for diagnosis or monitoring"],
]
story.append(simple_table(inv_data[0], inv_data[1:], col_widths=[4.5*cm, 10.5*cm]))
story.append(sp(6))

story.append(h2("Radiology"))
story.append(p("<b>Plain Radiograph (X-ray):</b> Often diagnostic. Key features:"))
xray_feats = [
    "<b>Skull:</b> \"Cotton wool\" appearance (mixed lytic-sclerotic), osteoporosis circumscripta, "
    "diploic thickening, frontal bossing",
    "<b>Vertebrae:</b> \"Picture frame\" vertebra (cortical thickening of end plates), \"ivory vertebra\" "
    "(diffuse sclerosis)",
    "<b>Pelvis:</b> Brim sign (thickened iliopectineal line), protrusio acetabuli, coarse trabeculation",
    "<b>Long bones:</b> Expansion, cortical thickening, \"blade of grass\" advancing lytic lesion, "
    "bowing deformity, \"chalk stick\" fracture (transverse fracture in convexity)",
    "<b>Femur proximal:</b> \"Shepherd's crook\" deformity from coxa vara",
]
for f in xray_feats:
    story.append(b(f))
story.append(sp(4))
story.append(p(
    "<b>Bone Scintigraphy (Tc-99m HDP bone scan):</b> Most sensitive for detecting extent and activity; "
    "shows intense uptake in affected areas. Best for <b>mapping disease extent</b>. "
    "\"Bull's-eye\" sign in skull."
))
story.append(p(
    "<b>CT:</b> Assesses cortical thickness, bony deformity, complication planning. "
    "<b>MRI:</b> Required to exclude sarcomatous transformation, assess spinal cord/nerve root compression."
))
story.append(exam_box(
    "Bone scan = most sensitive for extent. X-ray = most specific for diagnosis. "
    "ALP = best marker for monitoring. Serum Ca is NORMAL (contrast with hyperparathyroidism)."
))

# 1.5 COMPLICATIONS
story.append(sp(8))
story.append(h1("1.5  Complications"))
story.append(hr())
comp_data = [
    ["Complication", "Details"],
    ["Fractures", "\"Chalk-stick\" (transverse) fractures in bowed long bones; femoral shaft, "
     "subtrochanteric; occur in lytic phase; can be pathological"],
    ["Sarcomatous transformation", "<b>&lt;0.5% of cases</b> but the most feared complication. "
     "Usually osteosarcoma (&gt;50%). Also fibrosarcoma, chondrosarcoma. "
     "Suspect: new/worsening pain + soft tissue mass. Very poor prognosis."],
    ["Secondary osteoarthritis", "Adjacent joint (hip, knee) due to deformity and altered biomechanics; "
     "most common complication requiring orthopaedic intervention"],
    ["Nerve compression", "Hearing loss (VIII), cranial nerve palsies, spinal stenosis, "
     "cord compression, radiculopathy"],
    ["High-output cardiac failure", "Extensive disease (>15-35% skeleton); AV shunting; rare"],
    ["Hypercalcemia", "Immobilization of active Paget's; check calcium before immobilizing"],
    ["Benign giant cell tumor", "Adjacent to pagetic bone; responds to glucocorticoids"],
]
story.append(simple_table(comp_data[0], comp_data[1:], col_widths=[4.5*cm, 10.5*cm]))
story.append(sp(4))
story.append(warning_box(
    "Sarcomatous transformation (&lt;0.5%): presents as new pain in long-standing Paget's. "
    "5-year survival &lt;10%. Any sudden worsening pain = MRI urgently to exclude sarcoma."
))

# 1.6 MANAGEMENT ─── EMPHASIS
story.append(sp(8))
story.append(h1("1.6  Management of Paget's Disease"))
story.append(hr(color=GOLD, width=2))
story.append(p("<b>Indications for Treatment (Endocrine Society 2014 guidelines):</b>"))
ind_list = [
    "Symptomatic disease: bone pain, headache, neurological complications, pagetic radiculopathy/arthropathy",
    "Risk of future complications: weight-bearing bones, vertebral bodies, skull, bone adjacent to major joints",
    "Pre-operative: reduce vascularity and operative blood loss at pagetic surgical sites",
    "Immobilization hypercalciuria (prevent nephrolithiasis)",
    "High disease activity: ALP &gt;4x normal with involvement of high-risk sites",
    "Asymptomatic patients at risk: active disease near skull base, spine, major joints",
]
for i in ind_list:
    story.append(b(i))
story.append(sp(6))

story.append(h2("Pharmacological Management (MAINSTAY)"))
story.append(p(
    "<b>Bisphosphonates are the first-line treatment.</b> They suppress osteoclastic bone resorption, "
    "secondarily reducing osteoblastic formation. ALP normalises, and disordered pagetic bone is replaced "
    "by more organised lamellar bone."
))
drug_data = [
    ["Drug", "Route / Dose", "ALP Normalisation", "Notes / Exam Points"],
    ["Zoledronic acid\n(Zoledronate)", "5 mg IV single infusion\nover 15 min",
     "<b>~90%</b> at 6 months\n(BEST efficacy)",
     "<b>FIRST CHOICE</b> (esp. severe disease, rapid normalisation needed). "
     "Remission: 6.5 yrs avg. Flu-like side effects 1-3 days post-infusion."],
    ["Pamidronate", "30 mg/d IV x 3 days\n(4 hr infusion each)",
     "~50%", "IV bisphosphonate; used when oral not tolerated. "
     "Flu-like reaction; hypocalcemia risk."],
    ["Risedronate", "30 mg/d PO x 2 months", "~73%",
     "Oral; good efficacy. Must take on empty stomach, 30 min before food. "
     "2nd choice to zoledronate."],
    ["Alendronate", "40 mg/d PO x 6 months", "~63%",
     "Oral; requires strict dosing instructions to avoid esophageal irritation."],
    ["Tiludronate", "800 mg/d PO x 3 months", "~35%",
     "Less potent; less commonly used now."],
    ["Etidronate", "200-400 mg/d PO x 6 months", "~15%",
     "First-generation; least effective; impairs mineralisation if prolonged. "
     "Historical use only."],
    ["Calcitonin\n(Salmon calcitonin)", "100 U SC/IM daily x 6-18 mo\n(reduce to 50U 3x/wk)",
     "ALP falls ~50% (not normalised)",
     "SECOND LINE / adjunct. For patients intolerant of bisphosphonates. "
     "Analgesic effect. Nasal spray: less effective. Slower onset. "
     "Use before surgery if bisphosphonates not possible."],
]
story.append(simple_table(
    drug_data[0], drug_data[1:],
    col_widths=[3*cm, 3.5*cm, 3*cm, 5.5*cm]
))
story.append(sp(4))
story.append(exam_box(
    "ZOLEDRONIC ACID = drug of choice for Paget's (5 mg IV single dose, 90% ALP normalisation). "
    "Risedronate = best oral option. Etidronate = first gen, least effective, impairs mineralisation."
))

story.append(sp(6))
story.append(h3("Pre-Treatment Precautions"))
pre_list = [
    "Ensure adequate <b>calcium (1000-1500 mg/day)</b> and <b>Vitamin D (800-1000 IU/day)</b> supplementation "
    "BEFORE starting bisphosphonates (hypocalcemia risk, especially when bone formation continues after "
    "resorption is suppressed)",
    "Check renal function: <b>zoledronate is contraindicated</b> if eGFR &lt;35 mL/min/1.73m²",
    "Dental check before bisphosphonate therapy (osteonecrosis of jaw risk, though rare in Paget's doses)",
    "Monitor ALP every 3-6 months initially; then 6-12 monthly after remission",
]
for item in pre_list:
    story.append(b(item))

story.append(sp(6))
story.append(h3("Monitoring & Duration"))
mon_list = [
    "Target: <b>normalise ALP</b> (or reduce to within normal range) – indicates disease quiescence",
    "PINP and bone resorption markers (NTx, CTx) fall faster than ALP – useful for early treatment response",
    "Re-treat when ALP rises above normal or symptoms recur",
    "Zoledronate: remission typically lasts 2-7+ years; single infusion often sufficient for years",
    "No consensus on when to retreat; guided by ALP + symptoms + disease activity",
]
for m in mon_list:
    story.append(b(m))

# 1.7 ORTHOPAEDIC SURGICAL MANAGEMENT
story.append(sp(8))
story.append(h1("1.7  Orthopaedic Surgical Management"))
story.append(hr())
story.append(p(
    "<b>Medical treatment should PRECEDE surgery</b> whenever possible to reduce bone vascularity, "
    "decrease intraoperative blood loss, and facilitate healing."
))
surg_data = [
    ["Indication", "Procedure / Approach", "Key Points"],
    ["Fractures", "ORIF (nailing preferred for shaft fractures)\nCorrection osteotomy for deformity",
     "Intramedullary nail for femoral/tibial shaft fractures; avoid unlocking until bone disease suppressed. "
     "\"Chalk stick\" fractures tend to be transverse – easier to fix."],
    ["Secondary osteoarthritis\n(hip / knee)", "Total Hip Arthroplasty (THA) / Total Knee Arthroplasty (TKA)",
     "Most common indication. Pre-op bisphosphonates for 2-3 months. "
     "Anticipate altered bone anatomy, softer bone, increased bleeding. "
     "Protrusio acetabuli makes THA technically demanding."],
    ["Spinal stenosis / cord compression",
     "Laminectomy / decompression\nFusion for instability",
     "Medical management first (may resolve neurological symptoms). "
     "Surgery for progressive deficits, structural instability, or failure of medical therapy."],
    ["Osteotomy", "Corrective osteotomy of bowed tibia/femur",
     "Rarely needed; for severe deformity causing pain or gait problems. "
     "Pre-op medical treatment essential."],
    ["Sarcomatous transformation",
     "Wide surgical excision ± amputation\n+ Chemotherapy (sarcoma protocols)",
     "Extremely poor prognosis; managed as high-grade sarcoma. "
     "Radiation-resistant. Aggressive multi-modality treatment."],
]
story.append(simple_table(
    surg_data[0], surg_data[1:],
    col_widths=[3.5*cm, 4.5*cm, 7*cm]
))

# 1.8 PROGNOSIS
story.append(sp(8))
story.append(h1("1.8  Prognosis & Follow-up"))
story.append(hr())
prog_items = [
    "Overall prognosis is <b>good</b> with modern bisphosphonate therapy",
    "Mortality in uncomplicated Paget's = same as general population",
    "Sarcomatous transformation: survival &lt;1 year in majority; 5-yr survival &lt;5-10%",
    "Hearing loss is often irreversible even after treatment",
    "Follow-up: ALP every 3-6 months initially; imaging if new symptoms or rising ALP",
    "Secondary OA progression may be slowed but not reversed by bisphosphonates",
    "Newer data: prevalence and severity declining globally – possibly due to earlier treatment or "
    "decreased paramyxoviral exposure",
]
for pr in prog_items:
    story.append(b(pr))

# 1.9 HIGH-YIELD SUMMARY TABLE
story.append(sp(8))
story.append(h1("1.9  High-Yield Summary Table: Paget's Disease"))
story.append(hr())
hy_paget = [
    ["Feature", "Key Point"],
    ["Definition", "Localised bone remodelling disorder – osteoclast overactivity → disorganised bone"],
    ["Prevalence", "3% autopsy over 40; M > F; Western European origin"],
    ["Gene", "RANK (TNFRSF11A), OPG (TNFRSF11B), VCP mutations in familial forms"],
    ["Most common site", "Pelvis (most common single site), followed by spine, skull, femur, tibia"],
    ["Most common symptom", "Bone pain (+ warmth, deformity)"],
    ["Skull X-ray", "\"Cotton wool\" (mixed), osteoporosis circumscripta (lytic), enlargement"],
    ["Vertebra X-ray", "\"Picture frame\" vertebra; \"ivory vertebra\" (diffuse sclerosis)"],
    ["Long bone X-ray", "\"Blade of grass\" lytic advancing front; cortical thickening; bowing; "
     "\"chalk stick\" fractures"],
    ["Pathognomonic histology", "Mosaic/jigsaw cement lines (woven + lamellar bone)"],
    ["Best single biochemical marker", "Serum Total ALP (elevated); Ca & PO4 NORMAL"],
    ["Best imaging for extent", "Bone scan (Tc-99m HDP) – most sensitive"],
    ["1st-line treatment", "Zoledronic acid 5 mg IV (single dose) – 90% ALP normalisation"],
    ["Best oral drug", "Risedronate 30 mg/d x 2 months"],
    ["Dreaded complication", "Sarcomatous transformation (&lt;0.5%); osteosarcoma most common"],
    ["Most common ortho complication", "Secondary OA (hip > knee) requiring arthroplasty"],
    ["Surgery prep", "Bisphosphonates 2-3 months pre-op to reduce vascularity"],
    ["Fracture pattern", "Transverse \"chalk-stick\" in convexity of bowed bone"],
]
story.append(simple_table(hy_paget[0], hy_paget[1:], col_widths=[5*cm, 10*cm]))
story.append(PageBreak())

# ═══════════════════════════════════════════════════════════════════════════════
# PART 2  ──  EWING'S SARCOMA
# ═══════════════════════════════════════════════════════════════════════════════
story.append(chapter_banner("PART 2: EWING'S SARCOMA", TEAL))
story.append(sp(10))

# 2.1 EPIDEMIOLOGY & MOLECULAR
story.append(h1("2.1  Epidemiology & Molecular Biology"))
story.append(hr())
story.append(p(
    "Ewing sarcoma is the <b>3rd most common primary malignant bone tumour</b> overall, "
    "but the <b>2nd most common after osteosarcoma in patients &lt;30 years</b>, and the "
    "<b>MOST COMMON in patients &lt;10 years</b>. It belongs to the Ewing family of tumours (EFT) which "
    "also includes peripheral primitive neuroectodermal tumour (PNET) and Askin tumour (chest wall PNET)."
))
epi2_data = [
    ["Parameter", "Detail"],
    ["Incidence", "&lt;1 per million per year; 2nd most common bone sarcoma in children/adolescents"],
    ["Age", "Peak: 10-20 years (5-25 years most cases); rare &gt;30 or &lt;5 years"],
    ["Sex", "Slightly higher in males (M:F ~1.5:1)"],
    ["Race", "Exceedingly rare in individuals of African descent; predominantly Caucasian"],
    ["Predisposing factors", "None known"],
    ["Common locations", "Diaphysis/metaphysis of long bones (femur most common); flat bones "
     "(pelvis, scapula, ribs); skull rare; small bones rare"],
    ["Chromosomal translocation",
     "<b>t(11;22)(q24;q12)</b> – present in >85% of cases → EWS-FLI1 fusion gene "
     "(EWS gene on chr 22, FLI1 on chr 11). Other: t(21;22) → EWS-ERG; t(7;22) → EWS-ETV1"],
    ["Molecular marker", "CD99 (MIC-2 gene product) – strong membranous positivity; "
     "highly sensitive (not 100% specific)"],
]
story.append(simple_table(epi2_data[0], epi2_data[1:], col_widths=[4*cm, 11*cm]))
story.append(sp(6))
story.append(exam_box(
    "t(11;22)(q24;q12) = pathognomonic translocation (EWS-FLI1 fusion). "
    "CD99 (MIC-2) positivity = key IHC marker. "
    "Most common in ages 10-20; MOST common bone tumour under 10 years."
))

# 2.2 PATHOLOGY
story.append(sp(8))
story.append(h1("2.2  Pathology & Classification"))
story.append(hr())
story.append(p("<b>Gross:</b> Soft, grey-white tumour with areas of necrosis and haemorrhage, often with large "
    "soft tissue mass extending through cortex."))
story.append(p(
    "<b>Histology:</b> Small round blue cell tumour – uniform, small cells with scant cytoplasm, "
    "round nuclei with fine chromatin, arranged in sheets with little intercellular matrix. "
    "Homer-Wright pseudorosettes may be seen (PNET variant). "
    "PAS stain: <b>glycogen-positive</b> (intracellular glycogen)."
))
story.append(p("<b>Immunohistochemistry (IHC) panel:</b>"))
ihc_data = [
    ["Marker", "Ewing Sarcoma", "Utility"],
    ["CD99 (MIC-2)", "<b>Strongly +ve</b> (membranous)", "Most useful; high sensitivity"],
    ["FLI-1", "+ ve (nuclear)", "Correlates with EWS-FLI1 fusion"],
    ["Vimentin", "+ ve", "Non-specific"],
    ["NSE (neuron-specific enolase)", "+/- (PNET)", "Neural differentiation"],
    ["S100", "Focal + (PNET)", ""],
    ["Cytokeratin", "NEGATIVE", "Important differential: rules out carcinoma"],
    ["LCA (CD45)", "NEGATIVE", "Rules out lymphoma"],
    ["Desmin", "NEGATIVE", "Rules out rhabdomyosarcoma"],
    ["CD99 note", "Also + in lymphoblastic lymphoma", "Correlation with clinical + molecular needed"],
]
story.append(simple_table(ihc_data[0], ihc_data[1:], col_widths=[5*cm, 4*cm, 6*cm]))
story.append(sp(4))
story.append(p(
    "<b>Differential diagnosis of small round blue cell tumours (mnemonic: LEMON):</b>"
))
story.append(b("<b>L</b>ymphoma / lymphoblastic lymphoma"))
story.append(b("<b>E</b>wing sarcoma / PNET"))
story.append(b("<b>M</b>esenchymal chondrosarcoma"))
story.append(b("<b>O</b>steosarcoma (small cell variant)"))
story.append(b("<b>N</b>euroblastoma / rhabdomyosarcoma"))
story.append(exam_box(
    "Small round blue cell tumour + CD99 positive + t(11;22) = Ewing's sarcoma. "
    "PAS positive (glycogen). NEGATIVE for cytokeratin (not carcinoma) and LCA (not lymphoma)."
))

# 2.3 CLINICAL FEATURES
story.append(sp(8))
story.append(h1("2.3  Clinical Features"))
story.append(hr())
story.append(p(
    "<b>Pain is almost universal</b> and the most common presenting complaint. "
    "Onset is insidious; may respond initially to conservative treatment, leading to diagnostic delay. "
    "<b>Average delay from symptom onset to diagnosis: 34 weeks</b> "
    "(patient delay ~15 weeks, physician delay ~19 weeks)."
))
story.append(sp(4))
cf2_data = [
    ["Feature", "Details"],
    ["Pain", "Dull, aching; may be intermittent initially; worsens as tumour grows"],
    ["Swelling / soft tissue mass", "Often present; may be large and palpable; warmth and tenderness"],
    ["Fever / constitutional symptoms",
     "Can mimic osteomyelitis – fever, elevated WBC, elevated ESR/CRP. "
     "CLASSIC MIMIC – most important differential diagnosis in children."],
    ["Pathological fracture", "10-20% present with pathological fracture"],
    ["Neurological symptoms", "If spine/pelvis involved: weakness, paraplegia, bowel/bladder dysfunction"],
    ["Metastatic symptoms",
     "Lung metastases: dyspnoea, chest pain; bone metastases: diffuse pain; "
     "bone marrow: anaemia, thrombocytopenia"],
]
story.append(simple_table(cf2_data[0], cf2_data[1:], col_widths=[4*cm, 11*cm]))
story.append(sp(4))
story.append(warning_box(
    "Ewing sarcoma mimics osteomyelitis. Pus-like material on needle aspiration may be sent to "
    "microbiology only – ALWAYS send biopsy specimens to BOTH culture AND pathology."
))
story.append(sp(4))
story.append(p("<b>Laboratory findings:</b>"))
lab_list = [
    "Elevated ESR, CRP, WBC (mimics infection)",
    "<b>Elevated LDH (lactate dehydrogenase)</b> – poor prognostic marker",
    "Anaemia of chronic disease",
    "Normal or elevated alkaline phosphatase",
]
for ll in lab_list:
    story.append(b(ll))

# 2.4 IMAGING
story.append(sp(8))
story.append(h1("2.4  Imaging & Staging Workup"))
story.append(hr())
img_data = [
    ["Modality", "Findings / Role"],
    ["Plain X-ray (first-line)",
     "<b>\"Onion skin\" periosteal reaction</b> (laminated periostitis) – classic but variable. "
     "Diaphyseal destructive lesion; \"moth-eaten\" permeative pattern (Lodwick III). "
     "\"Sunburst\" periosteal reaction (less common than osteosarcoma). "
     "Codman's triangle may be present. Large soft tissue component often underestimated on X-ray."],
    ["MRI (MANDATORY for all cases)",
     "Mandatory for full extent of lesion and soft tissue mass. "
     "Entire bone must be imaged (lesion typically extends beyond X-ray abnormality). "
     "T1 hypointense, T2 hyperintense with large soft tissue component. "
     "Used to plan surgery/radiation field. Repeat after neoadjuvant chemotherapy."],
    ["CT Chest",
     "Baseline staging – lungs are MOST COMMON site of metastasis (&gt;20% at presentation). "
     "Repeat after chemotherapy before definitive local treatment."],
    ["Bone Scan (Tc-99m)",
     "Bone is 2nd most common site of metastasis. Detects skip lesions and distant bone involvement."],
    ["FDG PET/CT",
     "High sensitivity and accuracy for diagnosis, staging, detection of recurrence. "
     "Can replace bone marrow biopsy at some centres for staging."],
    ["Bone marrow biopsy",
     "Posterior iliac crest biopsy at some centres to rule out diffuse marrow involvement. "
     "FDG-PET increasingly used as alternative."],
    ["Whole-body MRI",
     "Some centres use for staging; excellent sensitivity for bone marrow involvement."],
]
story.append(simple_table(img_data[0], img_data[1:], col_widths=[4*cm, 11*cm]))
story.append(sp(4))
story.append(exam_box(
    "Classic X-ray = \"onion skin\" periosteal reaction in diaphysis. "
    "MRI of entire bone is mandatory. Lungs = most common metastatic site. "
    "Always check chest CT and bone scan at baseline."
))

# 2.5 STAGING
story.append(sp(8))
story.append(h1("2.5  Staging (Enneking System for Bone Sarcomas)"))
story.append(hr())
story.append(p(
    "All Ewing sarcomas are <b>high grade (Grade II)</b> by definition. "
    "Enneking staging is used for surgical planning."
))
enneking_data = [
    ["Stage", "Grade", "Site", "Metastasis", "Ewing's Sarcoma"],
    ["IA", "G1 (Low)", "T1 (Intracompartmental)", "M0", "Not applicable (Ewing = always high grade)"],
    ["IB", "G1 (Low)", "T2 (Extracompartmental)", "M0", "Not applicable"],
    ["IIA", "G2 (High)", "T1 (Intracompartmental)", "M0", "Localised, intracompartmental"],
    ["IIB", "G2 (High)", "T2 (Extracompartmental)", "M0", "<b>MOST Ewing's sarcomas at diagnosis</b>"],
    ["III", "Any", "Any", "M1 (Regional/distant)", "~25% at presentation (poor prognosis)"],
]
story.append(simple_table(
    enneking_data[0], enneking_data[1:],
    col_widths=[2*cm, 2.5*cm, 4*cm, 2.5*cm, 4*cm]
))
story.append(sp(4))
story.append(p(
    "<b>Resection margins (Enneking):</b> Intralesional → Marginal → Wide → Radical. "
    "Goal in Ewing sarcoma: <b>WIDE excision</b> margins when surgery is chosen for local control."
))

# 2.6 MANAGEMENT ─── EMPHASIS
story.append(sp(8))
story.append(h1("2.6  Management of Ewing's Sarcoma"))
story.append(hr(color=TEAL, width=2))
story.append(p(
    "Management is <b>multimodal</b> and requires a multidisciplinary team (orthopaedic oncologist, "
    "medical oncologist, radiation oncologist, paediatric oncologist, pathologist, radiologist). "
    "<b>CHEMOTHERAPY IS MANDATORY</b> – without it, long-term survival was &lt;10%; "
    "with modern multidrug regimens, 60-75% 5-year survival for localised disease."
))
story.append(sp(4))

story.append(h2("Overview of Treatment Strategy"))
overview_data = [
    ["Phase", "Treatment", "Duration / Details"],
    ["1. Neoadjuvant Chemotherapy", "VDC/IE alternating regimen", "~12-18 weeks (4-6 cycles)"],
    ["2. Local Control", "Surgery (Wide resection) ± Radiation", "After neoadjuvant chemo; re-stage first"],
    ["3. Adjuvant Chemotherapy", "Continue same regimen", "Total ~10-12 months"],
    ["Metastatic disease", "Same ± high-dose chemo + auto-SCT", "Poor prognosis; investigational"],
]
story.append(simple_table(
    overview_data[0], overview_data[1:],
    col_widths=[4.5*cm, 5.5*cm, 5*cm]
))
story.append(sp(6))

story.append(h2("A. Chemotherapy (Systemic Treatment)"))
story.append(p(
    "Chemotherapy treats <b>micrometastatic disease</b> that is assumed present at diagnosis "
    "(hence the pre-surgical 'neoadjuvant' phase) and reduces local tumour volume to facilitate surgery."
))
story.append(p("<b>Standard Regimen – VDC/IE alternating (every 2-3 weeks):</b>"))

chemo_data = [
    ["Regimen", "Drugs", "Cycle"],
    ["VDC", "Vincristine + Doxorubicin (Adriamycin) + Cyclophosphamide",
     "Alternates with IE (every 2 weeks with G-CSF support)"],
    ["IE", "Ifosfamide + Etoposide", "Alternates with VDC"],
    ["VAIA (European)", "Vincristine + Actinomycin-D + Ifosfamide + Doxorubicin",
     "Used in European EURO-EWING studies"],
    ["VIDE (induction)", "Vincristine + Ifosfamide + Doxorubicin + Etoposide",
     "Induction in Euro-Ewing 99; 6 cycles"],
    ["High-dose chemo + auto-SCT",
     "Busulfan + Melphalan (BuMel)", "For high-risk/metastatic: consolidation after standard chemo"],
]
story.append(simple_table(
    chemo_data[0], chemo_data[1:],
    col_widths=[3.5*cm, 6*cm, 5.5*cm]
))
story.append(sp(4))
story.append(p("<b>Response assessment:</b> After neoadjuvant chemotherapy:"))
resp_list = [
    "Repeat staging: X-ray (increased ossification), repeat MRI (decreased soft tissue mass), CT chest",
    "<b>Histological response:</b> &gt;95-100% necrosis = \"good response\" (favourable prognosis)",
    "Good histological response associated with improved event-free survival",
    "FDG-PET has prognostic value for assessing histological response",
]
for r in resp_list:
    story.append(b(r))
story.append(sp(6))

story.append(h2("B. Local Control: Surgery vs Radiation"))
story.append(p(
    "<b>Ewing sarcoma is radiosensitive</b> (unlike osteosarcoma), so radiation is a viable option. "
    "However, wide surgical resection is preferred when feasible due to lower local recurrence rates "
    "and avoidance of radiation-related complications (growth disturbance, secondary malignancy, fibrosis)."
))
story.append(sp(4))

lc_data = [
    ["Modality", "Indications", "Advantages", "Disadvantages"],
    ["Wide Surgical\nResection\n(PREFERRED)",
     "Accessible lesion; acceptable functional deficit; wide margins achievable; "
     "distal extremity tumours; small tumours after chemo response",
     "Lower local recurrence (&lt;10%); avoids radiation sequelae; "
     "allows histological response grading; better local control",
     "Functional loss; complex reconstruction needed; "
     "not feasible for all locations"],
    ["Radiation Therapy\n(ALTERNATIVE)",
     "Unresectable tumour (spine, pelvis, skull); would require mutilating surgery; "
     "marginal/contaminated resection; patient refusal of surgery",
     "Limb/organ preservation; avoids surgery morbidity; "
     "effective for radiosensitive Ewing's",
     "Long-term: growth disturbance in children, secondary sarcoma risk (1-2%), "
     "fibrosis, functional loss; does not allow histological grading"],
    ["Surgery + Radiation\n(COMBINED)",
     "Marginal or contaminated wide resection; close/positive margins post-resection",
     "Better local control than either alone when margins involved",
     "Cumulative side effects of both modalities"],
]
story.append(simple_table(
    lc_data[0], lc_data[1:],
    col_widths=[3*cm, 4.5*cm, 4*cm, 3.5*cm]
))
story.append(sp(4))
story.append(exam_box(
    "Surgery = preferred local treatment (lower local recurrence). "
    "Radiation = equally effective but has late complications (secondary sarcoma, growth arrest). "
    "Choice is INDIVIDUALISED. ALWAYS precede local treatment with neoadjuvant chemo."
))

story.append(sp(6))
story.append(h2("C. Limb Salvage vs. Amputation"))
limb_data = [
    ["Factor", "Favour Limb Salvage", "Favour Amputation"],
    ["Tumour response to chemo", "Good response (&gt;90-95% necrosis)", "Poor response; persistent large tumour"],
    ["Surgical margins achievable", "Wide margins achievable", "Only marginal or intralesional possible"],
    ["Vascular/nerve involvement", "Not encasing major vessels/nerves", "Encasing major neurovascular structures"],
    ["Functional outcome", "Expected function &gt; amputation", "Pathological fracture with contamination"],
    ["Patient age", "Older child/adult", "Very young child (complex reconstruction)"],
    ["Infection / complication", "No prior infection", "Fungal/refractory infection post-radiation"],
]
story.append(simple_table(
    limb_data[0], limb_data[1:],
    col_widths=[4*cm, 5.5*cm, 5.5*cm]
))
story.append(sp(4))
story.append(p(
    "<b>Surgical reconstruction options:</b> Endoprosthesis (most common); osteoarticular allograft; "
    "allograft-prosthesis composite; vascularised fibular graft; arthrodesis; rotationplasty "
    "(Winkelmann procedure for distal femur in young children)."
))

story.append(sp(6))
story.append(h2("D. Pelvic Ewing's Sarcoma – Special Considerations"))
story.append(p(
    "Pelvic Ewing's sarcoma carries the worst prognosis among all sites. "
    "Local treatment is controversial:"
))
pelv_list = [
    "Some centres treat with definitive radiation therapy alone (given morbidity of pelvic surgery)",
    "Others advocate combined surgery + radiation for better local control",
    "Large tumour size at presentation is common (poor prognosis)",
    "Internal hemipelvectomy or hindquarter amputation for unresectable disease",
    "Sacral involvement: complex reconstruction; high recurrence risk",
]
for pp in pelv_list:
    story.append(b(pp))

# 2.7 RADIATION
story.append(sp(8))
story.append(h1("2.7  Radiation Therapy Details"))
story.append(hr())
rad_data = [
    ["Aspect", "Details"],
    ["Radiosensitivity", "Ewing sarcoma is HIGHLY radiosensitive (unlike osteosarcoma)"],
    ["Definitive dose", "45-55.8 Gy in 1.8 Gy fractions to involved field (IMRT preferred)"],
    ["Adjuvant dose (post-surgery)", "45-50.4 Gy for positive/close margins"],
    ["Field", "Pre-chemo tumour volume + margin (not whole bone, reducing growth complications)"],
    ["Timing", "Concurrent with final chemotherapy cycles or after surgery"],
    ["Metastatic lung disease", "Whole lung irradiation (WLI): 15-18 Gy; consider for pulmonary metastases"],
    ["Complications", "Acute: skin reaction, fatigue, nausea. Late: secondary sarcoma (1-2%), "
     "growth plate arrest in children, joint fibrosis, lymphedema, bowel complications (pelvic RT)"],
    ["Children – special", "Growth disturbance; consider proton beam therapy to reduce dose to "
     "normal tissues if available"],
]
story.append(simple_table(rad_data[0], rad_data[1:], col_widths=[4.5*cm, 10.5*cm]))

# 2.8 PROGNOSIS
story.append(sp(8))
story.append(h1("2.8  Prognosis & Prognostic Factors"))
story.append(hr())
story.append(p(
    "Overall 5-year survival: <b>60-75% for localised disease</b> with current multimodal treatment. "
    "Prior to chemotherapy: &lt;10%. <b>Metastatic disease at presentation: 20-30%</b> long-term survival."
))
story.append(sp(4))

pf_data = [
    ["Prognostic Factor", "Good Prognosis", "Poor Prognosis"],
    ["Metastases at presentation", "Absent (localised disease)", "<b>WORST factor:</b> metastases present"],
    ["Histological response to chemo", "&gt;95% necrosis (good response)", "&lt;90% necrosis (poor response)"],
    ["Tumour size / volume", "&lt;8 cm / &lt;200 mL", "&gt;8 cm / &gt;200 mL (most important size cutoff)"],
    ["Location", "Distal extremity", "Pelvis, proximal femur, spine, ribs"],
    ["LDH level", "Normal", "<b>Elevated LDH = poor prognosis</b>"],
    ["Age", "Younger (&lt;14-15 years)", "Older age (&gt;17-18 years)"],
    ["Fever / WBC / ESR", "Absent", "Present (indicates more extensive disease)"],
    ["Time to relapse", "Late (&gt;2 years)", "Early relapse (&lt;2 years) – very poor outcome"],
    ["Histological grade", "N/A", "All Ewing = high grade (no prognostic value within Ewing)"],
    ["p53 mutation", "Absent", "p53 mutation = poor prognostic marker"],
]
story.append(simple_table(
    pf_data[0], pf_data[1:],
    col_widths=[4.5*cm, 4*cm, 6.5*cm]
))
story.append(sp(4))
story.append(exam_box(
    "WORST prognostic factor = metastases at presentation (only 20-30% survival). "
    "Histological response (&gt;95% necrosis) is key. Elevated LDH = poor prognosis. "
    "Pelvis = worst site; distal extremity = best site."
))

# 2.9 RECURRENCE
story.append(sp(8))
story.append(h1("2.9  Recurrence & Salvage Treatment"))
story.append(hr())
rec_list = [
    "Overall recurrence rate: ~30-40% for localised disease; higher for metastatic disease",
    "<b>Local recurrence:</b> ~20% 5-year survival",
    "<b>Distant recurrence (metastases):</b> ~10% 5-year survival",
    "Time to relapse is critical: relapse within 1 year = &lt;10% survival; "
    "late relapse (&gt;2 years) = marginally better outcomes",
    "<b>Salvage options:</b> Second-line chemotherapy (topotecan + cyclophosphamide; "
    "irinotecan + temozolomide); re-irradiation; surgery; high-dose chemo + autologous SCT",
    "Novel agents under investigation: IGF-1R inhibitors, PARP inhibitors, immune checkpoint inhibitors",
    "Follow-up imaging: chest X-ray/CT 3-6 monthly for first 2-3 years; then annually",
]
for rl in rec_list:
    story.append(b(rl))

# 2.10 HIGH-YIELD SUMMARY
story.append(sp(8))
story.append(h1("2.10  High-Yield Summary Table: Ewing's Sarcoma"))
story.append(hr())
hy_ewing = [
    ["Feature", "Key Point"],
    ["Family", "Ewing family of tumours: Ewing sarcoma, PNET, Askin tumour (chest wall)"],
    ["Age", "Peak 10-20 years; most common bone sarcoma &lt;10 years"],
    ["Race", "Rare in individuals of African descent"],
    ["Translocation", "<b>t(11;22)(q24;q12)</b> → EWS-FLI1 fusion (&gt;85%)"],
    ["IHC", "CD99 (MIC-2) strongly +ve; PAS +ve (glycogen); CK negative; LCA negative"],
    ["Histology", "Small round blue cells; sheet-like; Homer-Wright pseudorosettes in PNET"],
    ["Most common site", "Femoral diaphysis / metaphysis; flat bones (pelvis, ribs)"],
    ["Classic X-ray", "\"Onion skin\" periosteal reaction; diaphyseal permeative destruction"],
    ["Soft tissue mass", "Typically large; better seen on MRI"],
    ["Most common metastatic site", "Lungs (CT chest mandatory)"],
    ["Mimic", "Osteomyelitis (fever, elevated WBC, ESR, pus-like aspirate)"],
    ["Differential (small blue cells)", "Lymphoma, PNET, neuroblastoma, rhabdomyosarcoma, "
     "small cell osteosarcoma"],
    ["Staging system", "Enneking; all Ewing = high grade (Grade II/III)"],
    ["Treatment principle", "Multimodal: CHEMO (mandatory) + Local control (surgery preferred)"],
    ["Standard chemo", "VDC/IE alternating (Vincristine + Doxorubicin + Cyclophosphamide / "
     "Ifosfamide + Etoposide)"],
    ["Local treatment preferred", "Wide surgical resection (if feasible, &lt;10% local recurrence)"],
    ["Radiation", "Alternative to surgery; effective but risk of secondary sarcoma"],
    ["Good histological response", "&gt;95% necrosis after neoadjuvant chemo = favourable prognosis"],
    ["5-year survival (localised)", "60-75% with modern treatment"],
    ["5-year survival (metastatic)", "20-30%"],
    ["Worst prognostic factor", "Metastases at presentation"],
    ["LDH significance", "Elevated LDH = poor prognosis"],
    ["Local recurrence survival", "~20% at 5 years"],
    ["Distant recurrence survival", "~10% at 5 years"],
]
story.append(simple_table(hy_ewing[0], hy_ewing[1:], col_widths=[5*cm, 10*cm]))
story.append(PageBreak())

# ═══════════════════════════════════════════════════════════════════════════════
# PART 3  ──  COMPARISON TABLE
# ═══════════════════════════════════════════════════════════════════════════════
story.append(chapter_banner("PART 3: PAGET'S DISEASE vs. EWING'S SARCOMA – COMPARISON", MID_BLUE))
story.append(sp(10))

comp_tbl_data = [
    ["Parameter", "Paget's Disease of Bone", "Ewing's Sarcoma"],
    ["Definition", "Metabolic bone disease; disordered remodelling",
     "Primary malignant bone tumour; Ewing family of tumours"],
    ["Age", "Rare &lt;40; mostly 50-70+ years", "Peak 10-20 years; most common &lt;10 years"],
    ["Sex", "Males &gt; Females", "Slightly more in males"],
    ["Aetiology/Genetics",
     "RANK/OPG mutations; paramyxoviral (?); multifactorial",
     "t(11;22)(q24;q12) → EWS-FLI1 fusion"],
    ["Common sites", "Pelvis, spine, skull, femur, tibia",
     "Femoral diaphysis, pelvis, ribs; any site"],
    ["Pain", "Aching, chronic, site-specific", "Insidious, may mimic osteomyelitis"],
    ["Classic X-ray", "\"Cotton wool\" skull; \"Picture frame\" vertebra; "
     "\"Blade of grass\" long bone",
     "\"Onion skin\" periosteal reaction; permeative destruction"],
    ["Biochemical markers", "Elevated ALP; normal Ca & PO4",
     "Elevated ESR, WBC, LDH; ALP variable"],
    ["Histology", "Mosaic cement lines; giant osteoclasts; "
     "disorganised woven + lamellar bone",
     "Small round blue cells; PAS+ve; CD99 strongly +ve"],
    ["Diagnosis", "X-ray + Bone scan + ALP", "X-ray + MRI + Biopsy + Molecular"],
    ["Mainstay treatment", "Bisphosphonates (zoledronic acid first-line)",
     "Multimodal: Chemo (VDC/IE) + Surgery ± Radiation"],
    ["Role of surgery", "THA/TKA for OA; ORIF for fractures; "
     "decompression for neural compression",
     "Wide resection = preferred local control; amputation if needed"],
    ["Radiation therapy", "Used for bone pain (palliative); "
     "giant cell tumour variant responds to steroids",
     "Definitive or adjuvant; tumour is radiosensitive"],
    ["Chemotherapy", "Not primary treatment; sarcoma chemo if "
     "transformation occurs",
     "MANDATORY; VDC/IE; neoadjuvant + adjuvant"],
    ["Dreaded complication", "Sarcomatous transformation (&lt;0.5%): osteosarcoma",
     "Metastases (lungs, bone); recurrence"],
    ["Prognosis (overall)", "Good with treatment; normal life expectancy except if sarcoma",
     "Localised: 60-75% 5-yr survival; Metastatic: 20-30%"],
    ["Worst outcome scenario", "Sarcomatous transformation (&lt;5-10% 5-yr survival)",
     "Metastases at presentation (20-30% 5-yr survival)"],
    ["Monitoring", "ALP (3-6 monthly); bone scan for extent",
     "CT chest + bone scan/PET every 3-6 months x 3 years"],
]
story.append(simple_table(
    comp_tbl_data[0], comp_tbl_data[1:],
    col_widths=[4*cm, 6.5*cm, 4.5*cm]
))

story.append(sp(12))
story.append(h1("Quick Recall Mnemonics"))
story.append(hr())

story.append(h2("Paget's Disease of Bone – \"PAGETS\""))
mnem_paget = [
    "<b>P</b> – Pelvis (most common site); Pain (dull, aching)",
    "<b>A</b> – ALP elevated (normal Ca; normal PO4)",
    "<b>G</b> – Giant osteoclasts; Genetics (RANK, OPG mutations)",
    "<b>E</b> – Enlarged skull / bone; Etidronate (first gen, least effective)",
    "<b>T</b> – Transformation to sarcoma (&lt;0.5%); Tibia (sabre tibia, chalk-stick Fx)",
    "<b>S</b> – Scan (bone scan = most sensitive); Surgery pre-treat with bisphosphonates; "
    "Zoledronic acid = 1st choice (5 mg IV = 90% ALP normalisation)",
]
for m in mnem_paget:
    story.append(b(m))

story.append(sp(6))
story.append(h2("Ewing's Sarcoma – \"EWING\""))
mnem_ewing = [
    "<b>E</b> – EWS-FLI1 fusion t(11;22); Elevated LDH = poor prognosis",
    "<b>W</b> – White cell count elevated (mimics osteomyelitis); Wide resection preferred",
    "<b>I</b> – IE regimen (Ifosfamide + Etoposide) alternates with VDC; "
    "IHC = CD99 strongly positive",
    "<b>N</b> – No African descent affected (exceedingly rare); Neoadjuvant chemo MANDATORY",
    "<b>G</b> – Glycogen positive (PAS+ve); Grade II/III (all high grade); "
    "Good response = &gt;95% necrosis",
]
for m in mnem_ewing:
    story.append(b(m))

story.append(sp(12))
story.append(hr(color=DARK_BLUE))
story.append(Paragraph(
    "References: Campbell's Operative Orthopaedics 15th Ed 2026 | Harrison's 22E 2025 | "
    "Rockwood &amp; Green's 10th Ed 2025 | Miller's Review of Orthopaedics 9th Ed | "
    "Katzung Pharmacology 16th Ed | Firestein &amp; Kelley's Rheumatology | "
    "Endocrine Society Paget's Guidelines 2014",
    S_footer_note
))

# ─── PAGE NUMBER HEADER/FOOTER ────────────────────────────────────────────────
def on_page(canvas, doc):
    canvas.saveState()
    # Header
    canvas.setFillColor(DARK_BLUE)
    canvas.setFont("Helvetica-Bold", 8)
    canvas.drawString(2*cm, H - 1.5*cm, "Paget's Disease & Ewing's Sarcoma | Ortho PG Notes")
    canvas.drawRightString(W - 2*cm, H - 1.5*cm, "July 2026")
    # Footer
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(HexColor("#718096"))
    canvas.drawCentredString(W/2, 1.4*cm, f"Page {doc.page}")
    canvas.setStrokeColor(DARK_BLUE)
    canvas.setLineWidth(0.5)
    canvas.line(2*cm, H - 1.8*cm, W - 2*cm, H - 1.8*cm)
    canvas.line(2*cm, 1.8*cm, W - 2*cm, 1.8*cm)
    canvas.restoreState()

doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF generated: {OUTPUT_PATH}")
print(f"File size: {os.path.getsize(OUTPUT_PATH) / 1024:.1f} KB")
Running Command

cd /tmp/workspace/ortho-pg-pdf && python generate_pdf.py 2>&1

PDF generated successfully. Let me verify its page count:
Running Command

python3 -c "from pypdf import PdfReader; r = PdfReader('/tmp/workspace/ortho-pg-pdf/Pagets_Ewings_Ortho_PG.pdf'); print(f'Pages: {len(r.pages)}')"

Your PDF is ready - 18 pages of exam-focused content:

Pagets Ewings Ortho PG

PDF Document · PDF


Here's what's inside (sourced from Campbell's Operative Orthopaedics 15th Ed 2026, Harrison's 22E 2025, Rockwood & Green's 10th Ed 2025, and Miller's Review 9th Ed):

PART 1 - Paget's Disease of Bone (8 pages)

Sections covered:
  • Epidemiology & aetiology (RANK/OPG genetics, paramyxoviral theory, geographic prevalence)
  • 3-phase pathophysiology table (lytic → mixed → sclerotic) with X-ray correlates
  • Clinical features by site (skull, spine, pelvis, long bones, CVS, neurological)
  • Investigations: ALP, PINP, telopeptides, bone scan, X-ray signs (cotton wool, picture frame, blade of grass, chalk-stick fracture)
  • Complications including sarcomatous transformation (<0.5%)
  • Full drug table with management emphasis: Zoledronic acid (5 mg IV = 90% ALP normalisation, first-choice), Risedronate, Alendronate, Pamidronate, Calcitonin - doses, efficacy, exam points
  • Orthopaedic surgical management: THA/TKA, ORIF, spinal decompression, pre-op bisphosphonate protocol
  • High-yield summary table + mnemonic (PAGETS)

PART 2 - Ewing's Sarcoma (7 pages)

Sections covered:
  • Epidemiology (peak 10-20 yrs, most common <10 yrs, exceedingly rare in African descent)
  • Molecular biology: t(11;22)(q24;q12) → EWS-FLI1, CD99/MIC-2 positivity, PAS+ve
  • IHC panel differentials (lymphoma, neuroblastoma, rhabdomyosarcoma)
  • Clinical features including classic osteomyelitis mimic (34-week average diagnostic delay)
  • Imaging: onion-skin periosteal reaction, MRI whole bone mandatory, CT chest, PET/CT
  • Enneking staging
  • Management emphasis: VDC/IE chemotherapy is MANDATORY; surgery vs radiation decision framework; limb salvage vs amputation table; pelvic Ewing's special considerations; radiation doses and complications; histological response grading (>95% necrosis = good)
  • Prognosis table by factor (LDH, size, location, metastases, histological response)
  • Recurrence and salvage options
  • High-yield summary table + mnemonic (EWING)

PART 3 - Side-by-Side Comparison Table

Full parameter-by-parameter comparison of both conditions plus quick recall mnemonics for exams.

Make me pdf on pagets disease and ewings sarcoma for orthopedics pg examination with emphasis on management

Reading File
Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.