Skip to main content

SpeechMarkdown parser - convert SpeechMarkdown to SSML

Project description

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, and swift-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 and Cargo.toml remain 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 speechmarkdown_rust::{SpeechMarkdownParser, Platform};

// Convert to SSML
let ssml = SpeechMarkdownParser::to_ssml(
    "Hello (world)[emphasis:\"strong\"]",
    Platform::AmazonAlexa,
)?;

// Convert to plain text
let text = SpeechMarkdownParser::to_text("Hello (world)[emphasis:\"strong\"]")?;

// Parse to AST (JSON string)
let ast = SpeechMarkdownParser::parse("Hello world")?;

// Check if input contains SpeechMarkdown syntax
if SpeechMarkdownParser::is_speech_markdown(&input) {
    // ...
}

// Validate input
SpeechMarkdownParser::validate(&input)?;

// Convert SSML back to SpeechMarkdown (best-effort)
let smd = SpeechMarkdownParser::to_smd(r#"<speak><emphasis level="strong">word</emphasis></speak>"#)?;
// Returns: ++word++

Python

from speechmarkdown_rust import to_ssml, to_text, parse, is_speech_markdown, validate

ssml = to_ssml('Hello (world)[emphasis:"strong"]', 'amazon-alexa')
text = to_text('Hello (world)[emphasis:"strong"]')
ast = parse('Hello world')

is_smd = is_speech_markdown('Hello (world)[emphasis:"strong"]')  # True
is_smd = is_speech_markdown('Hello world')                       # False

validate('Hello (world)[emphasis:"strong"]')  # raises ValueError if invalid

# Convert SSML to SpeechMarkdown (best-effort)
smd = to_smd('<speak><emphasis level="strong">word</emphasis></speak>')
# Returns: ++word++

Node.js

const { to_ssml, to_text, parse, is_speech_markdown, validate } = require('speechmarkdown')

const ssml = to_ssml('Hello (world)[emphasis:"strong"]', 'amazon-alexa')
const text = to_text('Hello (world)[emphasis:"strong"]')
const ast = parse('Hello world')

is_speech_markdown('Hello (world)[emphasis:"strong"]')  // true
is_speech_markdown('Hello world')                       // false

validate('Hello (world)[emphasis:"strong"]')  // throws if invalid

// Convert SSML to SpeechMarkdown (best-effort)
const smd = to_smd('<speak><emphasis level="strong">word</emphasis></speak>')
// 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

#include "speechmarkdown.h"

// Convert to SSML
const char* ssml = speechmarkdown_to_ssml("Hello (world)[emphasis:\"strong\"]", "amazon-alexa");
speechmarkdown_free((char*)ssml);

// Convert to plain text
const char* text = speechmarkdown_to_text("Hello (world)[emphasis:\"strong\"]");
speechmarkdown_free((char*)text);

// Parse to JSON
const char* json = speechmarkdown_parse("Hello world");
speechmarkdown_free((char*)json);

// Check for SpeechMarkdown syntax
bool is_smd = speechmarkdown_is_speech_markdown("Hello (world)[emphasis:\"strong\"]");

// Validate
bool valid = speechmarkdown_validate("Hello (world)[emphasis:\"strong\"]");

// Convert SSML to SpeechMarkdown (best-effort)
const char* smd = speechmarkdown_to_smd("<speak><emphasis level=\"strong\">word</emphasis></speak>");
speechmarkdown_free((char*)smd);

// Get last error (thread-local)
const char* err = speechmarkdown_get_error();

Building from Source

Core Rust Library

The core Rust parser is built with:

cargo build --release

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:

cd bindings/python
maturin develop
# or for release: maturin build --release

Node.js:

cd bindings/nodejs
npm install
npm run build

.NET:

cd bindings/dotnet
dotnet build

Swift:

# Uses pre-built XCFramework from releases
# Or build from source:
./build-swift-package.sh

Development Workflow

The repository follows a unified development model where all language bindings share the same core Rust parser:

  1. Core changes: Modify src/ for parser logic changes
  2. Language changes: Modify bindings/<language>/ for binding-specific changes
  3. Testing: Each language has its own test suite
  4. Releases: All packages are released together with version synchronization

For Contributors:

  • Rust developers: Work in src/ and test with cargo test
  • Python developers: Work in bindings/python/ and test with pytest
  • Node.js developers: Work in bindings/nodejs/ and test with npm test
  • .NET developers: Work in bindings/dotnet/ and test with dotnet test
  • Swift developers: Work in bindings/swift/ and use SPM for testing

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

speechmarkdown_rust-0.4.4.tar.gz (515.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

speechmarkdown_rust-0.4.4-cp313-cp313-win_amd64.whl (266.9 kB view details)

Uploaded CPython 3.13Windows x86-64

speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (410.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (399.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

speechmarkdown_rust-0.4.4-cp313-cp313-macosx_11_0_arm64.whl (357.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

speechmarkdown_rust-0.4.4-cp313-cp313-macosx_10_12_x86_64.whl (366.8 kB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

File details

Details for the file speechmarkdown_rust-0.4.4.tar.gz.

File metadata

  • Download URL: speechmarkdown_rust-0.4.4.tar.gz
  • Upload date:
  • Size: 515.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for speechmarkdown_rust-0.4.4.tar.gz
Algorithm Hash digest
SHA256 73b24f5a46c2b8e65ca24bfed4a58b7bc90e6ddb96d904c63002e8efacc867df
MD5 99e06fde259c1430b1241029c7aa21b4
BLAKE2b-256 dfb85b54b2cb35348f5c164114709e696bfe0fdff8d077f28fb6d28d7ffa50f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4.tar.gz:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file speechmarkdown_rust-0.4.4-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.4-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 3a78ac44b2e5b1096b5a5269203035589485b7cd6315ec69c7667edf72cada57
MD5 16706e04d4007d09e2837919ac78fc0c
BLAKE2b-256 b9aea44c4f3c35e0f908b80c6a04d44f659866fab3dc501e8ee9e488d571d9ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4-cp313-cp313-win_amd64.whl:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d69d3985b75c5189226d73287536dea5214e0748b7c43e2b90a0af9a186195f9
MD5 977c00b64a285e48ce52394bc6efcf4e
BLAKE2b-256 1e5e03e70da68ad5ff6a2adca0012cde926114150ae1f29dde7f8a69bc8a2af6

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4ecddecafcbc057c03bfcd03cc476c4a164ab44867c19bff2a7b34186d90d0b4
MD5 49710557a6c4de268da3f9ea7bf7d840
BLAKE2b-256 ff3b3bfba501e1ec89808b11dcd6062d17d37746dd7408b2ad23b788b8c6895b

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file speechmarkdown_rust-0.4.4-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.4-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b7db4c2ad80c8a353fec079c239d4914fef67fee823f935287bf72d550864b2f
MD5 87cf0267b3db426d565914aef81e80f7
BLAKE2b-256 299cf72fddf9a39ebb06cdaff84ed42abb1a82ffdb8cf3bb366b8b42d9f76496

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file speechmarkdown_rust-0.4.4-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.4-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 340c1cb2e69af5babedeb70754540a112fc468ce765b20e4a03a94fb8a69b2e3
MD5 ff2da5c875ad8938c6dfc06844ea8f74
BLAKE2b-256 01e0254cd3e28869b52caf9fec274a7f90e573699dde139aef8bc184b642d72a

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.4-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: publish.yml on AACTools/speechmarkdown-rust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page