API Reference
This page documents the public API of the SSMD library.
Core Classes
Document
The primary class for creating and managing SSMD/SSML documents.
- class ssmd.Document(content: str = '', config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, escape_syntax: bool = False, escape_patterns: list[str] | None = None, parse_yaml_header: bool = False, strict: bool = False)[source]
Bases:
objectMain SSMD document container with incremental building and editing.
This is the primary interface for working with SSMD documents. It provides a clean, document-centric API for creating, editing, and exporting TTS content.
The Document stores content as fragments (pieces of text) with separators between them, allowing efficient incremental building and editing while preserving the document structure.
- Example:
Basic usage:
import ssmd # Create and build a document doc = ssmd.Document() doc.add_sentence("Hello world!") doc.add_sentence("This is SSMD.") # Export to different formats ssml = doc.to_ssml() text = doc.to_text() # Iterate for streaming TTS for sentence in doc.sentences(): tts_engine.speak(sentence)
Advanced usage:
# Load from SSML doc = ssmd.Document.from_ssml("<speak>Hello</speak>") # Edit the document doc[0] = "Modified content" doc.add_paragraph("New paragraph") # Access raw content print(doc.ssmd) # Raw SSMD markdown
Construction Methods:
- __init__(content: str = '', config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, escape_syntax: bool = False, escape_patterns: list[str] | None = None, parse_yaml_header: bool = False, strict: bool = False) None[source]
Initialize a new SSMD document.
- Args:
content: Optional initial SSMD content config: Configuration dictionary with options:
skip (list): Processor names to skip
output_speak_tag (bool): Wrap in <speak> tags (default: True)
pretty_print (bool): Format XML output (default: False)
auto_sentence_tags (bool): Auto-wrap sentences (default: False)
heading_levels (dict): Custom heading configurations
extensions (dict): Registered extension handlers
namespaces (dict): XML namespaces to add to the <speak> tag
sentence_model_size (str): spaCy model size for sentence detection (“sm”, “md”, “lg”, “trf”). Default: “sm”
sentence_spacy_model (str): Deprecated alias; model size is inferred from the name (overrides sentence_model_size)
sentence_use_spacy (bool): If False, use fast regex splitting instead of spaCy. Default: True
- capabilities: TTS capabilities (TTSCapabilities instance or
preset name). Presets: ‘espeak’, ‘pyttsx3’, ‘google’, ‘polly’, ‘azure’, ‘minimal’, ‘full’
- escape_syntax: If True, escape SSMD-like syntax in content to
prevent interpretation as markup. Useful for plain text or markdown that may coincidentally contain SSMD patterns.
- escape_patterns: List of specific pattern types to escape when
escape_syntax=True. If None, escapes all patterns. Valid values: ‘emphasis’, ‘annotations’, ‘breaks’, ‘marks’, ‘headings’, ‘directives’
- parse_yaml_header: If True, parse YAML front matter and store it
on doc.header while stripping it from the SSMD body. If False, YAML front matter is preserved as part of the content.
- strict: If True, emit warnings and apply ssml-green validation
rules where possible.
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc = ssmd.Document(capabilities='pyttsx3') >>> doc = ssmd.Document("Text", config={'auto_sentence_tags': True}) >>> # Fast sentence detection (no spaCy required) >>> doc = ssmd.Document(config={'sentence_use_spacy': False}) >>> # High quality sentence detection >>> doc = ssmd.Document(config={'sentence_model_size': 'lg'}) >>> # Escape SSMD syntax for plain text/markdown >>> doc = ssmd.Document(markdown, escape_syntax=True) >>> # Selective escaping >>> doc = ssmd.Document( ... text, ... escape_syntax=True, ... escape_patterns=['emphasis', 'annotations'] ... )
- classmethod from_ssml(ssml: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None) Document[source]
Create a Document from SSML string.
- Args:
ssml: SSML XML string config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance with converted content
- Example:
>>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> doc = ssmd.Document.from_ssml(ssml) >>> doc.ssmd '*Hello* world'
- classmethod from_text(text: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, parse_yaml_header: bool = False, strict: bool = False) Document[source]
Create a Document from plain text.
This is essentially the same as Document(text), but provides a symmetric API with from_ssml().
- Args:
text: Plain text or SSMD content config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance
- Example:
>>> doc = ssmd.Document.from_text("Hello world") >>> doc.ssmd 'Hello world'
Building Methods:
- add(text: str) Document[source]
Append text without separator.
Use this when you want to append content immediately after the previous content with no spacing.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc.add(" world") >>> doc.ssmd 'Hello world'
- add_sentence(text: str) Document[source]
Append text with newline separator.
Use this to add a new sentence on a new line.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First sentence.") >>> doc.add_sentence("Second sentence.") >>> doc.ssmd 'First sentence.\nSecond sentence.'
- add_paragraph(text: str) Document[source]
Append text with double newline separator.
Use this to start a new paragraph.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First paragraph.") >>> doc.add_paragraph("Second paragraph.") >>> doc.ssmd 'First paragraph.\n\nSecond paragraph.'
Export Methods:
- to_ssml() str[source]
Export document to SSML format.
- Returns:
SSML XML string
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc.to_ssml() '<speak>Hello <emphasis>world</emphasis>!</speak>'
- to_ssmd() str[source]
Export document to SSMD format with proper formatting.
Returns SSMD with proper line breaks (each sentence on a new line).
- Returns:
SSMD markdown string with proper formatting
- Example:
>>> doc = ssmd.Document.from_ssml('<speak><emphasis>Hi</emphasis></speak>') >>> doc.to_ssmd() '*Hi*'
- to_text() str[source]
Export document to plain text (strips all markup).
- Returns:
Plain text string with all SSMD markup removed
- Example:
>>> doc = ssmd.Document("Hello *world* @marker!") >>> doc.to_text() 'Hello world!'
Properties:
- property ssmd: str
Get raw SSMD content.
Returns the complete SSMD document by joining all fragments with their separators.
- Returns:
SSMD markdown string
- property capabilities: TTSCapabilities | str | None
Get TTS capabilities.
- Returns:
TTSCapabilities instance, preset name, or None
Iteration:
- sentences(as_documents: bool = False) Iterator[str | Document][source]
Iterate through sentence-level SSML chunks.
Sentences are always returned as explicit
<s>-wrapped SSML fragments so the streaming interface remains stable regardless of paragraph tags.- Args:
- as_documents: If True, yield Document objects instead of strings.
Each sentence will be wrapped in its own Document instance.
- Yields:
SSML sentence strings (str), or Document objects if as_documents=True
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> for sentence in doc.sentences(): ... tts_engine.speak(sentence)
>>> for sentence_doc in doc.sentences(as_documents=True): ... ssml = sentence_doc.to_ssml() ... ssmd = sentence_doc.to_ssmd()
- __iter__() Iterator[str | Document][source]
Iterate through sentences.
- Yields:
SSML sentence strings
- Example:
>>> doc = ssmd.Document("First. Second.") >>> for sentence in doc: ... print(sentence)
- __len__() int[source]
Return number of sentences in the document.
- Returns:
Number of sentences
- Example:
>>> doc = ssmd.Document("First sentence. Second sentence.") >>> len(doc) 2
List-like Interface:
- __getitem__(index: int) str[source]
- __getitem__(index: slice) list[str]
Get sentence(s) by index.
- Args:
index: Sentence index or slice
- Returns:
SSML sentence string or list of strings
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] # First sentence SSML >>> doc[-1] # Last sentence SSML >>> doc[0:2] # First two sentences
- __setitem__(index: int, value: str) None[source]
Replace sentence at index.
This reconstructs the document with the modified sentence.
- Args:
index: Sentence index value: New SSMD content for this sentence
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] = "Modified first sentence."
- __delitem__(index: int) None[source]
Delete sentence at index.
- Args:
index: Sentence index
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> del doc[1] # Remove second sentence
- __iadd__(other: str | Document) Document[source]
Support += operator for appending content.
- Args:
other: String or Document to append
- Returns:
Self for chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc += " world" >>> other = ssmd.Document("More") >>> doc += other
Editing Methods:
- insert(index: int, text: str, separator: str = '') Document[source]
Insert text at specific fragment index.
- Args:
index: Position to insert (0 = beginning) text: SSMD text to insert separator: Separator to use (“”, “n”, or “nn”)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.insert(0, "Start: ", "") >>> doc.ssmd 'Start: Hello world'
- remove(index: int) Document[source]
Remove fragment at index.
This is the same as del doc[index] but returns self for chaining.
- Args:
index: Fragment index to remove
- Returns:
Self for method chaining
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc.remove(1)
- clear() Document[source]
Remove all content from the document.
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.clear() >>> doc.ssmd ''
- replace(old: str, new: str, count: int = -1) Document[source]
Replace text across all fragments.
- Args:
old: Text to find new: Text to replace with count: Maximum replacements (-1 = all)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world. Hello again.") >>> doc.replace("Hello", "Hi") >>> doc.ssmd 'Hi world. Hi again.'
Advanced Methods:
- merge(other: Document, separator: str = '\n\n') Document[source]
Merge another document into this one.
- Args:
other: Document to merge separator: Separator to use between documents
- Returns:
Self for method chaining
- Example:
>>> doc1 = ssmd.Document("First document.") >>> doc2 = ssmd.Document("Second document.") >>> doc1.merge(doc2) >>> doc1.ssmd 'First document.\n\nSecond document.'
- split() list[Document][source]
Split document into individual sentence Documents.
- Returns:
List of Document objects, one per sentence
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> sentences = doc.split() >>> len(sentences) 3 >>> sentences[0].ssmd 'First.'
- get_fragment(index: int) str[source]
Get raw fragment by index (not sentence).
This accesses the internal fragment storage directly, which may be different from sentence boundaries.
- Args:
index: Fragment index
- Returns:
Raw SSMD fragment string
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document() >>> doc.add("First") >>> doc.add_sentence("Second") >>> doc.get_fragment(0) 'First' >>> doc.get_fragment(1) 'Second'
- __init__(content: str = '', config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, escape_syntax: bool = False, escape_patterns: list[str] | None = None, parse_yaml_header: bool = False, strict: bool = False) None[source]
Initialize a new SSMD document.
- Args:
content: Optional initial SSMD content config: Configuration dictionary with options:
skip (list): Processor names to skip
output_speak_tag (bool): Wrap in <speak> tags (default: True)
pretty_print (bool): Format XML output (default: False)
auto_sentence_tags (bool): Auto-wrap sentences (default: False)
heading_levels (dict): Custom heading configurations
extensions (dict): Registered extension handlers
namespaces (dict): XML namespaces to add to the <speak> tag
sentence_model_size (str): spaCy model size for sentence detection (“sm”, “md”, “lg”, “trf”). Default: “sm”
sentence_spacy_model (str): Deprecated alias; model size is inferred from the name (overrides sentence_model_size)
sentence_use_spacy (bool): If False, use fast regex splitting instead of spaCy. Default: True
- capabilities: TTS capabilities (TTSCapabilities instance or
preset name). Presets: ‘espeak’, ‘pyttsx3’, ‘google’, ‘polly’, ‘azure’, ‘minimal’, ‘full’
- escape_syntax: If True, escape SSMD-like syntax in content to
prevent interpretation as markup. Useful for plain text or markdown that may coincidentally contain SSMD patterns.
- escape_patterns: List of specific pattern types to escape when
escape_syntax=True. If None, escapes all patterns. Valid values: ‘emphasis’, ‘annotations’, ‘breaks’, ‘marks’, ‘headings’, ‘directives’
- parse_yaml_header: If True, parse YAML front matter and store it
on doc.header while stripping it from the SSMD body. If False, YAML front matter is preserved as part of the content.
- strict: If True, emit warnings and apply ssml-green validation
rules where possible.
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc = ssmd.Document(capabilities='pyttsx3') >>> doc = ssmd.Document("Text", config={'auto_sentence_tags': True}) >>> # Fast sentence detection (no spaCy required) >>> doc = ssmd.Document(config={'sentence_use_spacy': False}) >>> # High quality sentence detection >>> doc = ssmd.Document(config={'sentence_model_size': 'lg'}) >>> # Escape SSMD syntax for plain text/markdown >>> doc = ssmd.Document(markdown, escape_syntax=True) >>> # Selective escaping >>> doc = ssmd.Document( ... text, ... escape_syntax=True, ... escape_patterns=['emphasis', 'annotations'] ... )
- classmethod from_ssml(ssml: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None) Document[source]
Create a Document from SSML string.
- Args:
ssml: SSML XML string config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance with converted content
- Example:
>>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> doc = ssmd.Document.from_ssml(ssml) >>> doc.ssmd '*Hello* world'
- classmethod from_text(text: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, parse_yaml_header: bool = False, strict: bool = False) Document[source]
Create a Document from plain text.
This is essentially the same as Document(text), but provides a symmetric API with from_ssml().
- Args:
text: Plain text or SSMD content config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance
- Example:
>>> doc = ssmd.Document.from_text("Hello world") >>> doc.ssmd 'Hello world'
- add(text: str) Document[source]
Append text without separator.
Use this when you want to append content immediately after the previous content with no spacing.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc.add(" world") >>> doc.ssmd 'Hello world'
- add_sentence(text: str) Document[source]
Append text with newline separator.
Use this to add a new sentence on a new line.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First sentence.") >>> doc.add_sentence("Second sentence.") >>> doc.ssmd 'First sentence.\nSecond sentence.'
- add_paragraph(text: str) Document[source]
Append text with double newline separator.
Use this to start a new paragraph.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First paragraph.") >>> doc.add_paragraph("Second paragraph.") >>> doc.ssmd 'First paragraph.\n\nSecond paragraph.'
- to_ssml() str[source]
Export document to SSML format.
- Returns:
SSML XML string
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc.to_ssml() '<speak>Hello <emphasis>world</emphasis>!</speak>'
- to_ssmd() str[source]
Export document to SSMD format with proper formatting.
Returns SSMD with proper line breaks (each sentence on a new line).
- Returns:
SSMD markdown string with proper formatting
- Example:
>>> doc = ssmd.Document.from_ssml('<speak><emphasis>Hi</emphasis></speak>') >>> doc.to_ssmd() '*Hi*'
- to_text() str[source]
Export document to plain text (strips all markup).
- Returns:
Plain text string with all SSMD markup removed
- Example:
>>> doc = ssmd.Document("Hello *world* @marker!") >>> doc.to_text() 'Hello world!'
- property ssmd: str
Get raw SSMD content.
Returns the complete SSMD document by joining all fragments with their separators.
- Returns:
SSMD markdown string
- property capabilities: TTSCapabilities | str | None
Get TTS capabilities.
- Returns:
TTSCapabilities instance, preset name, or None
- sentences(as_documents: bool = False) Iterator[str | Document][source]
Iterate through sentence-level SSML chunks.
Sentences are always returned as explicit
<s>-wrapped SSML fragments so the streaming interface remains stable regardless of paragraph tags.- Args:
- as_documents: If True, yield Document objects instead of strings.
Each sentence will be wrapped in its own Document instance.
- Yields:
SSML sentence strings (str), or Document objects if as_documents=True
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> for sentence in doc.sentences(): ... tts_engine.speak(sentence)
>>> for sentence_doc in doc.sentences(as_documents=True): ... ssml = sentence_doc.to_ssml() ... ssmd = sentence_doc.to_ssmd()
- paragraphs(as_documents: bool = False) Iterator[str | Document][source]
Iterate through paragraph-level SSML chunks.
Paragraphs are returned with
<p>tags when supported by capabilities.- Args:
as_documents: If True, yield Document objects instead of strings.
- Yields:
SSML paragraph strings (str), or Document objects if as_documents=True
- __len__() int[source]
Return number of sentences in the document.
- Returns:
Number of sentences
- Example:
>>> doc = ssmd.Document("First sentence. Second sentence.") >>> len(doc) 2
- __getitem__(index: int) str[source]
- __getitem__(index: slice) list[str]
Get sentence(s) by index.
- Args:
index: Sentence index or slice
- Returns:
SSML sentence string or list of strings
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] # First sentence SSML >>> doc[-1] # Last sentence SSML >>> doc[0:2] # First two sentences
- __setitem__(index: int, value: str) None[source]
Replace sentence at index.
This reconstructs the document with the modified sentence.
- Args:
index: Sentence index value: New SSMD content for this sentence
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] = "Modified first sentence."
- __delitem__(index: int) None[source]
Delete sentence at index.
- Args:
index: Sentence index
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> del doc[1] # Remove second sentence
- __iter__() Iterator[str | Document][source]
Iterate through sentences.
- Yields:
SSML sentence strings
- Example:
>>> doc = ssmd.Document("First. Second.") >>> for sentence in doc: ... print(sentence)
- __iadd__(other: str | Document) Document[source]
Support += operator for appending content.
- Args:
other: String or Document to append
- Returns:
Self for chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc += " world" >>> other = ssmd.Document("More") >>> doc += other
- insert(index: int, text: str, separator: str = '') Document[source]
Insert text at specific fragment index.
- Args:
index: Position to insert (0 = beginning) text: SSMD text to insert separator: Separator to use (“”, “n”, or “nn”)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.insert(0, "Start: ", "") >>> doc.ssmd 'Start: Hello world'
- remove(index: int) Document[source]
Remove fragment at index.
This is the same as del doc[index] but returns self for chaining.
- Args:
index: Fragment index to remove
- Returns:
Self for method chaining
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc.remove(1)
- clear() Document[source]
Remove all content from the document.
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.clear() >>> doc.ssmd ''
- replace(old: str, new: str, count: int = -1) Document[source]
Replace text across all fragments.
- Args:
old: Text to find new: Text to replace with count: Maximum replacements (-1 = all)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world. Hello again.") >>> doc.replace("Hello", "Hi") >>> doc.ssmd 'Hi world. Hi again.'
- merge(other: Document, separator: str = '\n\n') Document[source]
Merge another document into this one.
- Args:
other: Document to merge separator: Separator to use between documents
- Returns:
Self for method chaining
- Example:
>>> doc1 = ssmd.Document("First document.") >>> doc2 = ssmd.Document("Second document.") >>> doc1.merge(doc2) >>> doc1.ssmd 'First document.\n\nSecond document.'
- split() list[Document][source]
Split document into individual sentence Documents.
- Returns:
List of Document objects, one per sentence
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> sentences = doc.split() >>> len(sentences) 3 >>> sentences[0].ssmd 'First.'
- get_fragment(index: int) str[source]
Get raw fragment by index (not sentence).
This accesses the internal fragment storage directly, which may be different from sentence boundaries.
- Args:
index: Fragment index
- Returns:
Raw SSMD fragment string
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document() >>> doc.add("First") >>> doc.add_sentence("Second") >>> doc.get_fragment(0) 'First' >>> doc.get_fragment(1) 'Second'
TTSCapabilities
Define TTS engine capabilities for automatic feature filtering.
- class ssmd.TTSCapabilities(emphasis: bool = True, break_tags: bool = True, paragraph: bool = True, language: bool = True, phoneme: bool = True, substitution: bool = True, prosody: bool = True, volume: bool = True, rate: bool = True, pitch: bool = True, say_as: bool = True, audio: bool = True, mark: bool = True, extensions: dict[str, bool] | None = None, sentence_tags: bool = True, heading_emphasis: bool = True, ssml_green: dict[str, bool] | None = None, language_scopes: dict[str, bool] | None = None)[source]
Bases:
objectDefine TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- __init__(emphasis: bool = True, break_tags: bool = True, paragraph: bool = True, language: bool = True, phoneme: bool = True, substitution: bool = True, prosody: bool = True, volume: bool = True, rate: bool = True, pitch: bool = True, say_as: bool = True, audio: bool = True, mark: bool = True, extensions: dict[str, bool] | None = None, sentence_tags: bool = True, heading_emphasis: bool = True, ssml_green: dict[str, bool] | None = None, language_scopes: dict[str, bool] | None = None)[source]
Initialize TTS capabilities.
- Args:
emphasis: Support for <emphasis> tags break_tags: Support for <break> tags paragraph: Support for <p> tags language: Support for <lang> tags phoneme: Support for <phoneme> tags substitution: Support for <sub> tags prosody: Support for <prosody> tags (general) volume: Support for volume attribute rate: Support for rate attribute pitch: Support for pitch attribute say_as: Support for <say-as> tags audio: Support for <audio> tags mark: Support for <mark> tags extensions: Dict of extension names and their support sentence_tags: Support for <s> tags heading_emphasis: Support for heading emphasis ssml_green: Raw ssml-green capabilities map (flattened) language_scopes: Optional language scope support map
- to_config() dict[str, Any][source]
Convert capabilities to SSMD config.
- Returns:
Configuration dict for SSMD converter
SSMLParser
Parse SSML and convert to SSMD format.
- class ssmd.SSMLParser(config: dict[str, Any] | None = None)[source]
Bases:
objectConvert SSML to SSMD markdown format.
This class provides the reverse conversion from SSML XML to the more human-readable SSMD markdown syntax.
- Example:
>>> parser = SSMLParser() >>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> ssmd = parser.to_ssmd(ssml) >>> print(ssmd) '*Hello* world'
- STANDARD_LOCALES = {'de-DE': 'de', 'en-GB': 'en-GB', 'en-US': 'en', 'es-ES': 'es', 'fr-FR': 'fr', 'it-IT': 'it', 'ja-JP': 'ja', 'ko-KR': 'ko', 'pt-PT': 'pt', 'ru-RU': 'ru', 'zh-CN': 'zh'}
- __init__(config: dict[str, Any] | None = None)[source]
Initialize SSML parser.
- Args:
config: Optional configuration dictionary
- to_ssmd(ssml: str, *, capabilities: TTSCapabilities | str | None = None) str[source]
Convert SSML to SSMD format.
- Args:
ssml: SSML XML string capabilities: Optional TTS capabilities (preset name or object)
- Returns:
SSMD markdown string with proper formatting (each sentence on new line)
- Example:
>>> parser = SSMLParser() >>> parser.to_ssmd('<speak><emphasis>Hello</emphasis></speak>') '*Hello*'
Convenience Functions
Parser Functions
Extract structured data from SSMD text.
- ssmd.parse_paragraphs(text: str, *, capabilities: TTSCapabilities | str | None = None, heading_levels: dict | None = None, extensions: dict | None = None, sentence_detection: bool = True, language: str = 'en', use_spacy: bool | None = None, model_size: str | None = None, parse_yaml_header: bool = False, strict_parse: bool = False) list[Paragraph][source]
Parse SSMD text into a list of Paragraphs.
This is the main parsing function. It handles: - Directive blocks (<div …> … </div>) - Paragraph and sentence splitting - All SSMD markup (emphasis, annotations, breaks, etc.)
- Args:
text: SSMD markdown text capabilities: TTS capabilities for filtering (optional) heading_levels: Custom heading configurations extensions: Custom extension handlers sentence_detection: If True, split text into sentences language: Default language for sentence detection use_spacy: If True, use spaCy for sentence detection model_size: spaCy model size (“sm”, “md”, “lg”) parse_yaml_header: If True, parse YAML front matter and apply
heading/extensions config while stripping it from the body. If False, YAML front matter is preserved as plain text.
strict_parse: If True, strip unsupported features based on capabilities.
- Returns:
List of Paragraph objects
- ssmd.parse_sentences(ssmd_text: str, *, capabilities: TTSCapabilities | str | None = None, include_default_voice: bool = True, sentence_detection: bool = True, language: str = 'en', model_size: str | None = None, spacy_model: str | None = None, use_spacy: bool | None = None, heading_levels: dict | None = None, extensions: dict | None = None, parse_yaml_header: bool = False, strict_parse: bool = False) list[Sentence][source]
Parse SSMD text into sentences (backward compatible API).
This is an alias for parse_paragraphs() with the old parameter names. Returned sentences include paragraph_index and sentence_index metadata.
- Args:
ssmd_text: SSMD formatted text to parse capabilities: TTS capabilities or preset name include_default_voice: If False, exclude sentences without voice context sentence_detection: Enable/disable sentence splitting language: Language code for sentence detection model_size: Size of spacy model (sm/md/lg) spacy_model: Full spacy model name (deprecated, use model_size) use_spacy: Force use of spacy for sentence detection heading_levels: Custom heading configurations extensions: Custom extension handlers parse_yaml_header: If True, parse YAML front matter and apply
heading/extensions config while stripping it from the body. If False, YAML front matter is preserved as plain text.
strict_parse: If True, strip unsupported features based on capabilities.
- Returns:
List of Sentence objects
- ssmd.parse_segments(ssmd_text: str, *, capabilities: TTSCapabilities | str | None = None, voice_context: VoiceAttrs | None = None) list[Segment][source]
Parse SSMD text into segments (backward compatible API).
- ssmd.parse_voice_blocks(ssmd_text: str) list[tuple[DirectiveAttrs, str]][source]
Parse SSMD text into directive blocks (backward compatible API).
Returns list of (DirectiveAttrs, text) tuples.
- ssmd.parse_spans(text: str, *, normalize: bool = True, default_lang: str | None = None, preserve_whitespace: bool | None = None) ParseSpansResult[source]
Parse SSMD text into clean text and annotation spans.
- Args:
text: SSMD markdown text normalize: If True (default), normalize whitespace between segments default_lang: Optional language to apply to the entire output preserve_whitespace: Deprecated. Use normalize=False instead.
- Returns:
ParseSpansResult with clean text, annotations, and warnings. Offsets in annotations are relative to the returned clean_text.
- Note:
Offsets are 0-based, half-open [start, end) intervals referring to clean_text.
Conversion Functions
Convert between SSMD, SSML, and plain text.
to_ssml
Convert SSMD markup to SSML.
- ssmd.to_ssml(ssmd_text: str, *, parse_yaml_header: bool = False, **config: Any) str[source]
Convert SSMD to SSML (convenience function).
Creates a temporary Document and converts to SSML. For repeated conversions with the same config, create a Document instance.
- Args:
ssmd_text: SSMD markdown text **config: Optional configuration parameters
- Returns:
SSML string
- Example:
>>> ssmd.to_ssml("Hello *world*!") '<speak>Hello <emphasis>world</emphasis>!</speak>'
to_text
Convert SSMD to plain text (strips all markup).
- ssmd.to_text(ssmd_text: str, *, parse_yaml_header: bool = False, **config: Any) str[source]
Convert SSMD to plain text (convenience function).
Strips all SSMD markup, returning plain text.
- Args:
ssmd_text: SSMD markdown text **config: Optional configuration parameters
- Returns:
Plain text with markup removed
- Example:
>>> ssmd.to_text("Hello *world* @marker!") 'Hello world!'
from_ssml
Convert SSML back to SSMD format.
- ssmd.from_ssml(ssml_text: str, *, capabilities: TTSCapabilities | str | None = None, **config: Any) str[source]
Convert SSML to SSMD format (convenience function).
- Args:
ssml_text: SSML XML string capabilities: Optional TTS capabilities (preset name or object) **config: Optional configuration parameters
- Returns:
SSMD markdown string
- Example:
>>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> ssmd.from_ssml(ssml) '*Hello* world'
Parser Data Structures
Sentence (alias: SSMDSentence)
Represents a sentence with voice context and segments.
- class ssmd.Sentence(segments: list[Segment] = <factory>, voice: VoiceAttrs | None = None, language: str | None = None, prosody: ProsodyAttrs | None = None, is_paragraph_end: bool = False, paragraph_index: int = 0, sentence_index: int = 0, breaks_after: list[BreakAttrs] = <factory>)[source]
Bases:
objectA sentence containing segments with directive context.
Represents a logical sentence unit that should be spoken together. Sentences are split on: - Directive changes (<div …> blocks) - Sentence boundaries (.!?) when sentence_detection=True - Paragraph breaks (
)
- Attributes:
segments: List of segments in the sentence voice: Voice context for entire sentence (from <div voice=…> directives) language: Language directive for the sentence prosody: Prosody directive for the sentence is_paragraph_end: True if sentence ends with paragraph break paragraph_index: Zero-based paragraph index for this sentence sentence_index: Zero-based sentence index within the document breaks_after: Pauses after the sentence
- voice: VoiceAttrs | None = None
- prosody: ProsodyAttrs | None = None
- breaks_after: list[BreakAttrs]
- to_ssml(capabilities: TTSCapabilities | None = None, extensions: dict | None = None, wrap_sentence: bool = False, warnings: list[str] | None = None) str[source]
Convert sentence to SSML.
- Args:
capabilities: TTS engine capabilities for filtering extensions: Custom extension handlers wrap_sentence: If True, wrap content in <s> tag warnings: Optional list to collect warnings
- Returns:
SSML string
Segment (alias: SSMDSegment)
Represents a text segment with metadata.
- class ssmd.Segment(text: str, emphasis: bool | str = False, prosody: ProsodyAttrs | None = None, language: str | None = None, voice: VoiceAttrs | None = None, say_as: SayAsAttrs | None = None, substitution: str | None = None, phoneme: PhonemeAttrs | None = None, audio: AudioAttrs | None = None, extension: str | None = None, breaks_before: list[BreakAttrs] = <factory>, breaks_after: list[BreakAttrs] = <factory>, marks_before: list[str] = <factory>, marks_after: list[str] = <factory>)[source]
Bases:
objectA segment of text with SSMD features.
Represents a portion of text with specific formatting and processing attributes. Segments are the atomic units of SSMD content.
- Attributes:
text: Raw text content emphasis: Emphasis level (True/”moderate”, “strong”, “reduced”, “none”, False) prosody: Volume, rate, pitch settings language: Language code for this segment voice: Voice settings for this segment say_as: Text interpretation hints substitution: Replacement text (alias) phoneme: IPA pronunciation audio: Audio file to play extension: Platform-specific extension name breaks_before: Pauses before this segment breaks_after: Pauses after this segment marks_before: Event markers before this segment marks_after: Event markers after this segment
- prosody: ProsodyAttrs | None = None
- voice: VoiceAttrs | None = None
- say_as: SayAsAttrs | None = None
- phoneme: PhonemeAttrs | None = None
- audio: AudioAttrs | None = None
- breaks_before: list[BreakAttrs]
- breaks_after: list[BreakAttrs]
VoiceAttrs
Voice configuration attributes.
- class ssmd.VoiceAttrs(name: str | None = None, language: str | None = None, gender: Literal['male', 'female', 'neutral'] | None = None, variant: int | None = None)[source]
Bases:
objectVoice attributes for TTS voice selection.
- Attributes:
name: Voice name (e.g., “Joanna”, “en-US-Wavenet-A”) language: BCP-47 language code (e.g., “en-US”, “fr-FR”) gender: Voice gender variant: Variant number for disambiguation
ProsodyAttrs
Prosody (volume, rate, pitch) attributes.
- class ssmd.ProsodyAttrs(volume: str | None = None, rate: str | None = None, pitch: str | None = None)[source]
Bases:
objectProsody attributes for volume, rate, and pitch control.
- Attributes:
- volume: Volume level (‘silent’, ‘x-soft’, ‘soft’, ‘medium’, ‘loud’,
‘x-loud’, or relative like ‘+10dB’)
- rate: Speech rate (‘x-slow’, ‘slow’, ‘medium’, ‘fast’, ‘x-fast’,
or relative like ‘+20%’)
- pitch: Pitch level (‘x-low’, ‘low’, ‘medium’, ‘high’, ‘x-high’,
or relative like ‘-5%’)
BreakAttrs
Pause/break attributes.
SayAsAttrs
Say-as interpretation attributes.
- class ssmd.SayAsAttrs(interpret_as: str, format: str | None = None, detail: str | None = None)[source]
Bases:
objectSay-as attributes for text interpretation.
- Attributes:
- interpret_as: Interpretation type (‘telephone’, ‘date’, ‘cardinal’,
‘ordinal’, ‘characters’, ‘expletive’, etc.)
format: Optional format string (e.g., ‘dd.mm.yyyy’ for dates) detail: Optional detail level (e.g., ‘2’ for verbosity)
PhonemeAttrs
Phonetic pronunciation attributes.
AudioAttrs
Audio file attributes.
- class ssmd.AudioAttrs(src: str, alt_text: str | None = None, clip_begin: str | None = None, clip_end: str | None = None, speed: str | None = None, repeat_count: int | None = None, repeat_dur: str | None = None, sound_level: str | None = None)[source]
Bases:
objectAudio file attributes.
- Attributes:
src: Audio file URL or path alt_text: Fallback text if audio cannot be played clip_begin: Start time for playback (e.g., “0s”, “500ms”) clip_end: End time for playback (e.g., “10s”, “5000ms”) speed: Playback speed as percentage (e.g., “150%”, “80%”) repeat_count: Number of times to repeat audio repeat_dur: Total duration for repetitions (e.g., “10s”) sound_level: Volume adjustment in dB (e.g., “+6dB”, “-3dB”)
Capability Presets
Pre-configured capability sets for common TTS engines.
- ssmd.MINIMAL_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.PYTTSX3_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.ESPEAK_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.GOOGLE_TTS_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.AZURE_TTS_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.AMAZON_POLLY_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.FULL_CAPABILITIES = <ssmd.capabilities.TTSCapabilities object>
Define TTS engine capabilities.
This class allows you to specify which SSML features your TTS engine supports. Unsupported features will be automatically stripped to plain text.
- Example:
>>> # Basic TTS with minimal support >>> caps = TTSCapabilities( ... emphasis=False, ... break_tags=True, ... prosody=False ... ) >>> >>> parser = SSMD(capabilities=caps) >>> ssml = parser.to_ssml("Hello *world*!") >>> # Output: <speak><p>Hello world!</p></speak> >>> # (emphasis stripped because not supported)
- ssmd.get_preset(name: str) TTSCapabilities[source]
Get a preset capability configuration.
- Args:
name: Preset name (espeak, pyttsx3, google, polly, azure, minimal, full)
- Returns:
TTSCapabilities instance
- Raises:
ValueError: If preset not found
Internal Modules
SSML Parser
Internal SSML to SSMD parsing engine.
SSML to SSMD converter - reverse conversion.
- class ssmd.ssml_parser.SSMLParser(config: dict[str, Any] | None = None)[source]
Bases:
objectConvert SSML to SSMD markdown format.
This class provides the reverse conversion from SSML XML to the more human-readable SSMD markdown syntax.
- Example:
>>> parser = SSMLParser() >>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> ssmd = parser.to_ssmd(ssml) >>> print(ssmd) '*Hello* world'
- STANDARD_LOCALES = {'de-DE': 'de', 'en-GB': 'en-GB', 'en-US': 'en', 'es-ES': 'es', 'fr-FR': 'fr', 'it-IT': 'it', 'ja-JP': 'ja', 'ko-KR': 'ko', 'pt-PT': 'pt', 'ru-RU': 'ru', 'zh-CN': 'zh'}
- __init__(config: dict[str, Any] | None = None)[source]
Initialize SSML parser.
- Args:
config: Optional configuration dictionary
- to_ssmd(ssml: str, *, capabilities: TTSCapabilities | str | None = None) str[source]
Convert SSML to SSMD format.
- Args:
ssml: SSML XML string capabilities: Optional TTS capabilities (preset name or object)
- Returns:
SSMD markdown string with proper formatting (each sentence on new line)
- Example:
>>> parser = SSMLParser() >>> parser.to_ssmd('<speak><emphasis>Hello</emphasis></speak>') '*Hello*'
Document Module
Document container implementation.
SSMD Document - Main document container with rich TTS features.
- class ssmd.document.Document(content: str = '', config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, escape_syntax: bool = False, escape_patterns: list[str] | None = None, parse_yaml_header: bool = False, strict: bool = False)[source]
Bases:
objectMain SSMD document container with incremental building and editing.
This is the primary interface for working with SSMD documents. It provides a clean, document-centric API for creating, editing, and exporting TTS content.
The Document stores content as fragments (pieces of text) with separators between them, allowing efficient incremental building and editing while preserving the document structure.
- Example:
Basic usage:
import ssmd # Create and build a document doc = ssmd.Document() doc.add_sentence("Hello world!") doc.add_sentence("This is SSMD.") # Export to different formats ssml = doc.to_ssml() text = doc.to_text() # Iterate for streaming TTS for sentence in doc.sentences(): tts_engine.speak(sentence)
Advanced usage:
# Load from SSML doc = ssmd.Document.from_ssml("<speak>Hello</speak>") # Edit the document doc[0] = "Modified content" doc.add_paragraph("New paragraph") # Access raw content print(doc.ssmd) # Raw SSMD markdown
- __init__(content: str = '', config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, escape_syntax: bool = False, escape_patterns: list[str] | None = None, parse_yaml_header: bool = False, strict: bool = False) None[source]
Initialize a new SSMD document.
- Args:
content: Optional initial SSMD content config: Configuration dictionary with options:
skip (list): Processor names to skip
output_speak_tag (bool): Wrap in <speak> tags (default: True)
pretty_print (bool): Format XML output (default: False)
auto_sentence_tags (bool): Auto-wrap sentences (default: False)
heading_levels (dict): Custom heading configurations
extensions (dict): Registered extension handlers
namespaces (dict): XML namespaces to add to the <speak> tag
sentence_model_size (str): spaCy model size for sentence detection (“sm”, “md”, “lg”, “trf”). Default: “sm”
sentence_spacy_model (str): Deprecated alias; model size is inferred from the name (overrides sentence_model_size)
sentence_use_spacy (bool): If False, use fast regex splitting instead of spaCy. Default: True
- capabilities: TTS capabilities (TTSCapabilities instance or
preset name). Presets: ‘espeak’, ‘pyttsx3’, ‘google’, ‘polly’, ‘azure’, ‘minimal’, ‘full’
- escape_syntax: If True, escape SSMD-like syntax in content to
prevent interpretation as markup. Useful for plain text or markdown that may coincidentally contain SSMD patterns.
- escape_patterns: List of specific pattern types to escape when
escape_syntax=True. If None, escapes all patterns. Valid values: ‘emphasis’, ‘annotations’, ‘breaks’, ‘marks’, ‘headings’, ‘directives’
- parse_yaml_header: If True, parse YAML front matter and store it
on doc.header while stripping it from the SSMD body. If False, YAML front matter is preserved as part of the content.
- strict: If True, emit warnings and apply ssml-green validation
rules where possible.
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc = ssmd.Document(capabilities='pyttsx3') >>> doc = ssmd.Document("Text", config={'auto_sentence_tags': True}) >>> # Fast sentence detection (no spaCy required) >>> doc = ssmd.Document(config={'sentence_use_spacy': False}) >>> # High quality sentence detection >>> doc = ssmd.Document(config={'sentence_model_size': 'lg'}) >>> # Escape SSMD syntax for plain text/markdown >>> doc = ssmd.Document(markdown, escape_syntax=True) >>> # Selective escaping >>> doc = ssmd.Document( ... text, ... escape_syntax=True, ... escape_patterns=['emphasis', 'annotations'] ... )
- classmethod from_ssml(ssml: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None) Document[source]
Create a Document from SSML string.
- Args:
ssml: SSML XML string config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance with converted content
- Example:
>>> ssml = '<speak><emphasis>Hello</emphasis> world</speak>' >>> doc = ssmd.Document.from_ssml(ssml) >>> doc.ssmd '*Hello* world'
- classmethod from_text(text: str, config: dict[str, Any] | None = None, capabilities: TTSCapabilities | str | None = None, parse_yaml_header: bool = False, strict: bool = False) Document[source]
Create a Document from plain text.
This is essentially the same as Document(text), but provides a symmetric API with from_ssml().
- Args:
text: Plain text or SSMD content config: Optional configuration parameters capabilities: Optional TTS capabilities
- Returns:
New Document instance
- Example:
>>> doc = ssmd.Document.from_text("Hello world") >>> doc.ssmd 'Hello world'
- add(text: str) Document[source]
Append text without separator.
Use this when you want to append content immediately after the previous content with no spacing.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc.add(" world") >>> doc.ssmd 'Hello world'
- add_sentence(text: str) Document[source]
Append text with newline separator.
Use this to add a new sentence on a new line.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First sentence.") >>> doc.add_sentence("Second sentence.") >>> doc.ssmd 'First sentence.\nSecond sentence.'
- add_paragraph(text: str) Document[source]
Append text with double newline separator.
Use this to start a new paragraph.
- Args:
text: SSMD text to append
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("First paragraph.") >>> doc.add_paragraph("Second paragraph.") >>> doc.ssmd 'First paragraph.\n\nSecond paragraph.'
- to_ssml() str[source]
Export document to SSML format.
- Returns:
SSML XML string
- Example:
>>> doc = ssmd.Document("Hello *world*!") >>> doc.to_ssml() '<speak>Hello <emphasis>world</emphasis>!</speak>'
- to_ssmd() str[source]
Export document to SSMD format with proper formatting.
Returns SSMD with proper line breaks (each sentence on a new line).
- Returns:
SSMD markdown string with proper formatting
- Example:
>>> doc = ssmd.Document.from_ssml('<speak><emphasis>Hi</emphasis></speak>') >>> doc.to_ssmd() '*Hi*'
- to_text() str[source]
Export document to plain text (strips all markup).
- Returns:
Plain text string with all SSMD markup removed
- Example:
>>> doc = ssmd.Document("Hello *world* @marker!") >>> doc.to_text() 'Hello world!'
- property ssmd: str
Get raw SSMD content.
Returns the complete SSMD document by joining all fragments with their separators.
- Returns:
SSMD markdown string
- property capabilities: TTSCapabilities | str | None
Get TTS capabilities.
- Returns:
TTSCapabilities instance, preset name, or None
- sentences(as_documents: bool = False) Iterator[str | Document][source]
Iterate through sentence-level SSML chunks.
Sentences are always returned as explicit
<s>-wrapped SSML fragments so the streaming interface remains stable regardless of paragraph tags.- Args:
- as_documents: If True, yield Document objects instead of strings.
Each sentence will be wrapped in its own Document instance.
- Yields:
SSML sentence strings (str), or Document objects if as_documents=True
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> for sentence in doc.sentences(): ... tts_engine.speak(sentence)
>>> for sentence_doc in doc.sentences(as_documents=True): ... ssml = sentence_doc.to_ssml() ... ssmd = sentence_doc.to_ssmd()
- paragraphs(as_documents: bool = False) Iterator[str | Document][source]
Iterate through paragraph-level SSML chunks.
Paragraphs are returned with
<p>tags when supported by capabilities.- Args:
as_documents: If True, yield Document objects instead of strings.
- Yields:
SSML paragraph strings (str), or Document objects if as_documents=True
- __len__() int[source]
Return number of sentences in the document.
- Returns:
Number of sentences
- Example:
>>> doc = ssmd.Document("First sentence. Second sentence.") >>> len(doc) 2
- __getitem__(index: int) str[source]
- __getitem__(index: slice) list[str]
Get sentence(s) by index.
- Args:
index: Sentence index or slice
- Returns:
SSML sentence string or list of strings
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] # First sentence SSML >>> doc[-1] # Last sentence SSML >>> doc[0:2] # First two sentences
- __setitem__(index: int, value: str) None[source]
Replace sentence at index.
This reconstructs the document with the modified sentence.
- Args:
index: Sentence index value: New SSMD content for this sentence
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc[0] = "Modified first sentence."
- __delitem__(index: int) None[source]
Delete sentence at index.
- Args:
index: Sentence index
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> del doc[1] # Remove second sentence
- __iter__() Iterator[str | Document][source]
Iterate through sentences.
- Yields:
SSML sentence strings
- Example:
>>> doc = ssmd.Document("First. Second.") >>> for sentence in doc: ... print(sentence)
- __iadd__(other: str | Document) Document[source]
Support += operator for appending content.
- Args:
other: String or Document to append
- Returns:
Self for chaining
- Example:
>>> doc = ssmd.Document("Hello") >>> doc += " world" >>> other = ssmd.Document("More") >>> doc += other
- insert(index: int, text: str, separator: str = '') Document[source]
Insert text at specific fragment index.
- Args:
index: Position to insert (0 = beginning) text: SSMD text to insert separator: Separator to use (“”, “n”, or “nn”)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.insert(0, "Start: ", "") >>> doc.ssmd 'Start: Hello world'
- remove(index: int) Document[source]
Remove fragment at index.
This is the same as del doc[index] but returns self for chaining.
- Args:
index: Fragment index to remove
- Returns:
Self for method chaining
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> doc.remove(1)
- clear() Document[source]
Remove all content from the document.
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world") >>> doc.clear() >>> doc.ssmd ''
- replace(old: str, new: str, count: int = -1) Document[source]
Replace text across all fragments.
- Args:
old: Text to find new: Text to replace with count: Maximum replacements (-1 = all)
- Returns:
Self for method chaining
- Example:
>>> doc = ssmd.Document("Hello world. Hello again.") >>> doc.replace("Hello", "Hi") >>> doc.ssmd 'Hi world. Hi again.'
- merge(other: Document, separator: str = '\n\n') Document[source]
Merge another document into this one.
- Args:
other: Document to merge separator: Separator to use between documents
- Returns:
Self for method chaining
- Example:
>>> doc1 = ssmd.Document("First document.") >>> doc2 = ssmd.Document("Second document.") >>> doc1.merge(doc2) >>> doc1.ssmd 'First document.\n\nSecond document.'
- split() list[Document][source]
Split document into individual sentence Documents.
- Returns:
List of Document objects, one per sentence
- Example:
>>> doc = ssmd.Document("First. Second. Third.") >>> sentences = doc.split() >>> len(sentences) 3 >>> sentences[0].ssmd 'First.'
- get_fragment(index: int) str[source]
Get raw fragment by index (not sentence).
This accesses the internal fragment storage directly, which may be different from sentence boundaries.
- Args:
index: Fragment index
- Returns:
Raw SSMD fragment string
- Raises:
IndexError: If index is out of range
- Example:
>>> doc = ssmd.Document() >>> doc.add("First") >>> doc.add_sentence("Second") >>> doc.get_fragment(0) 'First' >>> doc.get_fragment(1) 'Second'
Parser Module
SSMD parsing functions for extracting structured data.
SSMD parser - Parse SSMD text into structured Sentence/Segment objects.
This module provides functions to parse SSMD markdown into structured data that can be used for TTS processing or conversion to SSML.
- ssmd.parser.parse_paragraphs(text: str, *, capabilities: TTSCapabilities | str | None = None, heading_levels: dict | None = None, extensions: dict | None = None, sentence_detection: bool = True, language: str = 'en', use_spacy: bool | None = None, model_size: str | None = None, parse_yaml_header: bool = False, strict_parse: bool = False) list[Paragraph][source]
Parse SSMD text into a list of Paragraphs.
This is the main parsing function. It handles: - Directive blocks (<div …> … </div>) - Paragraph and sentence splitting - All SSMD markup (emphasis, annotations, breaks, etc.)
- Args:
text: SSMD markdown text capabilities: TTS capabilities for filtering (optional) heading_levels: Custom heading configurations extensions: Custom extension handlers sentence_detection: If True, split text into sentences language: Default language for sentence detection use_spacy: If True, use spaCy for sentence detection model_size: spaCy model size (“sm”, “md”, “lg”) parse_yaml_header: If True, parse YAML front matter and apply
heading/extensions config while stripping it from the body. If False, YAML front matter is preserved as plain text.
strict_parse: If True, strip unsupported features based on capabilities.
- Returns:
List of Paragraph objects
- ssmd.parser.parse_ssmd(text: str, *, capabilities: TTSCapabilities | str | None = None, heading_levels: dict | None = None, extensions: dict | None = None, sentence_detection: bool = True, language: str = 'en', use_spacy: bool | None = None, model_size: str | None = None, parse_yaml_header: bool = False, strict_parse: bool = False) list[Paragraph][source]
Parse SSMD text into paragraphs (backward compatible name).
This is an alias for parse_paragraphs().
- ssmd.parser.parse_sentences(ssmd_text: str, *, capabilities: TTSCapabilities | str | None = None, include_default_voice: bool = True, sentence_detection: bool = True, language: str = 'en', model_size: str | None = None, spacy_model: str | None = None, use_spacy: bool | None = None, heading_levels: dict | None = None, extensions: dict | None = None, parse_yaml_header: bool = False, strict_parse: bool = False) list[Sentence][source]
Parse SSMD text into sentences (backward compatible API).
This is an alias for parse_paragraphs() with the old parameter names. Returned sentences include paragraph_index and sentence_index metadata.
- Args:
ssmd_text: SSMD formatted text to parse capabilities: TTS capabilities or preset name include_default_voice: If False, exclude sentences without voice context sentence_detection: Enable/disable sentence splitting language: Language code for sentence detection model_size: Size of spacy model (sm/md/lg) spacy_model: Full spacy model name (deprecated, use model_size) use_spacy: Force use of spacy for sentence detection heading_levels: Custom heading configurations extensions: Custom extension handlers parse_yaml_header: If True, parse YAML front matter and apply
heading/extensions config while stripping it from the body. If False, YAML front matter is preserved as plain text.
strict_parse: If True, strip unsupported features based on capabilities.
- Returns:
List of Sentence objects
- ssmd.parser.parse_segments(ssmd_text: str, *, capabilities: TTSCapabilities | str | None = None, voice_context: VoiceAttrs | None = None) list[Segment][source]
Parse SSMD text into segments (backward compatible API).
- ssmd.parser.parse_voice_blocks(ssmd_text: str) list[tuple[DirectiveAttrs, str]][source]
Parse SSMD text into directive blocks (backward compatible API).
Returns list of (DirectiveAttrs, text) tuples.
- ssmd.parser.parse_spans(text: str, *, normalize: bool = True, default_lang: str | None = None, preserve_whitespace: bool | None = None) ParseSpansResult[source]
Parse SSMD text into clean text and annotation spans.
- Args:
text: SSMD markdown text normalize: If True (default), normalize whitespace between segments default_lang: Optional language to apply to the entire output preserve_whitespace: Deprecated. Use normalize=False instead.
- Returns:
ParseSpansResult with clean text, annotations, and warnings. Offsets in annotations are relative to the returned clean_text.
- Note:
Offsets are 0-based, half-open [start, end) intervals referring to clean_text.
Segment Module
Segment class for representing text portions with attributes.
Segment - A piece of text with SSMD attributes.
A Segment represents a portion of text with specific formatting and processing attributes. Segments are combined to form sentences.
- class ssmd.segment.ExtensionHandler(handler: collections.abc.Callable[[str], str], namespaces: dict[str, str] = <factory>)[source]
Bases:
object
- ssmd.segment.xsampa_to_ipa(xsampa: str) str[source]
Convert X-SAMPA notation to IPA.
- Args:
xsampa: X-SAMPA phoneme string
- Returns:
IPA phoneme string
- ssmd.segment.expand_language_code(code: str) str[source]
Expand 2-letter language code to full BCP-47 locale.
- Args:
code: Language code (e.g., “en”, “en-US”)
- Returns:
Full locale code (e.g., “en-US”)
- class ssmd.segment.Segment(text: str, emphasis: bool | str = False, prosody: ProsodyAttrs | None = None, language: str | None = None, voice: VoiceAttrs | None = None, say_as: SayAsAttrs | None = None, substitution: str | None = None, phoneme: PhonemeAttrs | None = None, audio: AudioAttrs | None = None, extension: str | None = None, breaks_before: list[BreakAttrs] = <factory>, breaks_after: list[BreakAttrs] = <factory>, marks_before: list[str] = <factory>, marks_after: list[str] = <factory>)[source]
Bases:
objectA segment of text with SSMD features.
Represents a portion of text with specific formatting and processing attributes. Segments are the atomic units of SSMD content.
- Attributes:
text: Raw text content emphasis: Emphasis level (True/”moderate”, “strong”, “reduced”, “none”, False) prosody: Volume, rate, pitch settings language: Language code for this segment voice: Voice settings for this segment say_as: Text interpretation hints substitution: Replacement text (alias) phoneme: IPA pronunciation audio: Audio file to play extension: Platform-specific extension name breaks_before: Pauses before this segment breaks_after: Pauses after this segment marks_before: Event markers before this segment marks_after: Event markers after this segment
- prosody: ProsodyAttrs | None = None
- voice: VoiceAttrs | None = None
- say_as: SayAsAttrs | None = None
- phoneme: PhonemeAttrs | None = None
- audio: AudioAttrs | None = None
- breaks_before: list[BreakAttrs]
- breaks_after: list[BreakAttrs]
Sentence Module
Sentence class for representing collections of segments.
Sentence - A collection of segments with voice context.
A Sentence represents a logical unit of speech that should be spoken together. Sentences contain segments and have an optional voice context.
- class ssmd.sentence.Sentence(segments: list[Segment] = <factory>, voice: VoiceAttrs | None = None, language: str | None = None, prosody: ProsodyAttrs | None = None, is_paragraph_end: bool = False, paragraph_index: int = 0, sentence_index: int = 0, breaks_after: list[BreakAttrs] = <factory>)[source]
Bases:
objectA sentence containing segments with directive context.
Represents a logical sentence unit that should be spoken together. Sentences are split on: - Directive changes (<div …> blocks) - Sentence boundaries (.!?) when sentence_detection=True - Paragraph breaks (
)
- Attributes:
segments: List of segments in the sentence voice: Voice context for entire sentence (from <div voice=…> directives) language: Language directive for the sentence prosody: Prosody directive for the sentence is_paragraph_end: True if sentence ends with paragraph break paragraph_index: Zero-based paragraph index for this sentence sentence_index: Zero-based sentence index within the document breaks_after: Pauses after the sentence
- voice: VoiceAttrs | None = None
- prosody: ProsodyAttrs | None = None
- breaks_after: list[BreakAttrs]
- to_ssml(capabilities: TTSCapabilities | None = None, extensions: dict | None = None, wrap_sentence: bool = False, warnings: list[str] | None = None) str[source]
Convert sentence to SSML.
- Args:
capabilities: TTS engine capabilities for filtering extensions: Custom extension handlers wrap_sentence: If True, wrap content in <s> tag warnings: Optional list to collect warnings
- Returns:
SSML string
Types Module
Data types used throughout the SSMD library.
Data types for SSMD.
This module defines the core data structures used throughout the SSMD library.
- class ssmd.types.VoiceAttrs(name: str | None = None, language: str | None = None, gender: Literal['male', 'female', 'neutral'] | None = None, variant: int | None = None)[source]
Bases:
objectVoice attributes for TTS voice selection.
- Attributes:
name: Voice name (e.g., “Joanna”, “en-US-Wavenet-A”) language: BCP-47 language code (e.g., “en-US”, “fr-FR”) gender: Voice gender variant: Variant number for disambiguation
- class ssmd.types.ProsodyAttrs(volume: str | None = None, rate: str | None = None, pitch: str | None = None)[source]
Bases:
objectProsody attributes for volume, rate, and pitch control.
- Attributes:
- volume: Volume level (‘silent’, ‘x-soft’, ‘soft’, ‘medium’, ‘loud’,
‘x-loud’, or relative like ‘+10dB’)
- rate: Speech rate (‘x-slow’, ‘slow’, ‘medium’, ‘fast’, ‘x-fast’,
or relative like ‘+20%’)
- pitch: Pitch level (‘x-low’, ‘low’, ‘medium’, ‘high’, ‘x-high’,
or relative like ‘-5%’)
- class ssmd.types.DirectiveAttrs(voice: VoiceAttrs | None = None, language: str | None = None, prosody: ProsodyAttrs | None = None)[source]
Bases:
objectDirective attributes that apply to a <div> block.
- Attributes:
voice: Voice attributes to apply (optional) language: Language code for <lang> wrapping prosody: Prosody attributes to apply
- voice: VoiceAttrs | None = None
- prosody: ProsodyAttrs | None = None
- class ssmd.types.BreakAttrs(time: str | None = None, strength: str | None = None)[source]
Bases:
objectBreak/pause attributes.
- Attributes:
time: Time duration (e.g., ‘500ms’, ‘2s’) strength: Break strength (‘none’, ‘x-weak’, ‘medium’, ‘strong’, ‘x-strong’)
- class ssmd.types.SayAsAttrs(interpret_as: str, format: str | None = None, detail: str | None = None)[source]
Bases:
objectSay-as attributes for text interpretation.
- Attributes:
- interpret_as: Interpretation type (‘telephone’, ‘date’, ‘cardinal’,
‘ordinal’, ‘characters’, ‘expletive’, etc.)
format: Optional format string (e.g., ‘dd.mm.yyyy’ for dates) detail: Optional detail level (e.g., ‘2’ for verbosity)
- class ssmd.types.AudioAttrs(src: str, alt_text: str | None = None, clip_begin: str | None = None, clip_end: str | None = None, speed: str | None = None, repeat_count: int | None = None, repeat_dur: str | None = None, sound_level: str | None = None)[source]
Bases:
objectAudio file attributes.
- Attributes:
src: Audio file URL or path alt_text: Fallback text if audio cannot be played clip_begin: Start time for playback (e.g., “0s”, “500ms”) clip_end: End time for playback (e.g., “10s”, “5000ms”) speed: Playback speed as percentage (e.g., “150%”, “80%”) repeat_count: Number of times to repeat audio repeat_dur: Total duration for repetitions (e.g., “10s”) sound_level: Volume adjustment in dB (e.g., “+6dB”, “-3dB”)
Utilities
Helper functions for SSML processing.
Utility functions for SSMD processing.
- ssmd.utils.escape_xml(text: str) str[source]
Escape XML special characters.
- Args:
text: Input text to escape
- Returns:
Text with XML entities escaped
- ssmd.utils.unescape_xml(text: str) str[source]
Unescape XML entities.
- Args:
text: Text with XML entities
- Returns:
Unescaped text
- ssmd.utils.format_ssmd_attr(key: str, value: str) str[source]
Format a key/value pair for SSMD annotations.
- ssmd.utils.format_xml(xml_text: str, pretty: bool = True) str[source]
Format XML with optional pretty printing.
- Args:
xml_text: XML string to format pretty: Enable pretty printing
- Returns:
Formatted XML string
- ssmd.utils.parse_yaml_header(text: str) tuple[dict[str, Any] | None, str][source]
Parse YAML front matter from SSMD text.
Supports YAML headers wrapped in — … — or — … … .
- Returns:
Tuple of (header_dict, body_text)
- ssmd.utils.extract_sentences(ssml: str) list[str][source]
Extract sentences from SSML.
Looks for <s> tags or falls back to <p> tags or <speak> content.
- Args:
ssml: SSML string
- Returns:
List of SSML sentence strings
- ssmd.utils.escape_ssmd_syntax(text: str, patterns: list[str] | None = None) str[source]
Escape SSMD syntax patterns to prevent interpretation as markup.
- Note:
Escaping is reversible but not length-preserving. Any offsets derived from escaped text should be mapped against the unescaped clean text instead.
This is useful when processing plain text or markdown that may contain characters that coincidentally match SSMD syntax patterns. Uses placeholder replacement which is reversed after SSML processing.
- Args:
text: Input text that may contain SSMD-like patterns patterns: List of pattern types to escape. If None, escapes all.
Valid values: ‘emphasis’, ‘annotations’, ‘breaks’, ‘marks’, ‘headings’, ‘directives’
- Returns:
Text with SSMD patterns replaced with placeholders
- Example:
>>> text = "This *word* should not be emphasized" >>> escape_ssmd_syntax(text) 'This \uf000word\uf000 should not be emphasized'
>>> text = 'Visit [our site]{src="https://example.com"}' >>> escaped = escape_ssmd_syntax(text) # Placeholders prevent SSMD interpretation
>>> # Selective escaping >>> escape_ssmd_syntax(text, patterns=['emphasis', 'breaks'])
- ssmd.utils.unescape_ssmd_syntax(text: str, *, xml_safe: bool = False) str[source]
Remove placeholder escaping from SSMD syntax.
This is used internally to replace placeholders with original characters after TTS processing.
- Args:
text: Text with placeholder-escaped SSMD syntax xml_safe: If True, keep XML special characters escaped when restoring
placeholders (e.g.,
<becomes<).- Returns:
Text with placeholders replaced by original characters
- Example:
>>> unescape_ssmd_syntax("This \uf000word\uf000 is escaped") 'This *word* is escaped'