Botulinum toxin in ENT in detail
"botulinum toxin" AND "otolaryngology"
| Type | Muscles | Voice Characteristics |
|---|---|---|
| Adductor SD (most common) | Thyroarytenoid (TA), lateral cricoarytenoid (LCA) | Strained, strangled, effortful; voiced-syllable breaks |
| Abductor SD | Posterior cricoarytenoid (PCA) | Breathy phonation breaks on voiceless consonants |
| Mixed SD | Both | Combined features |


| Synkinesis Type | Target Muscle | Goal |
|---|---|---|
| Ocular synkinesis (eye closure with other movements) | Affected orbicularis oculi | Reduces involuntary lid closure; improves visual field |
| Paralyzed brow droop | Contralateral forehead muscles | Improves dynamic symmetry |
| Mentalis synkinesis (chin dimpling) | Mentalis muscle | Smooths chin |
| Lower lip asymmetry | Contralateral depressor labii inferioris (DLI) | Balances lower lip |
| Platysmal synkinesis | Platysmal bands | Reduces downward oral commissure pull |
| Bogorad syndrome (crocodile tears / epiphora) | Lacrimal gland | Reduces excessive tearing |
| Application | Details |
|---|---|
| Stuttering | Experimental; BTX to laryngeal and articulatory muscles to reduce the increased muscle tension; evidence limited |
| Laryngeal myoclonus | Palatal myoclonus with laryngeal involvement may respond to BTX |
| Spastic dysarthria | BTX to hyperactive laryngeal/pharyngeal muscles in pseudobulbar palsy |
| Hyperhidrosis of head/neck | Intradermal injection in hyperhidrosis of scalp or cervicofacial region |
| Product | Type | Equivalence Notes |
|---|---|---|
| Botox (onabotulinumtoxinA) | Type A | Reference standard |
| Dysport (abobotulinumtoxinA) | Type A | ~3–4× higher unit dose needed |
| Xeomin (incobotulinumtoxinA) | Type A | ~1:1 with Botox |
| Myobloc/NeuroBloc (rimabotulinumtoxinB) | Type B | Longer duration for glandular applications; more painful injection |
Preparations are not interchangeable unit-for-unit because of differing manufacturing processes and molecular structures.
| Effect | Mechanism | Management |
|---|---|---|
| Transient breathiness/hypophonia | Intended TA weakening (SD); diffusion | Self-limiting; dose reduction next cycle |
| Dysphagia | Diffusion to pharyngeal muscles | Usually transient; soft diet, observation |
| Aspiration pneumonia | Severe dysphagia + diffusion | Rare; most dangerous complication |
| Ptosis (ocular injections) | Levator palpebrae diffusion | Avoid injection too close to orbital rim |
| Xerostomia | Over-reduction of salivary flow | Dose adjustment |
| Dental caries (sialorrhea in children) | Reduced salivary pH + volume | Dental surveillance mandatory |
| Antibody formation | Repeated high doses → reduced efficacy | Use lowest effective dose, maximize injection intervals |
| Application | Target | Route | Dose (Botox units) | Duration |
|---|---|---|---|---|
| Adductor SD | Thyroarytenoid (bilateral) | Transcricothyroid EMG-guided | 1.25–2.5 U/side | 3–4 months |
| Abductor SD | Posterior cricoarytenoid (unilateral) | Posterior lateral, EMG-guided | 3.75–5 U/side | 3–4 months |
| Vocal tremor (horizontal) | Thyroarytenoid (bilateral) | EMG-guided | 1 U/side | 3–4 months |
| Vocal tremor (vertical) | Strap muscles (bilateral) | EMG-guided | 2.5–5 U/side | 3–4 months |
| Sialorrhea | Parotid + submandibular glands | US-guided / palpation | Variable (product-dependent) | 3–9 months |
| Facial synkinesis | Multiple facial muscles | Transcutaneous | 40 U orbicularis (synkinesis) | 3–4 months |
| Frey syndrome | Intradermal facial skin | Intradermal | Variable | 3–6 months |
| Cricopharyngeal spasm / PE hypertonicity | Cricopharyngeus / constrictor | EMG-guided transcervical | 100 U Botox | Up to 12 months |
| Non-allergic rhinitis | Inferior/middle turbinate head | Intranasal | — | Up to 12 weeks |
| Hemifacial spasm | Hemifacial musculature | Transcutaneous | Variable | 3–4 months |
Generate a quick reference PDF on BTX injection techniques in ENT
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not exis…
mkdir -p /home/daytona/workspace/btx-ent-pdf && python3 -c "import reportlab; pr…
~/btx-ent-pdf/generate_pdf.py
#!/usr/bin/env python3
"""
Quick Reference PDF: Botulinum Toxin Injection Techniques in ENT
Uses ReportLab for full layout control.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.lib.colors import HexColor
import os
# ── Colour palette ──────────────────────────────────────────────────────────
NAVY = HexColor('#1A3A5C')
TEAL = HexColor('#0B7A8A')
LIGHT_TEAL= HexColor('#D6F0F3')
AMBER = HexColor('#E8A020')
LIGHT_AMB = HexColor('#FFF4DC')
WARN_RED = HexColor('#C0392B')
WARN_PINK = HexColor('#FDECEA')
LIGHT_GRAY= HexColor('#F2F5F7')
MID_GRAY = HexColor('#8A9BB0')
WHITE = colors.white
OUTPUT = '/home/daytona/workspace/btx-ent-pdf/BTX_ENT_Quick_Reference.pdf'
# ── Document setup ───────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=18*mm, bottomMargin=18*mm,
title='Botulinum Toxin in ENT – Quick Reference',
author='Orris Medical',
subject='BTX Injection Techniques – Otolaryngology'
)
W = A4[0] - 30*mm # usable width
# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
def style(name, parent='Normal', **kw):
s = ParagraphStyle(name, parent=base[parent])
for k, v in kw.items():
setattr(s, k, v)
return s
sTitle = style('sTitle', 'Normal', fontSize=22, textColor=WHITE,
fontName='Helvetica-Bold', leading=28, alignment=TA_CENTER)
sSub = style('sSub', 'Normal', fontSize=11, textColor=LIGHT_TEAL,
fontName='Helvetica', leading=16, alignment=TA_CENTER)
sH1 = style('sH1', 'Normal', fontSize=13, textColor=WHITE,
fontName='Helvetica-Bold', leading=18, spaceAfter=2)
sH2 = style('sH2', 'Normal', fontSize=10, textColor=NAVY,
fontName='Helvetica-Bold', leading=14, spaceBefore=6, spaceAfter=2)
sBody = style('sBody', 'Normal', fontSize=8.5, textColor=HexColor('#1C2B3A'),
fontName='Helvetica', leading=13, spaceAfter=3)
sBullet = style('sBullet', 'Normal', fontSize=8.5, textColor=HexColor('#1C2B3A'),
fontName='Helvetica', leading=12, leftIndent=10, spaceAfter=1)
sNote = style('sNote', 'Normal', fontSize=7.5, textColor=HexColor('#5A6A7A'),
fontName='Helvetica-Oblique', leading=11)
sWarn = style('sWarn', 'Normal', fontSize=8.5, textColor=WARN_RED,
fontName='Helvetica-Bold', leading=12)
sCell = style('sCell', 'Normal', fontSize=8, textColor=HexColor('#1C2B3A'),
fontName='Helvetica', leading=11)
sCellB = style('sCellB', 'Normal', fontSize=8, textColor=NAVY,
fontName='Helvetica-Bold', leading=11)
sCellH = style('sCellH', 'Normal', fontSize=8, textColor=WHITE,
fontName='Helvetica-Bold', leading=11, alignment=TA_CENTER)
sFooter = style('sFooter', 'Normal', fontSize=7, textColor=MID_GRAY,
fontName='Helvetica', leading=10, alignment=TA_CENTER)
# ── Helper builders ──────────────────────────────────────────────────────────
def section_header(text, color=NAVY):
"""Coloured banner heading."""
tbl = Table([[Paragraph(text, sH1)]], colWidths=[W])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
('ROUNDEDCORNERS', [3]),
]))
return tbl
def info_box(title, body_paras, bg=LIGHT_TEAL, border=TEAL):
"""Coloured info box."""
content = [Paragraph(title, sH2)] + body_paras
tbl = Table([[content]], colWidths=[W])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 1.2, border),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
]))
return tbl
def warn_box(text):
tbl = Table([[Paragraph('⚠ ' + text, sWarn)]], colWidths=[W])
tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), WARN_PINK),
('BOX', (0,0), (-1,-1), 1.2, WARN_RED),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
return tbl
def std_table(headers, rows, col_widths=None):
"""Standard data table with navy header row."""
data = [[Paragraph(h, sCellH) for h in headers]]
for row in rows:
data.append([Paragraph(str(c), sCell) for c in row])
if col_widths is None:
col_widths = [W / len(headers)] * len(headers)
tbl = Table(data, colWidths=col_widths, repeatRows=1)
style_cmds = [
('BACKGROUND', (0,0), (-1,0), NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
('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), 'MIDDLE'),
]
tbl.setStyle(TableStyle(style_cmds))
return tbl
def bullet(text):
return Paragraph(f'• {text}', sBullet)
def sp(h=4):
return Spacer(1, h*mm)
# ────────────────────────────────────────────────────────────────────────────
# PAGE HEADER / FOOTER callbacks
# ────────────────────────────────────────────────────────────────────────────
def on_page(canvas, doc):
canvas.saveState()
# Top stripe
canvas.setFillColor(NAVY)
canvas.rect(0, A4[1]-12*mm, A4[0], 12*mm, fill=1, stroke=0)
canvas.setFillColor(TEAL)
canvas.rect(0, A4[1]-14*mm, A4[0], 2*mm, fill=1, stroke=0)
canvas.setFont('Helvetica-Bold', 8)
canvas.setFillColor(WHITE)
canvas.drawString(15*mm, A4[1]-8*mm, 'BTX INJECTION TECHNIQUES IN ENT | QUICK REFERENCE')
canvas.setFont('Helvetica', 8)
canvas.drawRightString(A4[0]-15*mm, A4[1]-8*mm, f'Page {doc.page}')
# Bottom stripe
canvas.setFillColor(LIGHT_GRAY)
canvas.rect(0, 0, A4[0], 10*mm, fill=1, stroke=0)
canvas.setFont('Helvetica', 7)
canvas.setFillColor(MID_GRAY)
canvas.drawCentredString(A4[0]/2, 3.5*mm,
'Source: Cummings Otolaryngology (6e) · KJ Lee\'s Essential Otolaryngology (11e) · For clinical use under specialist supervision')
canvas.restoreState()
def on_first_page(canvas, doc):
# Full navy cover band
canvas.saveState()
canvas.setFillColor(NAVY)
canvas.rect(0, A4[1]-52*mm, A4[0], 52*mm, fill=1, stroke=0)
canvas.setFillColor(TEAL)
canvas.rect(0, A4[1]-54*mm, A4[0], 2*mm, fill=1, stroke=0)
canvas.setFillColor(AMBER)
canvas.rect(0, A4[1]-56*mm, A4[0], 2*mm, fill=1, stroke=0)
# Footer
canvas.setFillColor(LIGHT_GRAY)
canvas.rect(0, 0, A4[0], 10*mm, fill=1, stroke=0)
canvas.setFont('Helvetica', 7)
canvas.setFillColor(MID_GRAY)
canvas.drawCentredString(A4[0]/2, 3.5*mm,
'Source: Cummings Otolaryngology (6e) · KJ Lee\'s Essential Otolaryngology (11e) · For clinical use under specialist supervision')
canvas.restoreState()
# ────────────────────────────────────────────────────────────────────────────
# BUILD CONTENT
# ────────────────────────────────────────────────────────────────────────────
story = []
# ── COVER BLOCK (sits below the navy banner drawn by on_first_page) ──────────
story.append(Spacer(1, 42*mm)) # space for the cover banner
story.append(Paragraph('BOTULINUM TOXIN', sTitle))
story.append(Paragraph('Injection Techniques in Otolaryngology — Head & Neck Surgery', sSub))
story.append(Spacer(1, 3*mm))
story.append(Paragraph('QUICK REFERENCE GUIDE', style('qr','Normal',fontSize=9,
textColor=AMBER, fontName='Helvetica-Bold', alignment=TA_CENTER)))
story.append(sp(6))
# ── MECHANISM BOX ─────────────────────────────────────────────────────────────
mech_content = [
Paragraph('<b>Serotypes:</b> Eight (A–H); <b>BoNT-A</b> (onabotulinumtoxinA) is standard; BoNT-B used for glandular applications.', sBody),
Paragraph('<b>Motor mechanism:</b> Cleaves <b>SNAP-25</b> → blocks presynaptic ACh vesicle fusion → flaccid chemodenervation.', sBody),
Paragraph('<b>Autonomic mechanism:</b> Blocks parasympathetic secretomotor fibres → reduces glandular secretion.', sBody),
Paragraph('<b>Onset:</b> 2–3 days (glands) / 3–7 days (muscle) | <b>Duration:</b> 3–9 months depending on preparation.', sBody),
]
story.append(info_box('⚙ MECHANISM OF ACTION', mech_content, bg=LIGHT_TEAL, border=TEAL))
story.append(sp(4))
# ── PREPARATIONS TABLE ────────────────────────────────────────────────────────
story.append(section_header(' COMMERCIAL PREPARATIONS', color=TEAL))
story.append(sp(2))
prep_headers = ['Product', 'Toxin Type', 'Trade Name', 'Dose Equivalence Note']
prep_rows = [
['OnabotulinumtoxinA', 'Type A', 'Botox', 'Reference standard (1 U)'],
['AbobotulinumtoxinA', 'Type A', 'Dysport', '~3–4× higher units needed'],
['IncobotulinumtoxinA', 'Type A', 'Xeomin', '~1:1 with Botox'],
['RimabotulinumtoxinB', 'Type B', 'Myobloc / NeuroBloc', 'Preferred for glandular use; more painful'],
]
story.append(std_table(prep_headers, prep_rows, [50*mm, 25*mm, 35*mm, W-110*mm]))
story.append(Paragraph('⚠ Preparations are NOT interchangeable unit-for-unit.', sWarn))
story.append(sp(5))
# ════════════════════════════════════════════════════════════════════════════
# SECTION 1: LARYNGEAL APPLICATIONS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header(' 1. LARYNGEAL APPLICATIONS'))
story.append(sp(3))
# 1a — Adductor Spasmodic Dysphonia
story.append(KeepTogether([
Paragraph('1a. Adductor Spasmodic Dysphonia (AdSD)', sH2),
Paragraph('<i>Gold standard treatment. Idiopathic focal laryngeal dystonia; strained, strangled voice with voiced phonation breaks.</i>', sNote),
sp(2),
]))
asd_headers = ['Parameter', 'Detail']
asd_rows = [
['Target muscle', 'Thyroarytenoid (TA) — bilateral'],
['Needle', '27-gauge hollow EMG needle (transcricothyroid membrane)'],
['Guidance', 'EMG confirmation — patient phonates /i/ to recruit TA motor units'],
['Starting dose', '1.25–2.5 U Botox per side (bilateral)'],
['Onset', '3–7 days; peak effect ~2 weeks'],
['Duration', '3–4 months (average)'],
['Side effects', 'Transient breathiness, mild dysphagia (1–2 weeks); dose-dependent'],
['Repeat cycle', 'Every 3–4 months; titrate dose to minimise breathiness'],
]
story.append(std_table(asd_headers, asd_rows, [55*mm, W-55*mm]))
story.append(sp(4))
# 1b — Abductor Spasmodic Dysphonia
story.append(KeepTogether([
Paragraph('1b. Abductor Spasmodic Dysphonia (AbSD)', sH2),
Paragraph('<i>Breathy phonation breaks on voiceless consonants. Targets the only vocal fold abductor.</i>', sNote),
sp(2),
]))
absd_rows = [
['Target muscle', 'Posterior cricoarytenoid (PCA) — UNILATERAL (safety)'],
['Approach', 'Posterior lateral: thyroid cartilage rotated laterally + anteriorly; needle at posterior lateral cricoid'],
['Needle', '27-gauge hollow EMG needle'],
['Guidance', 'EMG confirmation — "sniff" manoeuvre recruits PCA motor units'],
['Starting dose', '3.75–5 U Botox per side (one side at a time)'],
['Duration', '3–4 months'],
['Key safety rule', 'NEVER inject both PCAs simultaneously — bilateral weakness risks airway compromise'],
]
story.append(std_table(asd_headers, absd_rows, [55*mm, W-55*mm]))
story.append(warn_box('BILATERAL PCA injection is CONTRAINDICATED — risk of acute airway obstruction.'))
story.append(sp(4))
# 1c — Vocal Tremor
story.append(KeepTogether([
Paragraph('1c. Essential Vocal / Laryngeal Tremor', sH2),
sp(2),
]))
vt_headers = ['Tremor Pattern', 'Target', 'Starting Dose', 'Notes']
vt_rows = [
['Horizontal glottic (vocal fold oscillation)',
'Thyroarytenoid — bilateral', '1 U/side', 'Low starting dose to avoid hypophonia'],
['Vertical laryngopharyngeal (larynx bobs up/down)',
'Strap muscles — bilateral', '2.5–5 U/side', 'Reduces laryngeal excursion amplitude'],
['Mixed pattern',
'TA + strap muscles', 'Alternate injections', 'Space 3–8 weeks apart to avoid dysphagia'],
]
story.append(std_table(vt_headers, vt_rows, [52*mm, 50*mm, 30*mm, W-132*mm]))
story.append(sp(4))
# 1d — Cricopharyngeal / PE Segment
story.append(KeepTogether([
Paragraph('1d. Cricopharyngeal Dysfunction & PE Segment Hypertonicity', sH2),
Paragraph('<i>UES fails to relax: post-stroke dysphagia, PD, ALS, Zenker\'s, post-laryngectomy prosthetic speech failure.</i>', sNote),
sp(2),
]))
cp_rows = [
['Target muscle', 'Cricopharyngeus / inferior pharyngeal constrictor'],
['Pre-procedure', 'Videofluoroscopy (modified barium swallow) to localise hypertonic segment; mark on skin'],
['Guidance', 'Hollow EMG needle — confirms intramuscular placement'],
['Dose', '100 U Botox OR 400 U Dysport into constrictor pharyngeal muscle group'],
['Duration', 'Up to 12 months (post-stroke); often long-lasting in post-laryngectomy patients'],
['Diagnostic step', '1% lidocaine injection first confirms hypertonicity; predicts BTX response'],
['Post-laryngectomy', 'Once fluent TE voice achieved, effect is often permanent (biofeedback reinforcement)'],
]
story.append(std_table(asd_headers, cp_rows, [55*mm, W-55*mm]))
story.append(sp(6))
# ════════════════════════════════════════════════════════════════════════════
# SECTION 2: SALIVARY GLAND APPLICATIONS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header(' 2. SALIVARY GLAND APPLICATIONS'))
story.append(sp(3))
# 2a — Sialorrhea
story.append(Paragraph('2a. Sialorrhea (Drooling)', sH2))
story.append(Paragraph(
'Indication: Neurogenic sialorrhea (CP, ALS, PD, post-stroke), medication-induced, pediatric neuromuscular disorders.',
sBody))
story.append(sp(2))
sial_rows = [
['Glands injected', 'Parotid + submandibular (all four in severe cases)'],
['Technique options', '1. Anatomic landmarks + palpation\n2. Ultrasound-guided (preferred — reduces diffusion risk)\n3. EMG-guided'],
['Product choice', 'BoNT-A (Botox/Dysport/Xeomin) OR BoNT-B (Myobloc — longer glandular duration)'],
['Onset', '2–3 days'],
['Duration', '3–9 months'],
['Setting', 'Outpatient; local anaesthesia. GA in uncooperative/paediatric patients'],
['Non-responders', '~10% regardless of dose'],
]
story.append(std_table(asd_headers, sial_rows, [55*mm, W-55*mm]))
story.append(sp(2))
sial_warn_rows = [
[Paragraph('Adverse Effect', sCellH), Paragraph('Mechanism', sCellH), Paragraph('Management', sCellH)],
[Paragraph('Dysphagia / aspiration pneumonia', sCell), Paragraph('Toxin diffusion to neck muscles', sCell), Paragraph('Lowest effective dose; US guidance', sCell)],
[Paragraph('Xerostomia', sCell), Paragraph('Over-reduction of salivary output', sCell), Paragraph('Dose adjustment; hydration', sCell)],
[Paragraph('Dental caries (paediatric)', sCell), Paragraph('↓ salivary pH + volume', sCell), Paragraph('Mandatory dental surveillance', sCell)],
[Paragraph('Gland atrophy', sCell), Paragraph('Chronic use → measurable ↓ gland size on USS', sCell), Paragraph('Monitor; histology preserved', sCell)],
]
sial_warn_tbl = Table(sial_warn_rows, colWidths=[60*mm, 65*mm, W-125*mm])
sial_warn_tbl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), WARN_RED),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WARN_PINK, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, HexColor('#CCCCCC')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(Paragraph('<b>Adverse Effects — Salivary Gland Injections</b>', sH2))
story.append(sial_warn_tbl)
story.append(sp(4))
# 2b — Frey Syndrome
story.append(KeepTogether([
Paragraph('2b. Frey Syndrome (Gustatory Sweating)', sH2),
Paragraph(
'<i>Sequela of parotidectomy (incidence 35–60%; subclinical up to 96%). Aberrant reinnervation of sweat glands by '
'parasympathetic fibres. Triggered by mastication.</i>', sNote),
sp(2),
]))
frey_rows = [
['Diagnosis', 'Minor starch-iodine test — iodine + starch powder; chew lemon wedge; blue-black spots confirm'],
['BTX preparation', 'OnabotulinumtoxinA (Botox)'],
['Injection technique', 'Intradermal injection across the affected facial skin region (multiple small depots)'],
['Step in management', '3rd line — after topical antiperspirant and glycopyrrolate 1% roll-on have failed'],
['Duration', '3–6 months; repeat as needed'],
['Surgical alternative', 'Tympanic neurectomy'],
]
story.append(std_table(asd_headers, frey_rows, [55*mm, W-55*mm]))
story.append(sp(6))
# ════════════════════════════════════════════════════════════════════════════
# SECTION 3: FACIAL NERVE / HEAD & NECK
# ════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header(' 3. FACIAL NERVE & HEAD / NECK APPLICATIONS'))
story.append(sp(3))
# 3a — Facial Synkinesis
story.append(Paragraph('3a. Post-Facial Paralysis Synkinesis', sH2))
story.append(Paragraph(
'Aberrant reinnervation after Bell\'s palsy, acoustic neuroma surgery, parotidectomy. '
'Involuntary co-contraction during voluntary facial movements.',
sBody))
story.append(sp(2))
syn_headers = ['Synkinesis Type', 'Target Muscle(s)', 'Dose (Botox)', 'Goal']
syn_rows = [
['Ocular synkinesis\n(eye closes with facial movement)',
'Affected orbicularis oculi', '20–40 U (dose-escalation)\nChua et al: 40 U optimal',
'Reduce involuntary lid closure; avoid ptosis'],
['Brow ptosis (paralysed side)',
'CONTRALATERAL forehead\n(frontalis)', '4–8 U',
'Improve dynamic brow symmetry'],
['Mentalis synkinesis\n(chin dimpling)',
'Mentalis', '2–5 U', 'Smooth chin contour'],
['Lower lip asymmetry',
'CONTRALATERAL depressor\nlabii inferioris (DLI)', '2–5 U',
'Balance lower lip position'],
['Platysmal synkinesis\n(pulls oral commissure down)',
'Platysmal bands (multiple\ninjection points)', '5–15 U total',
'Improve oral commissure excursion'],
['Bogorad syndrome\n(crocodile tears / epiphora)',
'Lacrimal gland', '2–5 U',
'Reduce excessive tearing'],
]
story.append(std_table(syn_headers, syn_rows,
[52*mm, 48*mm, 40*mm, W-140*mm]))
story.append(sp(2))
story.append(info_box('📌 Key Principle',
[Paragraph('Inject the <b>affected</b> side to weaken hyperactive muscle, OR the <b>contralateral</b> side '
'to improve symmetry — the choice depends on the specific deficit.', sBody)],
bg=LIGHT_AMB, border=AMBER))
story.append(sp(4))
# 3b — Hemifacial Spasm
story.append(KeepTogether([
Paragraph('3b. Hemifacial Spasm', sH2),
Paragraph('<i>Painless, irregular, unilateral facial contractions — usually from vascular compression of CN VII at brainstem exit zone.</i>', sNote),
sp(2),
]))
hfs_rows = [
['BTX role', 'First-line pharmacological treatment (alternative to microvascular decompression)'],
['Technique', 'Subcutaneous/intramuscular injection across affected hemifacial musculature'],
['Duration', '3–4 months; repeat injections required long-term'],
['Curative option', 'Microvascular decompression (MVD) — reserved for young/refractory patients'],
]
story.append(std_table(asd_headers, hfs_rows, [55*mm, W-55*mm]))
story.append(sp(6))
# ════════════════════════════════════════════════════════════════════════════
# SECTION 4: NASAL / RHINOLOGIC
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header(' 4. NASAL / RHINOLOGIC APPLICATION'))
story.append(sp(3))
story.append(Paragraph('Non-Allergic Rhinitis (Vasomotor Rhinitis)', sH2))
story.append(Paragraph(
'Exploits anticholinergic effect on nasal secretory mucosa to reduce rhinorrhoea.',
sBody))
story.append(sp(2))
nar_rows = [
['Indication', 'Non-allergic (vasomotor) rhinitis with predominant rhinorrhoea'],
['Injection site', 'Intranasally — head of inferior and middle turbinates (bilateral)'],
['Effect', 'Reduces rhinorrhoea; does NOT improve nasal obstruction or sneezing'],
['Duration', 'Up to 12 weeks (temporary)'],
['Position in treatment', 'Bridge to definitive surgery (posterior nasal neurectomy, vidian neurectomy)'],
['Advantage', 'Office-based; minimal side effects; no systemic absorption'],
]
story.append(std_table(asd_headers, nar_rows, [55*mm, W-55*mm]))
story.append(sp(6))
# ════════════════════════════════════════════════════════════════════════════
# MASTER QUICK REFERENCE TABLE
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header(' MASTER QUICK REFERENCE — ALL ENT APPLICATIONS', color=HexColor('#0D5C6E')))
story.append(sp(3))
master_headers = ['Application', 'Target', 'Guidance', 'Dose (Botox)', 'Duration']
master_rows = [
['Adductor SD', 'Thyroarytenoid (bilateral)', 'EMG; transcricothyroid', '1.25–2.5 U/side', '3–4 months'],
['Abductor SD', 'PCA (unilateral)', 'EMG; posterior-lateral', '3.75–5 U/side', '3–4 months'],
['Vocal tremor (horizontal)', 'Thyroarytenoid (bilateral)', 'EMG', '1 U/side', '3–4 months'],
['Vocal tremor (vertical)', 'Strap muscles (bilateral)', 'EMG', '2.5–5 U/side', '3–4 months'],
['Cricopharyngeal spasm', 'Cricopharyngeus', 'EMG; videofluoroscopy', '100 U total', 'Up to 12 months'],
['PE segment hypertonicity\n(post-laryngectomy)', 'Constrictor pharyngeus', 'EMG', '100 U Botox\n400 U Dysport', 'Often long-lasting'],
['Sialorrhea', 'Parotid + submandibular\n(all 4 glands)', 'US-guided (preferred)', 'Product-dependent', '3–9 months'],
['Frey syndrome', 'Intradermal facial skin', 'Anatomical', 'Multiple small depots', '3–6 months'],
['Facial synkinesis\n(ocular)', 'Orbicularis oculi (affected)', 'Anatomical', '40 U', '3–4 months'],
['Facial synkinesis\n(brow, lip)', 'Contralateral muscles', 'Anatomical', '4–8 U per site', '3–4 months'],
['Hemifacial spasm', 'Hemifacial musculature', 'Anatomical / subcutaneous', 'Titrated', '3–4 months'],
['Non-allergic rhinitis', 'Inf. + mid. turbinate head', 'Intranasal / anatomical', 'Variable', 'Up to 12 weeks'],
]
story.append(std_table(master_headers, master_rows,
[42*mm, 48*mm, 38*mm, 32*mm, W-160*mm]))
story.append(sp(6))
# ════════════════════════════════════════════════════════════════════════════
# SECTION 5: ADVERSE EFFECTS & GENERAL CAUTIONS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header(' 5. ADVERSE EFFECTS & GENERAL CAUTIONS', color=WARN_RED))
story.append(sp(3))
ae_headers = ['Adverse Effect', 'Cause', 'Management']
ae_rows = [
['Transient breathiness / hypophonia', 'TA over-weakening (AdSD)', 'Self-limiting 1–2 weeks; ↓ dose next cycle'],
['Dysphagia', 'Local diffusion to pharyngeal muscles', 'Soft diet; observation; usually resolves <2 weeks'],
['Aspiration pneumonia', 'Severe dysphagia with diffusion', 'Rare but serious; dose adjustment; US guidance'],
['Ptosis', 'Diffusion to levator palpebrae', 'Avoid injection within 1 cm of orbital rim'],
['Xerostomia', 'Excess reduction of salivary flow', 'Dose reduction; oral hydration'],
['Dental caries (paediatric)', '↓ salivary pH + volume', 'Mandatory dental surveillance programme'],
['Antibody formation', 'Repeated high doses → treatment failure', 'Use lowest effective dose; maximise injection intervals'],
['Bilateral airway obstruction', 'Bilateral PCA injection', 'AVOID — never inject both PCAs simultaneously'],
]
story.append(std_table(ae_headers, ae_rows, [52*mm, 60*mm, W-112*mm]))
story.append(sp(4))
# General cautions
cautions = [
'Use lowest effective dose and maximise interval between injection cycles.',
'Always confirm intramuscular/intraglandular placement with EMG or ultrasound for deep injections.',
'Preparations are NOT interchangeable — always specify product and unit system.',
'Disclose all BTX treatments to anaesthetist before neuromuscular-blocking agents are used.',
'Patient counselling: effect is temporary; repeated injections required for ongoing benefit.',
'Black box warning (FDA): serious adverse effects including dysphagia, aspiration pneumonia, and distant spread of toxin effect have been reported.',
]
story.append(info_box('⚠ GENERAL CAUTIONS',
[bullet(c) for c in cautions], bg=LIGHT_AMB, border=AMBER))
story.append(sp(4))
# ── References ─────────────────────────────────────────────────────────────
story.append(HRFlowable(width='100%', thickness=0.5, color=MID_GRAY))
story.append(sp(2))
refs = [
'Cummings CW et al. <i>Cummings Otolaryngology Head and Neck Surgery</i>, 6th ed. Mosby Elsevier, 2015. Chapters 57, 65, 111, 205.',
'Lee KJ. <i>Essential Otolaryngology: Head and Neck Surgery</i>, 11th ed. McGraw-Hill, 2016. Chapter on Chemodenervation.',
'Blitzer A, Brin MF, Ramig LO, eds. <i>Neurologic Disorders of the Larynx</i>, 2nd ed. Thieme, 2009.',
'Jaworek AJ, Sataloff RT. Spasmodic Dysphonia. <i>World J Otorhinolaryngol Head Neck Surg</i>. 2025 Dec. [PMID: 41477134]',
'Tikhtman R, Hsieh TY. Minimization of facial synkinesis. <i>Curr Opin Otolaryngol Head Neck Surg</i>. 2023 Oct. [PMID: 37610981]',
]
for r in refs:
story.append(Paragraph(r, sNote))
story.append(Spacer(1, 1*mm))
# ── Build ───────────────────────────────────────────────────────────────────
doc.build(story,
onFirstPage=on_first_page,
onLaterPages=on_page)
print(f'PDF written to: {OUTPUT}')
print(f'File size: {os.path.getsize(OUTPUT):,} bytes')
cd /home/daytona/workspace/btx-ent-pdf && python3 generate_pdf.py 2>&1
BTX ENT Quick Reference
PDF Document · PDF
| Section | Content |
|---|---|
| Cover + Mechanism | Serotypes, SNAP-25 mechanism, onset/duration, commercial preparations table |
| 1. Laryngeal | Adductor SD, Abductor SD (with bilateral PCA warning), Vocal tremor, Cricopharyngeal/PE segment — each with target, approach, EMG guidance, dose, duration |
| 2. Salivary Gland | Sialorrhea (US-guided technique, adverse effects table), Frey syndrome |
| 3. Facial Nerve / Head & Neck | Post-paralysis synkinesis (6 subtypes with specific targets), Hemifacial spasm |
| 4. Nasal | Non-allergic rhinitis — turbinate injection |
| Master Reference Table | All 12 ENT applications on one row-per-row table |
| 5. Adverse Effects | Full table + general cautions box including FDA black box warning |
| References | Cummings, KJ Lee, and recent PubMed citations |