UNPKG

@tanstack/highlight

Version:

Tiny class-based syntax highlighting for documentation.

31 lines (30 loc) • 1.71 kB
import { simpleLanguage, wordCategories } from './simple-language.js'; export { simpleLanguage as simpleWordLanguage, simpleLanguage as nativeCompiledWordLanguage } from './simple-language.js'; export function canCombineWords(options) { const categories = wordCategories(options).filter((entry) => Boolean(entry[1])); const terms = categories.flatMap(([, words]) => words.split(/\s+/)); const characters = options.wordCharacters || '\\w$'; const wholeWord = new RegExp(`^[${characters}]+$`, options.insensitive ? 'i' : ''); return categories.length > 1 && terms.every(word => word.length && wholeWord.test(word) && (!options.insensitive || /^[\x00-\x7f]+$/.test(word))); } export function compiledWordLanguage(options) { return simpleLanguage(options, options.insensitive ? undefined : mapWordPatterns, true); } function mapWordPatterns(options, flags, wordCharacters) { // These definitions satisfy canCombineWords, each match is a complete word. const known = new Set(); const classes = new Map(); for (const [className, words] of wordCategories(options)) { if (words) for (const word of words.split(/\s+/)) { if (known.has(word)) continue; known.add(word); if (className !== 'keyword') classes.set(word, className); } } // The regex admits only known terms, missing class entries are keywords. const regex = new RegExp(`(?<![${wordCharacters}])(?:${[...known].map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})(?![${wordCharacters}])`, flags); return [[regex, (match) => classes.get(match[0]) || 'keyword']]; }