Vocal palsy exercises voice therapy
vocal cord palsy voice therapy exercises rehabilitation speech therapy 2024
"vocal cord paralysis" AND "voice therapy"
https://pmc.ncbi.nlm.nih.gov/articles/PMC11623809
vocal cord paralysis voice therapy exercises larynx
| Exercise | Technique |
|---|---|
| Forced cough | Forced expiration with closed glottis (hard glottal stop) |
| Cough + vowel | Cough, then immediately release a vowel: /i/, /e/, /a/, /o/ |
| Energetic vowel/syllable emission | Sharp, energetic: /i/, /e/, /a/, /o/, /u/; then syllables: /ka/, /ke/, /ko/, /ga/, /ge/, /go/; then sequences: /kaka/, /keke/, /gogo/ with truncated final vowel |
| Prolonged vowel | Sustained: /aaaaa/, /eeeee/ on one breath |
| Measure | Description |
|---|---|
| MPT (Maximum Phonation Time) | Longest sustained /a/ on one breath; normal: women ~15 sec, men ~20 sec |
| VHI (Voice Handicap Index) | 30-item self-report of voice-related disability |
| S/Z Ratio | Ratio of sustained /s/ to /z/ duration (>1.2 = glottal insufficiency) |
| GRBAS Scale | Clinician rating: Grade, Roughness, Breathiness, Asthenia, Strain |
| Acoustic analysis | Fundamental frequency, jitter, shimmer, HNR (noise-to-harmonic ratio) |
Create a printable home exercise handout for vocal cord paralysis therapy
ls -la /tmp/workspace/ 2>/dev/null || echo "workspace empty or not found"
mkdir -p /tmp/workspace/vocal-palsy-handout
~/vocal-palsy-handout/build_handout.py
from docx import Document
from docx.shared import Pt, Inches, RGBColor, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import copy
# ── helpers ──────────────────────────────────────────────────────────────────
def set_cell_bg(cell, hex_color):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement("w:shd")
shd.set(qn("w:val"), "clear")
shd.set(qn("w:color"), "auto")
shd.set(qn("w:fill"), hex_color)
tcPr.append(shd)
def set_cell_borders(cell, top=None, bottom=None, left=None, right=None):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
borders = OxmlElement("w:tcBorders")
for side, val in [("top", top), ("bottom", bottom), ("left", left), ("right", right)]:
if val:
el = OxmlElement(f"w:{side}")
el.set(qn("w:val"), val.get("val", "single"))
el.set(qn("w:sz"), val.get("sz", "4"))
el.set(qn("w:color"), val.get("color", "000000"))
borders.append(el)
tcPr.append(borders)
def add_para(doc, text, style="Normal", bold=False, italic=False,
size=None, color=None, space_before=0, space_after=6,
align=WD_ALIGN_PARAGRAPH.LEFT):
p = doc.add_paragraph(style=style)
p.alignment = align
p.paragraph_format.space_before = Pt(space_before)
p.paragraph_format.space_after = Pt(space_after)
run = p.add_run(text)
run.bold = bold
run.italic = italic
if size:
run.font.size = Pt(size)
if color:
run.font.color.rgb = RGBColor(*bytes.fromhex(color))
return p
def add_bullet(doc, text, bold_prefix=None, indent=Inches(0.3)):
p = doc.add_paragraph(style="Normal")
p.paragraph_format.left_indent = indent
p.paragraph_format.first_line_indent = Pt(-10)
p.paragraph_format.space_after = Pt(3)
# bullet character
run_bullet = p.add_run("• ")
run_bullet.font.color.rgb = RGBColor(0x21, 0x96, 0xF3)
if bold_prefix:
rb = p.add_run(bold_prefix)
rb.bold = True
rb.font.size = Pt(11)
run_text = p.add_run(text)
run_text.font.size = Pt(11)
return p
def section_header(doc, title, bg="1565C0", fg="FFFFFF"):
tbl = doc.add_table(rows=1, cols=1)
tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
tbl.style = "Table Grid"
cell = tbl.cell(0, 0)
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
p.paragraph_format.left_indent = Pt(6)
run = p.add_run(title)
run.bold = True
run.font.size = Pt(13)
run.font.color.rgb = RGBColor(*bytes.fromhex(fg))
# remove table borders
tbl.style = "Table Grid"
doc.add_paragraph().paragraph_format.space_after = Pt(0)
return tbl
def add_exercise_box(doc, number, title, steps, tip=None,
header_bg="0D47A1", step_bg="E3F2FD"):
"""Full-width 2-row table: coloured header + white body."""
tbl = doc.add_table(rows=2, cols=1)
tbl.style = "Table Grid"
tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
# — header row
hdr = tbl.cell(0, 0)
set_cell_bg(hdr, header_bg)
hp = hdr.paragraphs[0]
hp.alignment = WD_ALIGN_PARAGRAPH.LEFT
hp.paragraph_format.space_before = Pt(4)
hp.paragraph_format.space_after = Pt(4)
hp.paragraph_format.left_indent = Pt(6)
hr = hp.add_run(f"Exercise {number}: {title}")
hr.bold = True
hr.font.size = Pt(12)
hr.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
# — body row
body = tbl.cell(1, 0)
set_cell_bg(body, "FAFAFA")
body.paragraphs[0].clear() # remove default empty para first
for i, step in enumerate(steps, 1):
sp = body.add_paragraph()
sp.paragraph_format.left_indent = Pt(10)
sp.paragraph_format.space_before = Pt(2)
sp.paragraph_format.space_after = Pt(2)
rn = sp.add_run(f"{i}. ")
rn.bold = True
rn.font.size = Pt(11)
rn.font.color.rgb = RGBColor(0x0D, 0x47, 0xA1)
rt = sp.add_run(step)
rt.font.size = Pt(11)
if tip:
tp = body.add_paragraph()
tp.paragraph_format.left_indent = Pt(10)
tp.paragraph_format.space_before = Pt(4)
tp.paragraph_format.space_after = Pt(4)
tip_run = tp.add_run("💡 Tip: ")
tip_run.bold = True
tip_run.font.size = Pt(10)
tip_run.font.color.rgb = RGBColor(0xE6, 0x5C, 0x00)
tr2 = tp.add_run(tip)
tr2.italic = True
tr2.font.size = Pt(10)
# small spacer after box
sp2 = doc.add_paragraph()
sp2.paragraph_format.space_after = Pt(4)
return tbl
# ── document setup ────────────────────────────────────────────────────────────
doc = Document()
# Page margins (A4-friendly)
for section in doc.sections:
section.page_width = Cm(21)
section.page_height = Cm(29.7)
section.top_margin = Cm(1.5)
section.bottom_margin = Cm(1.5)
section.left_margin = Cm(2.0)
section.right_margin = Cm(2.0)
# Default Normal style
normal = doc.styles["Normal"]
normal.font.name = "Calibri"
normal.font.size = Pt(11)
# ── HEADER BANNER ─────────────────────────────────────────────────────────────
banner_tbl = doc.add_table(rows=1, cols=2)
banner_tbl.style = "Table Grid"
banner_tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
left_cell = banner_tbl.cell(0, 0)
right_cell = banner_tbl.cell(0, 1)
left_cell.width = Cm(13)
right_cell.width = Cm(6)
set_cell_bg(left_cell, "0D47A1")
set_cell_bg(right_cell, "1565C0")
lp = left_cell.paragraphs[0]
lp.alignment = WD_ALIGN_PARAGRAPH.LEFT
lp.paragraph_format.left_indent = Pt(8)
lp.paragraph_format.space_before = Pt(8)
lp.paragraph_format.space_after = Pt(2)
r1 = lp.add_run("Vocal Cord Paralysis")
r1.bold = True
r1.font.size = Pt(20)
r1.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
lp2 = left_cell.add_paragraph()
lp2.alignment = WD_ALIGN_PARAGRAPH.LEFT
lp2.paragraph_format.left_indent = Pt(8)
lp2.paragraph_format.space_before = Pt(0)
lp2.paragraph_format.space_after = Pt(8)
r2 = lp2.add_run("Home Voice Therapy Exercise Programme")
r2.font.size = Pt(13)
r2.font.color.rgb = RGBColor(0xBB, 0xDE, 0xFB)
rp = right_cell.paragraphs[0]
rp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
rp.paragraph_format.right_indent = Pt(8)
rp.paragraph_format.space_before = Pt(8)
rp.paragraph_format.space_after = Pt(2)
r3 = rp.add_run("Patient: ____________________")
r3.font.size = Pt(10)
r3.font.color.rgb = RGBColor(0xE3, 0xF2, 0xFD)
rp2 = right_cell.add_paragraph()
rp2.alignment = WD_ALIGN_PARAGRAPH.RIGHT
rp2.paragraph_format.right_indent = Pt(8)
rp2.paragraph_format.space_before = Pt(2)
rp2.paragraph_format.space_after = Pt(2)
r4 = rp2.add_run("Date: _______________________")
r4.font.size = Pt(10)
r4.font.color.rgb = RGBColor(0xE3, 0xF2, 0xFD)
rp3 = right_cell.add_paragraph()
rp3.alignment = WD_ALIGN_PARAGRAPH.RIGHT
rp3.paragraph_format.right_indent = Pt(8)
rp3.paragraph_format.space_before = Pt(2)
rp3.paragraph_format.space_after = Pt(8)
r5 = rp3.add_run("SLP: ________________________")
r5.font.size = Pt(10)
r5.font.color.rgb = RGBColor(0xE3, 0xF2, 0xFD)
doc.add_paragraph().paragraph_format.space_after = Pt(2)
# ── IMPORTANT NOTE ────────────────────────────────────────────────────────────
note_tbl = doc.add_table(rows=1, cols=1)
note_tbl.style = "Table Grid"
note_cell = note_tbl.cell(0, 0)
set_cell_bg(note_cell, "FFF8E1")
np0 = note_cell.paragraphs[0]
np0.paragraph_format.left_indent = Pt(8)
np0.paragraph_format.space_before = Pt(5)
np0.paragraph_format.space_after = Pt(2)
nr = np0.add_run("⚠ Important: ")
nr.bold = True
nr.font.size = Pt(11)
nr.font.color.rgb = RGBColor(0xE6, 0x5C, 0x00)
nr2 = np0.add_run("Do NOT push through pain or severe throat discomfort. Stop and rest if you feel strain. These exercises are to be done gently and consistently.")
nr2.font.size = Pt(11)
np2 = note_cell.add_paragraph()
np2.paragraph_format.left_indent = Pt(8)
np2.paragraph_format.space_before = Pt(0)
np2.paragraph_format.space_after = Pt(5)
nr3 = np2.add_run("Frequency: ")
nr3.bold = True
nr3.font.size = Pt(11)
nr4 = np2.add_run("Complete ")
nr4.font.size = Pt(11)
nr5 = np2.add_run("all exercises twice daily")
nr5.bold = True
nr5.font.size = Pt(11)
nr6 = np2.add_run(", 7 days a week. Each full session takes approximately 20–25 minutes.")
nr6.font.size = Pt(11)
doc.add_paragraph().paragraph_format.space_after = Pt(4)
# ── SECTION 1: WARM-UP ───────────────────────────────────────────────────────
section_header(doc, " SECTION 1 — WARM-UP & RELAXATION (5 minutes)")
add_para(doc, "Always begin here. Relaxing the neck, jaw and shoulder muscles reduces tension that worsens voice problems.", size=11, space_after=4)
add_exercise_box(doc, 1, "Neck & Shoulder Release",
steps=[
"Sit upright in a chair with both feet flat on the floor.",
"Slowly roll your shoulders backward 5 times, then forward 5 times.",
"Gently tilt your head toward your right shoulder — hold 5 seconds. Repeat to the left.",
"Turn your head slowly to the right — hold 5 seconds. Turn to the left — hold 5 seconds.",
"Gently drop your chin to your chest — hold 5 seconds. Lift back up.",
"Repeat the full sequence 2 times.",
],
tip="Keep movements slow and smooth. You should feel a gentle stretch, not pain.")
add_exercise_box(doc, 2, "Jaw & Face Massage",
steps=[
"Open your mouth wide (like a big yawn) — hold 3 seconds, then close gently.",
"Using your fingertips, gently massage your jaw muscles in small circles for 20 seconds.",
"Massage from the chin, along the jawline to the temples.",
"Gently massage the front of your throat (below the chin) with upward strokes, 10 times.",
"Finish with a big, exaggerated yawn — let it happen naturally.",
],
tip="A genuine yawn stretches the throat and larynx. Encourage it!")
doc.add_paragraph().paragraph_format.space_after = Pt(2)
# ── SECTION 2: BREATHING ─────────────────────────────────────────────────────
section_header(doc, " SECTION 2 — BREATHING SUPPORT (5 minutes)")
add_para(doc, "Breath support is the power source for your voice. Diaphragmatic breathing improves the air pressure under your vocal cords.", size=11, space_after=4)
add_exercise_box(doc, 3, "Diaphragmatic (Belly) Breathing",
steps=[
"Place one hand on your chest and one on your belly.",
"Inhale slowly through your nose for 4 counts — your belly should RISE. Your chest should stay mostly still.",
"Exhale slowly through pursed lips for 6 counts — belly falls.",
"Repeat 10 times.",
"Progress: On exhale, make a quiet /ssssss/ sound for as long as possible.",
],
tip="If your chest rises first, you are chest-breathing. Practice lying down if sitting is difficult.")
add_exercise_box(doc, 4, "Breath Control — Sustained /s/ vs /z/",
steps=[
"Take a comfortable breath in.",
"Exhale on a long, steady /sssssss/ — time how long you can sustain it.",
"Rest 30 seconds.",
"Take a comfortable breath in.",
"Exhale on a long, voiced /zzzzzzz/ — time how long you can sustain it.",
"Record both times. Aim for /s/ and /z/ to be roughly equal (within 2 seconds of each other).",
],
tip="If /z/ is much shorter than /s/, your vocal cords are not closing well — report this to your SLP.")
doc.add_paragraph().paragraph_format.space_after = Pt(2)
# ── SECTION 3: VFE ───────────────────────────────────────────────────────────
section_header(doc, " SECTION 3 — VOCAL FUNCTION EXERCISES (VFE) (8 minutes)")
add_para(doc, "VFE is the core of your programme. These 4 exercises strengthen and balance all the muscles involved in voice production. Do them in order, 2 times each.", size=11, space_after=4)
add_exercise_box(doc, 5, "VFE 1 — Warm-Up Sustain (Adductor strength)",
steps=[
"Take a deep breath.",
'Sustain the sound /eeee/ on a comfortable pitch — as long as you possibly can on one breath.',
"Aim for at least 10 seconds. Target: 14+ seconds (men) / 12+ seconds (women).",
"Rest 30 seconds. Repeat 2 times.",
],
tip="Sound should be clear and steady, not breathy. Breathiness means the cords are not closing fully.")
add_exercise_box(doc, 6, "VFE 2 — Glide DOWN (Cricothyroid — cord lengthening)",
steps=[
"Take a deep breath.",
'Say the word "KNOLL" — starting at your HIGHEST comfortable pitch (falsetto is OK).',
"Glide slowly DOWN to your lowest comfortable pitch, like a siren going down.",
"Keep the sound smooth and connected throughout — do not let it break if possible.",
"Repeat 2 times.",
],
tip='If your voice cracks, that is okay — keep going. Avoid "vocal fry" (scratchy, crackling at the very bottom).')
add_exercise_box(doc, 7, "VFE 3 — Glide UP (Thyroarytenoid — cord thickening)",
steps=[
"Take a deep breath.",
'Say the word "KNOLL" — starting at a comfortably HIGH note (not your absolute highest).',
"Glide slowly DOWN — working the cord-contracting muscles.",
"Then immediately glide back UP to where you started.",
"Repeat 2 times.",
],
tip="Think of this as exercising both ends of the cord's range of motion.")
add_exercise_box(doc, 8, "VFE 4 — Power Notes (Adductory strength + breath)",
steps=[
"Take a deep breath.",
'Sing "KNOLL" on 5 rising musical notes (do-re-mi-fa-sol).',
"Women start on middle C. Men start one octave below middle C.",
"Each note should be clear, strong, and connected to the breath.",
"Repeat 2 times.",
],
tip="Focus on forward facial resonance — feel the buzz on your lips and nose bridge, not in your throat.")
doc.add_paragraph().paragraph_format.space_after = Pt(2)
# ── SECTION 4: PHONATION ────────────────────────────────────────────────────
section_header(doc, " SECTION 4 — PHONATION & GLOTTAL CLOSURE (5 minutes)")
add_para(doc, "These exercises train the vocal cords to close more firmly, which reduces breathiness and increases loudness.", size=11, space_after=4)
add_exercise_box(doc, 9, "Cough — Vowel Chain",
steps=[
"Produce a firm, deliberate cough (this snaps the cords shut).",
"Immediately — without pausing — release a clear vowel: /ah/.",
"Repeat with each vowel: cough + /ee/, cough + /oh/, cough + /oo/.",
"Do 2 full rounds of all 4 vowels.",
],
tip="The cough 'primes' the cords. The vowel immediately after should sound clearer than your resting voice.")
add_exercise_box(doc, 10, "Hard Glottal Attack on Vowels",
steps=[
"Say each vowel below with a firm, punchy onset — as if starting the word with a small pop:",
" /Ah!/ ... /Ee!/ ... /Oh!/ ... /Oo!/ ... /Eh!/",
"Then try syllables: /Ka/ ... /Ke/ ... /Ko/ ... /Ga/ ... /Go/",
"Then words starting with vowels: 'Arm', 'Egg', 'On', 'Up'",
"Do 5 repetitions of each group.",
],
tip="The 'hard attack' uses forceful glottal closure — use it selectively in exercises only, not in everyday speech.")
add_exercise_box(doc, 11, "Push/Pull Effort Phonation",
steps=[
"Sit at a table. Place both palms flat under the table edge.",
"Push UP against the table firmly while simultaneously saying /ah/ loudly.",
"Or: grip the sides of the chair seat and pull UP while phonating.",
"The effort should make your voice come out stronger and clearer.",
"Repeat 5 times, with a breath between each.",
],
tip="This uses the Valsalva reflex to close the cords. Do not hold your breath for more than 3 seconds.")
doc.add_paragraph().paragraph_format.space_after = Pt(2)
# ── SECTION 5: RESONANCE ────────────────────────────────────────────────────
section_header(doc, " SECTION 5 — RESONANCE & CARRY-OVER (3 minutes)")
add_para(doc, "Forward resonance reduces strain and projects voice more efficiently — essential for daily communication.", size=11, space_after=4)
add_exercise_box(doc, 12, "Humming & Lip Trill",
steps=[
"Hum on a comfortable pitch — feel the vibration on your LIPS and in your nose. Not in your throat.",
"Hum a simple scale up and down (5 notes).",
"Now do a lip trill (like blowing a raspberry) — let your voice carry through it.",
"Alternate: hum 5 seconds → lip trill 5 seconds → hum 5 seconds.",
"Repeat 3 times.",
],
tip="If you cannot feel the buzz in your face, place a finger on your lips — you should feel vibration there.")
add_exercise_box(doc, 13, "Resonant Voice into Speech",
steps=[
"Hum /mmm/ then open into /mmm-AH/, /mmm-EE/, /mmm-OH/.",
"Then extend to words: 'more', 'mine', 'noon', 'name', 'meow'.",
"Then phrases: 'My name is ___.' / 'More milk, please.' / 'Nice morning.'",
"Keep the same forward buzz feeling from the hum as you move into words.",
],
tip="Record yourself on your phone — compare the resonant voice to your resting voice. You should hear a fuller, less breathy sound.")
doc.add_paragraph().paragraph_format.space_after = Pt(4)
# ── DAILY LOG TABLE ───────────────────────────────────────────────────────────
section_header(doc, " DAILY PRACTICE LOG", bg="2E7D32")
add_para(doc, "Tick each session as you complete it. Bring this log to your next SLP appointment.", size=11, space_after=4)
log_tbl = doc.add_table(rows=9, cols=8)
log_tbl.style = "Table Grid"
log_tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
headers = ["Exercise", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
ex_names = [
"Ex 1-2 Warm-Up",
"Ex 3-4 Breathing",
"Ex 5 VFE Sustain",
"Ex 6 VFE Glide Down",
"Ex 7 VFE Glide Up",
"Ex 8 VFE Power",
"Ex 9-10 Phonation",
"Ex 11-13 Resonance",
]
for ci, h in enumerate(headers):
cell = log_tbl.cell(0, ci)
set_cell_bg(cell, "2E7D32")
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run(h)
run.bold = True
run.font.size = Pt(10)
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
for ri, name in enumerate(ex_names, 1):
for ci in range(8):
cell = log_tbl.cell(ri, ci)
if ci == 0:
set_cell_bg(cell, "E8F5E9")
p = cell.paragraphs[0]
p.paragraph_format.left_indent = Pt(4)
run = p.add_run(name)
run.font.size = Pt(10)
run.bold = True
else:
set_cell_bg(cell, "FFFFFF")
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.add_run("□ AM\n□ PM").font.size = Pt(9)
doc.add_paragraph().paragraph_format.space_after = Pt(4)
# ── VOCAL HYGIENE TIPS ───────────────────────────────────────────────────────
section_header(doc, " VOCAL HYGIENE — Daily Habits for Voice Health", bg="6A1B9A")
hygiene_tbl = doc.add_table(rows=1, cols=2)
hygiene_tbl.style = "Table Grid"
hygiene_tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
do_cell = hygiene_tbl.cell(0, 0)
dont_cell = hygiene_tbl.cell(0, 1)
set_cell_bg(do_cell, "F3E5F5")
set_cell_bg(dont_cell, "FFF3E0")
dp = do_cell.paragraphs[0]
dp.paragraph_format.left_indent = Pt(6)
dp.paragraph_format.space_before = Pt(4)
dr = dp.add_run("✔ DO")
dr.bold = True
dr.font.size = Pt(12)
dr.font.color.rgb = RGBColor(0x2E, 0x7D, 0x32)
dos = [
"Drink 8–10 glasses of water daily",
"Breathe through your nose when possible",
"Use a humidifier in dry environments",
"Speak at a comfortable, natural pitch",
"Rest your voice after long talking periods",
"Use good posture when speaking",
]
for d in dos:
bp = do_cell.add_paragraph()
bp.paragraph_format.left_indent = Pt(10)
bp.paragraph_format.space_after = Pt(2)
r1 = bp.add_run("• ")
r1.font.color.rgb = RGBColor(0x2E, 0x7D, 0x32)
bp.add_run(d).font.size = Pt(10)
donts_header = dont_cell.paragraphs[0]
donts_header.paragraph_format.left_indent = Pt(6)
donts_header.paragraph_format.space_before = Pt(4)
dnr = donts_header.add_run("✘ AVOID")
dnr.bold = True
dnr.font.size = Pt(12)
dnr.font.color.rgb = RGBColor(0xC6, 0x28, 0x28)
donts = [
"Whispering (strains cords more than speaking)",
"Shouting or speaking over loud noise",
"Caffeine and alcohol (dry out the throat)",
"Throat clearing (replace with sip of water)",
"Smoking or smoke-filled environments",
"Talking when you have a cold or laryngitis",
]
for d in donts:
bp = dont_cell.add_paragraph()
bp.paragraph_format.left_indent = Pt(10)
bp.paragraph_format.space_after = Pt(2)
r1 = bp.add_run("• ")
r1.font.color.rgb = RGBColor(0xC6, 0x28, 0x28)
bp.add_run(d).font.size = Pt(10)
doc.add_paragraph().paragraph_format.space_after = Pt(4)
# ── WHEN TO CALL ─────────────────────────────────────────────────────────────
section_header(doc, " WHEN TO CONTACT YOUR SPEECH THERAPIST / DOCTOR", bg="B71C1C")
warn_tbl = doc.add_table(rows=1, cols=1)
warn_tbl.style = "Table Grid"
wc = warn_tbl.cell(0, 0)
set_cell_bg(wc, "FFEBEE")
warnings = [
"Voice becomes suddenly much worse or disappears completely",
"Pain or significant discomfort during exercises",
"Choking or coughing on food or liquids (aspiration)",
"Difficulty breathing",
"No improvement after 4 weeks of consistent daily practice",
]
wp0 = wc.paragraphs[0]
wp0.paragraph_format.space_before = Pt(4)
wp0.paragraph_format.left_indent = Pt(8)
for w in warnings:
wbp = wc.add_paragraph()
wbp.paragraph_format.left_indent = Pt(10)
wbp.paragraph_format.space_after = Pt(3)
wr = wbp.add_run("⚠ ")
wr.font.color.rgb = RGBColor(0xB7, 0x1C, 0x1C)
wbp.add_run(w).font.size = Pt(11)
wlast = wc.add_paragraph()
wlast.paragraph_format.left_indent = Pt(8)
wlast.paragraph_format.space_before = Pt(4)
wlast.paragraph_format.space_after = Pt(6)
wlr = wlast.add_run("SLP contact: ________________________________ Tel: ________________________________")
wlr.bold = True
wlr.font.size = Pt(11)
doc.add_paragraph().paragraph_format.space_after = Pt(4)
# ── FOOTER ────────────────────────────────────────────────────────────────────
ft = doc.add_paragraph()
ft.alignment = WD_ALIGN_PARAGRAPH.CENTER
ft.paragraph_format.space_before = Pt(6)
ftr = ft.add_run("Evidence-based programme. Adapted from Stemple Vocal Function Exercises, Tang et al. (2024) Ann Med Surg, & PMC9895689. | For clinical use only.")
ftr.italic = True
ftr.font.size = Pt(8)
ftr.font.color.rgb = RGBColor(0x90, 0x90, 0x90)
# ── SAVE ──────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/vocal-palsy-handout/Vocal_Cord_Paralysis_Home_Exercise_Handout.docx"
doc.save(out_path)
print(f"Saved: {out_path}")
cd /tmp/workspace/vocal-palsy-handout && python3 build_handout.py 2>&1
python3 -c " from docx import Document doc = Document('/tmp/workspace/vocal-palsy-handout/Vocal_Cord_Paralysis_Home_Exercise_Handout.docx') print('Paragraphs:', len(doc.paragraphs)) print('Tables:', len(doc.tables)) print('First 10 para texts:') for p in doc.paragraphs[:10]: if p.text.strip(): print(' ', p.text[:80]) "
Vocal Cord Paralysis Home Exercise Handout
Word Document · DOCX
| Section | Exercises | Duration |
|---|---|---|
| 1. Warm-Up & Relaxation | Neck/shoulder release, jaw massage | 5 min |
| 2. Breathing Support | Diaphragmatic breathing, S/Z ratio | 5 min |
| 3. Vocal Function Exercises (VFE) | Sustain /ee/, Glide down, Glide up, Power notes | 8 min |
| 4. Phonation & Glottal Closure | Cough-vowel chain, hard glottal attack, push/pull technique | 5 min |
| 5. Resonance & Carry-over | Humming/lip trill, resonant voice into speech | 3 min |