SpeechMarkdown Rust
High-performance SpeechMarkdown parser written in Rust. Converts SpeechMarkdown syntax to platform-specific SSML for Amazon Alexa, Google Assistant, Microsoft Azure, and more.
Repository Structure
This repository contains the core Rust SpeechMarkdown parser with bindings for multiple languages:
speechmarkdown-rust/
├── src/ # Core Rust library (language-agnostic)
├── bindings/ # Language-specific bindings
│ ├── python/ # Python bindings via PyO3
│ ├── nodejs/ # Node.js bindings via napi-rs
│ ├── dotnet/ # .NET bindings via rust-cpp
│ └── swift/ # Swift bindings via C API + SPM
├── Package.swift # Swift Package Manager configuration (Swift-only)
├── build-swift-package.sh # Swift package build script (Swift-only)
└── Cargo.toml # Rust package configuration
Important Notes for Non-Swift Users:
- Swift-specific files are ignored by other build systems:
Package.swift,build-swift-package.sh, andswift-package-dist/are only used by Swift Package Manager. They do not affect Rust, Python, Node.js, or .NET builds. - Core Rust library unchanged: The
src/directory andCargo.tomlremain the single source of truth for the SpeechMarkdown parser across all languages. - Isolated language bindings: Each language in
bindings/has its own build configuration and doesn't interfere with others.
For Rust/.NET/Python/Node.js Developers: You can safely ignore Swift-specific files. Your respective package managers (Cargo, NuGet, PyPI, npm) only use the core library and your language's binding directory.
Install
| Language | Package | Install |
|---|---|---|
| Rust | speechmarkdown-rust | cargo add speechmarkdown-rust |
| Python | speechmarkdown-rust | pip install speechmarkdown-rust |
| Node.js | speechmarkdown | npm install speechmarkdown |
| .NET | SpeechMarkdown | dotnet add package SpeechMarkdown |
| Swift | Release asset | See Swift section below |
Supported Platforms
| Platform | String ID |
|---|---|
| Amazon Alexa | "amazon-alexa" or "alexa" |
| Google Assistant | "google-assistant" or "google" |
| Microsoft Azure | "microsoft-azure" or "azure" |
| Apple | "apple" |
| W3C | "w3c" |
| Samsung Bixby | "samsung-bixby" or "bixby" |
| ElevenLabs | "elevenlabs" |
| IBM Watson | "ibm-watson" or "watson" |
API
All bindings expose the same core methods:
| Method | Returns | Description |
|---|---|---|
to_ssml(input, platform) |
string |
Convert SpeechMarkdown to SSML for the given platform |
to_text(input) |
string |
Convert SpeechMarkdown to plain text (strips all markup) |
to_smd(ssml) |
string |
Convert SSML to SpeechMarkdown (best-effort, lossy for unsupported elements) |
parse(input) |
string (JSON) |
Parse SpeechMarkdown and return the AST as JSON |
is_speech_markdown(input) |
bool |
Check if a string contains SpeechMarkdown syntax |
validate(input) |
bool |
Validate that SpeechMarkdown parses without errors |
supported_ssml(platform) |
string (JSON) |
Get supported SSML elements for a platform |
Usage
Rust
use ;
// Convert to SSML
let ssml = to_ssml?;
// Convert to plain text
let text = to_text?;
// Parse to AST (JSON string)
let ast = parse?;
// Check if input contains SpeechMarkdown syntax
if is_speech_markdown
// Validate input
validate?;
// Convert SSML back to SpeechMarkdown (best-effort)
let smd = to_smd?;
// Returns: ++word++
Python
=
=
=
= # True
= # False
# raises ValueError if invalid
# Convert SSML to SpeechMarkdown (best-effort)
=
# Returns: ++word++
Node.js
const = require
const ssml =
const text =
const ast =
// true
// false
// throws if invalid
// Convert SSML to SpeechMarkdown (best-effort)
const smd =
// Returns: ++word++
.NET (C#)
using SpeechMarkdown;
var parser = new SpeechMarkdownParser();
string ssml = parser.ToSsml("Hello (world)[emphasis:\"strong\"]", Platform.AmazonAlexa);
string text = parser.ToText("Hello (world)[emphasis:\"strong\"]");
string json = parser.ParseToJson("Hello world");
bool isSmd = parser.IsSpeechMarkdown("Hello (world)[emphasis:\"strong\"]"); // true
parser.Validate("Hello (world)[emphasis:\"strong\"]"); // throws on invalid
// Convert SSML to SpeechMarkdown (best-effort)
string smd = parser.ToSmd("<speak><emphasis level=\"strong\">word</emphasis></speak>");
// Returns: ++word++
Swift
The repo root contains a Package.swift with a binary target pointing to a pre-built XCFramework. This enables both local development and Swift Package Index integration.
Option 1 — SPM (recommended):
// In your Package.swift:
.package(url: "https://github.com/AACTools/speechmarkdown-rust", branch: "spm")
Option 2 — Local package:
Download speechmarkdown-swift-package.zip from the latest release, unzip, and add as a local package in Xcode (File > Add Packages > Add Local).
Includes macOS (arm64 + x86_64), iOS device (arm64), and iOS simulator (arm64) slices.
To build from source: ./build-swift-package.sh
import SpeechMarkdown
let parser = SpeechMarkdownParser()
let ssml = try parser.toSsml(input: "Hello (world)[emphasis:\"strong\"]", platform: "amazon-alexa")
let text = try parser.toText(input: "Hello (world)[emphasis:\"strong\"]")
let json = try parser.parseToJson(input: "Hello world")
let isSmd = parser.isSpeechMarkdown(input: "Hello (world)[emphasis:\"strong\"]") // true
try parser.validate(input: "Hello (world)[emphasis:\"strong\"]") // throws on invalid
// Convert SSML to SpeechMarkdown (best-effort)
let smd = try parser.toSmd(ssml: "<speak><emphasis level=\"strong\">word</emphasis></speak>")
// Returns: ++word++
C API
// Convert to SSML
const char* ssml = ;
;
// Convert to plain text
const char* text = ;
;
// Parse to JSON
const char* json = ;
;
// Check for SpeechMarkdown syntax
bool is_smd = ;
// Validate
bool valid = ;
// Convert SSML to SpeechMarkdown (best-effort)
const char* smd = ;
;
// Get last error (thread-local)
const char* err = ;
Building from Source
Core Rust Library
The core Rust parser is built with:
This produces:
- Windows:
target/release/speechmarkdown_rust.dll - macOS:
target/release/libspeechmarkdown_rust.dylib - Linux:
target/release/libspeechmarkdown_rust.so
Language-Specific Builds
Each language binding has its own build process:
Python:
# or for release: maturin build --release
Node.js:
.NET:
Swift:
# Uses pre-built XCFramework from releases
# Or build from source:
Development Workflow
The repository follows a unified development model where all language bindings share the same core Rust parser:
- Core changes: Modify
src/for parser logic changes - Language changes: Modify
bindings/<language>/for binding-specific changes - Testing: Each language has its own test suite
- Releases: All packages are released together with version synchronization
For Contributors:
- Rust developers: Work in
src/and test withcargo test - Python developers: Work in
bindings/python/and test withpytest - Node.js developers: Work in
bindings/nodejs/and test withnpm test - .NET developers: Work in
bindings/dotnet/and test withdotnet test - Swift developers: Work in
bindings/swift/and use SPM for testing
License
MIT