Jacky Zhao
2024-01-01 b33f13ccaf4ec14a94ee0ee467dda04cf4981d00
quartz/plugins/transformers/toc.ts
@@ -3,17 +3,20 @@
import { visit } from "unist-util-visit"
import { toString } from "mdast-util-to-string"
import Slugger from "github-slugger"
import { wikilinkRegex } from "./ofm"
export interface Options {
  maxDepth: 1 | 2 | 3 | 4 | 5 | 6
  minEntries: 1
  showByDefault: boolean
  collapseByDefault: boolean
}
const defaultOptions: Options = {
  maxDepth: 3,
  minEntries: 1,
  showByDefault: true,
  collapseByDefault: false,
}
interface TocEntry {
@@ -22,6 +25,7 @@
  slug: string // this is just the anchor (#some-slug), not the canonical slug
}
const regexMdLinks = new RegExp(/\[([^\[]+)\](\(.*\))/, "g")
export const TableOfContents: QuartzTransformerPlugin<Partial<Options> | undefined> = (
  userOpts,
) => {
@@ -39,7 +43,16 @@
              let highestDepth: number = opts.maxDepth
              visit(tree, "heading", (node) => {
                if (node.depth <= opts.maxDepth) {
                  const text = toString(node)
                  let text = toString(node)
                  // strip link formatting from toc entries
                  text = text.replace(wikilinkRegex, (_, rawFp, __, rawAlias) => {
                    const fp = rawFp?.trim() ?? ""
                    const alias = rawAlias?.slice(1).trim()
                    return alias ?? fp
                  })
                  text = text.replace(regexMdLinks, "$1")
                  highestDepth = Math.min(highestDepth, node.depth)
                  toc.push({
                    depth: node.depth,
@@ -54,6 +67,7 @@
                  ...entry,
                  depth: entry.depth - highestDepth,
                }))
                file.data.collapseToc = opts.collapseByDefault
              }
            }
          }
@@ -66,5 +80,6 @@
declare module "vfile" {
  interface DataMap {
    toc: TocEntry[]
    collapseToc: boolean
  }
}