Skip to content

Commit

Permalink
TOC entries have links
Browse files Browse the repository at this point in the history
  • Loading branch information
irskep committed Aug 21, 2024
1 parent d32bc1d commit 1bdaab5
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 33 deletions.
16 changes: 4 additions & 12 deletions examples/full/docs/second.djot
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
{#second-doc-heading}
# Second
# second doc heading

[Linking to myself](#second-doc-heading)
Content

[Linking to myself again](second#second-doc-heading)
## Level 2

- List 1

- List 1.1
- List 1.2

- List 2

- List 2.1
Content
31 changes: 15 additions & 16 deletions src/plugins/tableOfContentsPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { BulletList, parse, renderHTML } from "@djot/djot";
import { Doc, parse, renderHTML } from "@djot/djot";
import { DjockeyDoc } from "../types";
import { TableOfContentsPlugin, TOCEntry } from "./tableOfContentsPlugin";
import { TableOfContentsPlugin } from "./tableOfContentsPlugin";

test("Generates TOCEntry tree", () => {
const doc: DjockeyDoc = {
djotDoc: parse(`
# Heading 1
djotDoc: parse(
`# Heading 1
## Heading 1.1
# Heading 2
### Heading 2.2
`),
`,
{ sourcePositions: true }
),
title: "Test doc",
originalExtension: ".djot",
absolutePath: "Test Doc.djot",
Expand All @@ -23,28 +28,22 @@ test("Generates TOCEntry tree", () => {
plg.onPass_read(doc);
plg.onPass_write(doc);

const html = renderHTML({
tag: "doc",
references: {},
autoReferences: {},
footnotes: {},
children: [doc.data.toc as BulletList],
});
const html = renderHTML(doc.data.tocDoc as Doc);

expect(html).toEqual(`<ul>
<li>
Heading 1
<a href="#Heading-1">Heading 1</a>
<ul>
<li>
Heading 1.1
<a href="#Heading-1-1">Heading 1.1</a>
</li>
</ul>
</li>
<li>
Heading 2
<a href="#Heading-2">Heading 2</a>
<ul>
<li>
Heading 2.2
<a href="#Heading-2-2">Heading 2.2</a>
</li>
</ul>
</li>
Expand Down
46 changes: 41 additions & 5 deletions src/plugins/tableOfContentsPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { BulletList, Heading, Inline, ListItem } from "@djot/djot";
import {
BulletList,
Doc,
Heading,
Inline,
Link,
ListItem,
Section,
} from "@djot/djot";
import { applyFilter } from "../engine/djotFiltersPlus";
import { DjockeyDoc, DjockeyPlugin } from "../types";

Expand All @@ -20,13 +28,28 @@ export class TableOfContentsPlugin implements DjockeyPlugin {
this.topLevelTOCEntries = new Array<TOCEntry>();

const tocStack = new Array<TOCEntry>();
const referenceStack = new Array<string>();

// THIS IS WRONG. Go by heading levels, not div nesting.
applyFilter(doc.djotDoc, () => ({
// IDs live on sections, not headings, so keep a stack of IDs.
section: {
enter: (node: Section) => {
const attrs = { ...node.autoAttributes, ...node.attributes };
if (attrs.id) {
referenceStack.push(attrs.id);
}
},
exit: (node: Section) => {
const attrs = { ...node.autoAttributes, ...node.attributes };
if (attrs.id) {
referenceStack.pop();
}
},
},
heading: (node: Heading) => {
const entry: TOCEntry = {
node,
id: { ...node.autoAttributes, ...node.attributes }.id!,
id: lastOf(referenceStack)!,
children: [],
};

Expand All @@ -53,21 +76,34 @@ export class TableOfContentsPlugin implements DjockeyPlugin {
}

onPass_write(doc: DjockeyDoc) {
doc.data.toc = renderTOCArray(this.topLevelTOCEntries);
const tocDoc: Doc = {
tag: "doc",
references: {},
autoReferences: {},
footnotes: {},
children: [renderTOCArray(this.topLevelTOCEntries)],
};
doc.data.tocDoc = tocDoc;
}
}

const renderTOCArray: (arr: TOCEntry[]) => BulletList = (arr) => {
const tocEntryToListItem = (entry: TOCEntry) => {
const entryLink: Link = {
tag: "link",
children: structuredClone(entry.node.children),
destination: `#${entry.id}`,
};
const entryChildren: BulletList[] = entry.children.length
? [renderTOCArray(entry.children)]
: [];

const result: ListItem = {
tag: "list_item",
children: [
{
tag: "para",
children: entry.node.children,
children: [entryLink],
},
...entryChildren,
],
Expand Down

0 comments on commit 1bdaab5

Please sign in to comment.