fix: transcludes and relative paths
This commit is contained in:
		@@ -3,9 +3,10 @@ import { QuartzComponent, QuartzComponentProps } from "./types"
 | 
			
		||||
import HeaderConstructor from "./Header"
 | 
			
		||||
import BodyConstructor from "./Body"
 | 
			
		||||
import { JSResourceToScriptElement, StaticResources } from "../util/resources"
 | 
			
		||||
import { FullSlug, RelativeURL, joinSegments } from "../util/path"
 | 
			
		||||
import { FullSlug, RelativeURL, joinSegments, normalizeHastElement } from "../util/path"
 | 
			
		||||
import { visit } from "unist-util-visit"
 | 
			
		||||
import { Root, Element, ElementContent } from "hast"
 | 
			
		||||
import { QuartzPluginData } from "../plugins/vfile"
 | 
			
		||||
 | 
			
		||||
interface RenderComponents {
 | 
			
		||||
  head: QuartzComponent
 | 
			
		||||
@@ -49,6 +50,18 @@ export function pageResources(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let pageIndex: Map<FullSlug, QuartzPluginData> | undefined = undefined
 | 
			
		||||
function getOrComputeFileIndex(allFiles: QuartzPluginData[]): Map<FullSlug, QuartzPluginData> {
 | 
			
		||||
  if (!pageIndex) {
 | 
			
		||||
    pageIndex = new Map()
 | 
			
		||||
    for (const file of allFiles) {
 | 
			
		||||
      pageIndex.set(file.slug!, file)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return pageIndex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function renderPage(
 | 
			
		||||
  slug: FullSlug,
 | 
			
		||||
  componentData: QuartzComponentProps,
 | 
			
		||||
@@ -62,17 +75,15 @@ export function renderPage(
 | 
			
		||||
      if (classNames.includes("transclude")) {
 | 
			
		||||
        const inner = node.children[0] as Element
 | 
			
		||||
        const transcludeTarget = inner.properties?.["data-slug"] as FullSlug
 | 
			
		||||
 | 
			
		||||
        // TODO: avoid this expensive find operation and construct an index ahead of time
 | 
			
		||||
        const page = componentData.allFiles.find((f) => f.slug === transcludeTarget)
 | 
			
		||||
        const page = getOrComputeFileIndex(componentData.allFiles).get(transcludeTarget)
 | 
			
		||||
        if (!page) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let blockRef = node.properties?.dataBlock as string | undefined
 | 
			
		||||
        if (blockRef?.startsWith("^")) {
 | 
			
		||||
        if (blockRef?.startsWith("#^")) {
 | 
			
		||||
          // block transclude
 | 
			
		||||
          blockRef = blockRef.slice(1)
 | 
			
		||||
          blockRef = blockRef.slice("#^".length)
 | 
			
		||||
          let blockNode = page.blocks?.[blockRef]
 | 
			
		||||
          if (blockNode) {
 | 
			
		||||
            if (blockNode.tagName === "li") {
 | 
			
		||||
@@ -84,7 +95,7 @@ export function renderPage(
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            node.children = [
 | 
			
		||||
              blockNode,
 | 
			
		||||
              normalizeHastElement(blockNode, slug, transcludeTarget),
 | 
			
		||||
              {
 | 
			
		||||
                type: "element",
 | 
			
		||||
                tagName: "a",
 | 
			
		||||
@@ -117,7 +128,9 @@ export function renderPage(
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          node.children = [
 | 
			
		||||
            ...(page.htmlAst.children.slice(startIdx, endIdx) as ElementContent[]),
 | 
			
		||||
            ...(page.htmlAst.children.slice(startIdx, endIdx) as ElementContent[]).map((child) =>
 | 
			
		||||
              normalizeHastElement(child as Element, slug, transcludeTarget),
 | 
			
		||||
            ),
 | 
			
		||||
            {
 | 
			
		||||
              type: "element",
 | 
			
		||||
              tagName: "a",
 | 
			
		||||
@@ -135,7 +148,9 @@ export function renderPage(
 | 
			
		||||
                { type: "text", value: page.frontmatter?.title ?? `Transclude of ${page.slug}` },
 | 
			
		||||
              ],
 | 
			
		||||
            },
 | 
			
		||||
            ...(page.htmlAst.children as ElementContent[]),
 | 
			
		||||
            ...(page.htmlAst.children as ElementContent[]).map((child) =>
 | 
			
		||||
              normalizeHastElement(child as Element, slug, transcludeTarget),
 | 
			
		||||
            ),
 | 
			
		||||
            {
 | 
			
		||||
              type: "element",
 | 
			
		||||
              tagName: "a",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user