The installation may currently fail. We recommend copying the code below and creating the extension manually in Eidos.
By: Mayne
Show the document's table of contents
import React, { useEffect, useState } from "react"
export default function (props) {
const [headings, setHeadings] = useState([])
const currentNode = props?.__context__?.currentNode
useEffect(() => {
if (!currentNode) {
return
}
eidos.currentSpace.getDocMarkdown(currentNode.id).then(res => {
const lines = res.split('\n')
const extractedHeadings = []
lines.forEach((line, index) => {
const match = line.match(/^(#{1,6})\s+(.+)$/)
if (match) {
const level = match[1].length
const text = match[2].trim()
const id = text.toLowerCase().replace(/[^\w\u4e00-\u9fa5]+/g, '-')
extractedHeadings.push({
level,
text,
id,
lineNumber: index + 1
})
}
})
setHeadings(extractedHeadings)
})
}, [currentNode])
if (currentNode?.type != 'doc') {
return (
<div className="flex items-center justify-center h-full text-sm text-muted-foreground">
<div className="text-center">
<p className="mb-2">📄</p>
<p>This module only supports document nodes</p>
<p className="text-xs mt-1">Please switch to a document node to view the table of contents</p>
</div>
</div>
)
}
return (
<div className="space-y-1">
{headings.map((heading) => (
<div
key={heading.id}
className="cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 rounded px-2 py-1 text-sm"
style={{ paddingLeft: `${(heading.level - 1) * 12}px` }}
onClick={() => {
const element = document.getElementById(heading.id)
eidos.currentSpace.navigate(`/${currentNode.id}#${heading.text}`)
if (element) {
element.scrollIntoView({ behavior: 'smooth' })
}
}}
>
{heading.text}
</div>
))}
</div>
)
}