essay answer on thornwald cyst

Reading File
Finding Sources
Finding Sources
Searching the Web

Thornwald cyst nasopharynx anatomy pathology clinical features

Reading Web Page

https://www.ejgm.co.uk/download/thornwaldts-cyst-7012.pdf

Finding Sources
Searching PubMed

Tornwaldt cyst nasopharynx

Searching Images

Thornwald Tornwaldt cyst nasopharynx MRI endoscopy

Here is a comprehensive essay on Thornwald (Tornwaldt) Cyst:

Thornwald (Tornwaldt) Cyst — A Comprehensive Essay

Definition and Nomenclature

A Thornwald cyst (also spelled Tornwaldt's cyst, or Tornwaldt's bursa) is a benign, midline cystic lesion located in the roof of the nasopharynx, arising from the persistent remnant of the embryonic pharyngeal bursa. The eponym derives from German physician Gustav Ludwig Tornwaldt, who in 1885 published a detailed account of 26 nasopharyngeal cases, describing both clinical symptoms and treatment methods. The original description is credited to A.F.C.J. Meyer in 1840. When the cyst becomes symptomatic, the condition is termed Tornwaldt's disease.

Embryology and Pathogenesis

The pharyngeal bursa (Bursa of Luschka) is an embryonic structure that forms during fetal development as a result of the transient adhesion between the notochord (mesenchymal) and the roof of the primitive nasopharynx (endodermal). This normally obliterates before birth. When this communication persists and the ostium becomes obstructed, a cyst forms — trapped secretions accumulate within the blind-ended pouch, resulting in the Thornwald cyst.
Two categories of Tornwaldt lesion are recognized based on the drainage pathway:
  1. Cystic type — Obstructed drainage, leading to progressive cyst formation
  2. Crusting type — Spontaneous drainage into the nasopharynx, resulting in crustingDue to recurrent or persistent drainage
The cyst is lined by respiratory (pseudostratified ciliated columnar) epithelium and accumulates proteinaceous fluid of variable viscosity, which accounts for the variable MRI signal characteristics.

Epidemiology

The reported incidence of Thornwald cysts based on MRI studies ranges from 1.5% to 5.3% of the general population, making them one of the more common incidental findings on head and neck imaging. They are most frequently identified in individuals between 15 and 60 years of age, with gradual fluid accumulation explaining the later age of detection. There is no strong sex predilection. Approximately 75% of cases result from trauma to the nasopharynx — including nasopharyngitis, adenoidectomy, or chemoradiation for nasopharyngeal carcinoma — which obstructs the bursal orifice.

Anatomy and Location

The pharyngeal bursa is situated above the superior pharyngeal constrictor muscle, approximately at the level of the fossa of Rosenmuller, nestled between the longus capitis muscles and extending superiorly toward the nasopharyngeal tubercle of the occiput (occipital tubercle). Thornwald cysts are therefore characteristically located in the midline of the posterior nasopharyngeal roof, deep to intact mucosa. Rarely, they may present in a slightly off-midline position.

Pathology

Macroscopic: A smooth, well-encapsulated, submucosal cystic mass. Size ranges from a few millimeters up to several centimeters; most typical cysts measure 2–10 mm in diameter, though "giant" cysts exceeding 4 cm have been reported and can cause significant airway compromise.
Microscopic: The cyst wall is lined by pseudostratified ciliated columnar (respiratory) epithelium — a key distinction from:
  • Rathke's cleft cyst — lined by stratified squamous epithelium
  • Adenoid retention cyst — also lined by respiratory epithelium but lacks the typical midline location and embryological basis
Cyst contents are mucoid to mucopurulent, with variable degrees of lymphocytic infiltration if infected.

Clinical Features

The majority of Thornwald cysts are asymptomatic incidental findings on imaging. When symptomatic (Tornwaldt's disease), the following features are recognised:
SymptomMechanism
Postnasal drip, halitosis, foul-tasting dischargeIntermittent drainage of cyst contents
Cervical pain and stiffnessSpasm of the longus capitis and prevertebral muscles adjacent to the cyst
VertigoSecondary to muscle spasm; not vestibular
Nasal obstructionLarge cysts causing mechanical obstruction
Otitis media with effusion (OME) / Eustachian tube dysfunctionCyst proximity or expansion compressing the Eustachian tube orifice
HeadacheDue to muscular tension
Snoring / sleep-disordered breathingParticularly in giant cysts
Cervical pain and stiffness with vertigo — classically described as the Tornwaldt triad — are the hallmark presentation, rather than nasal symptoms.

Diagnosis

Clinical / Endoscopic

Diagnostic nasal endoscopy reveals a smooth, submucosal, well-encapsulated mass along the posterior roof of the nasopharynx, typically midline and covered by intact mucosa. The pharyngeal orifice of the bursa may not be visible even when patent.

Imaging

CT scan shows a well-defined, sharply marginated, hypodense soft tissue mass on the posterior nasopharyngeal wall, without bony erosion or surrounding soft tissue reaction.
MRI is the gold standard for characterization:
  • T1-weighted: Intermediate to high signal intensity (variable depending on protein content of cyst fluid)
  • T2-weighted: High signal (hyperintense) — characteristic bright appearance
  • Post-Gadolinium: No enhancement (important for distinguishing from solid or necrotic neoplasm)
  • Well-circumscribed, thin-walled, between the longus capitis muscles at the midline posterior nasopharynx
Below is an axial T2-weighted MRI demonstrating the characteristic hyperintense midline nasopharyngeal cyst nestled between the longus colli muscles:
Tornwaldt cyst — axial T2 MRI showing hyperintense midline lesion between longus capitis muscles
A large Thornwald cyst on CT demonstrating the hypodense midline mass causing airway distortion:
Large Thornwaldt cyst on axial CT — hypodense midline mass with airway compromise

Differential Diagnosis

All midline nasopharyngeal cystic lesions must be considered:
LesionKey Distinguishing Feature
Rathke's pouch cystMidline, but lined by stratified squamous epithelium; extends toward sella
Adenoid retention cystRespiratory epithelium; lateral or diffuse adenoid tissue context
Branchial cleft cystLateral position (not midline)
Sphenoid sinus mucoceleOriginates in sphenoid sinus; bony expansion
Nasopharyngeal encephalocele/meningocoeleIntracranial connection on MRI; must be excluded BEFORE surgery
Nasopharyngeal carcinomaMass effect, mucosa destruction, lymphadenopathy, contrast enhancement
Neurenteric cystPosterior fossa or spinal location; intracranial communication
Juvenile angiofibromaMales, arising from sphenopalatine foramen; highly vascular on imaging
The most critical differential to exclude before any surgical intervention is a nasopharyngeal encephalocele, as inadvertent incision could cause catastrophic CSF leak or meningitis.

Treatment

Asymptomatic cysts require no intervention — monitoring with imaging is appropriate.
Symptomatic cysts are managed surgically:
  1. Transnasal endoscopic excision — complete surgical removal under endoscopic guidance is the definitive treatment
  2. Marsupialization — wide-opening of the cyst roof via a transnasal approach; prevents re-accumulation
  3. Both approaches result in complete symptom resolution in the vast majority of cases
There is no role for aspiration alone due to high recurrence. Medical management (e.g., antibiotics) may be used for acute superinfection prior to surgery but is not curative.

Complications

  • Superinfection (Thornwaldt's disease flare) — the most common complication; presents with purulent postnasal drip, halitosis, and febrile illness
  • Otitis media with effusion — due to Eustachian tube compression by large cysts (Lee, 2021 — PMID 31760788)
  • Airway obstruction — rare, seen with giant cysts, particularly in neonates
  • Recurrence — possible after incomplete excision; marsupialization reduces this risk

Key Points Summary

  • Thornwald cyst is a benign midline nasopharyngeal cyst arising from persistence of the embryonic pharyngeal bursa
  • Most are asymptomatic incidental findings on MRI; incidence 1.5–5.3%
  • Symptomatic triad: cervical pain/stiffness, vertigo, postnasal drip (Tornwaldt's disease)
  • MRI is gold standard: T2 hyperintense, T1 variable, no gadolinium enhancement, midline between longus capitis muscles
  • Histology: lined by pseudostratified ciliated columnar (respiratory) epithelium
  • Exclude encephalocele before surgery
  • Treatment: asymptomatic — observe; symptomatic — transnasal endoscopic excision or marsupialization

References: Miyahara & Matsunaga, Acta Otolaryngol 1994 [PMID 7856446]; Huang & Kang, N Engl J Med 2019 [PMID 31091377]; Lee, Ear Nose Throat J 2021 [PMID 31760788]; Konsulov et al., Cureus 2024 [PMID 38784350]; EJGM case series; drsanu.com clinical review.

make pdf

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Running Command

mkdir -p /home/daytona/workspace/thornwald-cyst-essay

Writing File

~/thornwald-cyst-essay/generate_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, Image as RLImage
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
import urllib.request
import os
import io

OUTPUT = "/home/daytona/workspace/thornwald-cyst-essay/Thornwald_Cyst_Essay.pdf"

# Download images
img_urls = {
    "mri_t2.jpg": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_a63d53a4e15973faba561bf34d7e192a8302bcb1043c3b0cf269848287b434b6.jpg",
    "ct_axial.jpg": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_130c4b2be0867c4d805d1a7d365bd58fdd49bd204e0904f90bb68b02ee4775e3.jpg",
}

img_dir = "/home/daytona/workspace/thornwald-cyst-essay/"
for fname, url in img_urls.items():
    path = os.path.join(img_dir, fname)
    if not os.path.exists(path):
        try:
            urllib.request.urlretrieve(url, path)
            print(f"Downloaded {fname}")
        except Exception as e:
            print(f"Could not download {fname}: {e}")

# Styles
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2.5*cm, bottomMargin=2.5*cm,
    title="Thornwald Cyst — A Comprehensive Essay",
    author="Orris Medical AI"
)

styles = getSampleStyleSheet()

title_style = ParagraphStyle(
    'Title', parent=styles['Title'],
    fontSize=22, textColor=colors.HexColor('#1a3a5c'),
    spaceAfter=6, alignment=TA_CENTER, fontName='Helvetica-Bold'
)
subtitle_style = ParagraphStyle(
    'Subtitle', parent=styles['Normal'],
    fontSize=11, textColor=colors.HexColor('#4a6fa5'),
    spaceAfter=12, alignment=TA_CENTER, fontName='Helvetica-Oblique'
)
h1_style = ParagraphStyle(
    'H1', parent=styles['Heading1'],
    fontSize=14, textColor=colors.HexColor('#1a3a5c'),
    spaceBefore=16, spaceAfter=6, fontName='Helvetica-Bold',
    borderPad=4
)
h2_style = ParagraphStyle(
    'H2', parent=styles['Heading2'],
    fontSize=11, textColor=colors.HexColor('#2c5f8a'),
    spaceBefore=10, spaceAfter=4, fontName='Helvetica-Bold'
)
body_style = ParagraphStyle(
    'Body', parent=styles['Normal'],
    fontSize=10, leading=15, alignment=TA_JUSTIFY,
    spaceAfter=6, fontName='Helvetica'
)
bullet_style = ParagraphStyle(
    'Bullet', parent=styles['Normal'],
    fontSize=10, leading=14, leftIndent=16,
    bulletIndent=6, spaceAfter=3, fontName='Helvetica'
)
caption_style = ParagraphStyle(
    'Caption', parent=styles['Normal'],
    fontSize=8.5, textColor=colors.HexColor('#555555'),
    alignment=TA_CENTER, spaceAfter=8, fontName='Helvetica-Oblique'
)
ref_style = ParagraphStyle(
    'Ref', parent=styles['Normal'],
    fontSize=8.5, leading=12, textColor=colors.HexColor('#444444'),
    spaceAfter=3, fontName='Helvetica'
)

def h1(text):
    return [HRFlowable(width="100%", thickness=1.5, color=colors.HexColor('#1a3a5c'), spaceAfter=4),
            Paragraph(text, h1_style)]

def h2(text):
    return [Paragraph(text, h2_style)]

def body(text):
    return [Paragraph(text, body_style)]

def bullet(items):
    return [Paragraph(f"• {item}", bullet_style) for item in items]

story = []

# Title block
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Thornwald (Tornwaldt) Cyst", title_style))
story.append(Paragraph("A Comprehensive Essay — ENT / Head & Neck", subtitle_style))
story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor('#4a6fa5'), spaceAfter=14))

# 1. Definition
story += h1("1. Definition and Nomenclature")
story += body(
    "A <b>Thornwald cyst</b> (also spelled Tornwaldt's cyst, or Tornwaldt's bursa) is a benign, midline cystic lesion "
    "located in the roof of the nasopharynx, arising from the persistent remnant of the embryonic pharyngeal bursa. "
    "The eponym derives from German physician <b>Gustav Ludwig Tornwaldt</b>, who in 1885 published a detailed account "
    "of 26 nasopharyngeal cases, describing both clinical symptoms and treatment. The original description is attributed "
    "to <b>A.F.C.J. Meyer</b> in 1840. When the cyst becomes symptomatic, the condition is termed <b>Tornwaldt's disease</b>."
)

# 2. Embryology
story += h1("2. Embryology and Pathogenesis")
story += body(
    "The <b>pharyngeal bursa</b> (Bursa of Luschka) forms during fetal development as a result of the transient adhesion "
    "between the notochord (mesenchymal origin) and the roof of the primitive nasopharynx (endodermal origin). This "
    "communication normally obliterates before birth. When it persists and the ostium becomes obstructed, "
    "trapped secretions accumulate within the blind-ended pouch, resulting in a Thornwald cyst."
)
story += body("Two categories are recognised based on the drainage pathway:")
story += bullet([
    "<b>Cystic type</b> — Obstructed drainage, leading to progressive cyst formation and fluid accumulation.",
    "<b>Crusting type</b> — Spontaneous drainage into the nasopharynx, resulting in crusting and postnasal discharge.",
])
story += body(
    "Approximately <b>75% of cases</b> are attributed to trauma to the nasopharynx — including nasopharyngitis, "
    "adenoidectomy, or chemoradiation for nasopharyngeal carcinoma — which obstructs the bursal orifice."
)

# 3. Epidemiology
story += h1("3. Epidemiology")
story += body(
    "Based on MRI studies, the reported incidence of Thornwald cysts ranges from <b>1.5% to 5.3%</b> of the general "
    "population, making them one of the more common incidental nasopharyngeal findings. They are most frequently "
    "identified in individuals aged <b>15 to 60 years</b>, with gradual fluid accumulation explaining the later age "
    "of detection. There is no strong sex predilection."
)

# 4. Anatomy
story += h1("4. Anatomy and Location")
story += body(
    "The pharyngeal bursa is situated above the superior pharyngeal constrictor muscle, approximately at the level "
    "of the <b>fossa of Rosenmuller</b>, nestled between the <b>longus capitis muscles</b> and extending superiorly "
    "toward the <b>nasopharyngeal tubercle of the occiput</b>. Thornwald cysts are therefore characteristically "
    "located in the <b>midline of the posterior nasopharyngeal roof</b>, deep to intact mucosa. Rarely, they may be "
    "slightly off-midline."
)

# 5. Pathology
story += h1("5. Pathology")
story += h2("Macroscopic")
story += body(
    "A smooth, well-encapsulated submucosal cystic mass. Size ranges from a few millimeters to several centimeters; "
    "most typical cysts measure <b>2–10 mm</b> in diameter. Giant cysts exceeding 4 cm have been reported and can "
    "cause significant airway compromise."
)
story += h2("Microscopic")
story += body(
    "The cyst wall is lined by <b>pseudostratified ciliated columnar (respiratory) epithelium</b>. Cyst contents are "
    "mucoid to mucopurulent, with variable degrees of lymphocytic infiltration when infected. This histological "
    "appearance is a key distinguishing feature:"
)
# Histology comparison table
hist_data = [
    ['Lesion', 'Epithelial Lining', 'Location'],
    ['Thornwald cyst', 'Pseudostratified ciliated columnar', 'Midline posterior nasopharynx'],
    ["Rathke's cleft cyst", 'Stratified squamous', 'Midline, extends toward sella'],
    ['Adenoid retention cyst', 'Respiratory epithelium', 'Lateral / diffuse adenoid tissue'],
    ['Branchial cleft cyst', 'Stratified squamous ± columnar', 'Lateral neck/nasopharynx'],
]
hist_table = Table(hist_data, colWidths=[5.2*cm, 6.2*cm, 5.6*cm])
hist_table.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a3a5c')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
    ('FONTSIZE', (0,0), (-1,-1), 9),
    ('BACKGROUND', (0,1), (-1,-1), colors.HexColor('#f0f4f8')),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#f0f4f8'), colors.white]),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#bbccdd')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('RIGHTPADDING', (0,0), (-1,-1), 6),
    ('TOPPADDING', (0,0), (-1,-1), 4),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
]))
story.append(Spacer(1, 4))
story.append(hist_table)
story.append(Spacer(1, 8))

# 6. Clinical Features
story += h1("6. Clinical Features")
story += body(
    "The majority of Thornwald cysts are <b>asymptomatic incidental findings</b> on imaging. When symptomatic "
    "(Tornwaldt's disease), the following features are recognised:"
)
clin_data = [
    ['Symptom / Sign', 'Mechanism'],
    ['Postnasal drip, halitosis, foul-tasting discharge', 'Intermittent drainage of cyst contents'],
    ['Cervical pain and stiffness', 'Spasm of longus capitis / prevertebral muscles'],
    ['Vertigo', 'Secondary to muscular spasm (not vestibular)'],
    ['Nasal obstruction', 'Mechanical — large cysts'],
    ['Otitis media with effusion (OME)', 'Eustachian tube compression'],
    ['Headache', 'Muscular tension; prevertebral involvement'],
    ['Snoring / sleep-disordered breathing', 'Airway narrowing by giant cysts'],
]
clin_table = Table(clin_data, colWidths=[9*cm, 8*cm])
clin_table.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#2c5f8a')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
    ('FONTSIZE', (0,0), (-1,-1), 9),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#eef2f7'), colors.white]),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#bbccdd')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('RIGHTPADDING', (0,0), (-1,-1), 6),
    ('TOPPADDING', (0,0), (-1,-1), 4),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
]))
story.append(clin_table)
story.append(Spacer(1, 6))
story += body(
    "The classical <b>Tornwaldt triad</b> — cervical pain/stiffness, vertigo, and postnasal drip — is considered "
    "pathognomonic of symptomatic disease. Notably, frank nasal symptoms are often not the dominant complaint."
)

# 7. Diagnosis
story += h1("7. Diagnosis")
story += h2("Clinical / Endoscopic")
story += body(
    "<b>Diagnostic nasal endoscopy</b> reveals a smooth, submucosal, well-encapsulated mass along the posterior "
    "roof of the nasopharynx, typically midline and covered by intact mucosa. The pharyngeal orifice of the bursa "
    "may not be visible even when patent."
)
story += h2("Imaging")
story += body(
    "<b>CT scan</b> demonstrates a well-defined, sharply marginated, hypodense soft tissue mass on the posterior "
    "nasopharyngeal wall without bony erosion or surrounding soft tissue reaction."
)
story += body(
    "<b>MRI is the gold standard</b> for characterisation and is preferred over CT for accurate evaluation:"
)
story += bullet([
    "<b>T1-weighted:</b> Intermediate to high signal intensity (variable depending on protein content)",
    "<b>T2-weighted:</b> Characteristically <b>hyperintense</b> (bright) — the most consistent MRI feature",
    "<b>Post-gadolinium:</b> No enhancement — critical distinction from solid or necrotic neoplasm",
    "Well-circumscribed, thin-walled lesion between the longus capitis muscles at the midline posterior nasopharynx",
    "Size typically 2–10 mm; no adjacent bone erosion or soft tissue infiltration",
])

# Images
story.append(Spacer(1, 8))
mri_path = os.path.join(img_dir, "mri_t2.jpg")
ct_path = os.path.join(img_dir, "ct_axial.jpg")

img_row = []
if os.path.exists(mri_path):
    img_row.append(RLImage(mri_path, width=7.8*cm, height=6*cm))
else:
    img_row.append(Paragraph("[MRI image unavailable]", caption_style))

if os.path.exists(ct_path):
    img_row.append(RLImage(ct_path, width=7.8*cm, height=6*cm))
else:
    img_row.append(Paragraph("[CT image unavailable]", caption_style))

img_table = Table([img_row], colWidths=[8.5*cm, 8.5*cm])
img_table.setStyle(TableStyle([
    ('ALIGN', (0,0), (-1,-1), 'CENTER'),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('LEFTPADDING', (0,0), (-1,-1), 4),
    ('RIGHTPADDING', (0,0), (-1,-1), 4),
]))
story.append(img_table)

cap_row = [
    Paragraph("<i>Fig 1. Axial T2-weighted MRI — hyperintense midline Tornwaldt cyst (arrow) between the longus capitis muscles.</i>", caption_style),
    Paragraph("<i>Fig 2. Axial CT — large hypodense midline Thornwald cyst causing airway compromise (4.6 × 2.7 cm).</i>", caption_style),
]
cap_table = Table([cap_row], colWidths=[8.5*cm, 8.5*cm])
cap_table.setStyle(TableStyle([
    ('ALIGN', (0,0), (-1,-1), 'CENTER'),
    ('LEFTPADDING', (0,0), (-1,-1), 4),
    ('RIGHTPADDING', (0,0), (-1,-1), 4),
]))
story.append(cap_table)
story.append(Spacer(1, 6))

# 8. Differential Diagnosis
story += h1("8. Differential Diagnosis")
diff_data = [
    ['Lesion', 'Key Distinguishing Feature'],
    ["Rathke's pouch cyst", "Midline; stratified squamous lining; extends toward sella turcica"],
    ["Adenoid retention cyst", "Respiratory epithelium; lateral/diffuse; no embryological bursa"],
    ["Branchial cleft cyst", "Lateral position — not midline"],
    ["Sphenoid sinus mucocele", "Originates in sphenoid sinus; bony expansion on CT"],
    ["Nasopharyngeal encephalocele", "Intracranial connection on MRI — MUST exclude before surgery"],
    ["Nasopharyngeal carcinoma", "Mucosal destruction, enhancement, cervical lymphadenopathy"],
    ["Neurenteric cyst", "Posterior fossa / spinal; may have intracranial communication"],
    ["Juvenile angiofibroma", "Young males; sphenopalatine foramen origin; highly vascular"],
]
diff_table = Table(diff_data, colWidths=[6*cm, 11*cm])
diff_table.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a3a5c')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
    ('FONTSIZE', (0,0), (-1,-1), 9),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#f0f4f8'), colors.white]),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#bbccdd')),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('RIGHTPADDING', (0,0), (-1,-1), 6),
    ('TOPPADDING', (0,0), (-1,-1), 4),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
]))
story.append(diff_table)
story.append(Spacer(1, 6))
story += body(
    "<b>Critical point:</b> A nasopharyngeal encephalocele must be excluded before any surgical intervention, "
    "as inadvertent incision could result in a catastrophic CSF leak or meningitis."
)

# 9. Treatment
story += h1("9. Treatment")
story += body(
    "<b>Asymptomatic cysts</b> require no intervention — clinical and imaging surveillance is appropriate."
)
story += body("<b>Symptomatic cysts</b> are managed surgically:")
story += bullet([
    "<b>Transnasal endoscopic excision</b> — complete removal under endoscopic guidance; the definitive approach.",
    "<b>Marsupialization</b> — wide opening of the cyst roof via transnasal approach; prevents re-accumulation and lowers recurrence risk.",
    "Both approaches result in <b>complete symptom resolution</b> in the vast majority of patients.",
    "Aspiration alone is not recommended due to high recurrence.",
    "Antibiotics may be used for acute superinfection prior to surgery but are not curative.",
])

# 10. Complications
story += h1("10. Complications")
story += bullet([
    "<b>Superinfection</b> (Thornwaldt's disease flare) — purulent postnasal drip, halitosis, febrile illness; most common complication.",
    "<b>Otitis media with effusion</b> — due to Eustachian tube compression by large cysts.",
    "<b>Airway obstruction</b> — rare; seen with giant cysts, particularly in neonates.",
    "<b>Recurrence</b> — possible after incomplete excision; marsupialization reduces this risk.",
])

# 11. Key Points
story += h1("11. Key Points Summary")
kp_data = [
    ['Key Point', 'Detail'],
    ['Nature', 'Benign midline developmental cyst of the nasopharynx'],
    ['Origin', 'Persistent embryonic pharyngeal bursa (notochord ↔ nasopharynx adhesion)'],
    ['Incidence', '1.5–5.3% of population (common incidental MRI finding)'],
    ['Location', 'Midline posterior nasopharyngeal roof, between longus capitis muscles'],
    ['Histology', 'Pseudostratified ciliated columnar (respiratory) epithelium'],
    ['Classic symptoms', 'Cervical pain/stiffness, vertigo, postnasal drip (Tornwaldt triad)'],
    ['Gold standard imaging', 'MRI: T2 hyperintense, T1 variable, no gadolinium enhancement'],
    ['Critical DDx', 'Nasopharyngeal encephalocele — exclude before surgery'],
    ['Treatment', 'Asymptomatic: observe; Symptomatic: endoscopic excision / marsupialization'],
]
kp_table = Table(kp_data, colWidths=[5.5*cm, 11.5*cm])
kp_table.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a3a5c')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
    ('FONTSIZE', (0,0), (-1,-1), 9),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
    ('TEXTCOLOR', (0,1), (0,-1), colors.HexColor('#1a3a5c')),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#eef7f0'), colors.white]),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#bbccdd')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('RIGHTPADDING', (0,0), (-1,-1), 6),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
]))
story.append(kp_table)
story.append(Spacer(1, 12))

# References
story += h1("References")
refs = [
    "1. Tornwaldt GL. Zur Frage der Bursa Pharyngea. Deut Med Wochenschr. 1887.",
    "2. Miyahara H, Matsunaga T. Tornwaldt's disease. Acta Otolaryngol Suppl. 1994. [PMID 7856446]",
    "3. Miller RH, Sneed WF. Thornwaldt's bursa. Clin Otolaryngol. 1985;10:21–5. [PMID 4006264]",
    "4. Huang CY, Kang BH. Tornwaldt's Cyst. N Engl J Med. 2019;380(20):1961. [PMID 31091377]",
    "5. Lee JH. Huge Tornwaldt Cyst With Otitis Media With Effusion. Ear Nose Throat J. 2021. [PMID 31760788]",
    "6. Konsulov S, et al. Symptomatic Tornwaldt Cyst: A Case Report. Cureus. 2024. [PMID 38784350]",
    "7. EJGM — Thornwaldt's Cyst: Electronic Journal of General Medicine. Konya University.",
    "8. Ikushima I, et al. MR imaging of Thornwaldt's cysts. AJR Am J Roentgenol. 1999;172:1663–5.",
]
for r in refs:
    story.append(Paragraph(r, ref_style))

story.append(Spacer(1, 8))
story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#aaaaaa')))
story.append(Spacer(1, 4))
story.append(Paragraph("Generated by Orris Medical AI — For educational purposes only.", caption_style))

doc.build(story)
print(f"PDF saved to {OUTPUT}")
Running Command

python /home/daytona/workspace/thornwald-cyst-essay/generate_pdf.py

Your PDF is ready:

Thornwald Cyst Essay

PDF Document · PDF

The document includes:
  • Full essay with all 11 sections (definition through key points)
  • Color-coded tables: histological comparison, clinical features, differential diagnosis, and key points summary
  • Two radiology images (axial T2 MRI and axial CT) with captions
  • Formatted references with PMIDs
This is a shared conversation. Sign in to Orris to start your own chat.