みてるぞ 1 week ago
parent
commit
419f46dfda
1 changed files with 41 additions and 26 deletions
  1. +41
    -26
      frontend/src/components/WikiBody.tsx

+ 41
- 26
frontend/src/components/WikiBody.tsx View File

@@ -17,21 +17,8 @@ export default ({ title, body }: Props) => {
const [realBody, setRealBody] = useState<string> ('')

useEffect (() => {
const matchIndices = (target: string, keyword: string) => {
const indices: number[] = []
let pos = 0

while (true)
{
const idx = target.indexOf (keyword, pos)
if (idx < 0)
break
indices.push (idx)
pos = idx + keyword.length
}

return indices
}
if (!(body))
return

void (async () => {
try
@@ -45,19 +32,47 @@ export default ({ title, body }: Props) => {
setPageNames ([])
}
}) ()
}, [])

useEffect (() => {
if (!(body))
return

const matchIndices = (target: string, keyword: string) => {
const indices: number[] = []
let pos = 0
let idx
while ((idx = target.indexOf (keyword, pos)) >= 0)
{
indices.push (idx)
pos = idx + keyword.length
}

const linkIndices: [string, [number, number]][] = []
pageNames.forEach (name => {
matchIndices (body ?? '', name).map (idx => [idx, idx + name.length]).forEach (([start, end]) => {
if (linkIndices.every (([, [st, ed]]) => (start < st || ed <= start) && (end < st || ed <= end)))
linkIndices.push ([name, [start, end]])
return indices
}

const linkIndices = (text: string, names: string[]): [string, [number, number]][] => {
const result: [string, [number, number]][] = []

names.forEach (name => {
matchIndices (text, name).forEach (idx => {
const start = idx
const end = idx + name.length
const overlaps = result.some (([, [st, ed]]) => start < ed && end > st)
if (!(overlaps))
result.push ([name, [start, end]])
})
})
})
linkIndices.sort (([, [a]], [, [b]]) => b - a)
linkIndices.forEach (([name, [start, end]]) => {
setRealBody (prev => `${ prev.slice (0, start) }[${ name }](/wiki/${ encodeURIComponent (name) })${ prev.slice (end) }`)
})
}, [])

return result.sort (([, [a]], [, [b]]) => b - a)
}

setRealBody (
linkIndices (body, pageNames).reduce ((acc, [name, [start, end]]) => (
acc.slice (0, start)
+ `[${ name }](/wiki/${ encodeURIComponent (name) })`
+ acc.slice (end)), body))
}, [pageNames])

return (
<ReactMarkdown components={{ a: (


Loading…
Cancel
Save