~/surgical-anatomy-study-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,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
# ── Color palette ──────────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1A3A5C")
MID_BLUE = colors.HexColor("#2E6DA4")
LIGHT_BLUE = colors.HexColor("#D6E8F7")
ACCENT_RED = colors.HexColor("#C0392B")
ACCENT_GREEN= colors.HexColor("#1E7B4B")
GOLD = colors.HexColor("#D4A017")
LIGHT_GRAY = colors.HexColor("#F4F6F9")
MID_GRAY = colors.HexColor("#BDC3C7")
WHITE = colors.white
BLACK = colors.HexColor("#1C1C1C")
WARN_BG = colors.HexColor("#FFF3CD")
WARN_BORDER = colors.HexColor("#F0A500")
TIP_BG = colors.HexColor("#E8F5E9")
TIP_BORDER = colors.HexColor("#2ECC71")
OUTPUT = "/home/daytona/workspace/surgical-anatomy-study-guide/Surgical_Anatomy_HN_Study_Guide.pdf"
# ── Styles ─────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
COVER_TITLE = S("CoverTitle", fontSize=28, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=34)
COVER_SUB = S("CoverSub", fontSize=13, textColor=LIGHT_BLUE,
fontName="Helvetica", alignment=TA_CENTER, leading=18)
COVER_DATE = S("CoverDate", fontSize=10, textColor=MID_GRAY,
fontName="Helvetica", alignment=TA_CENTER)
MOD_TITLE = S("ModTitle", fontSize=16, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_LEFT,
leading=20, spaceBefore=2, spaceAfter=2)
SEC_TITLE = S("SecTitle", fontSize=12, textColor=DARK_BLUE,
fontName="Helvetica-Bold", leading=16,
spaceBefore=10, spaceAfter=4)
BODY = S("Body", fontSize=9.5, textColor=BLACK,
fontName="Helvetica", leading=14,
spaceBefore=2, spaceAfter=2, alignment=TA_JUSTIFY)
BULLET = S("Bullet", fontSize=9.5, textColor=BLACK,
fontName="Helvetica", leading=14,
leftIndent=14, firstLineIndent=-10,
spaceBefore=1, spaceAfter=1)
SUBBULLET = S("SubBullet", fontSize=9, textColor=BLACK,
fontName="Helvetica", leading=13,
leftIndent=28, firstLineIndent=-10,
spaceBefore=1, spaceAfter=1)
BOLD_INLINE = S("BoldInline", fontSize=9.5, textColor=BLACK,
fontName="Helvetica-Bold", leading=14)
WARN_TXT = S("WarnTxt", fontSize=9.5, textColor=colors.HexColor("#7D4E00"),
fontName="Helvetica-Bold", leading=14,
leftIndent=8, rightIndent=8,
spaceBefore=4, spaceAfter=4)
TIP_TXT = S("TipTxt", fontSize=9.5, textColor=colors.HexColor("#1B5E20"),
fontName="Helvetica-Bold", leading=14,
leftIndent=8, rightIndent=8,
spaceBefore=4, spaceAfter=4)
REF_TXT = S("RefTxt", fontSize=8.5, textColor=MID_BLUE,
fontName="Helvetica-Oblique", leading=13,
leftIndent=10)
TABLE_HDR = S("TblHdr", fontSize=8.5, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=11)
TABLE_CELL = S("TblCell", fontSize=8.5, textColor=BLACK,
fontName="Helvetica", leading=12, alignment=TA_LEFT)
TABLE_CELL_C= S("TblCellC", fontSize=8.5, textColor=BLACK,
fontName="Helvetica", leading=12, alignment=TA_CENTER)
FOOTER_TXT = S("Footer", fontSize=7.5, textColor=MID_GRAY,
fontName="Helvetica", alignment=TA_CENTER)
# ── Helpers ────────────────────────────────────────────────────────────────────
def module_header(num, title):
"""Dark blue banner for each module."""
data = [[Paragraph(f"MODULE {num} | {title}", MOD_TITLE)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0),(-1,-1), 7),
("BOTTOMPADDING", (0,0),(-1,-1), 7),
("LEFTPADDING", (0,0),(-1,-1), 10),
("RIGHTPADDING", (0,0),(-1,-1), 10),
("ROUNDEDCORNERS",(0,0),(-1,-1), [4,4,4,4]),
]))
return t
def section_rule():
return HRFlowable(width="100%", thickness=0.5, color=MID_BLUE,
spaceAfter=4, spaceBefore=6)
def warn_box(text):
data = [[Paragraph(f"<b>! CLINICAL PEARL:</b> {text}", WARN_TXT)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), WARN_BG),
("LINEABOVE", (0,0),(-1, 0), 2, WARN_BORDER),
("LINEBELOW", (0,0),(-1,-1), 2, WARN_BORDER),
("LINEBEFORE", (0,0),(0, -1), 4, WARN_BORDER),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING", (0,0),(-1,-1), 5),
("LEFTPADDING", (0,0),(-1,-1), 8),
]))
return t
def tip_box(text):
data = [[Paragraph(f"<b>APPLIED TIP:</b> {text}", TIP_TXT)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), TIP_BG),
("LINEABOVE", (0,0),(-1, 0), 2, TIP_BORDER),
("LINEBELOW", (0,0),(-1,-1), 2, TIP_BORDER),
("LINEBEFORE", (0,0),(0, -1), 4, TIP_BORDER),
("TOPPADDING", (0,0),(-1,-1), 5),
("BOTTOMPADDING", (0,0),(-1,-1), 5),
("LEFTPADDING", (0,0),(-1,-1), 8),
]))
return t
def ref_line(text):
return Paragraph(f"Ref: {text}", REF_TXT)
def b(t): return f"<b>{t}</b>"
def em(t): return f"<i>{t}</i>"
def red(t): return f'<font color="#C0392B"><b>{t}</b></font>'
def grn(t): return f'<font color="#1E7B4B"><b>{t}</b></font>'
def blu(t): return f'<font color="#2E6DA4"><b>{t}</b></font>'
def make_table(headers, rows, col_widths, alt=True):
"""Generic styled table."""
hdr_row = [Paragraph(h, TABLE_HDR) for h in headers]
data = [hdr_row]
for i, row in enumerate(rows):
data.append([Paragraph(str(c), TABLE_CELL) for c in row])
t = Table(data, colWidths=col_widths)
style = [
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("GRID", (0,0), (-1,-1), 0.4, MID_GRAY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
]
t.setStyle(TableStyle(style))
return t
def bp(txt):
return Paragraph(f"• {txt}", BULLET)
def sbp(txt):
return Paragraph(f"◦ {txt}", SUBBULLET)
def sp(n=6):
return Spacer(1, n)
# ── Page layout ────────────────────────────────────────────────────────────────
PAGE_W, PAGE_H = A4
MARGIN = 2*cm
def on_page(canvas, doc):
canvas.saveState()
# Footer bar
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, 0, PAGE_W, 1.1*cm, fill=1, stroke=0)
canvas.setFillColor(WHITE)
canvas.setFont("Helvetica", 7.5)
canvas.drawCentredString(PAGE_W/2, 0.4*cm,
f"Surgical Anatomy of Head & Neck | OMFS Study Guide | Page {doc.page}")
# Top accent line
canvas.setFillColor(GOLD)
canvas.rect(0, PAGE_H-4, PAGE_W, 4, fill=1, stroke=0)
canvas.restoreState()
def on_first_page(canvas, doc):
# Full cover background
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, 0, PAGE_W, PAGE_H, fill=1, stroke=0)
canvas.setFillColor(GOLD)
canvas.rect(0, PAGE_H-6, PAGE_W, 6, fill=1, stroke=0)
canvas.rect(0, 0, PAGE_W, 6, fill=1, stroke=0)
# ── Build story ────────────────────────────────────────────────────────────────
story = []
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# COVER PAGE
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(Spacer(1, 5*cm))
story.append(Paragraph("SURGICAL ANATOMY", COVER_TITLE))
story.append(Paragraph("OF THE HEAD AND NECK", COVER_TITLE))
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="60%", thickness=1.5, color=GOLD,
hAlign="CENTER", spaceAfter=12))
story.append(Paragraph("Applied Study Guide for OMFS Residents", COVER_SUB))
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("Department of Oral and Maxillofacial Surgery", COVER_SUB))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Prepared by Dr. Hrushikesh Acharya (JR1) • June 2026", COVER_DATE))
story.append(Spacer(1, 2*cm))
# Quick reference box on cover
cov_data = [[Paragraph(
"<b>References:</b> Fonseca OMFS • Peterson's Principles • Ellis & Zide Surgical Approaches • "
"Gray's Anatomy (Standring) • Netter's H&N • Cummings Otolaryngology • "
"Scott-Brown's • Kademani & Tiwana Atlas • Brennan Clinical H&N Anatomy",
COVER_DATE)]]
cov_t = Table(cov_data, colWidths=[13*cm])
cov_t.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1),colors.HexColor("#0F2A45")),
("BOX",(0,0),(-1,-1),1,GOLD),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),10),
]))
story.append(cov_t)
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 1: LAYERS TEMPLATE
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(1, "UNIVERSAL LAYERS TEMPLATE"))
story.append(sp(8))
story.append(Paragraph(b("The Seven-Layer Model (applies to every region — skin to bone)"), SEC_TITLE))
rows = [
["1. Skin", "Thickness varies: thickest at scalp, thinnest at eyelid", "Incision design; cosmetic units; graft harvest"],
["2. Subcutaneous fat","Facial fat compartments; superficial vessels; sensory nerves","Fat grafting; compartment shifts in ageing"],
["3. SMAS / Muscle", "Galea → TPF → SMAS → platysma (one continuous sheet)", "Face-lift plane; motor nerve lies DEEP to this"],
["4. Deep fascia", "Parotid-masseteric (face); deep cervical fascia (neck)", "Boundary of safe dissection zones"],
["5. Sub-fascial plane","Motor nerve branches, ducts, deep vessels, glands", "HIGHEST-RISK surgical plane"],
["6. Periosteum", "Vascularised, elevatable", "Pericranial flap harvest; bone healing"],
["7. Bone", "Cortical tables; buttresses", "Fixation; osteotomy lines; graft harvest"],
]
story.append(make_table(["Layer","Content","Surgical Significance"],
rows, [3*cm, 7.5*cm, 6.5*cm]))
story.append(sp(6))
story.append(warn_box(
"GOLDEN RULE: Facial (motor) nerve branches lie DEEP to the SMAS. "
"Dissecting superficial to the SMAS keeps you safe in most facial approaches."))
story.append(sp(6))
story.append(Paragraph(b("SMAS Continuity"), SEC_TITLE))
for txt in [
f"{b('Superficial sheet:')} Galea aponeurotica (scalp) → Temporoparietal fascia/TPF (temple, {red('carries frontal branch CN VII')}) → SMAS (midface) → Platysma (neck)",
f"{b('Deep fascia sheet:')} Deep temporal fascia → Parotid-masseteric fascia → Investing layer of deep cervical fascia",
f"{b('Danger Space:')} Between alar fascia and prevertebral fascia. Infection tracks from skull base to mediastinum — descending necrotizing mediastinitis.",
]:
story.append(bp(txt))
story.append(sp(4))
story.append(tip_box(
"SMAS is a condensed fibromuscular layer contiguous with platysma, "
"situated below subcutaneous fat and OVER the mimetic musculature and motor nerve branches. "
"(Mitz & Peyronie 1974; confirmed in Cummings Otolaryngology)"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 2: SCALP
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(2, "THE SCALP"))
story.append(sp(8))
story.append(Paragraph(b("S-C-A-L-P Mnemonic"), SEC_TITLE))
rows = [
["S","Skin","Hair-bearing, thick",
"Cosmetic incisions; hair restoration; graft donor site"],
["C","Connective tissue","Dense, fibrous, richly vascular",
red("Scalp wounds bleed profusely — fibrous septa hold vessels open. Clamp before cutting")],
["A","Aponeurosis (Galea)","Tension-bearing layer",
"Lacerations through galea gape widely — must close galea separately"],
["L","Loose areolar","DANGER LAYER — potential space",
red("Infection/haematoma spreads here; emissary veins → dural sinuses → intracranial spread")],
["P","Pericranium (Periosteum)","Vascularised; elevatable",
grn("Pericranial flap for frontal sinus obliteration, dural repair, scalp reconstruction")],
]
story.append(make_table(["Letter","Layer","Property","Applied Significance"],
rows, [1.5*cm, 3.5*cm, 5*cm, 7*cm]))
story.append(sp(8))
story.append(Paragraph(b("Calvarium Bone Graft Harvest"), SEC_TITLE))
for txt in [
f"{b('Safe zone:')} Parietal bone, posterior to coronal suture, anterior to lambdoid suture; {b('outer table only')}",
f"{b('Avoid:')} Sagittal suture (superior sagittal sinus directly beneath); thin temporal squama",
f"{b('Why preferred:')} Membranous bone resists resorption; same operative field; minimal donor morbidity",
]:
story.append(bp(txt))
story.append(sp(4))
story.append(warn_box(
"A scalp flap raised in the LOOSE AREOLAR layer can devascularise the pericranium. "
"Always identify and preserve the layer you are in."))
story.append(sp(4))
story.append(ref_line("Fonseca OMFS (Reconstruction Vol); Gray's Anatomy (Standring) — Scalp"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 3: FOREHEAD, FRONTAL SINUS, CORONAL APPROACH
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(3, "FOREHEAD, FRONTAL SINUS & CORONAL APPROACH"))
story.append(sp(8))
story.append(Paragraph(b("Forehead Layers"), SEC_TITLE))
for txt in [
"Skin → Subcutaneous fat → Frontalis muscle (continuous with galea) → Loose areolar → Pericranium → Frontal bone",
f"{b('Supraorbital notch/foramen:')} junction of medial 1/3 and lateral 2/3 of the orbital rim — supraorbital and supratrochlear nerves/vessels exit here",
"Protect these during coronal dissection and all brow surgery — inadvertent traction causes forehead numbness",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Frontal Sinus — Fracture-Driven Management"), SEC_TITLE))
rows = [
["Anterior table alone", "ORIF (plates/screws)", "Cosmesis; contour"],
["Posterior table ± duct injury", "Obliteration or cranialization","CSF leak prevention"],
["Frontonasal duct injury", "Obliteration (pericranial flap)","Prevent mucocele; meningitis"],
]
story.append(make_table(["Fracture Pattern","Management","Goal"],
rows, [5*cm, 6*cm, 6*cm]))
story.append(sp(6))
story.append(Paragraph(b("Temporal Region — 7 Layers"), SEC_TITLE))
layers = [
("1. Skin","—"),
("2. Subcutaneous","Superficial temporal artery/vein; auriculotemporal nerve"),
(f"3. {red('TPF (Temporoparietal Fascia)')}",f"{red('Contains frontal branch of CN VII')} — most critical layer"),
(f"4. {grn('Loose areolar')}",f"{grn('SAFE dissection plane')}"),
("5. Deep temporal fascia","Splits over arch — encloses superficial temporal fat pad"),
("6. Temporalis muscle","Coronoid process insertion — used as a flap"),
("7. Periosteum → Bone","—"),
]
rows2 = [[n, d] for n,d in layers]
story.append(make_table(["Layer","Notes"], rows2, [5.5*cm, 11.5*cm]))
story.append(sp(6))
story.append(warn_box(
"PITANGUY'S LINE: Tragus → 1.5 cm above the lateral brow = course of the FRONTAL BRANCH of CN VII. "
"The branch crosses the zygomatic arch within the TPF. Dissecting DEEP to the superficial layer of "
"deep temporal fascia (sub-fascial plane) protects it."))
story.append(sp(6))
story.append(Paragraph(b("Coronal Approach — Safe Plane Protocol"), SEC_TITLE))
rows3 = [
["Frontal region","Subgaleal loose areolar plane","Below galea, above pericranium"],
["Temporal region","Below superficial layer of deep temporal fascia","Frontal branch stays in reflected flap"],
["At the arch","Incise deep temporal fascia obliquely; inter-fascial fat pad = visual guide","Strip periosteum off arch"],
]
story.append(make_table(["Zone","Safe Plane","Key Action"],
rows3, [4*cm, 7*cm, 6*cm]))
story.append(sp(4))
for txt in [
f"{b('Access gained:')} Frontal sinus, NOE complex, orbital roofs, zygomatic arches, anterior skull base",
f"{b('Pitfalls:')} Alopecia (tension on flap), frontal branch palsy, haematoma",
]:
story.append(bp(txt))
story.append(sp(4))
story.append(ref_line("Ellis & Zide — Surgical Approaches to the Facial Skeleton; Pitanguy & Ramos, PRS 1966"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 4: ORBIT
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(4, "EYELID, PERIORBITA & ORBITAL SURGERY"))
story.append(sp(8))
story.append(Paragraph(b("Eyelid Layers (anterior → posterior)"), SEC_TITLE))
for txt in [
f"Skin ({b('thinnest in the body')}) → Orbicularis oculi (pretarsal / preseptal / orbital) → {b('Orbital septum')} (KEY BARRIER — fat lies behind) → Preaponeurotic fat → Levator aponeurosis / capsulopalpebral fascia → Tarsus → Conjunctiva",
f"{b('Medial canthal tendon (MCT):')} anchors the lid complex medially — critical in NOE fractures",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Orbital Walls & Contents"), SEC_TITLE))
for txt in [
f"7 bones; {b('thinnest:')} lamina papyracea (medial wall) and orbital floor → why blowout fractures occur here",
"Infraorbital nerve traverses the floor canal → at risk in midface trauma",
f"Contents: globe, extraocular muscles, optic nerve, ophthalmic vessels",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Orbital Fractures"), SEC_TITLE))
rows = [
["Hydraulic","Globe compressed → pressure transmitted to thin floor/medial wall",
"Fat ± inferior rectus herniation → diplopia, enophthalmos"],
["Buckling","Force along rim → bone buckles inward",
"Can occur without significant rim deformity"],
[f"{red('White-eyed blowout (paeds)')}","Trapdoor: muscle entrapped with minimal fat herniation",
f"{red('SURGICAL EMERGENCY — vagal response, persistent diplopia')}"],
]
story.append(make_table(["Mechanism","Pathophysiology","Clinical Result"],
rows, [3.5*cm, 7*cm, 6.5*cm]))
story.append(sp(4))
story.append(warn_box(
"FORCED DUCTION TEST distinguishes true muscle entrapment from nerve palsy. "
"Entrapment = positive (restricted passive movement). Must perform under GA in the paediatric white-eyed blowout."))
story.append(sp(6))
story.append(Paragraph(b("Orbital Surgical Approaches"), SEC_TITLE))
rows2 = [
[grn("Transconjunctival (preferred)"),
"Inferior fornix → preseptal or retroseptal → periorbita → floor",
"No cutaneous scar; lowest ectropion rate"],
["Subciliary",
"2 mm below lash line → orbicularis → septum (do NOT open) → periosteum",
"Ectropion risk 5-20%"],
["Lateral brow","Skin → orbicularis → periosteum → frontozygomatic suture","Limited access; FZ fixation"],
]
story.append(make_table(["Approach","Layers","Key Point"],
rows2, [4.5*cm, 7.5*cm, 5*cm]))
story.append(sp(6))
story.append(warn_box(
f"{red('RETROBULBAR HAEMORRHAGE = BLINDNESS EMERGENCY.')}"
" Signs: proptosis, RAPD, IOP >40 mmHg, pain. "
"Immediate lateral canthotomy + inferior cantholysis within 90 minutes. "
"Never dissect past the POSTERIOR THIRD of the floor (optic nerve)."))
story.append(sp(4))
story.append(ref_line("Ellis & Zide — Surgical Approaches to the Facial Skeleton"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 5: MIDFACE — SMAS, BUTTRESSES, LE FORT
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(5, "MIDFACE: SMAS, BUTTRESSES & LE FORT FRACTURES"))
story.append(sp(8))
story.append(Paragraph(b("Midface Soft-Tissue Layers"), SEC_TITLE))
story.append(bp("Skin → Subcutaneous fat (nasolabial, malar, jowl compartments) → SMAS (with mimetic muscles: zygomaticus major/minor, levator labii embedded within) → Parotid-masseteric fascia → Sub-SMAS plane (facial nerve branches, parotid duct, buccal fat pad) → Periosteum → Bone"))
story.append(sp(4))
rows = [
["Orbicularis oris","Sphincter of oral aperture","Cleft lip repair — must reconstruct muscular continuity"],
["Buccinator","Cheek compressor; pierced by Stensen's duct","Protect Stensen's duct in buccal approaches"],
["Mentalis","Chin elevator; inserts into chin skin","MUST RE-SUTURE in genioplasty — prevents 'witch's chin'"],
]
story.append(make_table(["Muscle","Function","Surgical Significance"],
rows,[4*cm, 6*cm, 7*cm]))
story.append(sp(6))
story.append(Paragraph(b("Midface Skeletal Buttresses"), SEC_TITLE))
for txt in [
f"{b('Vertical buttresses:')} Nasomaxillary, Zygomaticomaxillary, Pterygomaxillary",
f"{b('Horizontal buttresses:')} Frontal bar, Infraorbital rim, Maxillary alveolus",
"Function: transmit and absorb masticatory and traumatic forces; dictate fracture lines",
f"{b('Maxillary sinus:')} Roof = orbital floor; Floor = alveolus; Ostium in medial wall; lined by Schneiderian membrane",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Le Fort Fracture Classification"), SEC_TITLE))
rows2 = [
["I","Horizontal — floating palate",
"Separates alveolus + palate from mid-face",
"Malocclusion; maxillary mobility at alveolar level"],
["II","Pyramidal",
"Nasofrontal suture + orbital floor + pterygoids",
"CSF rhinorrhea; high haemorrhage risk"],
["III","Craniofacial disjunction",
"Complete separation of facial skeleton from cranium",
"Highest haemorrhage; airway emergency; dural tears"],
]
story.append(make_table(["Type","Name","Fracture Line","Complications"],
rows2,[1.5*cm,3.5*cm,5.5*cm,6.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("Le Fort I Osteotomy — Step-by-Step"), SEC_TITLE))
steps = [
"Upper buccal sulcus mucosa incision (canine to canine bilaterally)",
"Subperiosteal dissection — expose pyriform rim, infraorbital foramen, ZM buttress",
"Osteotomy 1: Lateral nasal wall",
"Osteotomy 2: Anterior maxillary wall — 5 mm above root apices (protect PSA vessels)",
"Osteotomy 3: ZM buttress (bilateral)",
f"Osteotomy 4: {red('Pterygomaxillary junction — MOST DANGEROUS')} (descending palatine + maxillary artery)",
"Osteotomy 5: Nasal septum",
"Downfracture with Rowe's disimpaction forceps",
f"After downfracture: protect descending palatine artery, pterygoid plates, greater palatine pedicle",
]
for i, s in enumerate(steps, 1):
story.append(Paragraph(f"<b>{i}.</b> {s}", BULLET))
story.append(sp(4))
story.append(warn_box(
"HAEMORRHAGE CONTROL in Le Fort I/II/III: precise osteotome placement → tight packing → "
"maxillary artery ligation (in pterygopalatine fossa) → angiographic embolization if needed."))
story.append(sp(4))
story.append(ref_line("Fonseca OMFS; Miloro Peterson's Principles; Markowitz & Manson PRS 1991"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 6: NOSE & NOE
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(6, "NOSE, NOE COMPLEX & ZMC"))
story.append(sp(8))
story.append(Paragraph(b("Nasal Layers"), SEC_TITLE))
story.append(bp("Skin (thick at tip, thin at dorsum) → Subcutaneous/SMAS → Nasal muscles → Perichondrium/Periosteum → Cartilage framework (upper lateral, lower lateral, septal cartilages) → Nasal bones → Mucosa"))
for txt in [
f"{b('Internal nasal valve:')} narrowest airway point (angle between upper lateral cartilage and septum) — key in functional rhinoplasty",
f"{b('Blood supply:')} Angular artery (external carotid system) + Sphenopalatine artery branches (epistaxis source — posterior nasal bleeding)",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("NOE Fractures — Markowitz-Manson Classification"), SEC_TITLE))
rows = [
["Type I","Single central fragment","MCT attached and intact",
"ORIF of single fragment; MCT intact"],
["Type II","Comminuted; MCT on a fragment","Comminuted but MCT attached",
"Fixation of MCT-bearing fragment; no transnasal wiring usually"],
["Type III",f"{red('Comminuted; MCT detached')}","MCT avulsed from bone",
f"{red('Transnasal canthopexy wiring required')}"],
]
story.append(make_table(["Type","Bone Pattern","MCT Status","Management"],
rows,[1.5*cm,4*cm,4*cm,7.5*cm]))
story.append(sp(4))
story.append(warn_box(
"TELECANTHUS (increased intercanthal distance >35 mm) = sign of MCT avulsion. "
"Bowstring test: pull eyelid laterally and palpate for MCT tightening over the nasal bridge. "
"Also check for: nasolacrimal duct obstruction, CSF leak."))
story.append(sp(8))
story.append(Paragraph(b("ZMC — The Tetrapod"), SEC_TITLE))
for txt in [
f"{b('4 articulations:')} Frontozygomatic, Zygomaticomaxillary, Zygomaticotemporal, Zygomaticosphenoid",
f"{b('Nerve at risk:')} Infraorbital nerve (commonest sensory complication in midface surgery)",
f"{b('Classification:')} Knight & North (6 types); Zingg (A/B/C)",
]:
story.append(bp(txt))
story.append(sp(4))
rows2 = [
["Gillies temporal","Hairline → TPF → deep temporal fascia → temporalis → elevator under arch",
"Minimal; only useful for isolated arch reduction"],
["Keen intraoral","Upper buccal sulcus behind ZM buttress",
"PSA artery; pterygoid plexus haemorrhage"],
["Transconjunctival + upper buccal + lateral brow","Combination for full ZMC ORIF",
"Covers all 4 sutures for fixation"],
]
story.append(make_table(["Approach","Layers / Access","Risk"],
rows2,[4*cm,7.5*cm,5.5*cm]))
story.append(sp(4))
story.append(ref_line("Ellis & Zide; Markowitz & Manson PRS 1991 (NOE)"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 7: PAROTID & PAROTIDECTOMY
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(7, "PAROTID GLAND & PAROTIDECTOMY"))
story.append(sp(8))
story.append(Paragraph(b("Parotid Layers — Superficial to Deep"), SEC_TITLE))
layers7 = [
("Skin","—"),
("Subcutaneous fat","—"),
("SMAS","—"),
("Parotid capsule (investing fascia)","Derived from investing layer of deep cervical fascia"),
(f"{red('Facial nerve branches')}","Most superficial structure within gland parenchyma"),
("Retromandibular vein","Landmark within the gland — divides superficial/deep lobes"),
("External carotid artery","Deepest structure within the gland"),
]
rows7 = [[n, d] for n, d in layers7]
story.append(make_table(["Layer","Key Point"], rows7, [5.5*cm, 11.5*cm]))
story.append(sp(4))
for txt in [
f"{b('Auriculotemporal nerve (V3):')} traverses gland — carries parasympathetic secretomotor fibres via otic ganglion (Frey syndrome pathway)",
f"{b('Stensen\\'s duct:')} opens into the oral cavity opposite the upper 2nd molar; pierces buccinator",
f"{b('Facial nerve divides gland')} into superficial and deep lobes — surgery DEMANDS trunk identification before lobar dissection",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Parotidectomy — Step-by-Step Approach"), SEC_TITLE))
steps7 = [
f"Modified Blair incision (preauricular + posterior to the lobule + submandibular extension)",
"Raise skin flap superficial to the parotid capsule",
f"{b('Identify facial nerve trunk')} using 3 triangulating landmarks simultaneously:",
f"{b('Landmark 1:')} 1 cm deep and inferior to the TRAGAL POINTER",
f"{b('Landmark 2:')} 6-8 mm deep to the TYMPANOMASTOID SUTURE",
f"{b('Landmark 3:')} Superior to POSTERIOR BELLY OF DIGASTRIC",
"Alternatively: retrograde identification from a peripheral branch (buccal or marginal)",
"Dissect superficial lobe off the nerve from trunk to periphery (teasing technique)",
"Deep lobe: meticulous dissection around all nerve branches with bipolar haemostasis",
f"{b('Frey syndrome prevention:')} SMAS flap or AlloDerm sheet interposed between skin and gland bed",
]
for i, s in enumerate(steps7, 1):
story.append(Paragraph(f"<b>{i}.</b> {s}", BULLET))
story.append(sp(4))
story.append(warn_box(
"House-Brackmann Grade I-VI for facial nerve function assessment. "
"Frey syndrome (auriculotemporal nerve misdirection) presents as gustatory sweating weeks to months post-op; "
"treated with botulinum toxin injections."))
story.append(sp(4))
story.append(ref_line("Miloro Peterson's Principles; Cummings Otolaryngology; Kademani & Tiwana Atlas"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 8: TMJ, CONDYLE & ITF
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(8, "TMJ, CONDYLAR FRACTURES & INFRATEMPORAL FOSSA"))
story.append(sp(8))
story.append(Paragraph(b("TMJ Layers"), SEC_TITLE))
story.append(bp("Skin → Subcutaneous (superficial temporal vessels, auriculotemporal nerve) → TPF → Deep temporal fascia → Periosteum → Capsule → Superior joint space → Disc → Condyle"))
for txt in [
f"{b('Disc:')} Biconcave fibrocartilage; bilaminar (retrodiscal) zone is vascular and innervated — source of pain in internal derangement",
f"{b('Blood supply:')} Superficial temporal and maxillary arteries",
f"{b('Innervation:')} Auriculotemporal nerve (V3)",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("TMJ Procedures"), SEC_TITLE))
rows8 = [
["Arthrocentesis","Holmlund-Hellsing line (tragus-lateral canthus)","Minimal; outpatient"],
["Arthroscopy","Superior joint space; avoid thin fossa roof","No open incision"],
["Open surgery / TJR","Preauricular or endaural incision",f"{red('Highest facial nerve risk')}"],
]
story.append(make_table(["Procedure","Access / Landmark","Key Risk"],
rows8,[4*cm,7*cm,6*cm]))
story.append(sp(6))
story.append(Paragraph(b("Condylar Fracture Management"), SEC_TITLE))
rows9 = [
["Retromandibular (transparotid)","Parotid; retromandibular vein = landmark",
f"{red('CN VII risk (branches)')}","Subcondylar; displaced"],
["Endoscope-assisted transoral","No cutaneous scar; transoral endoscopic",
"Technically demanding","Less nerve risk"],
]
story.append(make_table(["Approach","Anatomy","Risk","Indication"],
rows9,[4*cm,5.5*cm,3.5*cm,4*cm]))
story.append(sp(4))
story.append(bp(f"{b('Open ORIF indications:')} dislocation into middle cranial fossa; foreign body; lateral displacement; unobtainable occlusion"))
story.append(sp(6))
story.append(Paragraph(b("Infratemporal Fossa Contents"), SEC_TITLE))
rows10 = [
["Pterygoid muscles","Action: lateral pterygoid drives disc displacement and condyle fracture direction"],
[f"{red('Pterygoid venous plexus')}", f"{red('Most dangerous venous bleed in the region — difficult to control')}"],
["Maxillary artery","Variable relation to lateral pterygoid — at risk in Le Fort I and ITF approaches"],
["V3 (mandibular nerve)","Motor + sensory; gives IAN and lingual nerve"],
["Chorda tympani","Taste from anterior 2/3 tongue; parasympathetics to submandibular gland"],
[f"{red('Middle meningeal artery')}", f"{red('Enters foramen spinosum — laceration → epidural haematoma')}"],
]
story.append(make_table(["Structure","Applied Significance"], rows10,[5*cm,12*cm]))
story.append(sp(4))
story.append(ref_line("Miloro Peterson's Principles; Ellis & Zide; Kademani & Tiwana Atlas"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 9: MANDIBLE & LOWER FACE
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(9, "MANDIBLE, LOWER FACE & ORTHOGNATHIC SURGERY"))
story.append(sp(8))
story.append(Paragraph(b("Lower Face Layers"), SEC_TITLE))
story.append(bp(f"Skin → Subcutaneous → Platysma / Depressor muscles / Mentalis → Investing fascia → {red('Marginal mandibular nerve')} (superficial to facial vessels at the lower border) → Periosteum → Mandible"))
story.append(sp(4))
story.append(warn_box(
"MARGINAL MANDIBULAR NERVE dips 1-2 cm BELOW the inferior border of the mandible in ~20% of patients. "
"All submandibular incisions must be placed AT LEAST 2 cm below the inferior border. "
"Hayes-Martin maneuver: ligate the facial vein and retract the nerve superiorly on the vascular stump."))
story.append(sp(6))
story.append(Paragraph(b("Mandibular Fracture Biomechanics"), SEC_TITLE))
rows_m = [
["Condyle","36%","Elevators (masseter, temporalis, medial pterygoid)",
"Medial displacement (lateral pterygoid pull)"],
["Body","21%","Elevators vs. depressors",
"Favorable (medial) vs. unfavorable (lateral) angulation"],
["Angle","20%","Pterygomasseteric sling",
"Unfavorable — sling opens the fracture"],
["Symphysis","14%","Depressors (digastric, mylohyoid, geniohyoid)",
"Anterior fragment pulled inferiorly; lip/chin numbness"],
]
story.append(make_table(["Site","Frequency","Muscle Force","Key Feature"],
rows_m,[3*cm,2.5*cm,5.5*cm,6*cm]))
story.append(sp(6))
story.append(Paragraph(b("IAN and Lingual Nerve — Applied Anatomy"), SEC_TITLE))
rows_n = [
[f"{b('Inferior Alveolar Nerve')}",
"Runs in mandibular canal; exits as mental nerve below 2nd premolar",
"Third molars, BSSO, ORIF, implants — assess with CBCT pre-op",
"0.5-5% (3rd molar); 13-40% transient in BSSO"],
[f"{b('Lingual Nerve')}",
"Submucosally on lingual plate; only 2-3 mm below alveolar crest at 3rd molar region",
"Lingual flap elevation; elevator slip; lingual split technique",
"0.5-2% (3rd molar)"],
]
story.append(make_table(["Nerve","Position","Risk Scenario","Incidence"],
rows_n,[3.5*cm,4.5*cm,5.5*cm,3.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("Mandibular Approaches"), SEC_TITLE))
rows_ap = [
["Intraoral vestibular","Mucosa → submucosa → mentalis/buccinator → periosteum → bone","Mental nerve"],
["Submandibular (Risdon)","Skin → subcutaneous → platysma → investing fascia → marginal mandibular n. (Hayes-Martin) → pterygomasseteric sling → periosteum → bone","Marginal mandibular nerve"],
]
story.append(make_table(["Approach","Layers","Primary Risk"],
rows_ap,[3.5*cm,9.5*cm,4*cm]))
story.append(sp(6))
story.append(Paragraph(b("Champy's Ideal Osteosynthesis Lines (1978)"), SEC_TITLE))
rows_ch = [
["Symphysis","2 plates — bicortical inferior; monocortical superior","High torsional stress"],
["Body","1 plate — superior border along external oblique","Tension zone superior"],
["Angle","1 plate — along external oblique ridge; monocortical superior, bicortical inferior","Sling opens fracture"],
]
story.append(make_table(["Region","Fixation","Rationale"],
rows_ch,[3*cm,8.5*cm,5.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("BSSO (Obwegeser-Dal Pont) — Step-by-Step"), SEC_TITLE))
bsso_steps = [
"Intraoral incision anterior to the ramus",
f"Medial cut: {b('above the lingula')} (horizontal medial osteotomy) — IAN canal just below",
f"Sagittal cut: along the {b('external oblique ridge')}",
"Inferior border cut connecting the two",
f"{b('IAN must stay in the DISTAL segment')} — confirm with nerve hooks",
"Split with osteotomes; avoid thin buccal plate (bad split risk)",
f"{b('Risks:')} IAN injury 13-40% transient; bad/unfavorable split; inferior alveolar artery injury",
]
for i, s in enumerate(bsso_steps, 1):
story.append(Paragraph(f"<b>{i}.</b> {s}", BULLET))
story.append(sp(4))
story.append(tip_box(
"GENIOPLASTY: osteotomy at least 5 mm below the mental foramen (to protect mental nerve). "
"Always re-suture mentalis in 2 layers — failure causes 'witch's chin' deformity. "
"Protect genioglossus/geniohyoid (tongue airway support)."))
story.append(sp(4))
story.append(ref_line("Champy et al. J Maxillofac Surg 1978; Miloro Peterson's Principles; Fonseca OMFS"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 10: FLOOR OF MOUTH & SUBMANDIBULAR
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(10, "FLOOR OF MOUTH, SUBLINGUAL & SUBMANDIBULAR"))
story.append(sp(8))
story.append(Paragraph(b("Mylohyoid — The Muscular Diaphragm"), SEC_TITLE))
for txt in [
f"{b('Origin:')} Mylohyoid line (internal surface of mandible)",
"Divides: sublingual space (above) from submandibular space (below)",
f"{b('Applied:')} Root apex position relative to the mylohyoid line determines whether a dentoalveolar abscess presents in the sublingual or submandibular space",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Hyoglossus — The Master Landmark"), SEC_TITLE))
rows10a = [
[grn("Superficial to hyoglossus"),
"Lingual nerve, Wharton's duct, Hypoglossal nerve (CN XII), Sublingual gland"],
[red("Deep to hyoglossus"),
"Lingual artery, CN IX (glossopharyngeal nerve), Lingual vein"],
]
story.append(make_table(["Relation","Structures"], rows10a, [5*cm, 12*cm]))
story.append(sp(4))
story.append(warn_box(
"LINGUAL ARTERY haemorrhage: ligate deep to hyoglossus or at the ECA origin. "
"NEVER ligate bilaterally — vessels are only ~2 cm apart at the midline. "
"Bilateral ligation causes tongue necrosis."))
story.append(sp(6))
story.append(Paragraph(b("Submandibular Triangle — 'Danger Quartet'"), SEC_TITLE))
story.append(bp("Layers: Skin → Subcutaneous → Platysma → Investing fascia → Marginal mandibular nerve (superficial) → Submandibular gland → 4 deep structures:"))
rows10b = [
["1. Facial artery","Enters triangle deep; exits superficial at anterior masseter border",
"Double-ligate before dividing"],
["2. Lingual nerve","Superior to gland; wraps lateral→deep→medial around Wharton's duct",
"Identify and preserve before duct ligation"],
["3. Hypoglossal nerve (CN XII)","Deepest; runs on surface of hyoglossus",
"Preserve — innervates all intrinsic tongue muscles"],
["4. Facial vein","Runs superficially; used in Hayes-Martin maneuver",
"Ligate to retract marginal mandibular nerve safely"],
]
story.append(make_table(["Structure","Anatomy","Applied Action"],
rows10b,[3.5*cm,7*cm,6.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("Submandibular Gland Excision — Step-by-Step"), SEC_TITLE))
smg_steps = [
"Incision 2 cm below the inferior border of the mandible",
"Divide skin → subcutaneous → platysma",
f"{b('Hayes-Martin maneuver:')} ligate the facial vein → retract marginal mandibular nerve superiorly on the stump",
"Double-ligate and divide the facial artery",
"Mobilise the superficial lobe anteriorly and inferiorly",
"Retract posterior border of mylohyoid — this opens the deep space",
"Identify the lingual nerve (superior, wrapping Wharton's duct)",
"Free lingual nerve from Wharton's duct by blunt dissection",
"Identify and protect the hypoglossal nerve (deepest — on hyoglossus)",
"Ligate and divide Wharton's duct flush at the sublingual caruncle",
"Remove gland — layered closure + drain",
]
for i, s in enumerate(smg_steps, 1):
story.append(Paragraph(f"<b>{i}.</b> {s}", BULLET))
story.append(sp(4))
story.append(ref_line("Miloro Peterson's Principles; Cummings Otolaryngology; Brennan Clinical H&N Anatomy"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 11: NECK
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(11, "NECK ANATOMY, DISSECTION & DEEP SPACE INFECTIONS"))
story.append(sp(8))
story.append(Paragraph(b("Cervical Fascial Layers"), SEC_TITLE))
rows11 = [
["Investing layer","SCM, trapezius, parotid, submandibular gland",
"Opened first in neck dissection; provides structural landmarks"],
["Pretracheal / visceral","Thyroid, trachea, esophagus",
"Opens for tracheostomy; contains pretracheal space"],
["Prevertebral","Prevertebral muscles, spine",
"NEVER breach — posterior to retropharyngeal space"],
["Carotid sheath","Carotid artery, IJV, vagus nerve",
"Contributions from all 3 layers; protect in all neck surgery"],
]
story.append(make_table(["Layer","Encloses","Surgical Significance"],
rows11,[3.5*cm,5*cm,8.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("Lymph Node Levels — Drainage Map"), SEC_TITLE))
rows11b = [
["I (IA/IB)","Submental / Submandibular",
"Floor of mouth, lips, anterior gingiva, submandibular gland"],
["II (IIA/IIB)","Upper jugular","Tongue, tonsil, oropharynx; IIA/IIB split by CN XI (spinal accessory)"],
["III","Middle jugular","Oral cavity, hypopharynx"],
["IV","Lower jugular",f"{red('Thoracic duct enters at LEFT level IV — chyle leak if damaged')}"],
["V","Posterior triangle",f"{red('CN XI (spinal accessory) at risk — trapezius paralysis')}"],
["VI","Central compartment","Thyroid, larynx, subglottis"],
]
story.append(make_table(["Level","Region","Drainage / Key Risk"],
rows11b,[2*cm,4*cm,11*cm]))
story.append(sp(6))
story.append(Paragraph(b("Neck Dissection Types"), SEC_TITLE))
rows11c = [
["Radical","Removes levels I-V + SCM + IJV + CN XI","Rarely used; significant morbidity"],
["Modified Radical","Levels I-V; preserves SCM and/or IJV and/or CN XI","Standard for N+ disease"],
["Selective","Level-specific; I-III for oral cavity SCC (supraomohyoid)","Elective N0 neck in oral cancer"],
["Extended","Includes additional structures (parotid, skin, carotid)","Extensive disease"],
]
story.append(make_table(["Type","Structures Removed/Preserved","Indication"],
rows11c,[3.5*cm,7.5*cm,6*cm]))
story.append(sp(6))
story.append(Paragraph(b("Deep Space Infection Spread Pathway"), SEC_TITLE))
for txt in [
f"{b('Route:')} Odontogenic infection → Parapharyngeal space (adjacent to carotid sheath) → Retropharyngeal space → DANGER SPACE (alar-prevertebral) → Posterior mediastinum",
f"{b('Result:')} Descending Necrotizing Mediastinitis — mortality 30-50% if not recognised and drained urgently",
f"{b('Ludwig\\'s Angina:')} bilateral submandibular + submental + sublingual space infection — floor of mouth elevated, tongue pushed up → airway emergency",
]:
story.append(bp(txt))
story.append(sp(4))
story.append(warn_box(
"Any patient with floor of mouth swelling + trismus + dysphagia + stridor has a deep space infection "
"until proven otherwise. Secure the airway FIRST (awake fibreoptic intubation or tracheostomy). "
"CT with contrast defines the extent and the spaces involved."))
story.append(sp(4))
story.append(ref_line("Cummings Otolaryngology; Scott-Brown's; Fonseca OMFS"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 12: AIRWAY
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(12, "AIRWAY: TRACHEOSTOMY & CRICOTHYROIDOTOMY"))
story.append(sp(8))
story.append(Paragraph(b("Tracheostomy Layers (Outer to Airway)"), SEC_TITLE))
trach_layers = [
("Skin","—"),
("Subcutaneous fat","Anterior jugular veins (avoid; cauterise or retract)"),
("Platysma","—"),
("Investing fascia","—"),
("Strap muscles","Separate in the midline avascular raphe — do NOT cut"),
("Pretracheal fascia","—"),
(f"{b('Thyroid isthmus')}","Lies over rings 2-4; retract superiorly or divide between ligatures"),
(f"{b('Tracheal wall')}","Enter between rings 2-3 or 3-4; Bjork flap tacked to skin"),
]
rows12 = [[n,d] for n,d in trach_layers]
story.append(make_table(["Layer","Key Action/Risk"], rows12, [5.5*cm, 11.5*cm]))
story.append(sp(6))
story.append(Paragraph(b("Tracheostomy Complications"), SEC_TITLE))
rows12b = [
[f"{red('Tracheoinnominate fistula')}","Brachiocephalic artery erosion by tube tip",
f"{red('Hyperinflate cuff → emergency sternotomy')}"],
["RLN injury","Lateral dissection away from midline","Stay strictly midline below cricoid"],
["Thyroidea ima artery","Variant; present in 3-10%","Identify and ligate — can cause significant haemorrhage"],
["Subglottic stenosis","Cuff over-inflation; ischaemia","High-volume low-pressure cuffs; keep <20 cmH2O"],
]
story.append(make_table(["Complication","Mechanism","Prevention / Management"],
rows12b,[4.5*cm,5.5*cm,7*cm]))
story.append(sp(6))
story.append(Paragraph(b("Cricothyroidotomy"), SEC_TITLE))
for txt in [
f"{b('Landmarks:')} Thyroid cartilage → palpate downward → cricothyroid membrane → cricoid cartilage",
f"{b('Incision:')} Horizontal stab through the LOWER half of the cricothyroid membrane (avoid superior cricothyroid artery superiorly)",
f"{red('CONTRAINDICATED in children <12')} — risk of subglottic stenosis and growth disturbance; use needle cricothyroidotomy instead",
"Convert to formal tracheostomy within 24-72 hours",
]:
story.append(bp(txt))
story.append(sp(4))
story.append(ref_line("Miloro Peterson's Principles; Fonseca OMFS; Cummings Otolaryngology"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 13: NERVE INJURY
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(13, "NERVE INJURY: CLASSIFICATION & MANAGEMENT"))
story.append(sp(8))
story.append(Paragraph(b("Classification Systems"), SEC_TITLE))
rows13 = [
["Neuropraxia","1st","Conduction block; axon intact","Full, spontaneous","Observation"],
["Axonotmesis","2nd","Axon lost; endoneurium intact","Good, spontaneous","Observation"],
["—","3rd","Axon + endoneurium lost","Incomplete","Medical ± surgical"],
["—","4th","Axon + endo + perineurium lost","Poor","Surgery usually needed"],
["Neurotmesis","5th","Complete transection","None","Surgery required"],
["—","6th (Mackinnon)","Mixed grade injury","Variable","Case-by-case"],
]
story.append(make_table(["Seddon","Sunderland","Pathology","Spontaneous Recovery","Management"],
rows13,[2.5*cm,3.5*cm,5.5*cm,3.5*cm,3*cm]))
story.append(sp(6))
story.append(Paragraph(b("Assessment Protocol"), SEC_TITLE))
for txt in [
"History and examination: first and most important",
f"{b('Neurosensory testing:')} light touch (cotton wool), two-point discrimination (2PD normal <6 mm), pinprick, thermal",
f"{b('Imaging:')} MRI or high-resolution ultrasound for nerve continuity assessment",
f"{b('Timeline:')} reassess at 1, 3, 6, and 12 months; most neuropraxia resolves by 3 months",
]:
story.append(bp(txt))
story.append(sp(6))
story.append(Paragraph(b("Procedure-Specific Nerve Risks"), SEC_TITLE))
rows13b = [
["Third molar extraction","IAN","0.5-5%","CBCT pre-op; coronectomy if intimate"],
["Third molar extraction","Lingual nerve","0.5-2%","Avoid lingual flap; careful elevator placement"],
["BSSO","IAN (transient)","13-40%","Keep IAN in distal segment; avoid excessive retraction"],
["Le Fort I","Infraorbital nerve","Varies","Careful periosteal elevation; limit traction"],
["Parotidectomy","Facial nerve (all branches)","Varies by tumour","Trunk identification first; bipolar dissection"],
["Condylar ORIF","Marginal mandibular / frontal","Significant","Approach selection; nerve monitoring"],
["Submandibular excision","Marginal mandibular + hypoglossal","Significant","Hayes-Martin; identify and preserve CN XII"],
["Implant placement","IAN / mental nerve","Varies","2 mm clearance from IAN; assess anterior loop"],
]
story.append(make_table(["Procedure","Nerve at Risk","Incidence","Prevention"],
rows13b,[4*cm,3.5*cm,2.5*cm,7*cm]))
story.append(sp(4))
story.append(warn_box(
"Trigeminal nerve injuries are LARGELY PREVENTABLE. They are often mixed "
"(numbness + neuropathic pain), significantly impact quality of life, and carry medicolegal implications. "
"Mandatory documented informed consent is required before every procedure where nerve risk exists. "
"(Renton & Van der Cruyssen, Oral Surgery 2020)"))
story.append(sp(4))
story.append(ref_line("Seddon Brain 1943; Sunderland Brain 1951; Renton & Van der Cruyssen Oral Surg 2020"))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 14: COMPLICATIONS
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(14, "COMPLICATIONS — ANATOMICAL BASIS & MANAGEMENT"))
story.append(sp(8))
rows14 = [
["Third molar","IAN / lingual nerve injury",
"Proximity — IAN in canal, lingual nerve 2-3 mm from crest",
"Observe → medical (gabapentin/steroids) → microsurgery (<3 months)"],
["BSSO","Bad split / IAN injury",
"Thin buccal plate; IAN intimacy with medial cortex",
"Re-fixate; intraoperative nerve decompression; repair if transected"],
["Le Fort I","Haemorrhage",
"Maxillary artery / descending palatine artery at pterygomaxillary junction",
"Packing → maxillary artery ligation → embolisation"],
["Orbital repair","Blindness",
"Retrobulbar haemorrhage; optic nerve posterior floor",
"IMMEDIATE lateral canthotomy + inferior cantholysis"],
["Parotidectomy","Facial palsy / Frey syndrome",
"CN VII in gland; auriculotemporal misdirection",
"Nerve repair; botulinum toxin for Frey"],
["Neck dissection","Chyle leak",
"Thoracic duct at left level IV",
"Low-fat diet + pressure → surgical ligation"],
["Tracheostomy","Tracheoinnominate fistula",
"Brachiocephalic artery erosion by cuff / tube tip",
"Hyperinflate cuff → digital compression → emergency sternotomy"],
["BSSO / genioplasty","'Witch's chin'",
"Mentalis not re-sutured; chin ptosis",
"Prevention: 2-layer mentalis closure; late: revision surgery"],
["Orbital blowout repair","Inferior rectus entrapment post-plate",
"Plate placed over inferior rectus",
"Protect muscle; place mesh posterior to muscle bulk"],
]
story.append(make_table(["Procedure","Complication","Anatomical Basis","Management"],
rows14,[3.5*cm,3.5*cm,5*cm,5*cm]))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# MODULE 15: GRAND SUMMARY
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header(15, "GRAND SUMMARY — LANDMARKS & QUICK REFERENCE"))
story.append(sp(8))
story.append(Paragraph(b("Region-by-Region Summary Table"), SEC_TITLE))
rows15 = [
["Scalp","Loose areolar (danger layer)","Direct / coronal approach"],
["Temple","Frontal branch within TPF","Coronal — sub-fascial plane"],
["Orbit","Optic nerve; inferior rectus","Transconjunctival approach"],
["Midface","Descending palatine / maxillary artery","Upper buccal sulcus"],
["Parotid / TMJ","Facial nerve branches","Modified Blair / retromandibular"],
["Mandible","IAN, mental, marginal mandibular nerves","Vestibular / Risdon"],
["Floor of mouth","Lingual artery (deep to hyoglossus)","Transoral"],
["Submandibular","Danger quartet","Submandibular (Hayes-Martin)"],
["Neck","IJV, CN XI, carotid, thoracic duct","Selective neck dissection"],
["Airway","RLN, thyroid isthmus","Tracheostomy / cricothyroidotomy"],
]
story.append(make_table(["Region","Critical Structure","Primary Approach"],
rows15,[3.5*cm,7*cm,6.5*cm]))
story.append(sp(8))
story.append(Paragraph(b("Clinical Landmarks — Top to Bottom"), SEC_TITLE))
landmarks = [
("Supraorbital notch","Junction medial 1/3 : lateral 2/3 of orbital rim","Supraorbital / supratrochlear nerves + vessels"),
("Infraorbital foramen","1 cm below orbital rim on the pupillary line","Infraorbital nerve; injections; ORIF approach"),
("Tragal pointer","Tip of tragal cartilage","1 cm deep & inferior = CN VII trunk"),
("Pitanguy's line","Tragus → 1.5 cm above lateral brow","Frontal branch CN VII course"),
("Stensen's duct orifice","Opposite upper 2nd molar; anterior masseter border","Parotid duct; salivary calculi"),
("Mental foramen","Below 2nd premolar, 1 cm above lower border","Mental nerve; implant planning"),
("Hyoid bone","C3","Floor of mouth; tongue base attachment"),
("Thyroid cartilage","C4-C5","Carotid bifurcation level"),
("Cricothyroid membrane","Between thyroid and cricoid cartilages","Emergency airway"),
("Cricoid cartilage","C6","RLN enters larynx here; tracheostomy reference"),
("Tracheal rings 2-4","Below cricoid","Tracheostomy insertion site"),
]
rows_l = [[n,pos,sig] for n,pos,sig in landmarks]
story.append(make_table(["Landmark","Level / Location","Applied Significance"],
rows_l,[4.5*cm,4.5*cm,8*cm]))
story.append(sp(8))
story.append(Paragraph(b("Radiographic Landmarks"), SEC_TITLE))
rows_r = [
["OPG","Mandibular canal, mental foramen, lingula, pterygomaxillary fissure",
"Review quadrant by quadrant; check symmetry; assess IAN proximity to roots"],
["CBCT","IAN canal 3D position, anterior mental loop, sinus septa, implant bone",
"Mandatory before BSSO, complex extractions, implants"],
["CT","Frontal sinus tables, orbital walls, Le Fort lines, carotid encasement",
"Carotid >270 encasement = inoperable; assess posterior table fractures"],
["Cephalometry","S, N, A, B, ANS, PNS, Go, Pog; SNA / SNB / ANB",
"Orthognathic planning; ANB normal 2 degrees; class III <0 degrees"],
]
story.append(make_table(["Modality","Key Landmarks","Applied Use"],
rows_r,[2.5*cm,8*cm,6.5*cm]))
story.append(PageBreak())
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# REFERENCES
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
story.append(module_header("—", "REFERENCES"))
story.append(sp(8))
story.append(Paragraph(b("Standard Textbooks"), SEC_TITLE))
books = [
"Fonseca RJ. Oral and Maxillofacial Surgery, 3rd Ed. Elsevier Saunders.",
"Miloro M. Peterson's Principles of Oral and Maxillofacial Surgery, 3rd Ed. PMPH-USA.",
"Ellis E, Zide MF. Surgical Approaches to the Facial Skeleton, 2nd Ed. Lippincott Williams & Wilkins.",
"Kademani D, Tiwana PS. Atlas of Oral and Maxillofacial Surgery. Elsevier Saunders.",
"Brennan PA. Clinical Head and Neck Anatomy for Surgeons. CRC Press.",
"Standring S (Ed.). Gray's Anatomy: The Anatomical Basis of Clinical Practice, 41st Ed. Elsevier.",
"Norton NS. Netter's Head and Neck Anatomy for Dentistry, 3rd Ed. Elsevier.",
"Cummings CW et al. Cummings Otolaryngology: Head and Neck Surgery, 7th Ed. Elsevier.",
"Scott-Brown's Otorhinolaryngology Head and Neck Surgery. CRC Press/Taylor & Francis.",
]
for b_ in books:
story.append(bp(b_))
story.append(sp(8))
story.append(Paragraph(b("Key Articles"), SEC_TITLE))
articles = [
"Seddon HJ. A classification of nerve injuries. Brain. 1943;66(4):237-288.",
"Sunderland S. A classification of peripheral nerve injuries producing loss of function. Brain. 1951;74(4):491-516.",
"Champy M, Lodde JP, Schmitt R, et al. Mandibular osteosynthesis by miniature screwed plates via a buccal approach. J Maxillofac Surg. 1978;6(1):14-21.",
"Markowitz BL, Manson PN, Sargent L, et al. Management of the medial canthal tendon in nasoethmoid orbital fractures. Plast Reconstr Surg. 1991;87(5):843-853.",
"Pitanguy I, Ramos AS. The frontal branch of the facial nerve: importance of its variations in face lifting. Plast Reconstr Surg. 1966;38(4):352-356.",
"Renton T, Van der Cruyssen F. Diagnosis, pathophysiology, management and prevention of trigeminal nerve injuries. Oral Surg. 2020;13(4):397-423.",
"Mitz V, Peyronie M. The superficial musculo-aponeurotic system (SMAS) in the parotid and cheek area. Plast Reconstr Surg. 1974;54(1):80-88.",
]
for a_ in articles:
story.append(bp(a_))
story.append(sp(12))
story.append(HRFlowable(width="100%", thickness=1, color=GOLD, spaceAfter=8))
story.append(Paragraph(
"Department of Oral and Maxillofacial Surgery | "
"Prepared by Dr. Hrushikesh Acharya (JR1) | June 2026 | "
"For educational use only",
FOOTER_TXT))
# ── Build document ──────────────────────────────────────────────────────────────
doc = BaseDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=MARGIN+0.5*cm, bottomMargin=MARGIN+0.5*cm,
)
frame_cover = Frame(0, 0, PAGE_W, PAGE_H, leftPadding=MARGIN,
rightPadding=MARGIN, topPadding=MARGIN,
bottomPadding=MARGIN, id="cover")
frame_body = Frame(MARGIN, 1.5*cm, PAGE_W-2*MARGIN, PAGE_H-3.5*cm,
id="body")
doc.addPageTemplates([
PageTemplate(id="First", frames=[frame_cover], onPage=on_first_page),
PageTemplate(id="Later", frames=[frame_body], onPage=on_page),
])
from reportlab.platypus import NextPageTemplate
story.insert(0, NextPageTemplate("Later"))
story.insert(0, NextPageTemplate("First"))
# Shift cover elements to use cover frame properly
# Re-insert page template switch after cover PageBreak
# Find the PageBreak after cover and insert the template switch
for i, el in enumerate(story):
if isinstance(el, PageBreak) and i > 3:
story.insert(i+1, NextPageTemplate("Later"))
break
doc.build(story)
print("PDF created:", OUTPUT)