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: object

Main 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 config: dict[str, Any]

Get configuration dictionary.

Returns:

Configuration dict

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 config: dict[str, Any]

Get configuration dictionary.

Returns:

Configuration dict

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'
__repr__() str[source]

String representation of document.

Returns:

Representation string

Example:
>>> doc = ssmd.Document("Hello.
World.”)
>>> repr(doc)
'Document(2 sentences, 13 chars)'
__str__() str[source]

String conversion returns SSMD content.

Returns:

SSMD string

Example:
>>> doc = ssmd.Document("Hello *world*")
>>> str(doc)
'Hello *world*'

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: 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)
__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

supports_extension(extension_name: str) bool[source]

Check if an extension is supported.

Args:

extension_name: Name of the extension

Returns:

True if supported

supports_key(key: str, default: bool = True) bool[source]

Check raw ssml-green capability key.

Args:

key: ssml-green key to check default: Default if key is missing

Returns:

True if supported

SSMLParser

Parse SSML and convert to SSMD format.

class ssmd.SSMLParser(config: dict[str, Any] | None = None)[source]

Bases: object

Convert 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.

ssmd.iter_sentences_spans(text_or_doc: str | Any, *, preserve_whitespace: bool = False, language: str = 'en', use_spacy: bool | None = None, model_size: str | None = None) list[tuple[str, int, int]][source]

Iterate over sentence spans in clean text coordinates.

ssmd.lint(text: str, profile: str = 'ssmd-core') list[LintIssue][source]

Lint SSMD text against a capability profile.

Offsets in lint issues refer to the clean text coordinate system.

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: object

A 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

segments: list[Segment]
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]
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

to_ssmd() str[source]

Convert sentence to SSMD markdown.

Returns:

SSMD string

to_text() str[source]

Convert sentence to plain text.

Returns:

Plain text with all markup removed

property text: str

Get plain text content of the sentence.

Returns:

Plain text string

__str__() str[source]

String representation returns plain text.

__len__() int[source]

Return number of segments.

__iter__()[source]

Iterate over segments.

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: object

A 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

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]
breaks_after: list[BreakAttrs]
marks_before: list[str]
marks_after: list[str]
to_ssml(capabilities: TTSCapabilities | None = None, extensions: dict | None = None, warnings: list[str] | None = None) str[source]

Convert segment to SSML.

Args:

capabilities: TTS engine capabilities for filtering extensions: Custom extension handlers

Returns:

SSML string

to_ssmd() str[source]

Convert segment to SSMD markdown.

Returns:

SSMD string

to_text() str[source]

Convert segment to plain text.

Returns:

Plain text with all markup removed

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: object

Voice 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

name: str | None = None
language: str | None = None
gender: Literal['male', 'female', 'neutral'] | None = None
variant: int | None = None

ProsodyAttrs

Prosody (volume, rate, pitch) attributes.

class ssmd.ProsodyAttrs(volume: str | None = None, rate: str | None = None, pitch: str | None = None)[source]

Bases: object

Prosody 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%’)

volume: str | None = None
rate: str | None = None
pitch: str | None = None

BreakAttrs

Pause/break attributes.

class ssmd.BreakAttrs(time: str | None = None, strength: str | None = None)[source]

Bases: object

Break/pause attributes.

Attributes:

time: Time duration (e.g., ‘500ms’, ‘2s’) strength: Break strength (‘none’, ‘x-weak’, ‘medium’, ‘strong’, ‘x-strong’)

time: str | None = None
strength: str | None = None

SayAsAttrs

Say-as interpretation attributes.

class ssmd.SayAsAttrs(interpret_as: str, format: str | None = None, detail: str | None = None)[source]

Bases: object

Say-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)

interpret_as: str
format: str | None = None
detail: str | None = None

PhonemeAttrs

Phonetic pronunciation attributes.

class ssmd.PhonemeAttrs(ph: str, alphabet: str = 'ipa')[source]

Bases: object

Phoneme pronunciation attributes.

Attributes:

ph: Phonetic pronunciation string alphabet: Phonetic alphabet (ipa or x-sampa)

ph: str
alphabet: str = 'ipa'

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: object

Audio 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”)

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

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: object

Convert 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: object

Main 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 config: dict[str, Any]

Get configuration dictionary.

Returns:

Configuration dict

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'
__repr__() str[source]

String representation of document.

Returns:

Representation string

Example:
>>> doc = ssmd.Document("Hello.
World.”)
>>> repr(doc)
'Document(2 sentences, 13 chars)'
__str__() str[source]

String conversion returns SSMD content.

Returns:

SSMD string

Example:
>>> doc = ssmd.Document("Hello *world*")
>>> str(doc)
'Hello *world*'

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.

ssmd.parser.iter_sentences_spans(text_or_doc: str | Any, *, preserve_whitespace: bool = False, language: str = 'en', use_spacy: bool | None = None, model_size: str | None = None) list[tuple[str, int, int]][source]

Iterate over sentence spans in clean text coordinates.

ssmd.parser.lint(text: str, profile: str = 'ssmd-core') list[LintIssue][source]

Lint SSMD text against a capability profile.

Offsets in lint issues refer to the clean text coordinate system.

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

handler: Callable[[str], str]
namespaces: dict[str, str]
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: object

A 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

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]
breaks_after: list[BreakAttrs]
marks_before: list[str]
marks_after: list[str]
to_ssml(capabilities: TTSCapabilities | None = None, extensions: dict | None = None, warnings: list[str] | None = None) str[source]

Convert segment to SSML.

Args:

capabilities: TTS engine capabilities for filtering extensions: Custom extension handlers

Returns:

SSML string

to_ssmd() str[source]

Convert segment to SSMD markdown.

Returns:

SSMD string

to_text() str[source]

Convert segment to plain text.

Returns:

Plain text with all markup removed

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: object

A 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

segments: list[Segment]
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]
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

to_ssmd() str[source]

Convert sentence to SSMD markdown.

Returns:

SSMD string

to_text() str[source]

Convert sentence to plain text.

Returns:

Plain text with all markup removed

property text: str

Get plain text content of the sentence.

Returns:

Plain text string

__str__() str[source]

String representation returns plain text.

__len__() int[source]

Return number of segments.

__iter__()[source]

Iterate over segments.

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: object

Voice 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

name: str | None = None
language: str | None = None
gender: Literal['male', 'female', 'neutral'] | None = None
variant: int | None = None
class ssmd.types.ProsodyAttrs(volume: str | None = None, rate: str | None = None, pitch: str | None = None)[source]

Bases: object

Prosody 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%’)

volume: str | None = None
rate: str | None = None
pitch: str | None = None
class ssmd.types.DirectiveAttrs(voice: VoiceAttrs | None = None, language: str | None = None, prosody: ProsodyAttrs | None = None)[source]

Bases: object

Directive 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
language: str | None = None
prosody: ProsodyAttrs | None = None
class ssmd.types.BreakAttrs(time: str | None = None, strength: str | None = None)[source]

Bases: object

Break/pause attributes.

Attributes:

time: Time duration (e.g., ‘500ms’, ‘2s’) strength: Break strength (‘none’, ‘x-weak’, ‘medium’, ‘strong’, ‘x-strong’)

time: str | None = None
strength: str | None = None
class ssmd.types.SayAsAttrs(interpret_as: str, format: str | None = None, detail: str | None = None)[source]

Bases: object

Say-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)

interpret_as: str
format: str | None = None
detail: str | None = None
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: object

Audio 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”)

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
class ssmd.types.PhonemeAttrs(ph: str, alphabet: str = 'ipa')[source]

Bases: object

Phoneme pronunciation attributes.

Attributes:

ph: Phonetic pronunciation string alphabet: Phonetic alphabet (ipa or x-sampa)

ph: str
alphabet: str = 'ipa'

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.build_config_from_header(header: dict[str, Any]) dict[str, Any][source]
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 &lt;).

Returns:

Text with placeholders replaced by original characters

Example:
>>> unescape_ssmd_syntax("This \uf000word\uf000 is escaped")
'This *word* is escaped'