Shortcode emoji —
:smile:→ 😄 (built-in table, extensible).
Module mdEmoji | Source packages/front/office/md/src/extra/emoji.js | Deps mdNode, mdAstWalker, mdAstTypes | Worker-safe yes
Post-parse AST pass — scans runs of adjacent text nodes and replaces :name: matches from the table with the corresponding emoji character. Preserves surrounding text. Table is extensible/replaceable at install time.
Resolve
import { runtime } from '@awacloud/fw';
import { fw_require, modules, extras } from '@awacloud/md';
runtime.registerAll(fw_require);
runtime.registerAll(modules);
runtime.registerAll(extras);
const md = runtime.resolve('md');
const mdEmoji = runtime.resolve('mdEmoji');
const m = md.createMd().use(mdEmoji);
API
| Export | Signature | Description |
|---|---|---|
name |
string |
'mdEmoji', the key .use() deduplicates on |
install |
(md, opts?) => void |
Patches md.parse and md.renderHtml; opts.table extends the default table |
DEFAULT_EMOJI_TABLE |
Record<string,string> |
Built-in shortcode table (Object.keys(DEFAULT_EMOJI_TABLE) lists it) |
expandEmojiInAst |
(root: Node, table: Record<string,string> | Map<string,string>) => Node |
Standalone helper; replaces :code: in runs of adjacent text nodes and returns root |
Overriding the table
md.use({ name: 'emoji-custom', install(md) {
mdEmoji.install(md, { table: { coffee: '☕', target: '🎯' } });
}});
// or merge with the default:
mdEmoji.install(md, { table: { ...mdEmoji.DEFAULT_EMOJI_TABLE, custom: '🎯' } });
Examples
Case 1 — built-in
const md = runtime.resolve('md');
const mdEmoji = runtime.resolve('mdEmoji');
const m = md.createMd().use(mdEmoji);
m.renderHtml(':rocket: launch :tada:');
// '<p>🚀 launch 🎉</p>\n'
Case 2 — extended table
const m = md.createMd().use({ name: 'e', install(md) {
mdEmoji.install(md, { table: { custom: '🌟' } });
}});
m.renderHtml(':custom:'); // '<p>🌟</p>\n'
Case 3 — a name holding an underscore
const m = md.createMd().use(mdEmoji);
m.renderHtml(':heart_eyes: and *:fox_face:*');
// '<p>😍 and <em>🦊</em></p>\n'
m.renderHtml(':not_a_real_emoji:');
// '<p>:not_a_real_emoji:</p>\n' — unknown names stay verbatim
Notes
- Built-in shortcodes: emotions (smile, grin, wink, …), weather, hands, food, animals, GitHub aliases (+1, -1, tada, rocket, …).
- Unknown shortcode → left as-is (no replacement). The lookup is a
Map, so a shortcode named like anObject.prototypemember (:constructor:,:toString:,:valueOf:,:hasOwnProperty:) is a miss too and stays verbatim in the document. expandEmojiInAst(root, table)accepts a plain object or aMapastableand returnsroot.- Match pattern:
/:[a-z0-9_+\-]+:/g— strict (no Unicode in the shortcode). - Shortcodes are matched over runs of adjacent text nodes, not node by node. The inline parser splits a name holding
_or-into several text nodes (:heart_eyes:arrives as:heart,_,eyes:), so scanning each node alone would miss it; the joined run expands, which keeps the underscore-bearing defaults (heart_eyes,fox_face,white_check_mark, …) working. Emphasis that actually formed is a boundary: in_x_ :fox_face:the<em>is kept and only the text after it is scanned. - Adjacent
:(::name::) are treated as two consecutive shortcodes.
See also
mdWikilinks— another post-walk extramdHighlight- Extending