Last active
May 31, 2024 09:55
-
-
Save unnoq/15d747dbb45f04b5ceb02b1f73c6666b to your computer and use it in GitHub Desktop.
tiptap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { clone } from 'radash'; | |
import type { JSONContent } from '@tiptap/core'; | |
export function highlightContent(content: JSONContent[], words: string[]) { | |
let i = 0; | |
const result: JSONContent[] = []; | |
while (i < content.length) { | |
const child = content[i]!; | |
if (child.text) { | |
const matches: { pos: number; word: string }[] = []; | |
for (const word of words) { | |
let start = 0; | |
while (start < child.text.length) { | |
const pos = child.text.indexOf(word, start); | |
if (pos < 0) break; | |
start = pos + word.length; | |
matches.push({ | |
pos, | |
word, | |
}); | |
} | |
} | |
const sortedMatches = matches.sort((a, b) => a.pos - b.pos); | |
let currentPos = 0; | |
for (const match of sortedMatches) { | |
if (match.pos > currentPos) { | |
const pre = clone(child); | |
pre.text = child.text.slice(0, match.pos); | |
result.push(pre); | |
} | |
const mid = clone(child); | |
mid.text = match.word; | |
mid.marks = [ | |
...(mid.marks ?? []), | |
{ | |
type: 'highlight', | |
}, | |
]; | |
result.push(mid); | |
currentPos += match.word.length; | |
} | |
if (currentPos < child.text.length - 1) { | |
const suf = clone(child); | |
suf.text = child.text.slice(currentPos); | |
result.push(suf); | |
} | |
} | |
if (child.content) { | |
child.content = highlightContent(child.content, words); | |
result.push(child); | |
} | |
i++; | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment