SSMD - Speech Synthesis Markdown
SSMD (Speech Synthesis Markdown) is a lightweight Python library that provides a
human-friendly markdown-like syntax for creating SSML (Speech Synthesis Markup Language)
documents. It’s designed to make TTS (Text-to-Speech) content more readable and
maintainable. See SPECIFICATION.md in the repo for the canonical syntax rules.
Features
✨ Markdown-like syntax - More intuitive than raw SSML
🎯 Scoped SSML output - Generic, SSML 1.1, and provider-adapted targets with explicit loss policies 🔄 Bidirectional - Convert SSMD↔SSML or strip to plain text
📊 Parser API - Extract structured data for custom TTS pipelines
📝 TTS streaming - Iterate through sentences for real-time TTS
🛠️ TTS capabilities - Provider-aware rendering with explicit loss policies 🎨 Extensible - Custom extensions for platform-specific features
🧪 Type-safe - Full mypy type checking support
Canonical SSMD 0.9
New documents declare ssmd_version: "0.9" and use fenced directive blocks instead of
raw XML:
---
ssmd_version: "0.9"
---
:::{voice="host"}
Hello *world*!
:::
SSML conversion covers explicit supported semantics. Use --target generic,
--target ssml-1.1, or --target provider and choose a loss policy rather than
assuming universal SSML support.
Structure-only downstream parsing
For downstream TTS pipelines that own written-to-spoken normalization and sentence
segmentation, use ssmd.parse_structure() to obtain clean text, annotation ranges,
zero-width break/mark/paragraph events, and YAML front matter without invoking sentence
detection:
SSMD parse_structure()
-> caller-owned text normalization
-> caller-owned sentence segmentation
-> caller-owned TTS/G2P
Annotations refer to ranges in clean_text; structural event positions refer to
boundaries in that text. SSMD removes its markup and preserves metadata, but does not
perform general written-to-spoken language normalization.
Quick Example
This quick API example uses body fragments for brevity; standalone files should use the versioned 0.9 document shown above.
import ssmd
# Convert SSMD to SSML
ssml = ssmd.to_ssml("Hello *world*!")
# → <speak>Hello <emphasis>world</emphasis>!</speak>
# Convert SSML back to SSMD
ssmd_text = ssmd.from_ssml('<speak><emphasis>Hello</emphasis></speak>')
# Complete SSMD 0.9 document, starting with a version header:
# ---
# ssmd_version: '0.9'
# ---
# *Hello*
# Strip markup for plain text
plain = ssmd.to_text("Hello *world* @marker!")
# → Hello world!
# Or use the Parser API for structured data
from ssmd import parse_paragraphs
for paragraph in parse_paragraphs("Hello *world*!"):
for sentence in paragraph.sentences:
for seg in sentence.segments:
print(f"Text: {seg.text}, Emphasis: {seg.emphasis}")