Browse Source

Add more supporting functions for ToC component

master
buttercat1791 10 months ago
parent
commit
ee85059dee
  1. 72
      src/lib/components/TableOfContents.svelte

72
src/lib/components/TableOfContents.svelte

@ -6,11 +6,75 @@ @@ -6,11 +6,75 @@
let { rootAddress } = $props<{ rootAddress: string }>();
let publicationTree = getContext('publicationTree') as PublicationTree;
let tocAddresses = $state<Map<string, TocEntry>>(new Map());
let tocRoot = $state<TocEntry | null>(null);
// Determine the event kind.
// If index, use the publication tree to build the table of contents.
// If single event, build the table of contents from the rendered HTML.
// Each rendered `<h>` should receive an entry in the ToC.
function normalizeHashPath(title: string): string {
// TODO: Confirm this uses good normalization logic to produce unique hrefs within the page.
return title.toLowerCase().replace(/ /g, '-');
}
async function insertIntoTocFromPublicationTree(address: string): Promise<void> {
const targetEvent = await publicationTree.getEvent(address);
if (!targetEvent) {
console.warn(`[ToC] Event ${address} not found.`);
// TODO: Determine how to handle this case in the UI.
return;
}
const hierarchyEvents = await publicationTree.getHierarchy(address);
if (hierarchyEvents.length === 0) {
// This means we are at root.
return;
}
// Michael J 05 May 2025 - In this loop, we assume that the parent of the current event has
// already been populated into the ToC. As long as the root is set when the component is
// initialized, this code will work fine.
let currentParentTocNode: TocEntry | null = tocRoot;
for (let i = 0; i < hierarchyEvents.length; i++) {
const currentEvent = hierarchyEvents[i];
const currentAddress = currentEvent.tagAddress();
if (tocAddresses.has(currentAddress)) {
continue;
}
const currentEventChildAddresses = await publicationTree.getChildAddresses(currentAddress);
for (let address of currentEventChildAddresses) {
if (address === null) {
continue;
}
const childEvent = await publicationTree.getEvent(address);
if (!childEvent) {
console.warn(`[ToC] Event ${address} not found.`);
continue;
}
currentParentTocNode!.children ??= [];
const childTocEntry: TocEntry = {
title: childEvent.getMatchingTags('title')[0][1],
href: `${page.url.pathname}#${normalizeHashPath(childEvent.getMatchingTags('title')[0][1])}`,
expanded: false,
children: null,
};
currentParentTocNode!.children.push(childTocEntry);
tocAddresses.set(address, childTocEntry);
}
currentParentTocNode = tocAddresses.get(currentAddress)!;
}
}
function buildTocFromDocument(parentElement: HTMLElement): void {
const entries: TocEntry[] = [];
const currentPathname = page.url.pathname;
@ -30,8 +94,8 @@ @@ -30,8 +94,8 @@
const tocEntry: TocEntry = {
title,
href,
expanded: false, // Default to not expanded; can be changed as needed.
children: null, // These are leaf entries from a flat scan of headers.
expanded: false,
children: null,
};
entries.push(tocEntry);
}
@ -39,10 +103,6 @@ @@ -39,10 +103,6 @@
// TODO: Update ToC state within the component.
}
let toc = $state<TocEntry[]>([]);
const publicationTree = getContext('publicationTree') as PublicationTree;
</script>
<!-- TODO: Add contents. -->

Loading…
Cancel
Save