Supertonic 3 Expression Tags: How to Use Text Shortcuts in Neural TTS

Supertonic 3 automatically expands three expression tags—@ to "at", e.g., to "for example,", and i.e., to "that is,"—during preprocessing before sending text to the neural TTS model.

Supertonic 3 by supertone-inc/supertonic is a neural text-to-speech engine that normalizes common textual shortcuts before tokenization. The library's UnicodeProcessor handles expression tags automatically across all language bindings, converting shorthand symbols into spoken words to improve pronunciation accuracy.

Available Expression Tags in Supertonic 3

The UnicodeProcessor (implemented in every language binding) recognizes three expression tags and expands them before the text reaches the neural model:

  • @ → expands to at (handles email addresses and social handles)
  • e.g., → expands to for example, (Latin abbreviation for exempli gratia)
  • i.e., → expands to that is, (Latin abbreviation for id est)

These mappings are defined in the expr_replacements dictionary (Python) or exprReplacements object (JavaScript) within each language binding's helper file.

How Expression Tags Work Internally

The expansion happens automatically during the preprocessing phase in the UnicodeProcessor class.

The Preprocessing Pipeline

According to the source code in py/helper.py (lines 69-77) and web/helper.js (lines 72-78), the processor executes these steps in order:

  1. Unicode Normalisation – Applies NFKD normalization to decompose characters.
  2. Emoji and Punctuation Cleaning – Strips Unicode emoji ranges and replaces various punctuation marks.
  3. Expression Tag Replacement – Substitutes the three entries in expr_replacements (or exprReplacements) with their expanded forms.
  4. Language Wrapping – Wraps the cleaned string in <lang> tags (e.g., <en>text</en>), where lang is one of the values in AVAILABLE_LANGS.

The language tags themselves are not expression tags; they are required model input format markers added after expression normalization (see the line text = f"<{lang}>" + text + f"</{lang}>" in the Python helper).

Using Expression Tags in Your Code

Because replacements are performed automatically by the UnicodeProcessor, you do not need manual preprocessing. Simply include the tags in your raw input text.

JavaScript (Web) Implementation

In web/helper.js, the UnicodeProcessor handles the expansion automatically:

import { loadTextToSpeech, loadVoiceStyle } from './helper.js';

// Load model assets (ONNX files, indexer, configurations)
const { textToSpeech } = await loadTextToSpeech('/onnx_dir');

// Load a voice style (optional)
const style = await loadVoiceStyle(['/styles/style1.json']);

// Input text containing expression tags
const raw = "Contact us @ support@example.com. e.g., we can help you. i.e., you will get a response.";

// Invoke TTS—the processor replaces tags automatically
const { wav } = await textToSpeech.call(
  raw,          // text with expression tags
  'en',         // language code
  style,        // voice style
  50            // total diffusion steps
);

// wav contains the audio waveform ready for playback

Python Implementation

The Python implementation in py/helper.py provides identical functionality:

from py.helper import load_text_to_speech, load_voice_style

# Load model assets

tts = load_text_to_speech('/path/to/onnx')

# Load a voice style (optional)

style = load_voice_style(['/path/to/style.json'])

# Input text with expression tags

raw = "Send an email @ support@example.com. e.g., you can ask questions. i.e., we reply quickly."

# Synthesize speech—expression tags expand internally

wav, duration = tts(raw, 'en', style, total_step=50)

# wav is a NumPy array of PCM samples

Other Language Bindings

All Supertonic 3 language bindings expose a UnicodeProcessor (or equivalent) that runs the same replacement logic:

In each implementation, supply the raw string containing @, e.g.,, or i.e., directly to the TTS function. The processor substitutes these automatically before handing text to the model.

Expression Tag Implementation Files

The replacement logic is defined in these canonical source files across the supertone-inc/supertonic repository:

These files serve as the canonical source of truth for expression tag behavior across the entire Supertonic 3 codebase.

Summary

  • Supertonic 3 supports three expression tags: @, e.g.,, and i.e.,
  • The UnicodeProcessor automatically expands these to at, for example,, and that is, respectively
  • Replacement occurs during preprocessing in all language bindings (Python, JavaScript, Rust, Go, Java, C++, C#)
  • No manual intervention required—simply include tags in raw input text
  • Language wrapping tags (<en>, <ja>, etc.) are separate from expression tags and added after normalization

Frequently Asked Questions

Do I need to manually preprocess text before sending it to Supertonic 3?

No. The UnicodeProcessor class handles expression tag expansion automatically during the preprocessing pipeline. Simply include @, e.g.,, or i.e., in your input string, and the library will replace them before tokenization.

Are language tags like <en> considered expression tags?

No. Language tags such as <en> and </en> are required model input format markers that wrap the entire text after expression normalization. They are distinct from expression tags and are added automatically by the processor.

Can I add custom expression tags to Supertonic 3?

The current implementation in web/helper.js and py/helper.py hardcodes only three expression tags (@, e.g.,, i.e.,) in the expr_replacements (or exprReplacements) dictionary. To add custom tags, you would need to modify the source code in the respective language binding.

Do all Supertonic 3 language bindings support the same expression tags?

Yes. All official language bindings—Python, JavaScript (Web), Rust, Go, Java, C++, and C#—implement identical UnicodeProcessor logic with the same three expression tag mappings, ensuring consistent behavior across platforms.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →