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.7.tar.gz (515.4 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.7-cp313-cp313-win_amd64.whl (266.9 kB view details)

Uploaded CPython 3.13Windows x86-64

speechmarkdown_rust-0.4.7-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.7-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.7-cp313-cp313-macosx_11_0_arm64.whl (357.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

speechmarkdown_rust-0.4.7-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.7.tar.gz.

File metadata

  • Download URL: speechmarkdown_rust-0.4.7.tar.gz
  • Upload date:
  • Size: 515.4 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.7.tar.gz
Algorithm Hash digest
SHA256 f7d058581da597189433909f55bc45e187fc0c0075e96504817b5b3b97acebb8
MD5 f1d5197c8d422dd3a1b62df3d033e6c0
BLAKE2b-256 141eb22681dde920982289f2442d6b668b017881801c8457cf2a7d50e2b27ff0

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7.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.7-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.7-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 8c027e0fbc362049db8d107b770ed046d28431883bec90bc8dd44ebd543ee573
MD5 09234086d85a29ee691950392dd7d6a8
BLAKE2b-256 45bd48d0579f7f5b2a70d712ecb682ff0162ab670e6d1f912e4cd8ed2e9b711e

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7-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.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3e931f02eaa0daa1406ec222f2b1f3d2637c50b770055f5851e4050487f31365
MD5 9465f5b682f1d3e8c8bdde30198853c0
BLAKE2b-256 9854d8f7e7c3d2832e856e9004acb0a9a5a07902c712290f06454eae54fd39fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7-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.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1aa1eb252b9ecec36d2f2513836d9cfc45ddae1bdcb10072271b317e7b669206
MD5 8c16c521bc9e926842ac69a7426f0b14
BLAKE2b-256 0ecd30d1041622f933f7f90ce6a18fb27b6fce59f4e6f2a8f9ad2d54a87adb9f

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7-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.7-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.7-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa1dc90d3b27224369e64cf564333d09059520b1bb18ffe154530937c8c1844b
MD5 00031f2c0896d1855c52781fa4be8e41
BLAKE2b-256 ced6d1fcf3c790e1d1290a0a6d31aae641714c86fd6edc2d3f698ef72a9550b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7-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.7-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for speechmarkdown_rust-0.4.7-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5c577d123ee0352ccfb431e137b27cf3820a02db4053b67828ab9120c4fbea04
MD5 774499b0879690c018c2468b1aaaff33
BLAKE2b-256 d8157d91dfff5bbf9516cbd53b0fd14fa67c6234191e95fbc0797ac49d7ea69f

See more details on using hashes here.

Provenance

The following attestation bundles were made for speechmarkdown_rust-0.4.7-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