~bigbes/lethe

ref: f0f651bfc74681988f56bd610074e1dce6dbee1c lethe/web/src/features/search/highlightSnippet.ts -rw-r--r-- 711 bytes
f0f651bf — Eugene Blikh feat: add search data layer — adapter, highlight helper, hook, and tests 23 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react'

const MARKER_RUNES = /\x02|\x03/g

/**
 * Splits a snippet string on \x02/\x03 marker runes and interleaves plain text
 * with `<mark>` elements for matched segments.
 *
 * Respects IV2 — no dangerouslySetInnerHTML, marker-rune split with React text
 * nodes only, safe against XSS.
 */
export function highlightSnippet(snippet: string): (string | React.JSX.Element)[] {
  const parts = snippet.split(MARKER_RUNES)
  const out: (string | React.JSX.Element)[] = []
  let inMatch = false
  for (const p of parts) {
    if (p === '') continue
    if (inMatch) out.push(React.createElement('mark', { key: out.length }, p))
    else out.push(p)
    inMatch = !inMatch
  }
  return out
}