mirror of
https://github.com/zadam/trilium.git
synced 2025-12-22 07:14:24 +01:00
chore(toc): reintroduce hierarchy
This commit is contained in:
parent
60342c0f6f
commit
87a98201b4
@ -2,15 +2,22 @@ import { CKTextEditor, ModelElement } from "@triliumnext/ckeditor5";
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor, useTriliumEvent } from "../react/hooks";
|
import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor } from "../react/hooks";
|
||||||
import RightPanelWidget from "./RightPanelWidget";
|
import RightPanelWidget from "./RightPanelWidget";
|
||||||
|
|
||||||
interface CKHeading {
|
interface RawHeading {
|
||||||
level: number;
|
level: number;
|
||||||
text: string;
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CKHeading extends RawHeading {
|
||||||
element: ModelElement;
|
element: ModelElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface HeadingsWithNesting extends RawHeading {
|
||||||
|
children: HeadingsWithNesting[];
|
||||||
|
}
|
||||||
|
|
||||||
export default function TableOfContents() {
|
export default function TableOfContents() {
|
||||||
const { note, noteContext } = useActiveNoteContext();
|
const { note, noteContext } = useActiveNoteContext();
|
||||||
const noteType = useNoteProperty(note, "type");
|
const noteType = useNoteProperty(note, "type");
|
||||||
@ -56,16 +63,48 @@ function EditableTextTableOfContents() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AbstractTableOfContents({ headings }: {
|
function AbstractTableOfContents({ headings }: {
|
||||||
headings: {
|
headings: RawHeading[];
|
||||||
level: number;
|
|
||||||
text: string;
|
|
||||||
}[];
|
|
||||||
}) {
|
}) {
|
||||||
return headings.map(heading => (
|
const nestedHeadings = buildHeadingTree(headings);
|
||||||
<li>{heading.text}</li>
|
return nestedHeadings.map(heading => <TableOfContentsHeading heading={heading} />);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function TableOfContentsHeading({ heading }: { heading: HeadingsWithNesting }) {
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<span className="title">{heading.text}</span>
|
||||||
|
{heading.children && (
|
||||||
|
<ul>
|
||||||
|
{heading.children.map(heading => <TableOfContentsHeading heading={heading} />)}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildHeadingTree(headings: RawHeading[]): HeadingsWithNesting[] {
|
||||||
|
const root: HeadingsWithNesting = { level: 0, text: "", children: [] };
|
||||||
|
const stack: HeadingsWithNesting[] = [root];
|
||||||
|
|
||||||
|
for (const h of headings) {
|
||||||
|
const node: HeadingsWithNesting = { ...h, children: [] };
|
||||||
|
|
||||||
|
// Pop until we find a parent with lower level
|
||||||
|
while (stack.length > 1 && stack[stack.length - 1].level >= h.level) {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach to current parent
|
||||||
|
stack[stack.length - 1].children.push(node);
|
||||||
|
|
||||||
|
// This node becomes the new parent
|
||||||
|
stack.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root.children;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function extractTocFromTextEditor(editor: CKTextEditor) {
|
function extractTocFromTextEditor(editor: CKTextEditor) {
|
||||||
const headings: CKHeading[] = [];
|
const headings: CKHeading[] = [];
|
||||||
|
|
||||||
@ -85,3 +124,4 @@ function extractTocFromTextEditor(editor: CKTextEditor) {
|
|||||||
|
|
||||||
return headings;
|
return headings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user