UNPKG

@mintlify/common

Version:

Commonly shared code within Mintlify

79 lines (78 loc) 2.86 kB
import { visit } from 'unist-util-visit'; const KEYBOARD_SYMBOL_RANGES = [ [0x2318, 0x2319], // ⌘⌙ (Command/Apple key) [0x2325, 0x2326], // ⌥⌦ (Option/Alt key) [0x2303, 0x2303], // ⌃ (Control key) [0x21e7, 0x21e7], // ⇧ (Shift key) [0x232b, 0x232c], // ⌫⌬ (Backspace/Delete keys) [0x21a9, 0x21a9], // ↩ (Return key) [0x21b5, 0x21b5], // ↵ (Enter key) [0x2380, 0x2380], // ⌀ (Null key) [0x2387, 0x238a], // ⌧⌨〈〉 (Clear, Keyboard, Left/Right angle brackets) [0x21e4, 0x21e5], // ⇤⇥ (Tab keys) ]; const isKeyboardSymbol = (char) => { const code = char.codePointAt(0); if (code === undefined) return false; return KEYBOARD_SYMBOL_RANGES.some((range) => { const [start, end] = range; return start !== undefined && end !== undefined && code >= start && code <= end; }); }; const containsKeyboardSymbols = (text) => { const trimmed = text.trim(); if (trimmed.length === 0) return false; for (const char of trimmed) { if (isKeyboardSymbol(char)) { return true; } } return false; }; const extractTextFromChildren = (children) => { let text = ''; for (const child of children) { if (child && typeof child === 'object' && 'type' in child) { if (child.type === 'text' && 'value' in child) { text += child.value; } else if (child.type === 'element' || child.type === 'mdxJsxTextElement') { if ('children' in child && Array.isArray(child.children)) { text += extractTextFromChildren(child.children); } } } } return text; }; export const rehypeKeyboardSymbols = () => (tree) => { visit(tree, 'element', (node, _, parent) => { if (node.tagName !== 'code') return; if (parent && parent.type === 'element' && parent.tagName === 'pre') return; const text = extractTextFromChildren(node.children); if (containsKeyboardSymbols(text)) { node.properties['data-symbols'] = 'true'; } }); visit(tree, 'mdxJsxTextElement', (node, _, parent) => { if (node.name !== 'code') return; if (parent && parent.type === 'element' && parent.tagName === 'pre') return; const text = extractTextFromChildren(node.children); if (containsKeyboardSymbols(text)) { const existingAttr = node.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'data-symbols'); if (!existingAttr) { node.attributes.push({ type: 'mdxJsxAttribute', name: 'data-symbols', value: 'true', }); } } }); };