Analysis this question paper and give perfect answer
| Type | Features |
|---|---|
| Homogeneous | Uniform flat white plaque; smooth or finely wrinkled; low malignant potential |
| Non-homogeneous | Irregular surface; higher malignant potential |
| - Erythroleukoplakia | Mixed red and white areas (speckled) |
| - Verrucous | Irregular, corrugated, exophytic |
| - Nodular | Small red/white nodular projections |
| Proliferative Verrucous (PVL) | Multifocal, irreversible, highest malignant potential; F>M; HPV-associated |
| Feature | NF-1 (von Recklinghausen's) | NF-2 |
|---|---|---|
| Gene | NF1 on chromosome 17q11.2 | NF2 on chromosome 22q12 |
| Gene product | Neurofibromin | Merlin/Schwannomin |
| Prevalence | 1:3000 (most common) | 1:25,000 |
| Main features | Multiple neurofibromas + cafe-au-lait spots | Bilateral acoustic neuromas |
| Letter | Feature | Normal | Suspicious |
|---|---|---|---|
| A | Asymmetry | Symmetrical (fold equals both halves) | Asymmetrical - one half doesn't match the other |
| B | Border | Regular, well-defined smooth border | Irregular, notched, scalloped, or indistinct borders |
| C | Color | Uniform single color | Variegated - multiple shades of brown, black, red, white, blue |
| D | Diameter | <6mm | >6mm (size of a pencil eraser); however, amelanotic melanomas can be smaller |
| E | Evolution | Stable lesion | Any change in size, shape, color, bleeding, itching over time |
4 mm: Poor prognosis
| Variant | Description | Associated HL subtype |
|---|---|---|
| Classic RS | Binucleated, owl-eye nucleoli | Mixed cellularity, nodular sclerosis |
| Lacunar cells | Retraction artifact in formalin; nucleus sits in clear space (lacuna) | Nodular sclerosis |
| Mononuclear (Hodgkin cell) | Single nucleus, prominent nucleolus | All subtypes |
| Lymphocytic/Histiocytic (L&H/"Popcorn") | Multilobated nucleus, small nucleolus, pale chromatin | Nodular lymphocyte predominant HL |
| Feature | Fibrous Dysplasia | Ossifying Fibroma |
|---|---|---|
| Bone trabeculae | Chinese letter/irregular woven bone | Rounded/spherical bony lamellae |
| Osteoblastic rimming | ABSENT | PRESENT |
| Border | Blends with normal bone | Well-defined, encapsulated |
| Recurrence | Low (burns out after puberty) | Tends to recur |
| Feature | NF-1 (von Recklinghausen) | McCune-Albright Syndrome |
|---|---|---|
| Number | 6 or more (diagnostic) | Fewer, but larger |
| Size | >5mm (pre-pubertal); >15mm (post-pubertal) | Large |
| Border | Irregular - "Coast of California" | Smooth - "Coast of Maine" |
| Distribution | Generalized | Unilateral (follows Blaschko's lines) |
Create a comprehensive study guide PDF for oral pathology
ls /home/daytona/workspace/ && mkdir -p /home/daytona/workspace/oral-path-guide
~/oral-path-guide/generate_study_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
from reportlab.lib.colors import HexColor
import os
OUTPUT_PATH = "/home/daytona/workspace/oral-path-guide/Oral_Pathology_Study_Guide.pdf"
# ── Color Palette ──────────────────────────────────────────────────
NAVY = HexColor("#1A237E")
TEAL = HexColor("#00695C")
ORANGE = HexColor("#E65100")
LIGHT_BLUE = HexColor("#E3F2FD")
LIGHT_GREEN= HexColor("#E8F5E9")
LIGHT_ORANGE=HexColor("#FFF3E0")
LIGHT_TEAL = HexColor("#E0F2F1")
GOLD = HexColor("#F9A825")
WHITE = colors.white
DARK_GRAY = HexColor("#37474F")
MID_GRAY = HexColor("#90A4AE")
LIGHT_GRAY = HexColor("#ECEFF1")
RED_DARK = HexColor("#B71C1C")
PURPLE = HexColor("#4A148C")
# ── Styles ─────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("DocTitle",
fontSize=28, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=34, spaceAfter=6)
subtitle_style = S("DocSubtitle",
fontSize=14, textColor=HexColor("#B3E5FC"), fontName="Helvetica",
alignment=TA_CENTER, leading=18)
part_style = S("Part",
fontSize=20, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=26)
h1_style = S("H1",
fontSize=16, textColor=NAVY, fontName="Helvetica-Bold",
spaceBefore=14, spaceAfter=6, leading=20,
borderPad=4)
h2_style = S("H2",
fontSize=13, textColor=TEAL, fontName="Helvetica-Bold",
spaceBefore=10, spaceAfter=4, leading=17)
h3_style = S("H3",
fontSize=11, textColor=ORANGE, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3, leading=14)
body_style = S("Body",
fontSize=10, textColor=DARK_GRAY, fontName="Helvetica",
spaceBefore=3, spaceAfter=3, leading=14, alignment=TA_JUSTIFY)
bullet_style = S("Bullet",
fontSize=10, textColor=DARK_GRAY, fontName="Helvetica",
spaceBefore=2, spaceAfter=2, leading=13,
leftIndent=16, bulletIndent=6)
note_style = S("Note",
fontSize=9.5, textColor=RED_DARK, fontName="Helvetica-BoldOblique",
spaceBefore=4, spaceAfter=4, leading=13,
leftIndent=10)
mnemonic_style = S("Mnemonic",
fontSize=10, textColor=PURPLE, fontName="Helvetica-Bold",
spaceBefore=4, spaceAfter=4, leading=14,
leftIndent=10)
def B(text): return f"<b>{text}</b>"
def I(text): return f"<i>{text}</i>"
def BI(text): return f"<b><i>{text}</i></b>"
def C(text, c): return f'<font color="{c}">{text}</font>'
def p(text, style=None): return Paragraph(text, style or body_style)
def h1(text): return Paragraph(text, h1_style)
def h2(text): return Paragraph(text, h2_style)
def h3(text): return Paragraph(text, h3_style)
def bp(text): return Paragraph(f"• {text}", bullet_style)
def note(text): return Paragraph(f"★ {text}", note_style)
def mnemonic(text): return Paragraph(f"🔑 {text}", mnemonic_style)
def sp(n=6): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.5, color=MID_GRAY, spaceAfter=4, spaceBefore=4)
def colored_box(content_list, bg_color=LIGHT_BLUE, border_color=NAVY):
"""Wrap content in a colored box using a 1-cell table."""
inner = Table([[content_list]], colWidths=["100%"])
inner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("BOX", (0,0), (-1,-1), 1, border_color),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return inner
def make_table(headers, rows, col_widths=None, header_bg=NAVY, alt_bg=LIGHT_BLUE):
"""Helper to build a styled table."""
data = [[Paragraph(B(h), S("th", fontSize=9.5, textColor=WHITE,
fontName="Helvetica-Bold", leading=13))
for h in headers]]
for i, row in enumerate(rows):
data.append([Paragraph(str(cell),
S(f"td{i}", fontSize=9, textColor=DARK_GRAY,
fontName="Helvetica", leading=12))
for cell in row])
page_w = A4[0] - 4*cm
if col_widths is None:
col_widths = [page_w / len(headers)] * len(headers)
t = Table(data, colWidths=col_widths)
style = [
("BACKGROUND", (0,0), (-1,0), header_bg),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9.5),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, alt_bg]),
("GRID", (0,0), (-1,-1), 0.4, MID_GRAY),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]
t.setStyle(TableStyle(style))
return t
# ══════════════════════════════════════════════════════════════════
# PAGE TEMPLATE WITH HEADER/FOOTER
# ══════════════════════════════════════════════════════════════════
class OralPathDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
BaseDocTemplate.__init__(self, filename, **kw)
frame = Frame(self.leftMargin, self.bottomMargin,
self.width, self.height, id="main")
template = PageTemplate(id="main", frames=frame,
onPage=self._on_page)
self.addPageTemplates([template])
def _on_page(self, canvas, doc):
canvas.saveState()
# Header bar (skip page 1 - cover)
if doc.page > 1:
canvas.setFillColor(NAVY)
canvas.rect(0, A4[1]-1.1*cm, A4[0], 1.1*cm, fill=1, stroke=0)
canvas.setFont("Helvetica-Bold", 9)
canvas.setFillColor(WHITE)
canvas.drawString(1.5*cm, A4[1]-0.75*cm, "ORAL PATHOLOGY & MICROBIOLOGY – COMPREHENSIVE STUDY GUIDE")
canvas.drawRightString(A4[0]-1.5*cm, A4[1]-0.75*cm, f"Page {doc.page}")
# Footer
canvas.setFillColor(LIGHT_GRAY)
canvas.rect(0, 0, A4[0], 0.8*cm, fill=1, stroke=0)
canvas.setFont("Helvetica", 7.5)
canvas.setFillColor(DARK_GRAY)
canvas.drawCentredString(A4[0]/2, 0.28*cm,
"III BDS – Rajiv Gandhi University of Health Sciences | For Educational Purposes Only")
canvas.restoreState()
# ══════════════════════════════════════════════════════════════════
# COVER PAGE
# ══════════════════════════════════════════════════════════════════
def cover_page():
elems = []
# Big colored header block
cover_table = Table(
[[Paragraph("ORAL PATHOLOGY", title_style)],
[Paragraph("& MICROBIOLOGY", title_style)],
[sp(4)],
[Paragraph("COMPREHENSIVE STUDY GUIDE", subtitle_style)],
[sp(8)],
[Paragraph("III BDS • Rajiv Gandhi University of Health Sciences, Karnataka", subtitle_style)],
],
colWidths=[A4[0]-4*cm]
)
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 20),
("RIGHTPADDING", (0,0), (-1,-1), 20),
("BOX", (0,0), (-1,-1), 2, GOLD),
]))
elems.append(sp(30))
elems.append(cover_table)
elems.append(sp(20))
# Info boxes
info = [
("📚 Topics Covered", "Potentially Malignant Disorders • Leukoplakia • Neural Tumors • Neurofibromatosis • Dentigerous Cyst • Solitary Bone Cyst • Pindborg Tumour • Malignant Melanoma • Lipoma • Reed-Sternberg Cells • Sjogren's Syndrome • Fibrous Dysplasia • Oral Infections & More"),
("🎯 Exam Focus", "Long Essays • Short Essays • Short Answers • Key Mnemonics • Comparison Tables • Histopathology Highlights"),
("📅 Edition", "Based on RGUHS QP Code 1188 • 17-Nov-2021 | Updated 2024"),
]
for icon_title, desc in info:
t = Table([[Paragraph(B(icon_title), S("it", fontSize=11, textColor=TEAL,
fontName="Helvetica-Bold", leading=14)),
Paragraph(desc, S("id", fontSize=9.5, textColor=DARK_GRAY,
fontName="Helvetica", leading=13))
]],
colWidths=[5*cm, A4[0]-4*cm-5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("BOX", (0,0), (-1,-1), 1, NAVY),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
elems.append(t)
elems.append(sp(8))
elems.append(PageBreak())
return elems
# ══════════════════════════════════════════════════════════════════
# TABLE OF CONTENTS
# ══════════════════════════════════════════════════════════════════
def toc_page():
elems = []
elems.append(sp(10))
elems.append(h1("TABLE OF CONTENTS"))
elems.append(hr())
elems.append(sp(6))
toc_items = [
("PART A – LONG ESSAYS", "", NAVY, True),
("1.", "Potentially Malignant Disorders & Leukoplakia", DARK_GRAY, False),
("2.", "Neural Tumors & Neurofibromatosis", DARK_GRAY, False),
("PART B – SHORT ESSAYS", "", NAVY, True),
("3.", "Radiological Variants of Dentigerous Cyst", DARK_GRAY, False),
("4.", "Solitary Bone Cyst (Traumatic Bone Cyst)", DARK_GRAY, False),
("5.", "Pindborg Tumour (CEOT)", DARK_GRAY, False),
("6.", "ABCDE Rule of Malignant Melanoma", DARK_GRAY, False),
("7.", "Lipoma", DARK_GRAY, False),
("8.", "Reed-Sternberg Cells", DARK_GRAY, False),
("9.", "Primary Sicca Syndrome (Sjogren's Syndrome)", DARK_GRAY, False),
("10.", "Histopathology of Fibrous Dysplasia", DARK_GRAY, False),
("PART C – SHORT ANSWERS", "", NAVY, True),
("11.", "Thistle Tube Pulp Chamber", DARK_GRAY, False),
("12.", "Touton Type Giant Cells", DARK_GRAY, False),
("13.", "Tadpole Shaped Cells", DARK_GRAY, False),
("14.", "Snail Track Ulcer", DARK_GRAY, False),
("15.", "Cafe-au-lait Spots", DARK_GRAY, False),
("PART D – QUICK REVISION", "", NAVY, True),
("", "Key Comparison Tables", DARK_GRAY, False),
("", "Important Mnemonics", DARK_GRAY, False),
("", "Examination Tips", DARK_GRAY, False),
]
for num, title, color, is_header in toc_items:
if is_header:
elems.append(sp(6))
row_bg = NAVY
txt = Paragraph(f"{num} {title}" if num else title,
S("toch", fontSize=11, textColor=WHITE,
fontName="Helvetica-Bold", leading=15))
else:
row_bg = LIGHT_BLUE if int(toc_items.index((num,title,color,is_header))) % 2 == 0 else WHITE
txt = Paragraph(f"{num} {title}",
S("tocb", fontSize=10, textColor=color,
fontName="Helvetica", leading=14))
t = Table([[txt]], colWidths=[A4[0]-4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), row_bg),
("TOPPADDING", (0,0), (-1,-1), 5 if is_header else 4),
("BOTTOMPADDING", (0,0), (-1,-1), 5 if is_header else 4),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 0.3, MID_GRAY),
]))
elems.append(t)
elems.append(PageBreak())
return elems
# ══════════════════════════════════════════════════════════════════
# PART A – LONG ESSAYS
# ══════════════════════════════════════════════════════════════════
def part_a():
elems = []
# Part Banner
banner = Table([[Paragraph("PART A — LONG ESSAYS (2 × 10 = 20 Marks)", part_style)]],
colWidths=[A4[0]-4*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 2, GOLD),
]))
elems.append(banner)
elems.append(sp(14))
# ── Q1: Leukoplakia ──────────────────────────────────────────
elems.append(h1("Q1. Potentially Malignant Disorders & Leukoplakia"))
elems.append(hr())
elems.append(sp(4))
elems.append(h2("A. Oral Potentially Malignant Disorders (OPMDs)"))
elems.append(p(f"{B('WHO Definition (2005, revised 2017):')} Clinical presentations that carry a risk of cancer development in the oral cavity, whether in a clinically definable precursor lesion or in clinically normal oral mucosa."))
elems.append(sp(4))
elems.append(p(B("Complete List of OPMDs:")))
opmd_items = [
("1", "Leukoplakia", "Most common OPMD; 0.2–3.4% prevalence"),
("2", "Erythroplakia", "Highest malignant transformation (~50%)"),
("3", "Erythroleukoplakia (Speckled)", "Mixed red + white; intermediate risk"),
("4", "Oral Submucous Fibrosis (OSMF)", "Areca nut chewing; Indian subcontinent"),
("5", "Oral Lichen Planus", "Erosive/atrophic types carry risk"),
("6", "Actinic Keratosis / Cheilitis", "UV radiation; lower lip"),
("7", "Palatal changes (Reverse smoking)", "Nicotinic stomatitis"),
("8", "Discoid Lupus Erythematosus", "Autoimmune; mucosal form"),
("9", "Dyskeratosis Congenita", "X-linked; leukoplakia + nail dystrophy + skin pigmentation"),
]
elems.append(make_table(["#", "Disorder", "Key Feature"],
opmd_items, [1*cm, 7*cm, 8.5*cm]))
elems.append(sp(10))
elems.append(h2("B. Leukoplakia – In Detail"))
elems.append(p(f"{B('Definition:')} A white plaque of questionable risk having excluded other known diseases or disorders that carry no increased risk for cancer. {I('(WHO 2005)')}"))
elems.append(sp(4))
elems.append(h3("Etiology"))
etiol = [
("Tobacco (most important)", "Cigarettes, bidis, hookah, smokeless – 6× increased risk"),
("Alcohol", "Potentiates tobacco effect synergistically"),
("Candida albicans", "Superimposed infection; may cause 'candidal leukoplakia'"),
("HPV (16, 18)", "Especially in Proliferative Verrucous Leukoplakia (PVL)"),
("Sanguinaria", "Herbal toothpaste ingredient; alveolar leukoplakia"),
("UV Radiation", "Actinic cheilitis of lips"),
("Nutritional deficiency", "Iron, B12, folate"),
("Idiopathic", "Up to 20% of cases; higher malignant potential"),
]
elems.append(make_table(["Cause", "Notes"], etiol, [7.5*cm, 9*cm]))
elems.append(sp(8))
elems.append(h3("Sites & Malignant Potential"))
sites = [
("Buccal Mucosa", "Most common overall site"),
("Floor of Mouth + Ventral Tongue", "HIGHEST malignant transformation potential"),
("Lower Lip", "Actinic involvement; moderate risk"),
("Commissures, Gingiva, Palate", "Variable"),
("Retromolar Pad", "High risk"),
]
elems.append(make_table(["Site", "Note"], sites, [8*cm, 8.5*cm]))
elems.append(sp(8))
elems.append(h3("Clinical Classification"))
clin = [
("Homogeneous", "Uniform flat white plaque; smooth/finely wrinkled surface", "LOW"),
("Non-homogeneous – Erythroleukoplakia", "Mixed red and white (speckled)", "HIGH"),
("Non-homogeneous – Verrucous", "Irregular, corrugated, exophytic surface", "HIGH"),
("Non-homogeneous – Nodular", "Small red/white nodular projections", "HIGH"),
("Proliferative Verrucous (PVL)", "Multifocal, irreversible; F>M; HPV assoc.", "HIGHEST"),
]
elems.append(make_table(["Type", "Features", "Malignant Risk"],
clin, [4.5*cm, 9*cm, 3*cm]))
elems.append(sp(8))
elems.append(h3("Histopathology & Epithelial Dysplasia Grading"))
elems.append(p("The epithelium shows hyperkeratosis (hyperorthokeratosis or hyperparakeratosis) and acanthosis. The key finding is epithelial dysplasia graded as:"))
dysplasia = [
("Mild", "Lower 1/3 of epithelium involved", "Low risk"),
("Moderate", "Lower 2/3 of epithelium", "Intermediate"),
("Severe", ">2/3 but basement membrane intact", "High risk"),
("Carcinoma in Situ", "Full thickness; BM intact", "Treat as malignant"),
]
elems.append(make_table(["Grade", "Extent", "Clinical Implication"],
dysplasia, [4*cm, 8*cm, 4.5*cm]))
elems.append(sp(6))
elems.append(p(B("WHO Criteria for Dysplasia (any 5+ = dysplasia):")))
for feat in [
"Loss of polarity of basal cells",
"Basal cell hyperplasia",
"Drop-shaped rete ridges",
"Increased nuclear:cytoplasmic (N:C) ratio",
"Nuclear hyperchromatism & pleomorphism",
"Abnormal mitoses (esp. in upper layers)",
"Individual cell keratinization (dyskeratosis)",
"Loss of cellular cohesion",
"Two-cell-thick or thicker suprabasal mitoses",
]:
elems.append(bp(feat))
elems.append(sp(8))
elems.append(h3("Risk Factors for Malignant Transformation"))
elems.append(mnemonic("Mnemonic: 'FANSLD' – Female, Alveolar/FOM, Non-smoker, Size >200mm², Long duration, Dysplasia present"))
risk = [
("Non-homogeneous type", "High"),
("Floor of mouth / ventral tongue", "High"),
("Female gender, non-smoker (paradox)", "High"),
("Moderate-severe dysplasia on biopsy", "Very High"),
("Size > 200 mm2", "High"),
("Duration > 5 years", "Moderate"),
("Idiopathic leukoplakia", "Higher than tobacco-related"),
("PVL subtype", "Highest – nearly all transform"),
]
elems.append(make_table(["Risk Factor", "Level"], risk, [10*cm, 6.5*cm]))
elems.append(sp(8))
elems.append(h3("Management"))
mgmt = [
("Step 1", "Eliminate etiology (tobacco cessation, antifungals)"),
("Step 2", "Biopsy – punch/incisional (mandatory for diagnosis and dysplasia grading)"),
("Step 3", "Surgical excision (gold standard) or CO2 laser ablation"),
("Step 4", "Photodynamic therapy (PDT) – alternative"),
("Step 5", "Topical retinoids (high recurrence ~30%)"),
("Step 6", "Lifelong follow-up every 3–6 months"),
]
elems.append(make_table(["Step", "Action"], mgmt, [2.5*cm, 14*cm]))
elems.append(sp(4))
elems.append(note("Overall malignant transformation rate: 0.7–2.9%. Recurrence after treatment: 10–34%."))
elems.append(sp(10))
elems.append(PageBreak())
# ── Q2: Neural Tumors & Neurofibromatosis ──────────────────────
elems.append(h1("Q2. Neural Tumors – Classification & Neurofibromatosis"))
elems.append(hr())
elems.append(sp(4))
elems.append(h2("A. Classification of Neural Tumors"))
neural_class = [
("Traumatic Neuroma", "Benign", "Non-neoplastic; most common; lip/mental nerve"),
("Palisaded Encapsulated Neuroma (PEN)", "Benign", "Palate; encapsulated; no systemic association"),
("Neurofibroma", "Benign", "NF-1 associated; plexiform is pathognomonic"),
("Schwannoma (Neurilemmoma)", "Benign", "Encapsulated; Antoni A & B; S-100+"),
("Granular Cell Tumor", "Benign", "Tongue; pseudoepitheliomatous hyperplasia above"),
("Mucosal Neuroma", "Benign", "MEN 2B; tongue/lips"),
("MPNST", "Malignant", "Arises in NF-1; poor prognosis"),
("Neuroblastoma", "Malignant", "Children; adrenal/jaw"),
("PNET", "Malignant", "Primitive neuroectodermal tumor"),
("Malignant Granular Cell Tumor", "Malignant", "Rare; rapid growth"),
]
elems.append(make_table(["Tumor", "Nature", "Key Feature"],
neural_class, [6*cm, 3*cm, 7.5*cm]))
elems.append(sp(10))
elems.append(h2("B. Neurofibromatosis – Types"))
nf_types = [
("Gene", "NF1 – chr. 17q11.2", "NF2 – chr. 22q12"),
("Gene product", "Neurofibromin (tumor suppressor)", "Merlin / Schwannomin"),
("Prevalence", "1 : 3,000 (most common)", "1 : 25,000"),
("Inheritance", "Autosomal dominant (50% new mutation)", "Autosomal dominant"),
("Hallmark", "Multiple neurofibromas + CAL spots", "Bilateral acoustic neuromas"),
("Lisch nodules", "Present (iris hamartomas)", "Absent"),
]
elems.append(make_table(["Feature", "NF-1 (von Recklinghausen)", "NF-2"],
nf_types, [4.5*cm, 7.5*cm, 4.5*cm]))
elems.append(sp(10))
elems.append(h2("C. NF-1 Diagnostic Criteria (NIH) – 2 or more required"))
elems.append(mnemonic("Mnemonic: 'CALF On Spine' – CAL spots (6+), Axillary freckling, Lisch nodules, Fibromas (2+), Optic glioma, Neurofibromas (plexiform), Skeletal dysplasia, First-degree relative"))
nih = [
("1", "Six or more cafe-au-lait macules", ">5 mm prepubertal; >15 mm postpubertal"),
("2", "Two or more neurofibromas / 1 plexiform", "Plexiform is pathognomonic of NF-1"),
("3", "Axillary / inguinal freckling", "Crowe's sign"),
("4", "Optic pathway glioma", "Most common CNS tumor in NF-1"),
("5", "Two or more Lisch nodules", "Iris hamartomas on slit-lamp"),
("6", "Distinctive osseous lesion", "Sphenoid dysplasia; tibial bowing"),
("7", "First-degree relative with NF-1", "Using above criteria"),
]
elems.append(make_table(["#", "Criterion", "Details"], nih, [1*cm, 7*cm, 8.5*cm]))
elems.append(sp(8))
elems.append(h3("Oral Manifestations of NF-1"))
for item in [
"Neurofibroma of tongue, buccal mucosa, gingiva",
"Plexiform neurofibroma causing macroglossia or facial asymmetry",
"Enlargement of mandibular canal and mental foramen",
"Loss/rarefaction of lamina dura",
"Irregular alveolar bone trabeculation",
"TMJ abnormalities; coronoid hyperplasia",
"Premature exfoliation of teeth (rare)",
]:
elems.append(bp(item))
elems.append(sp(8))
elems.append(h3("Histopathology of Neurofibroma vs Schwannoma"))
histo_nn = [
("Encapsulation", "ABSENT (unencapsulated)", "PRESENT (well-encapsulated)"),
("Cell types", "Schwann cells + fibroblasts + perineurial cells", "Schwann cells predominantly"),
("Nuclear shape", "Wavy / buckled ('carrot-shaped') nuclei", "Elongated; palisaded"),
("Architecture", "Loose myxoid stroma", "Antoni A (palisaded) + Antoni B (loose)"),
("Verocay bodies", "Absent", "PRESENT (nuclear palisading around acellular zones)"),
("Mast cells", "Characteristic, numerous", "Fewer"),
("S-100 protein", "Positive (Schwann cells)", "Strongly positive"),
("Palisading", "ABSENT", "PRESENT"),
]
elems.append(make_table(["Feature", "Neurofibroma", "Schwannoma"],
histo_nn, [5*cm, 6.5*cm, 5*cm]))
elems.append(sp(6))
elems.append(note("Complications of NF-1: Malignant transformation (MPNST ~10%), learning disabilities, epilepsy, hypertension (pheochromocytoma), scoliosis, optic glioma."))
elems.append(PageBreak())
return elems
# ══════════════════════════════════════════════════════════════════
# PART B – SHORT ESSAYS
# ══════════════════════════════════════════════════════════════════
def part_b():
elems = []
banner = Table([[Paragraph("PART B — SHORT ESSAYS (8 × 5 = 40 Marks)", part_style)]],
colWidths=[A4[0]-4*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 2, GOLD),
]))
elems.append(banner)
elems.append(sp(14))
# Q3 Dentigerous Cyst ────────────────────────────────────────
elems.append(h1("Q3. Radiological Variants of Dentigerous Cyst"))
elems.append(hr())
elems.append(p(f"{B('Definition:')} Odontogenic cyst arising from separation of follicular epithelium from the crown of an unerupted/impacted tooth, attached at the cemento-enamel junction (CEJ)."))
elems.append(sp(4))
elems.append(h3("Standard Radiological Features"))
for f in [
"Well-defined unilocular radiolucency with corticated (sclerotic) border",
"Crown of unerupted tooth projects into the cystic lumen",
"Attached at the cemento-enamel junction (CEJ) all around",
"Most common associated tooth: mandibular 3rd molar > maxillary canine > maxillary 3rd molar",
]:
elems.append(bp(f))
elems.append(sp(6))
elems.append(h3("Three Radiological Variants"))
variants = [
("Central\n(Pericoronal)", "90% of cases", "Radiolucency symmetrically surrounds the crown; crown projects centrally into the cystic space; attached all around at CEJ", "Most common; classic appearance"),
("Lateral", "Rare", "Cyst develops to one side of the crown/root; radiolucency on lateral aspect; partially erupted tooth often", "Mimic periodontal/lateral periodontal cyst"),
("Circumferential", "Rare", "Cystic sac envelops the entire tooth including root surface; cyst surrounds crown AND portion of root", "Distinguish from OKC & ameloblastoma"),
]
elems.append(make_table(["Variant", "Frequency", "Radiological Description", "Clinical Note"],
variants, [2.5*cm, 2*cm, 8*cm, 4*cm]))
elems.append(sp(6))
elems.append(note("DD: OKC (scalloped edges, often displaces teeth more), Unicystic Ameloblastoma, AOT (pericoronal + calcifications), Eruption cyst (soft tissue)"))
elems.append(sp(10))
# Q4 Solitary Bone Cyst ────────────────────────────────────────
elems.append(h1("Q4. Solitary Bone Cyst (Traumatic Bone Cyst)"))
elems.append(hr())
elems.append(p(f"{B('Synonyms:')} Simple bone cyst • Traumatic bone cyst • Hemorrhagic bone cyst • Idiopathic bone cavity • Unicameral bone cyst"))
elems.append(p(f"{B('Etiology (Trauma Theory):')} Intramedullary hemorrhage fails to organize → fluid resorbs → empty bony cavity remains."))
elems.append(sp(6))
elems.append(h3("Clinical Features"))
sbc_clin = [
("Age", "10–20 years (2nd decade)"),
("Sex", "Slight male predominance"),
("Site", "Symphysis / parasymphysis of mandible (premolar-molar region)"),
("Symptoms", "Usually ASYMPTOMATIC – found on routine X-ray"),
("Vitality of teeth", "VITAL (key distinguishing feature)"),
("Aspiration", "Empty cavity (no fluid) or blood-tinged fluid"),
]
elems.append(make_table(["Feature", "Details"], sbc_clin, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Radiological Features (Key)"))
for r in [
"Well-defined unilocular radiolucency",
"THIN or absent corticated border",
"Characteristic SCALLOPING between roots – radiolucency scallops upward between roots ('fallen leaves' pattern)",
"No root resorption; no displacement of teeth",
"No expansion (usually); cortex intact",
]:
elems.append(bp(r))
elems.append(sp(4))
elems.append(h3("Histopathology"))
elems.append(p(f"• {B('No epithelial lining')} – this is NOT a true cyst!"))
elems.append(p("• Thin fibrous connective tissue wall"))
elems.append(p("• May contain loose CT, hemosiderin deposits, occasional giant cells"))
elems.append(sp(4))
elems.append(p(f"{B('Treatment:')} Surgical exploration + curettage of bony walls → stimulates bleeding and new bone formation. Spontaneous resolution can occur."))
elems.append(note("Prognosis: Excellent. Recurrence very rare."))
elems.append(sp(10))
# Q5 Pindborg Tumour ───────────────────────────────────────────
elems.append(h1("Q5. Pindborg Tumour (CEOT – Calcifying Epithelial Odontogenic Tumour)"))
elems.append(hr())
elems.append(p(f"First described by {B('Jens Jorgen Pindborg')} in {B('1955')}. Benign, locally aggressive odontogenic epithelial neoplasm. Rare (~1% of odontogenic tumors)."))
elems.append(sp(6))
elems.append(h3("Clinical Features"))
ceot = [
("Age", "30–50 years (4th–5th decade)"),
("Sex", "No predilection"),
("Location", "Mandible > Maxilla (2:1); premolar-molar region"),
("Behavior", "Slow-growing, painless swelling; locally aggressive"),
("Associated tooth", "Impacted tooth in ~50%"),
("Variants", "Central/intraosseous (94%) vs Peripheral/extraosseous (6%)"),
]
elems.append(make_table(["Feature", "Details"], ceot, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Radiological Features"))
for r in [
"Unilocular or multilocular radiolucency",
"Mixed radiolucent-radiopaque pattern",
"'DRIVEN SNOW' appearance – irregular calcifications scattered through radiolucency (PATHOGNOMONIC)",
"Associated crown of impacted tooth",
"Indistinct/irregular borders (locally aggressive)",
]:
elems.append(bp(r))
elems.append(sp(6))
elems.append(h3("Histopathology (HIGH YIELD)"))
ceot_histo = [
("Cells", "Sheets, islands, strands of polyhedral epithelial cells; prominent intercellular bridges"),
("Nuclei", "Marked pleomorphism with hyperchromatism – 'BIZARRE giant nuclei' (despite benign behavior!)"),
("Amyloid-like material", "Homogeneous eosinophilic material between cells; stains +ve with Congo red; apple-green birefringence under polarized light (PATHOGNOMONIC)"),
("Liesegang rings", "Concentric calcifications within amyloid deposits; correspond to 'driven snow' on X-ray"),
("Cytoplasm", "Abundant eosinophilic cytoplasm"),
]
elems.append(make_table(["Feature", "Description"], ceot_histo, [4.5*cm, 12*cm]))
elems.append(sp(4))
elems.append(note("Treatment: Conservative excision with marginal resection. Recurrence ~14%."))
elems.append(sp(10))
# Q6 ABCDE Melanoma ────────────────────────────────────────────
elems.append(h1("Q6. A, B, C, D, E Rule of Malignant Melanoma"))
elems.append(hr())
abcde = [
("A", "ASYMMETRY", "Normal mole: symmetrical", "Suspicious: one half doesn't mirror the other"),
("B", "BORDER", "Regular, smooth, well-defined", "Irregular, notched, scalloped, or indistinct"),
("C", "COLOR", "Uniform single shade of brown", "Variegated: multiple shades of brown, black, red, white, blue"),
("D", "DIAMETER", "< 6 mm", "> 6 mm (size of pencil eraser); small amelanotic melanomas can be < 6 mm"),
("E", "EVOLUTION", "Stable lesion over time", "Any change in size, shape, color, or new symptom (bleeding, itching, crusting)"),
]
elems.append(make_table(["Letter", "Stands for", "Normal", "Suspicious Finding"],
abcde, [1.5*cm, 3.5*cm, 5*cm, 6.5*cm]))
elems.append(sp(8))
elems.append(h3("Clark's Levels (Invasion Depth)"))
clark = [
("I", "Confined to epidermis (in situ)"),
("II", "Into papillary dermis"),
("III", "Fills papillary dermis"),
("IV", "Into reticular dermis"),
("V", "Into subcutaneous fat – worst prognosis"),
]
elems.append(make_table(["Level", "Description"], clark, [2.5*cm, 14*cm]))
elems.append(sp(6))
elems.append(h3("Breslow's Thickness"))
elems.append(p("Most important single prognostic factor for melanoma:"))
breslow = [
("< 1 mm", "Good prognosis; sentinel node biopsy based on other features"),
("1–2 mm", "Intermediate"),
("2–4 mm", "Poor prognosis"),
("> 4 mm", "Very poor; high risk of distant metastasis"),
]
elems.append(make_table(["Thickness", "Prognosis"], breslow, [4*cm, 12.5*cm]))
elems.append(sp(6))
elems.append(h3("Oral Malignant Melanoma"))
for item in [
"Rare – ~0.5% of all melanomas",
"Sites: hard palate and maxillary alveolar ridge (most common)",
"Presents as painless brown-black macule or nodule; may be AMELANOTIC (pink)",
"Often advanced at diagnosis",
"Poor prognosis: 5-year survival ~15–20%",
"No primary treatment consensus; wide local excision + immunotherapy",
]:
elems.append(bp(item))
elems.append(sp(10))
# Q7 Lipoma ───────────────────────────────────────────────────
elems.append(h1("Q7. Lipoma"))
elems.append(hr())
elems.append(p(f"Most common benign soft tissue tumor in the body. {B('Relatively rare in the oral cavity (~4% of benign oral tumors).')} Composed of mature adipocytes."))
elems.append(sp(6))
elems.append(h3("Clinical Features"))
lip_clin = [
("Age", "40–60 years (middle-aged adults)"),
("Site", "Buccal mucosa (most common) > floor of mouth > tongue > palate > lips"),
("Appearance", "Soft, compressible, fluctuant, well-circumscribed, sessile or pedunculated"),
("Color", "Yellowish or normal overlying mucosa"),
("Surface", "Smooth; non-tender"),
("Growth", "Slow-growing"),
]
elems.append(make_table(["Feature", "Detail"], lip_clin, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Variants of Lipoma"))
lip_var = [
("Simple lipoma", "Pure mature adipose tissue – most common"),
("Fibrolipoma", "Fibrous stroma + adipose; most common intraoral variant"),
("Myxolipoma", "Myxoid stroma prominent"),
("Angiolipoma", "Vascular component; more painful; multiple lesions"),
("Spindle cell lipoma", "Spindle cells + adipocytes; CD34+"),
("Pleomorphic lipoma", "Floret giant cells; elderly males"),
("Sialolipoma", "Contains entrapped salivary gland elements; jaws"),
("Infiltrating lipoma", "Locally infiltrating; no capsule; higher recurrence"),
]
elems.append(make_table(["Variant", "Distinguishing Feature"], lip_var, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Histopathology"))
for h in [
"Lobules of MATURE adipocytes (large, clear cytoplasm with peripheral, flattened/scalloped nuclei)",
"Thin fibrous capsule surrounds the tumor",
"Thin fibrous septa dividing lobules",
"Signet ring appearance – fat displaces nucleus to periphery",
"NO lipoblasts (differentiates from liposarcoma)",
"In fibrolipoma: dense fibrous tissue admixed with fat",
]:
elems.append(bp(h))
elems.append(sp(4))
elems.append(p(f"{B('Treatment:')} Conservative surgical excision. Recurrence rare."))
elems.append(sp(10))
# Q8 Reed-Sternberg Cells ─────────────────────────────────────
elems.append(h1("Q8. Reed-Sternberg Cells"))
elems.append(hr())
elems.append(p(f"Hallmark of {B('Hodgkin Lymphoma (HL)')}. Large, binucleated/multinucleated neoplastic B-cells. First described by {B('Dorothy Reed (1902)')} and {B('Carl Sternberg (1898)')}."))
elems.append(p(f"{B('Origin:')} Germinal center B lymphocytes (confirmed by clonal IGH gene rearrangements + somatic hypermutation – Küppers 1994)."))
elems.append(sp(6))
elems.append(h3("Classic Morphology"))
for m in [
"Large cell – 15 to 45 micrometres diameter",
"BINUCLEATED (most characteristic) – mirror-image nuclei side by side",
"Each nucleus: single large eosinophilic 'OWL-EYE NUCLEOLUS' surrounded by a pale halo",
"Prominent, thick nuclear membrane",
"Abundant pale/eosinophilic cytoplasm",
]:
elems.append(bp(m))
elems.append(sp(6))
elems.append(h3("Variants"))
rs_var = [
("Classic RS", "Binucleated, owl-eye nucleoli", "Mixed cellularity, Nodular sclerosis"),
("Lacunar cell", "Nucleus sits in clear space (retraction artifact in formalin)", "Nodular sclerosis (pathognomonic)"),
("Mononuclear (Hodgkin cell)", "Single nucleus, prominent nucleolus", "All subtypes"),
("L&H / 'Popcorn' cell", "Multilobated nucleus, small nucleolus, pale chromatin", "Nodular lymphocyte predominant HL"),
]
elems.append(make_table(["Variant", "Morphology", "Associated Subtype"],
rs_var, [3.5*cm, 7*cm, 6*cm]))
elems.append(sp(6))
elems.append(h3("Immunohistochemistry"))
ihc = [
("CD15 (Leu-M1)", "POSITIVE – most important"),
("CD30 (Ki-1)", "POSITIVE – activation marker"),
("CD45 (LCA)", "NEGATIVE"),
("CD20", "NEGATIVE (usually; positive in NLPHL)"),
("PAX5", "Weakly positive"),
("EBV (LMP-1)", "Positive in ~40% (especially mixed cellularity)"),
]
elems.append(make_table(["Marker", "Result"], ihc, [6*cm, 10.5*cm]))
elems.append(sp(6))
elems.append(h3("Subtypes of Classical Hodgkin Lymphoma (WHO 2022)"))
hl_sub = [
("Nodular Sclerosis", "65–70%", "Lacunar cells; collagen bands; mediastinum", "Best prognosis"),
("Mixed Cellularity", "~25%", "Classic RS cells; EBV+; HIV-associated", "Intermediate"),
("Lymphocyte-rich", "~5%", "Rare RS cells; lymphocyte-predominant background", "Very good"),
("Lymphocyte-depleted", "Rare", "Numerous RS; few lymphocytes; HIV", "Worst prognosis"),
]
elems.append(make_table(["Subtype", "Frequency", "Features", "Prognosis"],
hl_sub, [5*cm, 2.5*cm, 6.5*cm, 2.5*cm]))
elems.append(sp(10))
# Q9 Sjogren's Syndrome ────────────────────────────────────────
elems.append(h1("Q9. Primary Sicca Syndrome (Sjogren's Syndrome)"))
elems.append(hr())
elems.append(p(f"{B('Definition:')} Chronic autoimmune exocrinopathy with lymphocytic infiltration of exocrine glands, causing xerostomia (dry mouth) and keratoconjunctivitis sicca (dry eyes) WITHOUT an associated connective tissue disease (primary)."))
elems.append(p(f"{B('Secondary SS:')} Features above + another CTD (RA, SLE, scleroderma, primary biliary cirrhosis)."))
elems.append(sp(6))
elems.append(h3("Epidemiology & Etiology"))
sj_epid = [
("Sex", "Female : Male = 9 : 1"),
("Age", "Peak 40–60 years; can occur at any age"),
("Genetics", "HLA-DR3, HLA-B8 association"),
("Autoantigens", "SS-A/Ro and SS-B/La (anti-Ro and anti-La antibodies)"),
("Triggers", "EBV, HCV, HTLV-1, retroviruses"),
]
elems.append(make_table(["Feature", "Details"], sj_epid, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Clinical Features"))
sj_clin = [
("Xerostomia", "Dry mouth; difficulty chewing, swallowing, speaking"),
("Parotid swelling", "Bilateral, firm, non-tender recurrent swelling"),
("Oral candidiasis", "Very common complication"),
("Rampant caries", "Cervical caries due to reduced buffering"),
("Tongue", "Lobulated, fissured, atrophic (bald tongue)"),
("Keratoconjunctivitis sicca", "Gritty/sandy eye sensation; reduced tears"),
("Schirmer's test", "< 5 mm in 5 minutes (abnormal)"),
("Systemic", "Arthralgia, Raynaud's, neuropathy, renal tubular acidosis"),
("Lymphoma risk", "40× increased risk of B-cell NHL (most serious complication)"),
]
elems.append(make_table(["Feature", "Details"], sj_clin, [4.5*cm, 12*cm]))
elems.append(sp(6))
elems.append(h3("Histopathology of Minor Salivary Gland Biopsy (Gold Standard)"))
for h in [
"Periductal and periacinar LYMPHOCYTIC infiltration (predominantly CD4+ T cells)",
"FOCUS SCORE: >1 focus per 4 mm² = DIAGNOSTIC (1 focus = >50 lymphocytes per 4 mm²)",
"Acinar atrophy and loss of glandular architecture",
"Ductal dilatation with metaplasia",
"Epimyoepithelial islands in parotid (lymphoepithelial lesion)",
]:
elems.append(bp(h))
elems.append(sp(6))
elems.append(h3("Diagnostic Tests Summary"))
sj_diag = [
("Schirmer's test", "< 5 mm/5 min", "Lacrimal gland function"),
("Rose Bengal / Lissamine green staining", "Corneal damage visualization", "Ocular surface"),
("Minor SG biopsy", "Focus score ≥ 1/4mm²", "Gold standard"),
("Sialometry", "< 1.5 mL/15 min (unstimulated)", "Salivary flow"),
("Parotid scintigraphy", "Reduced uptake & excretion", "Gland function"),
("Anti-Ro/SS-A", "Positive ~70%", "Most sensitive autoantibody"),
("Anti-La/SS-B", "Positive ~50%", "More specific than anti-Ro"),
]
elems.append(make_table(["Test", "Diagnostic Threshold", "What It Assesses"],
sj_diag, [5*cm, 5*cm, 6.5*cm]))
elems.append(sp(6))
elems.append(note("Treatment: Pilocarpine (muscarinic agonist) for dry mouth; artificial tears; fluoride for caries prevention; hydroxychloroquine/rituximab for systemic disease."))
elems.append(sp(10))
# Q10 Fibrous Dysplasia ──────────────────────────────────────
elems.append(h1("Q10. Histopathology of Fibrous Dysplasia"))
elems.append(hr())
elems.append(p(f"{B('Definition:')} A benign, non-neoplastic fibro-osseous lesion where normal medullary bone is replaced by fibrous tissue containing irregular trabeculae of woven bone."))
elems.append(p(f"{B('Pathogenesis:')} Somatic activating mutation in {B('GNAS1 gene (chromosome 20q13.2)')} encoding Gs-alpha protein → abnormal osteoblast differentiation → woven bone instead of lamellar bone."))
elems.append(sp(6))
elems.append(h3("Types"))
fd_types = [
("Monostotic", "Single bone", "70–80%", "Jaws most common; mandible > maxilla"),
("Polyostotic", "Multiple bones", "20–30%", "Skull, ribs, femur, jaws"),
("McCune-Albright Syndrome", "Polyostotic FD + CAL spots (coast of Maine) + endocrine dysfunction", "Rare", "Precocious puberty, hyperthyroidism"),
("Mazabraud Syndrome", "FD + intramuscular myxomas", "Rare", "—"),
]
elems.append(make_table(["Type", "Features", "Frequency", "Notes"],
fd_types, [3.5*cm, 7*cm, 2.5*cm, 3.5*cm]))
elems.append(sp(6))
elems.append(h3("Histopathology – HIGH YIELD"))
elems.append(p(B("1. Fibrous component:")))
for f in [
"Cellular fibrous stroma with spindle-shaped fibroblasts/osteoprogenitor cells",
"SWIRLING / STORIFORM arrangement (like 'rushing water')",
"Loose to moderately dense connective tissue",
"NO capsule – lesion blends imperceptibly with surrounding normal bone",
]:
elems.append(bp(f))
elems.append(sp(4))
elems.append(p(B("2. Bony component (MOST characteristic):")))
for f in [
"Irregular, curvilinear trabeculae of WOVEN BONE",
"'CHINESE LETTERS' or 'ALPHABET SOUP' pattern – trabeculae resemble Chinese characters",
"Trabeculae lack OSTEOBLASTIC RIMMING (key feature – differentiates from ossifying fibroma)",
"Woven bone (immature), not lamellar",
"Variable size and shape of trabeculae",
"In older lesions: maturation to lamellar bone may occur",
]:
elems.append(bp(f))
elems.append(sp(4))
elems.append(p(B("3. Additional features:")))
for f in [
"Scattered osteoclast-like giant cells at edges of trabeculae",
"Foamy histiocytes/lipid-laden cells occasionally",
"Thin-walled blood vessels in stroma",
"NO inflammatory cells (unless secondarily infected)",
]:
elems.append(bp(f))
elems.append(sp(6))
elems.append(h3("Critical Comparison: Fibrous Dysplasia vs Ossifying Fibroma"))
fd_vs_of = [
("Bone trabeculae shape", "'Chinese letters' / irregular woven bone", "Rounded/spherical bony lamellae or osteoid"),
("Osteoblastic rimming", "ABSENT", "PRESENT"),
("Border of lesion", "BLENDS with surrounding bone (no capsule)", "Well-defined, encapsulated / 'shell out' easily"),
("Recurrence", "Low; self-limiting after puberty ('burns out')", "Tends to recur; may be aggressive"),
("Radiological", "'Ground glass' / 'orange peel'", "Mixed RL-RO with defined border"),
("Patient age", "Children/adolescents", "Middle-aged adults; F>M"),
]
elems.append(make_table(["Feature", "Fibrous Dysplasia", "Ossifying Fibroma"],
fd_vs_of, [5*cm, 6*cm, 5.5*cm]))
elems.append(note("Radiology: 'Ground glass' (most classic), 'Orange peel', 'Fingerprint' pattern. Bowing/expansion of cortex without perforation."))
elems.append(PageBreak())
return elems
# ══════════════════════════════════════════════════════════════════
# PART C – SHORT ANSWERS
# ══════════════════════════════════════════════════════════════════
def part_c():
elems = []
banner = Table([[Paragraph("PART C — SHORT ANSWERS (5 × 2 = 10 Marks)", part_style)]],
colWidths=[A4[0]-4*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), ORANGE),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 2, GOLD),
]))
elems.append(banner)
elems.append(sp(14))
# Q11 Thistle Tube ─────────────────────────────────────────────
elems.append(h1("Q11. Thistle Tube Pulp Chamber"))
elems.append(hr())
elems.append(p(f"A morphological description of pulp chamber shape seen on periapical radiographs, characteristic of {B('Dentinogenesis Imperfecta (DI)')}."))
elems.append(sp(4))
for f in [
f"{B('Shape:')} Resembles a 'thistle tube' or vase – narrow at the cervical region, bulbous/wide at the inferior portion",
f"{B('Condition:')} Dentinogenesis Imperfecta Types I, II, III (hereditary opalescent dentin)",
f"{B('Gene:')} DSPP gene mutation (dentin sialophosphoprotein) – Types II and III",
f"{B('Radiological:')} Pulp chambers and canals are partially or completely OBLITERATED by abnormal dentin deposition",
f"{B('Type III (Brandywine):')} Particularly known for thistle tube appearance + 'shell teeth' (extremely thin dentin)",
f"{B('Clinical correlation:')} Teeth appear amber/brownish-blue (opalescent); fracture-prone; worn occlusal surfaces",
]:
elems.append(bp(f))
elems.append(sp(10))
# Q12 Touton Giant Cells ───────────────────────────────────────
elems.append(h1("Q12. Touton Type Giant Cells"))
elems.append(hr())
elems.append(p("A distinctive type of multinucleated giant cell with a characteristic morphology named after Karl Touton."))
elems.append(sp(4))
elems.append(h3("Morphology"))
for f in [
f"{B('Ring/wreath of nuclei')} arranged in a circle in the center of the cell (ring = 'garland' appearance)",
f"{B('Central homogeneous eosinophilic cytoplasm')} – inside the ring of nuclei",
f"{B('Peripheral foamy/xanthomatous (lipid-laden) cytoplasm')} – outside the ring of nuclei",
"Memory aid: 'Touton = two zones of cytoplasm separated by a wreath of nuclei'",
]:
elems.append(bp(f))
elems.append(sp(4))
elems.append(h3("Associated Conditions"))
touton = [
("Juvenile Xanthogranuloma (JXG)", "MOST CLASSIC association; Touton cells are pathognomonic"),
("Xanthoma / Xanthomatosis", "Foam cells + Touton giant cells"),
("Necrobiotic xanthogranuloma", "Periorbital; paraproteinemia"),
("Dermatofibroma", "Occasionally seen"),
]
elems.append(make_table(["Condition", "Note"], touton, [6*cm, 10.5*cm]))
elems.append(sp(4))
elems.append(h3("Comparison of Giant Cell Types"))
gc_compare = [
("Touton", "Wreath of nuclei centrally; foamy periphery", "JXG, xanthoma"),
("Langhan's", "Nuclei arranged in horseshoe/U-shape at periphery", "Tuberculosis, sarcoid, fungal"),
("Foreign body", "Nuclei scattered randomly throughout cytoplasm", "Foreign body reaction"),
("Osteoclast", "Multiple nuclei, large ruffled border", "Normal bone; giant cell lesions"),
]
elems.append(make_table(["Type", "Nuclear Arrangement", "Seen In"],
gc_compare, [3.5*cm, 7*cm, 6*cm]))
elems.append(sp(10))
# Q13 Tadpole Cells ────────────────────────────────────────────
elems.append(h1("Q13. Tadpole Shaped Cells"))
elems.append(hr())
elems.append(p(f"Cells with a {B('broad head and a tapering tail')} resembling a tadpole, representing a specific cytological/histological finding."))
elems.append(sp(4))
elems.append(h3("Morphology"))
for f in [
"Broad end (head): contains the nucleus with eosinophilic cytoplasm",
"Narrow tapering end (tail): cytoplasmic elongation",
"Eosinophilic cytoplasm; eccentric nuclei",
"In rhabdomyosarcoma: primitive rhabdomyoblasts adopting this shape",
]:
elems.append(bp(f))
elems.append(sp(4))
elems.append(h3("Associated Conditions"))
tadpole = [
("Embryonal Rhabdomyosarcoma", "MOST CLASSIC association in oral pathology; primitive rhabdomyoblasts"),
("Spindle Cell / Sarcomatoid Carcinoma", "Pleomorphic carcinoma with spindle/tadpole cells"),
("Squamous Cell Carcinoma (poorly diff.)", "Keratinizing dyskeratotic cells"),
]
elems.append(make_table(["Condition", "Note"], tadpole, [6*cm, 10.5*cm]))
elems.append(sp(4))
elems.append(p(f"{B('IHC (Rhabdomyosarcoma):')} Desmin, MyoD1, Myogenin positive; MYOD1 is most specific."))
elems.append(sp(10))
# Q14 Snail Track Ulcer ────────────────────────────────────────
elems.append(h1("Q14. Snail Track Ulcer"))
elems.append(hr())
elems.append(p(f"A {B('serpiginous (winding, snake-like)')} pattern of superficial oral ulceration that resembles the slime trail left by a snail."))
elems.append(sp(4))
elems.append(h3("Characteristics"))
for f in [
"Shallow, superficial ulcers with irregular, winding margins",
"Undermined edges; base covered with grayish-white slough",
"Multiple coalescing ulcers forming a serpiginous pattern",
"Highly PAINLESS despite appearance (important diagnostic clue)",
"Highly infectious (Treponema pallidum organisms present in the lesion)",
]:
elems.append(bp(f))
elems.append(sp(4))
elems.append(h3("Associated Conditions"))
snail = [
("Secondary Syphilis", "MOST CLASSIC – mucous patches that coalesce into snail-track pattern; painless"),
("Herpes Zoster (intraoral)", "Ruptured vesicles coalesce along dermatomal distribution"),
("Erythema Multiforme", "Occasionally produces serpiginous ulcers"),
("Tertiary Syphilis", "Gummatous ulcers on palate; more destructive"),
]
elems.append(make_table(["Condition", "Note"], snail, [5.5*cm, 11*cm]))
elems.append(sp(4))
elems.append(p(f"{B('Diagnosis of Syphilis:')} Dark-field microscopy (gold standard for primary) • VDRL/RPR (screening) • FTA-ABS/TPPA (confirmatory)"))
elems.append(p(f"{B('Treatment:')} Benzathine penicillin G (drug of choice)"))
elems.append(sp(10))
# Q15 Cafe-au-lait ─────────────────────────────────────────────
elems.append(h1("Q15. Cafe-au-lait Spots"))
elems.append(hr())
elems.append(p(f"Flat, well-demarcated, light brown hyperpigmented macules; color resembles 'coffee with milk.' Represent {B('melanin accumulation in keratinocytes')} (not melanocytes)."))
elems.append(sp(4))
elems.append(h3("Key Comparison: NF-1 vs McCune-Albright"))
cal_compare = [
("Number", "6 or more (diagnostic criterion)", "Fewer, larger spots"),
("Size threshold", ">5 mm prepubertal; >15 mm postpubertal", "Large; >1.5 cm often"),
("Border", "Irregular – 'COAST OF CALIFORNIA'", "Smooth – 'COAST OF MAINE'"),
("Distribution", "Generalized / scattered", "Unilateral; follows Blaschko's lines"),
("Associated features", "Neurofibromas, Lisch nodules, MPNST risk", "Polyostotic FD, endocrine hyperfunction"),
]
elems.append(make_table(["Feature", "NF-1 (von Recklinghausen)", "McCune-Albright Syndrome"],
cal_compare, [4.5*cm, 6.5*cm, 5.5*cm]))
elems.append(sp(6))
elems.append(h3("Syndromes with Cafe-au-lait Spots"))
cal_syn = [
("NF-1 (von Recklinghausen)", "6+ spots diagnostic; NF1 gene (chr 17)"),
("McCune-Albright Syndrome", "Polyostotic FD + precocious puberty + CAL (GNAS1 mutation)"),
("Legius Syndrome", "NF-1 like; SPRED1 mutation; no neurofibromas"),
("Bloom Syndrome", "BLM gene; photosensitivity; chromosomal instability"),
("Fanconi Anemia", "FANC gene family; aplastic anemia; increased malignancy risk"),
("Tuberous Sclerosis", "Ashleaf hypopigmented patches more typical; CAL occasional"),
]
elems.append(make_table(["Syndrome", "Key Feature"], cal_syn, [6*cm, 10.5*cm]))
elems.append(sp(4))
elems.append(note("Normal individuals can have 1–2 cafe-au-lait spots. Only 6+ spots are diagnostic for NF-1."))
elems.append(note("Crowe's sign (axillary freckling) = small cafe-au-lait spots in axillary/inguinal folds; specific for NF-1."))
elems.append(PageBreak())
return elems
# ══════════════════════════════════════════════════════════════════
# PART D – QUICK REVISION
# ══════════════════════════════════════════════════════════════════
def part_d():
elems = []
banner = Table([[Paragraph("PART D — QUICK REVISION & EXAM TIPS", part_style)]],
colWidths=[A4[0]-4*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), PURPLE),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 2, GOLD),
]))
elems.append(banner)
elems.append(sp(14))
elems.append(h1("Key Mnemonics"))
elems.append(hr())
mnemonics_list = [
("OPMDs", "'LEAOP DLD' – Leukoplakia, Erythroplakia, Actinic cheilitis, OSMF, PVL, Discoid LE, Lichen planus, Dyskeratosis congenita"),
("NF-1 Criteria", "'CALF ON S' – CAL spots(6+), Axillary freckling, Lisch nodules, Fibromas(2+), Optic glioma, Neurofibromas(plexiform), Skeletal dysplasia"),
("CEOT (Pindborg)", "'DADS' – Driven snow, Amyloid, Dense calcification, Sheets of polyhedral cells"),
("Leukoplakia Risk", "'FANSLD' – Female, Alveolar/FOM, Non-smoker, Size>200mm², Long duration, Dysplasia"),
("Sjogren's", "'SAXE' – Salivary gland swelling, Autoantibodies(Ro/La), Xerophthalmia, Exocrinopathy"),
("RS cell IHC", "'CD30 and 15 are Positive, CD45 is Negative' = classic Hodgkin"),
("Giant cell types", "'TOLF' – Touton(wreath), Osteoclast(ruffled), Langhan's(horseshoe), Foreign body(scattered)"),
("Syphilis", "'123' – Primary(chancre), Secondary(snail track+rash), Tertiary(gumma)"),
]
for abbrev, mnem in mnemonics_list:
row = Table([[
Paragraph(B(abbrev), S("ma", fontSize=10, textColor=PURPLE, fontName="Helvetica-Bold", leading=13)),
Paragraph(mnem, S("mb", fontSize=9.5, textColor=DARK_GRAY, fontName="Helvetica", leading=13))
]], colWidths=[4.5*cm, A4[0]-4*cm-4.5*cm])
row.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_TEAL),
("BOX", (0,0), (-1,-1), 0.5, TEAL),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
elems.append(row)
elems.append(sp(4))
elems.append(sp(10))
elems.append(h1("Master Comparison Table: Odontogenic Cysts"))
elems.append(hr())
cyst_comp = [
("Dentigerous Cyst", "2nd–3rd decade; M>F", "Unilocular RL; crown in cystic space; at CEJ", "Stratified sq. epi (2–3 layers); non-keratinized", "Enucleation; low recurrence"),
("OKC (KCOT)", "2nd decade; M>F", "Unilocular or multilocular; scalloped borders; parallel to long axis", "Thin parakeratinized corrugated surface; basal palisading; daughter cysts; satellite cysts", "High recurrence (25–60%); Carnoy's solution"),
("Radicular Cyst", "Any age; apex of non-vital tooth", "Well-defined RL at apex; tooth non-vital", "Stratified sq. epi; Rushton bodies; arcades of epi", "Enucleation; periapical surgery"),
("Solitary Bone Cyst", "10–20 years", "Scalloping between roots; empty cavity", "NO epithelial lining", "Exploration + curettage"),
]
elems.append(make_table(["Cyst", "Demographics", "Radiology", "Histopathology", "Treatment"],
cyst_comp, [3.5*cm, 3*cm, 4*cm, 4*cm, 2*cm]))
elems.append(sp(10))
elems.append(h1("Exam Writing Tips"))
elems.append(hr())
tips = [
"Always write a clear DEFINITION first – examiners reward structured openings.",
"For Long Essays (10 marks): Introduction → Etiology → Clinical → Radiology → Histopathology → Treatment → Prognosis.",
"For Short Essays (5 marks): Focus on 3–4 key aspects; draw a labeled diagram where relevant.",
"For Short Answers (2 marks): Write 4–5 concise, factual bullet points; avoid lengthy prose.",
"ALWAYS draw labeled diagrams for: Dentigerous cyst variants, Histopathology of CEOT, Fibrous dysplasia trabeculae, RS cells.",
"Highlight HIGH-YIELD words by underlining: 'driven snow,' 'Chinese letters,' 'owl-eye nucleoli,' 'coast of California vs Maine.'",
"Use comparison tables whenever asked to 'classify' or 'differentiate' – saves time and earns marks.",
"For Sjogren's: Always mention Focus Score (>1/4mm²) – it's a favorite exam point.",
"For Fibrous Dysplasia: 'Absent osteoblastic rimming' is the single most tested histopathological feature.",
"For Leukoplakia: 'WHO 2005 definition' + 'malignant transformation rate 0.7–2.9%' = guaranteed marks.",
]
for i, tip in enumerate(tips, 1):
t = Table([[
Paragraph(str(i), S("tn", fontSize=11, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=14)),
Paragraph(tip, S("tc", fontSize=10, textColor=DARK_GRAY, fontName="Helvetica", leading=13))
]], colWidths=[1.2*cm, A4[0]-4*cm-1.2*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), TEAL if i % 2 == 1 else NAVY),
("BACKGROUND", (1,0), (1,0), LIGHT_GREEN if i % 2 == 1 else LIGHT_BLUE),
("BOX", (0,0), (-1,-1), 0.5, MID_GRAY),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
elems.append(t)
elems.append(sp(3))
elems.append(sp(20))
# Footer note
footer_box = Table([[
Paragraph(
"This study guide covers all questions from the RGUHS III BDS Oral Pathology & Microbiology paper "
"(Q.P. Code 1188, Nov 2021). Content is prepared for educational purposes based on standard "
"oral pathology textbooks including Neville, Regezi, and Shafer's. "
"Always verify with your prescribed textbook and university notes.",
S("fn", fontSize=8.5, textColor=DARK_GRAY, fontName="Helvetica-Oblique",
alignment=TA_CENTER, leading=12))
]], colWidths=[A4[0]-4*cm])
footer_box.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_GRAY),
("BOX", (0,0), (-1,-1), 1, MID_GRAY),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
]))
elems.append(footer_box)
return elems
# ══════════════════════════════════════════════════════════════════
# BUILD
# ══════════════════════════════════════════════════════════════════
def build():
doc = OralPathDocTemplate(
OUTPUT_PATH,
pagesize=A4,
leftMargin=2*cm,
rightMargin=2*cm,
topMargin=1.8*cm,
bottomMargin=1.5*cm,
)
story = []
story += cover_page()
story += toc_page()
story += part_a()
story += part_b()
story += part_c()
story += part_d()
doc.build(story)
print(f"PDF saved to: {OUTPUT_PATH}")
if __name__ == "__main__":
build()
cd /home/daytona/workspace/oral-path-guide && python generate_study_guide.py 2>&1
ls -lh /home/daytona/workspace/oral-path-guide/Oral_Pathology_Study_Guide.pdf
python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/oral-path-guide/Oral_Pathology_Study_Guide.pdf') print(f'Total pages: {len(r.pages)}') for i, page in enumerate(r.pages[:3]): text = page.extract_text() print(f'--- Page {i+1} preview ---') print(text[:200]) "
Oral Pathology Study Guide
PDF Document · PDF
| Part | Content | Marks |
|---|---|---|
| Cover + TOC | Title page with topic index | - |
| Part A – Long Essays | Q1: OPMDs + Leukoplakia (full detail with 6 tables) | 10+10 |
| Q2: Neural Tumors + Neurofibromatosis (NIH criteria, histopath comparison) | ||
| Part B – Short Essays | Q3–Q10: All 8 short essay answers with clinical/radiological/histo tables | 5×8 |
| Part C – Short Answers | Q11–Q15: Thistle tube, Touton cells, Tadpole cells, Snail track, CAL spots | 2×5 |
| Part D – Quick Revision | 8 key mnemonics, master cyst comparison table, 10 exam writing tips | - |