From 2de48b267a8f2d6ed0461d2febc266559c2d8d47 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 14 Nov 2023 20:01:48 -0800 Subject: [PATCH 001/213] fix: set htmlAst after walking tree in ofm (closes #589) --- quartz/plugins/transformers/ofm.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 50c4d5c6..a8399d01 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -436,7 +436,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin const blockTagTypes = new Set(["blockquote"]) return (tree, file) => { file.data.blocks = {} - file.data.htmlAst = tree visit(tree, "element", (node, index, parent) => { if (blockTagTypes.has(node.tagName)) { @@ -478,6 +477,8 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin } } }) + + file.data.htmlAst = tree } }) } From 8fc7b9f4c68bb8c41a156e92cfbddf3144678dcc Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 09:43:30 -0800 Subject: [PATCH 002/213] feat: deref symlinks when copying static assets (closes #588) --- quartz/plugins/emitters/static.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quartz/plugins/emitters/static.ts b/quartz/plugins/emitters/static.ts index 6f5d19d4..f0118e2e 100644 --- a/quartz/plugins/emitters/static.ts +++ b/quartz/plugins/emitters/static.ts @@ -11,7 +11,10 @@ export const Static: QuartzEmitterPlugin = () => ({ async emit({ argv, cfg }, _content, _resources, _emit): Promise { const staticPath = joinSegments(QUARTZ, "static") const fps = await glob("**", staticPath, cfg.configuration.ignorePatterns) - await fs.promises.cp(staticPath, joinSegments(argv.output, "static"), { recursive: true }) + await fs.promises.cp(staticPath, joinSegments(argv.output, "static"), { + recursive: true, + dereference: true, + }) return fps.map((fp) => joinSegments(argv.output, "static", fp)) as FilePath[] }, }) From 06426c8f7e87e9476e3ede9f9d15771db601e3e6 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 19:27:54 -0800 Subject: [PATCH 003/213] feat: support repeated anchor tag (closes #592) --- quartz/plugins/transformers/ofm.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index a8399d01..9ae99228 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -110,7 +110,7 @@ function canonicalizeCallout(calloutName: string): keyof typeof callouts { // ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) // (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias) -const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)?(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g") +const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g") const highlightRegex = new RegExp(/==([^=]+)==/, "g") const commentRegex = new RegExp(/%%(.+)%%/, "g") // from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts @@ -178,9 +178,9 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin src = src.replaceAll(wikilinkRegex, (value, ...capture) => { const [rawFp, rawHeader, rawAlias] = capture const fp = rawFp ?? "" - const anchor = rawHeader?.trim().slice(1) + const anchor = rawHeader?.trim().replace(/^#+/, "") const displayAnchor = anchor ? `#${slugAnchor(anchor)}` : "" - const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? "" + const displayAlias = rawAlias ?? anchor ?? "" const embedDisplay = value.startsWith("!") ? "!" : "" return `${embedDisplay}[[${fp}${displayAnchor}${displayAlias}]]` }) From f861a7c160a0b3be76a16c5bf2ea1a8d076a9662 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 19:31:18 -0800 Subject: [PATCH 004/213] fix: regression where clicking anchors on the same page wouldn't set the anchor in the url --- quartz/components/scripts/spa.inline.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index 0318ec34..bc13c931 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -15,7 +15,7 @@ const isLocalUrl = (href: string) => { if (window.location.origin === url.origin) { return true } - } catch (e) {} + } catch (e) { } return false } @@ -109,6 +109,7 @@ function createRouter() { if (isSamePage(url) && url.hash) { const el = document.getElementById(decodeURIComponent(url.hash.substring(1))) el?.scrollIntoView() + history.pushState({}, "", url) return } From 5befcf4780a9f1c2872dead5d25100d47452ea1e Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 19:32:25 -0800 Subject: [PATCH 005/213] fix: format --- quartz/components/scripts/spa.inline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index bc13c931..c0152b52 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -15,7 +15,7 @@ const isLocalUrl = (href: string) => { if (window.location.origin === url.origin) { return true } - } catch (e) { } + } catch (e) {} return false } From a26eb59392c617bf567df23ee45d16b3fce69da3 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 20:13:28 -0800 Subject: [PATCH 006/213] feat: scrub link formatting from toc entries --- quartz/plugins/transformers/ofm.ts | 5 ++++- quartz/plugins/transformers/toc.ts | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 9ae99228..e9510bb2 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -110,7 +110,10 @@ function canonicalizeCallout(calloutName: string): keyof typeof callouts { // ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) // (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias) -const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g") +export const wikilinkRegex = new RegExp( + /!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, + "g", +) const highlightRegex = new RegExp(/==([^=]+)==/, "g") const commentRegex = new RegExp(/%%(.+)%%/, "g") // from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts diff --git a/quartz/plugins/transformers/toc.ts b/quartz/plugins/transformers/toc.ts index 87c5802f..d0781ec2 100644 --- a/quartz/plugins/transformers/toc.ts +++ b/quartz/plugins/transformers/toc.ts @@ -3,6 +3,7 @@ import { Root } from "mdast" 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 @@ -24,6 +25,7 @@ interface TocEntry { slug: string // this is just the anchor (#some-slug), not the canonical slug } +const regexMdLinks = new RegExp(/\[([^\[]+)\](\(.*\))/, "g") export const TableOfContents: QuartzTransformerPlugin | undefined> = ( userOpts, ) => { @@ -41,7 +43,16 @@ export const TableOfContents: QuartzTransformerPlugin | undefin 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, From 95b1141b9df7b8de3fdb893454326daf752d7f66 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 15 Nov 2023 20:35:45 -0800 Subject: [PATCH 007/213] fix: include anchor when normalizing urls for spa/popovers --- quartz/components/scripts/popover.inline.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index 9506ec41..2bd21d1e 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -2,14 +2,18 @@ import { computePosition, flip, inline, shift } from "@floating-ui/dom" // from micromorph/src/utils.ts // https://github.com/natemoo-re/micromorph/blob/main/src/utils.ts#L5 -export function normalizeRelativeURLs(el: Element | Document, base: string | URL) { - const update = (el: Element, attr: string, base: string | URL) => { - el.setAttribute(attr, new URL(el.getAttribute(attr)!, base).pathname) +export function normalizeRelativeURLs(el: Element | Document, destination: string | URL) { + const rebase = (el: Element, attr: string, newBase: string | URL) => { + const rebased = new URL(el.getAttribute(attr)!, newBase) + el.setAttribute(attr, rebased.pathname + rebased.hash) } - el.querySelectorAll('[href^="./"], [href^="../"]').forEach((item) => update(item, "href", base)) - - el.querySelectorAll('[src^="./"], [src^="../"]').forEach((item) => update(item, "src", base)) + el.querySelectorAll('[href^="./"], [href^="../"]').forEach((item) => + rebase(item, "href", destination), + ) + el.querySelectorAll('[src^="./"], [src^="../"]').forEach((item) => + rebase(item, "src", destination), + ) } const p = new DOMParser() From 50f0ba29a247c81b5f29d290e54f7e1aabb18ab3 Mon Sep 17 00:00:00 2001 From: Zijing Zhang <50045289+pluveto@users.noreply.github.com> Date: Fri, 17 Nov 2023 07:31:20 +0800 Subject: [PATCH 008/213] feat: cname emitter (#590) * feat: cname emitter * feat: impl cname.ts * Update cname.ts * Update index.ts * Update cname.ts * Update cname.ts * Update cname.ts * Update cname.ts --- quartz/plugins/emitters/cname.ts | 29 +++++++++++++++++++++++++++++ quartz/plugins/emitters/index.ts | 1 + 2 files changed, 30 insertions(+) create mode 100644 quartz/plugins/emitters/cname.ts diff --git a/quartz/plugins/emitters/cname.ts b/quartz/plugins/emitters/cname.ts new file mode 100644 index 00000000..ffe2c6d1 --- /dev/null +++ b/quartz/plugins/emitters/cname.ts @@ -0,0 +1,29 @@ +import { FilePath, joinSegments } from "../../util/path" +import { QuartzEmitterPlugin } from "../types" +import fs from "fs" +import chalk from "chalk" + +export function extractDomainFromBaseUrl(baseUrl: string) { + const url = new URL(`https://${baseUrl}`) + return url.hostname +} + +export const CNAME: QuartzEmitterPlugin = () => ({ + name: "CNAME", + getQuartzComponents() { + return [] + }, + async emit({ argv, cfg }, _content, _resources, _emit): Promise { + if (!cfg.configuration.baseUrl) { + console.warn(chalk.yellow("CNAME emitter requires `baseUrl` to be set in your configuration")) + return [] + } + const path = joinSegments(argv.output, "CNAME") + const content = extractDomainFromBaseUrl(cfg.configuration.baseUrl) + if (!content) { + return [] + } + fs.writeFileSync(path, content) + return [path] as FilePath[] + }, +}) diff --git a/quartz/plugins/emitters/index.ts b/quartz/plugins/emitters/index.ts index 99a2c54d..bc378c47 100644 --- a/quartz/plugins/emitters/index.ts +++ b/quartz/plugins/emitters/index.ts @@ -7,3 +7,4 @@ export { Assets } from "./assets" export { Static } from "./static" export { ComponentResources } from "./componentResources" export { NotFoundPage } from "./404" +export { CNAME } from "./cname" From 727b9b5d72464d26427a8bdf3ab06e522e67b21c Mon Sep 17 00:00:00 2001 From: Matt Vogel Date: Fri, 17 Nov 2023 13:23:39 -0500 Subject: [PATCH 009/213] feat: add class `alias` to aliases (#585) --- quartz/plugins/transformers/links.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 8d16136f..eec473c1 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -54,6 +54,16 @@ export const CrawlLinks: QuartzTransformerPlugin | undefined> = node.properties.className ??= [] node.properties.className.push(isAbsoluteUrl(dest) ? "external" : "internal") + // Check if the link has alias text + if ( + node.children.length === 1 && + node.children[0].type === "text" && + node.children[0].value !== dest + ) { + // Add the 'alias' class if the text content is not the same as the href + node.properties.className.push("alias") + } + if (opts.openLinksInNewTab) { node.properties.target = "_blank" } From ea08c0511a084f9ed77d1503847f4834046e2695 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 17 Nov 2023 10:29:07 -0800 Subject: [PATCH 010/213] fix: dont run explorer scripts on non-explorer pages (closes #596) --- quartz/components/scripts/explorer.inline.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/quartz/components/scripts/explorer.inline.ts b/quartz/components/scripts/explorer.inline.ts index 9fe18654..72404ed2 100644 --- a/quartz/components/scripts/explorer.inline.ts +++ b/quartz/components/scripts/explorer.inline.ts @@ -120,9 +120,9 @@ function setupExplorer() { } } }) - } else { + } else if (explorer?.dataset.tree) { // If tree is not in localStorage or config is disabled, use tree passed from Explorer as dataset - explorerState = JSON.parse(explorer?.dataset.tree as string) + explorerState = JSON.parse(explorer.dataset.tree) } } @@ -130,12 +130,13 @@ window.addEventListener("resize", setupExplorer) document.addEventListener("nav", () => { setupExplorer() - const explorerContent = document.getElementById("explorer-ul") + observer.disconnect() + // select pseudo element at end of list const lastItem = document.getElementById("explorer-end") - - observer.disconnect() - observer.observe(lastItem as Element) + if (lastItem) { + observer.observe(lastItem) + } }) /** From 3f0be7fbe470500a57c457ad1d1c039175330697 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 17 Nov 2023 10:46:23 -0800 Subject: [PATCH 011/213] fix: check content-type before applying spa patch (closes #597) --- quartz/components/scripts/spa.inline.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index c0152b52..29cc3344 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -45,7 +45,14 @@ let p: DOMParser async function navigate(url: URL, isBack: boolean = false) { p = p || new DOMParser() const contents = await fetch(`${url}`) - .then((res) => res.text()) + .then((res) => { + const contentType = res.headers.get("content-type") + if (contentType?.startsWith("text/html")) { + return res.text() + } else { + window.location.assign(url) + } + }) .catch(() => { window.location.assign(url) }) From 6a05fa777c3830631d8aeb16bdda287a1fea3b80 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 17 Nov 2023 14:00:49 -0800 Subject: [PATCH 012/213] fix: bad transform in wikilink pre-transform (closes #598) --- quartz/plugins/transformers/ofm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index e9510bb2..2e47cedf 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -183,7 +183,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin const fp = rawFp ?? "" const anchor = rawHeader?.trim().replace(/^#+/, "") const displayAnchor = anchor ? `#${slugAnchor(anchor)}` : "" - const displayAlias = rawAlias ?? anchor ?? "" + const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? "" const embedDisplay = value.startsWith("!") ? "!" : "" return `${embedDisplay}[[${fp}${displayAnchor}${displayAlias}]]` }) From 516d9a27e7e2c08efdf24857b03f1831dbaf7da7 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 18 Nov 2023 18:27:44 -0800 Subject: [PATCH 013/213] fix: explicit undefined check in header transclude --- quartz/components/renderPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 36b06464..5cb39d9a 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -104,7 +104,7 @@ export function renderPage( break } - if (startIdx) { + if (startIdx !== undefined) { endIdx = i } else if (el.properties?.id === blockRef) { startIdx = i @@ -112,7 +112,7 @@ export function renderPage( } } - if (!startIdx) { + if (startIdx === undefined) { return } From 296c1cf83f587706d23ffc2f14962628d0534953 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 18 Nov 2023 18:46:58 -0800 Subject: [PATCH 014/213] fix: spa shouldn't use popover script directly --- quartz/components/scripts/popover.inline.ts | 17 +---------------- quartz/components/scripts/spa.inline.ts | 4 +--- quartz/util/path.ts | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index 2bd21d1e..371563ba 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -1,20 +1,5 @@ import { computePosition, flip, inline, shift } from "@floating-ui/dom" - -// from micromorph/src/utils.ts -// https://github.com/natemoo-re/micromorph/blob/main/src/utils.ts#L5 -export function normalizeRelativeURLs(el: Element | Document, destination: string | URL) { - const rebase = (el: Element, attr: string, newBase: string | URL) => { - const rebased = new URL(el.getAttribute(attr)!, newBase) - el.setAttribute(attr, rebased.pathname + rebased.hash) - } - - el.querySelectorAll('[href^="./"], [href^="../"]').forEach((item) => - rebase(item, "href", destination), - ) - el.querySelectorAll('[src^="./"], [src^="../"]').forEach((item) => - rebase(item, "src", destination), - ) -} +import { normalizeRelativeURLs } from "../../util/path" const p = new DOMParser() async function mouseEnterHandler( diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index 29cc3344..c2a44c9a 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -1,10 +1,8 @@ import micromorph from "micromorph" -import { FullSlug, RelativeURL, getFullSlug } from "../../util/path" -import { normalizeRelativeURLs } from "./popover.inline" +import { FullSlug, RelativeURL, getFullSlug, normalizeRelativeURLs } from "../../util/path" // adapted from `micromorph` // https://github.com/natemoo-re/micromorph - const NODE_TYPE_ELEMENT = 1 let announcer = document.createElement("route-announcer") const isElement = (target: EventTarget | null): target is Element => diff --git a/quartz/util/path.ts b/quartz/util/path.ts index 173eb2ec..e450339f 100644 --- a/quartz/util/path.ts +++ b/quartz/util/path.ts @@ -84,6 +84,22 @@ export function transformInternalLink(link: string): RelativeURL { return res } +// from micromorph/src/utils.ts +// https://github.com/natemoo-re/micromorph/blob/main/src/utils.ts#L5 +export function normalizeRelativeURLs(el: Element | Document, destination: string | URL) { + const rebase = (el: Element, attr: string, newBase: string | URL) => { + const rebased = new URL(el.getAttribute(attr)!, newBase) + el.setAttribute(attr, rebased.pathname + rebased.hash) + } + + el.querySelectorAll('[href^="./"], [href^="../"]').forEach((item) => + rebase(item, "href", destination), + ) + el.querySelectorAll('[src^="./"], [src^="../"]').forEach((item) => + rebase(item, "src", destination), + ) +} + // resolve /a/b/c to ../.. export function pathToRoot(slug: FullSlug): RelativeURL { let rootPath = slug From 9a599aebeada7f95170dac98c3f30023d9e7453f Mon Sep 17 00:00:00 2001 From: Rune Antonsen Date: Mon, 20 Nov 2023 17:28:16 +0100 Subject: [PATCH 015/213] feat(breadcrumbs): add option to hide current page (#601) * feat(breadcrumbs): add option to hide current page * Remove debug lines Co-authored-by: Jacky Zhao --------- Co-authored-by: ruant Co-authored-by: Jacky Zhao --- docs/features/breadcrumbs.md | 1 + quartz/components/Breadcrumbs.tsx | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/features/breadcrumbs.md b/docs/features/breadcrumbs.md index 20c3b8d6..a241aac4 100644 --- a/docs/features/breadcrumbs.md +++ b/docs/features/breadcrumbs.md @@ -20,6 +20,7 @@ Component.Breadcrumbs({ rootName: "Home", // name of first/root element resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles hideOnRoot: true, // whether to hide breadcrumbs on root `index.md` page + showCurrentPage: true, // wether to display the current page in the breadcrumbs }) ``` diff --git a/quartz/components/Breadcrumbs.tsx b/quartz/components/Breadcrumbs.tsx index 29c73a81..8998c406 100644 --- a/quartz/components/Breadcrumbs.tsx +++ b/quartz/components/Breadcrumbs.tsx @@ -25,6 +25,10 @@ interface BreadcrumbOptions { * Wether to display breadcrumbs on root `index.md` */ hideOnRoot: boolean + /** + * Wether to display the current page in the breadcrumbs. + */ + showCurrentPage: boolean } const defaultOptions: BreadcrumbOptions = { @@ -32,6 +36,7 @@ const defaultOptions: BreadcrumbOptions = { rootName: "Home", resolveFrontmatterTitle: true, hideOnRoot: true, + showCurrentPage: true, } function formatCrumb(displayName: string, baseSlug: FullSlug, currentSlug: SimpleSlug): CrumbData { @@ -95,10 +100,12 @@ export default ((opts?: Partial) => { } // Add current file to crumb (can directly use frontmatter title) - crumbs.push({ - displayName: fileData.frontmatter!.title, - path: "", - }) + if (options.showCurrentPage) { + crumbs.push({ + displayName: fileData.frontmatter!.title, + path: "", + }) + } } return (