Skip to content

Instantly share code, notes, and snippets.

@zbeyens
Last active March 29, 2024 15:36
Show Gist options
  • Save zbeyens/4e909b340f9b0c44c99d39d3f4bdb4af to your computer and use it in GitHub Desktop.
Save zbeyens/4e909b340f9b0c44c99d39d3f4bdb4af to your computer and use it in GitHub Desktop.
export const searchRange = (
editor: PlateEditor,
search: string | [string, string],
{
match,
// from,
}: {
match?: GetNodeEntriesOptions['match']
from?: Point
} = {},
): Range | null => {
if (!Array.isArray(search) ? !search.length : !search[0].length || !search[1].length) return null
const [startSearch, endSearch] = Array.isArray(search) ? search.map(s => s.toLowerCase()) : [search.toLowerCase(), '']
const entries = Array.from(
getNodeEntries<MyParagraphElement>(editor, {
at: [],
match: match
? match
: (_, p) => {
return p.length === 1
},
}),
)
for (const [node, path] of entries) {
// if (from && Path.isBefore(path, from.path)) continue
const combinedText = getNodeString(node).toLowerCase()
let searchIndex = combinedText.indexOf(startSearch)
while (searchIndex !== -1) {
// if (from && Path.equals(path, from.path) && searchIndex < from.offset) {
// searchIndex = combinedText.indexOf(startSearch, searchIndex + 1)
// continue
// }
let globalOffset = 0
let startPath: Path | undefined,
endPath: Path | undefined,
anchorOffset: number | undefined,
focusOffset: number | undefined
traverseTextNodes(
node.children,
(childNode, childPath) => {
if (isVoid(editor, childNode)) return
const textLength = (isText(childNode) && childNode.text.length) || 0
const newGlobalOffset = globalOffset + textLength
if (startPath === undefined && newGlobalOffset > searchIndex) {
startPath = childPath
anchorOffset = searchIndex - globalOffset
}
if (startPath !== undefined && newGlobalOffset >= searchIndex + startSearch.length) {
const endSearchIndex = combinedText.indexOf(endSearch, searchIndex + startSearch.length)
if (endSearchIndex !== -1) {
endPath = childPath
focusOffset = endSearchIndex - globalOffset + endSearch.length
return true // Found the complete range, stop traversing
}
}
globalOffset = newGlobalOffset
},
path,
)
if (startPath && endPath) {
return {
anchor: { path: startPath, offset: anchorOffset! },
focus: { path: endPath, offset: focusOffset! },
}
}
searchIndex = combinedText.indexOf(startSearch, searchIndex + 1)
}
}
return null
}
// usage
while (true) {
const range = searchRange(editor, ['{{', '}}'])
if (!range) return
if (range) {
let jsonString = getEditorString(editor, range).slice(1, -1)
editor.selection = range
deleteText(editor, { unit: 'character', reverse: true })
// ...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment