Typography
Typography provides automatic typographic replacements as you type. It converts ASCII sequences like -- to em dashes, ... to ellipses, -> to arrows, 1/2 to fractions, (c) to copyright symbols, and straight quotes to curly smart quotes. All categories can be enabled or disabled individually.
Not included in StarterKit. Add it separately.
Live Playground
Section titled “Live Playground”Type any of the sequences below and watch them convert automatically. Try -- for an em dash, ... for an ellipsis, -> for an arrow, 1/2 for a fraction, or (c) for a copyright symbol. Press Backspace right after to undo the replacement.
import { Editor, Document, Paragraph, Text, Typography } from '@domternal/core';import '@domternal/theme';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [Document, Paragraph, Text, Typography], content: '<p>Type -- for em dash, ... for ellipsis, or (c) for copyright.</p>',});All replacements happen as you type. Type the trigger sequence and it converts automatically. Press Backspace immediately after to undo the replacement.
import { Component, signal } from '@angular/core';import { DomternalEditorComponent, DomternalToolbarComponent } from '@domternal/angular';import { Editor, Document, Paragraph, Text, Typography } from '@domternal/core';
@Component({ selector: 'app-editor', imports: [DomternalEditorComponent, DomternalToolbarComponent], templateUrl: './editor.html',})export class EditorComponent { editor = signal<Editor | null>(null); extensions = [Document, Paragraph, Text, Typography]; content = '<p>Type -- for em dash, ... for ellipsis, or (c) for copyright.</p>';}@if (editor(); as ed) { <domternal-toolbar [editor]="ed" />}<domternal-editor [extensions]="extensions" [content]="content" (editorCreated)="editor.set($event)"/>import { Domternal } from '@domternal/react';import { Document, Paragraph, Text, Typography } from '@domternal/core';
export default function Editor() { return ( <Domternal extensions={[Document, Paragraph, Text, Typography]} content="<p>Type -- for em dash, ... for ellipsis, or (c) for copyright.</p>" > <Domternal.Toolbar /> <Domternal.Content /> </Domternal> );}import { Editor, Document, Paragraph, Text, Typography } from '@domternal/core';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [ Document, Paragraph, Text, Typography.configure({ smartQuotes: false, // disable smart quotes guillemets: false, // disable guillemets }), ],});Typography is purely input rule based - no theme, toolbar, or commands needed. It works identically in headless and themed setups.
Options
Section titled “Options”All options are booleans that enable or disable a category of replacements. All default to true.
| Option | Type | Default | Description |
|---|---|---|---|
emDash | boolean | true | -- to em dash |
ellipsis | boolean | true | ... to ellipsis |
arrows | boolean | true | <-, ->, => to arrows |
fractions | boolean | true | 1/2, 1/4, 3/4, 1/3, 2/3 to fraction characters |
symbols | boolean | true | (c), (r), (tm), (sm) to symbols (case-insensitive) |
math | boolean | true | +/-, !=, <=, >= to math operators |
guillemets | boolean | true | <<, >> to guillemets |
smartQuotes | boolean | true | Straight quotes to curly quotes |
openDoubleQuote | string | \u201C (") | Opening double quote character |
closeDoubleQuote | string | \u201D (") | Closing double quote character |
openSingleQuote | string | \u2018 (') | Opening single quote character |
closeSingleQuote | string | \u2019 (') | Closing single quote character |
Typography.configure({ emDash: true, ellipsis: true, arrows: false, // disable arrow replacements fractions: true, symbols: true, math: false, // disable math replacements guillemets: false, // disable guillemets smartQuotes: true, openDoubleQuote: '\u00AB', // use « as opening double quote closeDoubleQuote: '\u00BB', // use » as closing double quote})Commands
Section titled “Commands”Typography does not register any commands.
Keyboard shortcuts
Section titled “Keyboard shortcuts”Typography does not register any keyboard shortcuts.
Input rules
Section titled “Input rules”Typography registers up to 22 input rules depending on which categories are enabled. All replacements are undoable with Backspace immediately after triggering.
Em dash (1 rule)
Section titled “Em dash (1 rule)”| Input | Result | Unicode |
|---|---|---|
-- | — | U+2014 |
Ellipsis (1 rule)
Section titled “Ellipsis (1 rule)”| Input | Result | Unicode |
|---|---|---|
... | … | U+2026 |
Arrows (3 rules)
Section titled “Arrows (3 rules)”| Input | Result | Unicode |
|---|---|---|
<- | ← | U+2190 |
-> | → | U+2192 |
=> | ⇒ | U+21D2 |
Fractions (5 rules)
Section titled “Fractions (5 rules)”| Input | Result | Unicode |
|---|---|---|
1/2 | ½ | U+00BD |
1/4 | ¼ | U+00BC |
3/4 | ¾ | U+00BE |
1/3 | ⅓ | U+2153 |
2/3 | ⅔ | U+2154 |
Symbols (4 rules)
Section titled “Symbols (4 rules)”| Input | Result | Unicode |
|---|---|---|
(c) | © | U+00A9 |
(r) | ® | U+00AE |
(tm) | ™ | U+2122 |
(sm) | ℠ | U+2120 |
Symbol replacements are case-insensitive: (C), (R), (TM), and (SM) also work.
Math (4 rules)
Section titled “Math (4 rules)”| Input | Result | Unicode |
|---|---|---|
+/- | ± | U+00B1 |
!= | ≠ | U+2260 |
<= | ≤ | U+2264 |
>= | ≥ | U+2265 |
Guillemets (2 rules)
Section titled “Guillemets (2 rules)”| Input | Result | Unicode |
|---|---|---|
<< | « | U+00AB |
>> | » | U+00BB |
Smart quotes (2 rules)
Section titled “Smart quotes (2 rules)”| Input | Result |
|---|---|
"text" | ”text” (curly double quotes) |
'text' | ’text’ (curly single quotes) |
Smart quotes replace the closing quote character, which triggers the conversion of the entire quoted text. The single quote rule uses a lookbehind to avoid converting apostrophes in contractions (e.g., don't stays as-is).
Toolbar items
Section titled “Toolbar items”Typography does not register any toolbar items.
How it works
Section titled “How it works”Typography uses ProseMirror input rules via the addInputRules() hook. Each rule consists of a regex pattern (with $ anchor to match at cursor) and a replacement.
Simple replacements
Section titled “Simple replacements”Most rules use the textInputRule helper, which creates an InputRule that replaces the matched text with a Unicode character:
textInputRule({ find: /--$/, replace: '\u2014' }) // -- → —The replacement happens in a single ProseMirror transaction: the matched text range is replaced with a text node containing the Unicode character. All simple replacements are undoable with Backspace.
Smart quote replacements
Section titled “Smart quote replacements”Smart quotes use custom InputRule handlers (not textInputRule) because they need match groups to extract the quoted text and wrap it with the configured quote characters:
- Double quotes: regex
/"([^"]+)"$/- matches"text"and replaces with"text"(using configured quote characters) - Single quotes: regex
/(?:^|[\s([{])'([^']+)'$/- matches'text'only when the opening quote follows whitespace or brackets
The single quote pattern includes a prefix check to preserve apostrophes in contractions. If the character before the opening ' is a word character, the rule does not match.
Exports
Section titled “Exports”import { Typography } from '@domternal/core';import type { TypographyOptions } from '@domternal/core';| Export | Type | Description |
|---|---|---|
Typography | Extension | The typography extension |
TypographyOptions | TypeScript type | Options for Typography.configure() |
Source
Section titled “Source”@domternal/core - Typography.ts