From 12904ab7960edc3bedd77c65cf5e6a5d599d882d Mon Sep 17 00:00:00 2001 From: Xinyang Yu <47915643+xy-241@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:00:20 +0800 Subject: [PATCH 01/92] docs: Adds back Xinyang's cs garden to showcase (#1323) adding back my garden which was deleted from the cleanup showcase --- docs/showcase.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/showcase.md b/docs/showcase.md index 8730c35..5fd7133 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -25,5 +25,6 @@ Want to see what Quartz can do? Here are some cool community gardens: - [🪴Aster's notebook](https://notes.asterhu.com) - [Gatekeeper Wiki](https://www.gatekeeper.wiki) - [Ellie's Notes](https://ellie.wtf) +- [🥷🏻🌳🍃 Computer Science & Thinkering Garden](https://notes.yxy.ninja) If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/v4/docs/showcase.md)! From 27a41abb62cc9005ed4234bdb02f38b6cfeedec3 Mon Sep 17 00:00:00 2001 From: Andrew <80933354+ndrooo@users.noreply.github.com> Date: Thu, 8 Aug 2024 21:07:47 -0400 Subject: [PATCH 02/92] feat(toc,explorer): add accessibility for toggle (#1327) * Restore focus highlight on explorer toggle button. Remove `unset: all` declaration causing `outline` property to be unset. This allows the default browser focus highlight to be shown. * Fix semantics of expandable sections (explorer, toc). This adds the appropriate aria attributes for the [disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-image-description/#javascriptandcsssourcecode) and uses `visibility: hidden` to remove the hidden elements from the focus order without disrupting the animations. Further work is needed on the tree view nodes. * Run prettier for SCSS files. --- quartz/components/Explorer.tsx | 2 ++ quartz/components/TableOfContents.tsx | 8 +++++++- quartz/components/scripts/explorer.inline.ts | 4 ++++ quartz/components/scripts/toc.inline.ts | 4 ++++ quartz/components/styles/explorer.scss | 13 +++++++++++-- quartz/components/styles/toc.scss | 12 +++++++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/quartz/components/Explorer.tsx b/quartz/components/Explorer.tsx index 24583a1..e4c3dfa 100644 --- a/quartz/components/Explorer.tsx +++ b/quartz/components/Explorer.tsx @@ -91,6 +91,8 @@ export default ((userOpts?: Partial) => { data-collapsed={opts.folderDefaultState} data-savestate={opts.useSavedState} data-tree={jsonTree} + aria-controls="explorer-content" + aria-expanded={opts.folderDefaultState === "open"} >

{opts.title ?? i18n(cfg.locale).components.explorer.title}

-

{i18n(cfg.locale).components.tableOfContents.title}

{ function toggleExplorer(this: HTMLElement) { this.classList.toggle("collapsed") + this.setAttribute( + "aria-expanded", + this.getAttribute("aria-expanded") === "true" ? "false" : "true", + ) const content = this.nextElementSibling as MaybeHTMLElement if (!content) return diff --git a/quartz/components/scripts/toc.inline.ts b/quartz/components/scripts/toc.inline.ts index 546859e..acc81b2 100644 --- a/quartz/components/scripts/toc.inline.ts +++ b/quartz/components/scripts/toc.inline.ts @@ -16,6 +16,10 @@ const observer = new IntersectionObserver((entries) => { function toggleToc(this: HTMLElement) { this.classList.toggle("collapsed") + this.setAttribute( + "aria-expanded", + this.getAttribute("aria-expanded") === "true" ? "false" : "true", + ) const content = this.nextElementSibling as HTMLElement | undefined if (!content) return content.classList.toggle("collapsed") diff --git a/quartz/components/styles/explorer.scss b/quartz/components/styles/explorer.scss index d4875e7..2f94b15 100644 --- a/quartz/components/styles/explorer.scss +++ b/quartz/components/styles/explorer.scss @@ -1,7 +1,6 @@ @use "../../styles/variables.scss" as *; button#explorer { - all: unset; background-color: transparent; border: none; text-align: left; @@ -46,8 +45,18 @@ button#explorer { list-style: none; overflow: hidden; max-height: none; - transition: max-height 0.35s ease; + transition: + max-height 0.35s ease, + visibility 0s linear 0s; margin-top: 0.5rem; + visibility: visible; + + &.collapsed { + transition: + max-height 0.35s ease, + visibility 0s linear 0.35s; + visibility: hidden; + } &.collapsed > .overflow::after { opacity: 0; diff --git a/quartz/components/styles/toc.scss b/quartz/components/styles/toc.scss index 27ff62a..6845812 100644 --- a/quartz/components/styles/toc.scss +++ b/quartz/components/styles/toc.scss @@ -29,8 +29,18 @@ button#toc { list-style: none; overflow: hidden; max-height: none; - transition: max-height 0.5s ease; + transition: + max-height 0.5s ease, + visibility 0s linear 0s; position: relative; + visibility: visible; + + &.collapsed { + transition: + max-height 0.5s ease, + visibility 0s linear 0.5s; + visibility: hidden; + } &.collapsed > .overflow::after { opacity: 0; From 9acaa1c8ac8c8afd3fa08d3b1f58a60006fcfc6f Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 8 Aug 2024 18:19:45 -0700 Subject: [PATCH 03/92] feat: custom global latex macros (closes #1325) --- docs/plugins/Latex.md | 1 + quartz/plugins/transformers/latex.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/plugins/Latex.md b/docs/plugins/Latex.md index ac43678..236cbec 100644 --- a/docs/plugins/Latex.md +++ b/docs/plugins/Latex.md @@ -12,6 +12,7 @@ This plugin adds LaTeX support to Quartz. See [[features/Latex|Latex]] for more This plugin accepts the following configuration options: - `renderEngine`: the engine to use to render LaTeX equations. Can be `"katex"` for [KaTeX](https://katex.org/) or `"mathjax"` for [MathJax](https://www.mathjax.org/) [SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html). Defaults to KaTeX. +- `customMacros`: custom macros for all LaTeX blocks. It takes the form of a key-value pair where the key is a new command name and the value is the expansion of the macro. For example: `{"\\R": "\\mathbb{R}"}` ## API diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts index c9f6bff..757333a 100644 --- a/quartz/plugins/transformers/latex.ts +++ b/quartz/plugins/transformers/latex.ts @@ -5,10 +5,16 @@ import { QuartzTransformerPlugin } from "../types" interface Options { renderEngine: "katex" | "mathjax" + customMacros: MacroType +} + +interface MacroType { + [key: string]: string } export const Latex: QuartzTransformerPlugin = (opts?: Options) => { const engine = opts?.renderEngine ?? "katex" + const macros = opts?.customMacros ?? {} return { name: "Latex", markdownPlugins() { @@ -16,9 +22,9 @@ export const Latex: QuartzTransformerPlugin = (opts?: Options) => { }, htmlPlugins() { if (engine === "katex") { - return [[rehypeKatex, { output: "html" }]] + return [[rehypeKatex, { output: "html", macros }]] } else { - return [rehypeMathjax] + return [[rehypeMathjax, { macros }]] } }, externalResources() { From 39eebca3cfa8adf504d08d54e6fc05912641b40f Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 8 Aug 2024 18:28:13 -0700 Subject: [PATCH 04/92] chore: ts fixes --- quartz/plugins/transformers/citations.ts | 4 ++-- quartz/plugins/transformers/description.ts | 2 +- quartz/plugins/transformers/frontmatter.ts | 2 +- quartz/plugins/transformers/gfm.ts | 4 +--- quartz/plugins/transformers/lastmod.ts | 4 +--- quartz/plugins/transformers/latex.ts | 2 +- quartz/plugins/transformers/links.ts | 3 +-- quartz/plugins/transformers/ofm.ts | 4 +--- quartz/plugins/transformers/oxhugofm.ts | 4 +--- quartz/plugins/transformers/syntax.ts | 6 ++---- quartz/plugins/transformers/toc.ts | 4 +--- 11 files changed, 13 insertions(+), 26 deletions(-) diff --git a/quartz/plugins/transformers/citations.ts b/quartz/plugins/transformers/citations.ts index bb302e4..5242f37 100644 --- a/quartz/plugins/transformers/citations.ts +++ b/quartz/plugins/transformers/citations.ts @@ -17,7 +17,7 @@ const defaultOptions: Options = { csl: "apa", } -export const Citations: QuartzTransformerPlugin | undefined> = (userOpts) => { +export const Citations: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "Citations", @@ -38,7 +38,7 @@ export const Citations: QuartzTransformerPlugin | undefined> = // using https://github.com/syntax-tree/unist-util-visit as they're just anochor links plugins.push(() => { return (tree, _file) => { - visit(tree, "element", (node, index, parent) => { + visit(tree, "element", (node, _index, _parent) => { if (node.tagName === "a" && node.properties?.href?.startsWith("#bib")) { node.properties["data-no-popover"] = true } diff --git a/quartz/plugins/transformers/description.ts b/quartz/plugins/transformers/description.ts index 5900745..c7e592e 100644 --- a/quartz/plugins/transformers/description.ts +++ b/quartz/plugins/transformers/description.ts @@ -18,7 +18,7 @@ const urlRegex = new RegExp( "g", ) -export const Description: QuartzTransformerPlugin | undefined> = (userOpts) => { +export const Description: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "Description", diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index 5ab239a..70a60d8 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -40,7 +40,7 @@ function coerceToArray(input: string | string[]): string[] | undefined { .map((tag: string | number) => tag.toString()) } -export const FrontMatter: QuartzTransformerPlugin | undefined> = (userOpts) => { +export const FrontMatter: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "FrontMatter", diff --git a/quartz/plugins/transformers/gfm.ts b/quartz/plugins/transformers/gfm.ts index 48681ff..eec26f7 100644 --- a/quartz/plugins/transformers/gfm.ts +++ b/quartz/plugins/transformers/gfm.ts @@ -14,9 +14,7 @@ const defaultOptions: Options = { linkHeadings: true, } -export const GitHubFlavoredMarkdown: QuartzTransformerPlugin | undefined> = ( - userOpts, -) => { +export const GitHubFlavoredMarkdown: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "GitHubFlavoredMarkdown", diff --git a/quartz/plugins/transformers/lastmod.ts b/quartz/plugins/transformers/lastmod.ts index 2c7b9ce..fe8c01b 100644 --- a/quartz/plugins/transformers/lastmod.ts +++ b/quartz/plugins/transformers/lastmod.ts @@ -27,9 +27,7 @@ function coerceDate(fp: string, d: any): Date { } type MaybeDate = undefined | string | number -export const CreatedModifiedDate: QuartzTransformerPlugin | undefined> = ( - userOpts, -) => { +export const CreatedModifiedDate: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "CreatedModifiedDate", diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts index 757333a..28b4d50 100644 --- a/quartz/plugins/transformers/latex.ts +++ b/quartz/plugins/transformers/latex.ts @@ -12,7 +12,7 @@ interface MacroType { [key: string]: string } -export const Latex: QuartzTransformerPlugin = (opts?: Options) => { +export const Latex: QuartzTransformerPlugin> = (opts) => { const engine = opts?.renderEngine ?? "katex" const macros = opts?.customMacros ?? {} return { diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 2805818..b6a2c91 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -8,7 +8,6 @@ import { simplifySlug, splitAnchor, transformLink, - joinSegments, } from "../../util/path" import path from "path" import { visit } from "unist-util-visit" @@ -33,7 +32,7 @@ const defaultOptions: Options = { externalLinkIcon: true, } -export const CrawlLinks: QuartzTransformerPlugin | undefined> = (userOpts) => { +export const CrawlLinks: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "LinkProcessing", diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index a406c86..0dea893 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -136,9 +136,7 @@ const wikilinkImageEmbedRegex = new RegExp( /^(?(?!^\d*x?\d*$).*?)?(\|?\s*?(?\d+)(x(?\d+))?)?$/, ) -export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin | undefined> = ( - userOpts, -) => { +export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } const mdastToHtml = (ast: PhrasingContent | Paragraph) => { diff --git a/quartz/plugins/transformers/oxhugofm.ts b/quartz/plugins/transformers/oxhugofm.ts index 6e70bb1..cdbffcf 100644 --- a/quartz/plugins/transformers/oxhugofm.ts +++ b/quartz/plugins/transformers/oxhugofm.ts @@ -47,9 +47,7 @@ const quartzLatexRegex = new RegExp(/\$\$[\s\S]*?\$\$|\$.*?\$/, "g") * markdown to make it compatible with quartz but the list of changes applied it * is not exhaustive. * */ -export const OxHugoFlavouredMarkdown: QuartzTransformerPlugin | undefined> = ( - userOpts, -) => { +export const OxHugoFlavouredMarkdown: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "OxHugoFlavouredMarkdown", diff --git a/quartz/plugins/transformers/syntax.ts b/quartz/plugins/transformers/syntax.ts index f11734e..5d3aae0 100644 --- a/quartz/plugins/transformers/syntax.ts +++ b/quartz/plugins/transformers/syntax.ts @@ -19,10 +19,8 @@ const defaultOptions: Options = { keepBackground: false, } -export const SyntaxHighlighting: QuartzTransformerPlugin = ( - userOpts?: Partial, -) => { - const opts: Partial = { ...defaultOptions, ...userOpts } +export const SyntaxHighlighting: QuartzTransformerPlugin> = (userOpts) => { + const opts: CodeOptions = { ...defaultOptions, ...userOpts } return { name: "SyntaxHighlighting", diff --git a/quartz/plugins/transformers/toc.ts b/quartz/plugins/transformers/toc.ts index bfc2f98..791547b 100644 --- a/quartz/plugins/transformers/toc.ts +++ b/quartz/plugins/transformers/toc.ts @@ -25,9 +25,7 @@ interface TocEntry { } const slugAnchor = new Slugger() -export const TableOfContents: QuartzTransformerPlugin | undefined> = ( - userOpts, -) => { +export const TableOfContents: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { name: "TableOfContents", From 2db735a150e9749ba4a900deb4f82ed5d4775b70 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 8 Aug 2024 18:38:17 -0700 Subject: [PATCH 05/92] docs: recommend at least node 20 in gh --- docs/hosting.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/hosting.md b/docs/hosting.md index 4bbaeb5..0130275 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -61,6 +61,7 @@ jobs: with: fetch-depth: 0 # Fetch all history for git info - uses: actions/setup-node@v4 + node-version: 22 - name: Install Dependencies run: npm ci - name: Build Quartz From e89c395f7c8cabffb880ce36cc27926667b608de Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 8 Aug 2024 19:17:20 -0700 Subject: [PATCH 06/92] fix: unmemoize explorer on rebuild (closes #1077) --- quartz/build.ts | 21 +++++++++++++++------ quartz/components/Explorer.tsx | 12 +++++++----- quartz/util/ctx.ts | 1 + 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/quartz/build.ts b/quartz/build.ts index 972a7e8..342a27c 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -38,8 +38,13 @@ type BuildData = { type FileEvent = "add" | "change" | "delete" +function newBuildId() { + return new Date().toISOString() +} + async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) { const ctx: BuildCtx = { + buildId: newBuildId(), argv, cfg, allSlugs: [], @@ -167,6 +172,7 @@ async function partialRebuildFromEntrypoint( const perf = new PerfTimer() console.log(chalk.yellow("Detected change, rebuilding...")) + ctx.buildId = newBuildId() // UPDATE DEP GRAPH const fp = joinSegments(argv.directory, toPosixPath(filepath)) as FilePath @@ -363,14 +369,10 @@ async function rebuildFromEntrypoint( const perf = new PerfTimer() console.log(chalk.yellow("Detected change, rebuilding...")) + ctx.buildId = newBuildId() + try { const filesToRebuild = [...toRebuild].filter((fp) => !toRemove.has(fp)) - - const trackedSlugs = [...new Set([...contentMap.keys(), ...toRebuild, ...trackedAssets])] - .filter((fp) => !toRemove.has(fp)) - .map((fp) => slugifyFilePath(path.posix.relative(argv.directory, fp) as FilePath)) - - ctx.allSlugs = [...new Set([...initialSlugs, ...trackedSlugs])] const parsedContent = await parseMarkdown(ctx, filesToRebuild) for (const content of parsedContent) { const [_tree, vfile] = content @@ -384,6 +386,13 @@ async function rebuildFromEntrypoint( const parsedFiles = [...contentMap.values()] const filteredContent = filterContent(ctx, parsedFiles) + // re-update slugs + const trackedSlugs = [...new Set([...contentMap.keys(), ...toRebuild, ...trackedAssets])] + .filter((fp) => !toRemove.has(fp)) + .map((fp) => slugifyFilePath(path.posix.relative(argv.directory, fp) as FilePath)) + + ctx.allSlugs = [...new Set([...initialSlugs, ...trackedSlugs])] + // TODO: we can probably traverse the link graph to figure out what's safe to delete here // instead of just deleting everything await rimraf(path.join(argv.output, ".*"), { glob: true }) diff --git a/quartz/components/Explorer.tsx b/quartz/components/Explorer.tsx index e4c3dfa..ec7c48e 100644 --- a/quartz/components/Explorer.tsx +++ b/quartz/components/Explorer.tsx @@ -44,12 +44,9 @@ export default ((userOpts?: Partial) => { // memoized let fileTree: FileNode let jsonTree: string + let lastBuildId: string = "" function constructFileTree(allFiles: QuartzPluginData[]) { - if (fileTree) { - return - } - // Construct tree from allFiles fileTree = new FileNode("") allFiles.forEach((file) => fileTree.add(file)) @@ -76,12 +73,17 @@ export default ((userOpts?: Partial) => { } const Explorer: QuartzComponent = ({ + ctx, cfg, allFiles, displayClass, fileData, }: QuartzComponentProps) => { - constructFileTree(allFiles) + if (ctx.buildId !== lastBuildId) { + lastBuildId = ctx.buildId + constructFileTree(allFiles) + } + return (
+
{ const data = await fetchData const container = document.getElementById("search-container") const sidebar = container?.closest(".sidebar") as HTMLElement - const searchIcon = document.getElementById("search-icon") + const searchButton = document.getElementById("search-button") const searchBar = document.getElementById("search-bar") as HTMLInputElement | null const searchLayout = document.getElementById("search-layout") const idDataMap = Object.keys(data) as FullSlug[] @@ -191,6 +191,8 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { } searchType = "basic" // reset search type after closing + + searchButton?.focus() } function showSearch(searchTypeNew: SearchType) { @@ -458,8 +460,8 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { document.addEventListener("keydown", shortcutHandler) window.addCleanup(() => document.removeEventListener("keydown", shortcutHandler)) - searchIcon?.addEventListener("click", () => showSearch("basic")) - window.addCleanup(() => searchIcon?.removeEventListener("click", () => showSearch("basic"))) + searchButton?.addEventListener("click", () => showSearch("basic")) + window.addCleanup(() => searchButton?.removeEventListener("click", () => showSearch("basic"))) searchBar?.addEventListener("input", onType) window.addCleanup(() => searchBar?.removeEventListener("input", onType)) diff --git a/quartz/components/scripts/util.ts b/quartz/components/scripts/util.ts index 4ffff29..d0a16c6 100644 --- a/quartz/components/scripts/util.ts +++ b/quartz/components/scripts/util.ts @@ -3,6 +3,7 @@ export function registerEscapeHandler(outsideContainer: HTMLElement | null, cb: function click(this: HTMLElement, e: HTMLElementEventMap["click"]) { if (e.target !== this) return e.preventDefault() + e.stopPropagation() cb() } diff --git a/quartz/components/styles/search.scss b/quartz/components/styles/search.scss index 8a9ec67..cc2daca 100644 --- a/quartz/components/styles/search.scss +++ b/quartz/components/styles/search.scss @@ -5,18 +5,21 @@ max-width: 14rem; flex-grow: 0.3; - & > #search-icon { + & > .search-button { background-color: var(--lightgray); + border: none; border-radius: 4px; + font-family: inherit; + font-size: inherit; height: 2rem; + padding: 0; display: flex; align-items: center; + text-align: inherit; cursor: pointer; white-space: nowrap; - - & > div { - flex-grow: 1; - } + width: 100%; + justify-content: space-between; & > p { display: inline; From 323167a001706745e6bd19efb38b0a877859c813 Mon Sep 17 00:00:00 2001 From: Karthi Fair Hawn <61026741+karthifairhawn@users.noreply.github.com> Date: Sat, 10 Aug 2024 21:02:51 +0530 Subject: [PATCH 09/92] docs(hosting): missing key with: (#1334) --- docs/hosting.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/hosting.md b/docs/hosting.md index 0130275..853e30f 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -61,7 +61,8 @@ jobs: with: fetch-depth: 0 # Fetch all history for git info - uses: actions/setup-node@v4 - node-version: 22 + with: + node-version: 22 - name: Install Dependencies run: npm ci - name: Build Quartz From c5f0b69a52c6d23b9db6daf9ae3f1d75684ef2d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:37:54 -0700 Subject: [PATCH 10/92] chore(deps): bump preact from 10.22.1 to 10.23.2 (#1342) Bumps [preact](https://github.com/preactjs/preact) from 10.22.1 to 10.23.2. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.22.1...10.23.2) --- updated-dependencies: - dependency-name: preact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 738fe8f..c17446d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.22.1", + "preact": "^10.23.2", "preact-render-to-string": "^6.5.7", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", @@ -4691,9 +4691,9 @@ } }, "node_modules/preact": { - "version": "10.22.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz", - "integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==", + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index 3800706..eed47c0 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.22.1", + "preact": "^10.23.2", "preact-render-to-string": "^6.5.7", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", From 0ee103a514003e0977c0ae40169a35eb265d4797 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:38:15 -0700 Subject: [PATCH 11/92] chore(deps): bump shiki from 1.10.3 to 1.12.1 (#1344) Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.10.3 to 1.12.1. - [Release notes](https://github.com/shikijs/shiki/releases) - [Changelog](https://github.com/shikijs/shiki/blob/main/CHANGELOG.md) - [Commits](https://github.com/shikijs/shiki/commits/v1.12.1/packages/shiki) --- updated-dependencies: - dependency-name: shiki dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index c17446d..d1a4f7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "rfdc": "^1.4.1", "rimraf": "^6.0.1", "serve-handler": "^6.1.5", - "shiki": "^1.10.3", + "shiki": "^1.12.1", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", @@ -820,9 +820,9 @@ } }, "node_modules/@shikijs/core": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz", - "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.12.1.tgz", + "integrity": "sha512-biCz/mnkMktImI6hMfMX3H9kOeqsInxWEyCHbSlL8C/2TR1FqfmGxTLRNwYCKsyCyxWLbB8rEqXRVZuyxuLFmA==", "dependencies": { "@types/hast": "^3.0.4" } @@ -5412,11 +5412,11 @@ } }, "node_modules/shiki": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz", - "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.12.1.tgz", + "integrity": "sha512-nwmjbHKnOYYAe1aaQyEBHvQymJgfm86ZSS7fT8OaPRr4sbAcBNz7PbfAikMEFSDQ6se2j2zobkXvVKcBOm0ysg==", "dependencies": { - "@shikijs/core": "1.10.3", + "@shikijs/core": "1.12.1", "@types/hast": "^3.0.4" } }, diff --git a/package.json b/package.json index eed47c0..b6c3a1d 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "rfdc": "^1.4.1", "rimraf": "^6.0.1", "serve-handler": "^6.1.5", - "shiki": "^1.10.3", + "shiki": "^1.12.1", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", From d27c29273640b2d67a7af1fa9c6410077c7cbe9f Mon Sep 17 00:00:00 2001 From: Andrew <80933354+ndrooo@users.noreply.github.com> Date: Mon, 12 Aug 2024 23:06:19 -0400 Subject: [PATCH 12/92] feat: Mark the external link icon as aria-hidden (#1346) --- quartz/plugins/transformers/links.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index b6a2c91..38bc0dc 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -65,6 +65,7 @@ export const CrawlLinks: QuartzTransformerPlugin> = (userOpts) type: "element", tagName: "svg", properties: { + "aria-hidden": "true", class: "external-icon", viewBox: "0 0 512 512", }, From cb68069d455cf513da4eefeab7868062085b4064 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 04:24:48 -0400 Subject: [PATCH 13/92] chore(deps-dev): bump typescript from 5.5.3 to 5.5.4 (#1343) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.5.3 to 5.5.4. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.5.3...v5.5.4) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d1a4f7e..7e69442 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,7 +82,7 @@ "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.16.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": "20 || >=22", @@ -6170,9 +6170,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index b6c3a1d..afb57e9 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,6 @@ "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.16.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" } } From eb23cbe8da4ce90bf6a34f7e92148babc9a3049b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 04:25:07 -0400 Subject: [PATCH 14/92] chore(deps): bump rehype-citation from 2.0.0 to 2.1.1 (#1341) Bumps [rehype-citation](https://github.com/timlrx/rehype-citation) from 2.0.0 to 2.1.1. - [Release notes](https://github.com/timlrx/rehype-citation/releases) - [Commits](https://github.com/timlrx/rehype-citation/compare/v2.0.0...v2.1.1) --- updated-dependencies: - dependency-name: rehype-citation dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e69442..db6be1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "pretty-time": "^1.1.0", "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", - "rehype-citation": "^2.0.0", + "rehype-citation": "^2.1.1", "rehype-katex": "^7.0.0", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.13.2", @@ -100,9 +100,9 @@ } }, "node_modules/@citation-js/core": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.9.tgz", - "integrity": "sha512-fSbkB32JayDChZnAYC/kB+sWHRvxxL7ibVetyBOyzOc+5aCnjb6UVsbcfhnkOIEyAMoRRvWDyFmakEoTtA5ttQ==", + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.14.tgz", + "integrity": "sha512-dgeGqYDSQmn2MtnWZkwPGpJQPh43yr1lAAr9jl1NJ9pIY1RXUQxtlAUZVur0V9PHdbfQC+kkvB1KC3VpgVV3MA==", "dependencies": { "@citation-js/date": "^0.5.0", "@citation-js/name": "^0.4.2", @@ -130,9 +130,9 @@ } }, "node_modules/@citation-js/plugin-bibjson": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibjson/-/plugin-bibjson-0.7.9.tgz", - "integrity": "sha512-YNCWIrkhqZ3cZKewHkLBixABo2PvOWnU+8dBx6KfN47ysdECR76xENe86YYpJ0ska2D5ZnTP0jKZIrUHQoxYfQ==", + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibjson/-/plugin-bibjson-0.7.14.tgz", + "integrity": "sha512-Hcmk01KrpHwcl5uVoLE6TRaJRFg7/qUvpJDcKqx3LLLCsNbaBlISfRDeFETrjjipTetkX70RvtS7FfGUN58gCQ==", "dependencies": { "@citation-js/date": "^0.5.0", "@citation-js/name": "^0.4.2" @@ -145,9 +145,9 @@ } }, "node_modules/@citation-js/plugin-bibtex": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.9.tgz", - "integrity": "sha512-gIJpCd6vmmTOcRfDrSOjtoNhw2Mi94UwFxmgJ7GwkXyTYcNheW5VlMMo1tlqjakJGARQ0eOsKcI57gSPqJSS2g==", + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.14.tgz", + "integrity": "sha512-xHOHqhF6dthLRv46N9U+mQgYLiiWQHLvQWK9+mcBKz+/3NWge62Xb1oBouNWwLEPd5FV/8gp9fp7SOp93T0dUg==", "dependencies": { "@citation-js/date": "^0.5.0", "@citation-js/name": "^0.4.2", @@ -161,9 +161,9 @@ } }, "node_modules/@citation-js/plugin-csl": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.9.tgz", - "integrity": "sha512-mbD7CnUiPOuVnjeJwo+d0RGUcY0PE8n01gHyjq0qpTeS42EGmQ9+LzqfsTUVWWBndTwc6zLRuIF1qFAUHKE4oA==", + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.14.tgz", + "integrity": "sha512-7AKB8lMz1IqdtoE33NnWIpteLYMuSl3xqT+Cax7sQKwAIJEoq2HBmb43Ja8xQQ36nREAupQJv1V6XksIAmYnCg==", "dependencies": { "@citation-js/date": "^0.5.0", "citeproc": "^2.4.6" @@ -4826,16 +4826,16 @@ } }, "node_modules/rehype-citation": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rehype-citation/-/rehype-citation-2.0.0.tgz", - "integrity": "sha512-rGawTBI8SJA1Y4IRyROvpYF6oXBVNFXlJYHIJ2jJH3HgeuCbAC9AO8wE/NMPLDOPQ8+Q8QkZm93fKsnUNbvwZA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/rehype-citation/-/rehype-citation-2.1.1.tgz", + "integrity": "sha512-9aXDHR4pnR8Yyt6DFDXq2EKcxhwjf4HuF5kxvQDbhH8xfY5VjqJQNmIzpsXAn6YcmytOGWNf+82WnIroKAaLSw==", "dependencies": { - "@citation-js/core": "^0.7.1", + "@citation-js/core": "^0.7.14", "@citation-js/date": "^0.5.1", "@citation-js/name": "^0.4.2", - "@citation-js/plugin-bibjson": "^0.7.2", - "@citation-js/plugin-bibtex": "^0.7.2", - "@citation-js/plugin-csl": "^0.7.2", + "@citation-js/plugin-bibjson": "^0.7.14", + "@citation-js/plugin-bibtex": "^0.7.14", + "@citation-js/plugin-csl": "^0.7.14", "citeproc": "^2.4.63", "cross-fetch": "^4.0.0", "hast-util-from-dom": "^5.0.0", diff --git a/package.json b/package.json index afb57e9..afaa3ff 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "pretty-time": "^1.1.0", "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", - "rehype-citation": "^2.0.0", + "rehype-citation": "^2.1.1", "rehype-katex": "^7.0.0", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.13.2", From a5f2f874f75dd53c83b2db883e6871cb84eccf09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 05:07:05 -0400 Subject: [PATCH 15/92] chore(deps-dev): bump tsx from 4.16.2 to 4.17.0 (#1340) Bumps [tsx](https://github.com/privatenumber/tsx) from 4.16.2 to 4.17.0. - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.16.2...v4.17.0) --- updated-dependencies: - dependency-name: tsx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 265 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 142 insertions(+), 125 deletions(-) diff --git a/package-lock.json b/package-lock.json index db6be1b..d4d5961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.16.2", + "tsx": "^4.17.0", "typescript": "^5.5.4" }, "engines": { @@ -479,6 +479,22 @@ "node": ">=12" } }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", + "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/openbsd-x64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", @@ -5745,12 +5761,12 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.16.2.tgz", - "integrity": "sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.17.0.tgz", + "integrity": "sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==", "dev": true, "dependencies": { - "esbuild": "~0.21.5", + "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -5764,9 +5780,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", + "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", "cpu": [ "ppc64" ], @@ -5776,13 +5792,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", + "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", "cpu": [ "arm" ], @@ -5792,13 +5808,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", + "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", "cpu": [ "arm64" ], @@ -5808,13 +5824,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", + "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", "cpu": [ "x64" ], @@ -5824,13 +5840,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", "cpu": [ "arm64" ], @@ -5840,13 +5856,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", + "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", "cpu": [ "x64" ], @@ -5856,13 +5872,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", + "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", "cpu": [ "arm64" ], @@ -5872,13 +5888,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", + "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", "cpu": [ "x64" ], @@ -5888,13 +5904,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", + "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", "cpu": [ "arm" ], @@ -5904,13 +5920,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", + "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", "cpu": [ "arm64" ], @@ -5920,13 +5936,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", + "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", "cpu": [ "ia32" ], @@ -5936,13 +5952,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", + "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", "cpu": [ "loong64" ], @@ -5952,13 +5968,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", + "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", "cpu": [ "mips64el" ], @@ -5968,13 +5984,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", + "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", "cpu": [ "ppc64" ], @@ -5984,13 +6000,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", + "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", "cpu": [ "riscv64" ], @@ -6000,13 +6016,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", + "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", "cpu": [ "s390x" ], @@ -6016,13 +6032,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", + "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", "cpu": [ "x64" ], @@ -6032,13 +6048,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", + "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", "cpu": [ "x64" ], @@ -6048,13 +6064,13 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", + "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", "cpu": [ "x64" ], @@ -6064,13 +6080,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", + "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", "cpu": [ "x64" ], @@ -6080,13 +6096,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", + "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", "cpu": [ "arm64" ], @@ -6096,13 +6112,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", + "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", "cpu": [ "ia32" ], @@ -6112,13 +6128,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", + "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", "cpu": [ "x64" ], @@ -6128,45 +6144,46 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", + "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.23.0", + "@esbuild/android-arm": "0.23.0", + "@esbuild/android-arm64": "0.23.0", + "@esbuild/android-x64": "0.23.0", + "@esbuild/darwin-arm64": "0.23.0", + "@esbuild/darwin-x64": "0.23.0", + "@esbuild/freebsd-arm64": "0.23.0", + "@esbuild/freebsd-x64": "0.23.0", + "@esbuild/linux-arm": "0.23.0", + "@esbuild/linux-arm64": "0.23.0", + "@esbuild/linux-ia32": "0.23.0", + "@esbuild/linux-loong64": "0.23.0", + "@esbuild/linux-mips64el": "0.23.0", + "@esbuild/linux-ppc64": "0.23.0", + "@esbuild/linux-riscv64": "0.23.0", + "@esbuild/linux-s390x": "0.23.0", + "@esbuild/linux-x64": "0.23.0", + "@esbuild/netbsd-x64": "0.23.0", + "@esbuild/openbsd-arm64": "0.23.0", + "@esbuild/openbsd-x64": "0.23.0", + "@esbuild/sunos-x64": "0.23.0", + "@esbuild/win32-arm64": "0.23.0", + "@esbuild/win32-ia32": "0.23.0", + "@esbuild/win32-x64": "0.23.0" } }, "node_modules/typescript": { diff --git a/package.json b/package.json index afaa3ff..6bd0267 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.16.2", + "tsx": "^4.17.0", "typescript": "^5.5.4" } } From e47c29d2fd4eae06c511c914e2a5fcb057b44d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:14:29 -0700 Subject: [PATCH 16/92] chore(deps): bump rehype-katex from 7.0.0 to 7.0.1 (#1356) Bumps [rehype-katex](https://github.com/remarkjs/remark-math) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/remarkjs/remark-math/releases) - [Commits](https://github.com/remarkjs/remark-math/compare/rehype-katex@7.0.0...rehype-katex@7.0.1) --- updated-dependencies: - dependency-name: rehype-katex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4d5961..f7e2029 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", "rehype-citation": "^2.1.1", - "rehype-katex": "^7.0.0", + "rehype-katex": "^7.0.1", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.13.2", "rehype-raw": "^7.0.0", @@ -4863,9 +4863,9 @@ } }, "node_modules/rehype-katex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", - "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", diff --git a/package.json b/package.json index 6bd0267..96e5164 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", "rehype-citation": "^2.1.1", - "rehype-katex": "^7.0.0", + "rehype-katex": "^7.0.1", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.13.2", "rehype-raw": "^7.0.0", From 21e1921822b00816881bff50a74a43fd9a51d262 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:14:45 -0700 Subject: [PATCH 17/92] chore(deps): bump @napi-rs/simple-git from 0.1.16 to 0.1.17 (#1357) Bumps [@napi-rs/simple-git](https://github.com/Brooooooklyn/simple-git) from 0.1.16 to 0.1.17. - [Release notes](https://github.com/Brooooooklyn/simple-git/releases) - [Commits](https://github.com/Brooooooklyn/simple-git/compare/v0.1.16...v0.1.17) --- updated-dependencies: - dependency-name: "@napi-rs/simple-git" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 144 ++++++++++++++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 97 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7e2029..3af48a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.8", - "@napi-rs/simple-git": "0.1.16", + "@napi-rs/simple-git": "0.1.17", "async-mutex": "^0.5.0", "chalk": "^5.3.0", "chokidar": "^3.6.0", @@ -609,30 +609,33 @@ } }, "node_modules/@napi-rs/simple-git": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.16.tgz", - "integrity": "sha512-C5wRPw9waqL2jk3jEDeJv+f7ScuO3N0a39HVdyFLkwKxHH4Sya4ZbzZsu2JLi6eEqe7RuHipHL6mC7B2OfYZZw==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.17.tgz", + "integrity": "sha512-lH8bYk2kqfbKsht/Gejd8K+y069ZXPHBfrlcj1ptS6xlJbHhncHxpFyy57W+PTuCcN+MPGVjs+3CiufG8EUrCQ==", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@napi-rs/simple-git-android-arm-eabi": "0.1.16", - "@napi-rs/simple-git-android-arm64": "0.1.16", - "@napi-rs/simple-git-darwin-arm64": "0.1.16", - "@napi-rs/simple-git-darwin-x64": "0.1.16", - "@napi-rs/simple-git-linux-arm-gnueabihf": "0.1.16", - "@napi-rs/simple-git-linux-arm64-gnu": "0.1.16", - "@napi-rs/simple-git-linux-arm64-musl": "0.1.16", - "@napi-rs/simple-git-linux-x64-gnu": "0.1.16", - "@napi-rs/simple-git-linux-x64-musl": "0.1.16", - "@napi-rs/simple-git-win32-arm64-msvc": "0.1.16", - "@napi-rs/simple-git-win32-x64-msvc": "0.1.16" + "@napi-rs/simple-git-android-arm-eabi": "0.1.17", + "@napi-rs/simple-git-android-arm64": "0.1.17", + "@napi-rs/simple-git-darwin-arm64": "0.1.17", + "@napi-rs/simple-git-darwin-x64": "0.1.17", + "@napi-rs/simple-git-freebsd-x64": "0.1.17", + "@napi-rs/simple-git-linux-arm-gnueabihf": "0.1.17", + "@napi-rs/simple-git-linux-arm64-gnu": "0.1.17", + "@napi-rs/simple-git-linux-arm64-musl": "0.1.17", + "@napi-rs/simple-git-linux-powerpc64le-gnu": "0.1.17", + "@napi-rs/simple-git-linux-s390x-gnu": "0.1.17", + "@napi-rs/simple-git-linux-x64-gnu": "0.1.17", + "@napi-rs/simple-git-linux-x64-musl": "0.1.17", + "@napi-rs/simple-git-win32-arm64-msvc": "0.1.17", + "@napi-rs/simple-git-win32-x64-msvc": "0.1.17" } }, "node_modules/@napi-rs/simple-git-android-arm-eabi": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm-eabi/-/simple-git-android-arm-eabi-0.1.16.tgz", - "integrity": "sha512-dbrCL0Pl5KZG7x7tXdtVsA5CO6At5ohDX3myf5xIYn9kN4jDFxsocl8bNt6Vb/hZQoJd8fI+k5VlJt+rFhbdVw==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm-eabi/-/simple-git-android-arm-eabi-0.1.17.tgz", + "integrity": "sha512-P+B95PKy46Dq9q1sr18wCn+Uj/WShMIyBBA+ezVHWJge6JSeGh4hLhKEpv3+Rk6S7ITCXxrr7Pn7U4o20nVqhQ==", "cpu": [ "arm" ], @@ -645,9 +648,9 @@ } }, "node_modules/@napi-rs/simple-git-android-arm64": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm64/-/simple-git-android-arm64-0.1.16.tgz", - "integrity": "sha512-xYz+TW5J09iK8SuTAKK2D5MMIsBUXVSs8nYp7HcMi8q6FCRO7yJj96YfP9PvKsc/k64hOyqGmL5DhCzY9Cu1FQ==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm64/-/simple-git-android-arm64-0.1.17.tgz", + "integrity": "sha512-qggMcxfNKiQsAa1pupFuC8fajvAz6QQcZirHxTPWUxQSEwUvliL8cyKM4QdJwSac0VEITTmHaegDSXsn43EvGg==", "cpu": [ "arm64" ], @@ -660,9 +663,9 @@ } }, "node_modules/@napi-rs/simple-git-darwin-arm64": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-arm64/-/simple-git-darwin-arm64-0.1.16.tgz", - "integrity": "sha512-XfgsYqxhUE022MJobeiX563TJqyQyX4FmYCnqrtJwAfivESVeAJiH6bQIum8dDEYMHXCsG7nL8Ok0Dp8k2m42g==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-arm64/-/simple-git-darwin-arm64-0.1.17.tgz", + "integrity": "sha512-LYgvP3Rw1lCkBW0Ud4xZFUZ2SI+Y2vvy9X/OEzlmqee5VPC1wiez2kZ62lD3ABU0Ta4Khv7W+eJsaXiTuvcq+Q==", "cpu": [ "arm64" ], @@ -675,9 +678,9 @@ } }, "node_modules/@napi-rs/simple-git-darwin-x64": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.16.tgz", - "integrity": "sha512-tkEVBhD6vgRCbeWsaAQqM3bTfpIVGeitamPPRVSbsq8qgzJ5Dx6ZedH27R7KSsA/uao7mZ3dsrNLXbu1Wy5MzA==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.17.tgz", + "integrity": "sha512-CyLbxyLILT47jdNDTCREdO0LELKWqfkbw9EV4gaFrLZVD1Dej+NnZogR4oDrg7N12pcgVWnleaK1hcBDs7SeLQ==", "cpu": [ "x64" ], @@ -689,10 +692,25 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/simple-git-freebsd-x64": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-freebsd-x64/-/simple-git-freebsd-x64-0.1.17.tgz", + "integrity": "sha512-SHWa3o5EZWYh7UoLi2sO4uLjZd58UFHaMttw4O9PZPvFcdjz5LjC6CQclwZbLyPDPMGefalrkUeYTs+/VJ+XEA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@napi-rs/simple-git-linux-arm-gnueabihf": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm-gnueabihf/-/simple-git-linux-arm-gnueabihf-0.1.16.tgz", - "integrity": "sha512-R6VAyNnp/yRaT7DV1Ao3r67SqTWDa+fNq2LrNy0Z8gXk2wB9ZKlrxFtLPE1WSpWknWtyRDLpRlsorh7Evk7+7w==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm-gnueabihf/-/simple-git-linux-arm-gnueabihf-0.1.17.tgz", + "integrity": "sha512-nQpwitNfSN4qGmDpWOlS3XqeE7NARxCvL+lxO0CtKih2iBuWIoU0wViVKdf9fb/Rm3xsQHcblMkliMnjcAOupg==", "cpu": [ "arm" ], @@ -705,9 +723,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-arm64-gnu": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-gnu/-/simple-git-linux-arm64-gnu-0.1.16.tgz", - "integrity": "sha512-LAGI0opFKw/HBMCV2qIBK3uWSEW9h4xd2ireZKLJy8DBPymX6NrWIamuxYNyCuACnFdPRxR4LaRFy4J5ZwuMdw==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-gnu/-/simple-git-linux-arm64-gnu-0.1.17.tgz", + "integrity": "sha512-JD8nSLa9WY1kAppMufYqcqFYYjZKjZZFdZtlpz6Kn0kk4Qmm3Rvt1etnuQBwax9R2wG4n9YPYfpidDxic8rlNw==", "cpu": [ "arm64" ], @@ -720,9 +738,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-arm64-musl": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-musl/-/simple-git-linux-arm64-musl-0.1.16.tgz", - "integrity": "sha512-I57Ph0F0Yn2KW93ep+V1EzKhACqX0x49vvSiapqIsdDA2PifdEWLc1LJarBolmK7NKoPqKmf6lAKKO9lhiZzkg==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-musl/-/simple-git-linux-arm64-musl-0.1.17.tgz", + "integrity": "sha512-PRdVIEvgdIuJhDvdneO3X7XfZwujU7MOyymwK3kR1RMJPlbwzxdQBA86am/jEkBP7d8Cx8RbREzJ6y/2hAHKOQ==", "cpu": [ "arm64" ], @@ -734,10 +752,40 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/simple-git-linux-powerpc64le-gnu": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-powerpc64le-gnu/-/simple-git-linux-powerpc64le-gnu-0.1.17.tgz", + "integrity": "sha512-afbfsJMpQjtdLP3BRGj/hKpRqymxw2Lt+dmyoRej0zKxZnuPrws3Fi85RyYsT/6Tq0hSUAMeh5UtxGAOH3q8gA==", + "cpu": [ + "powerpc64le" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/simple-git-linux-s390x-gnu": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-s390x-gnu/-/simple-git-linux-s390x-gnu-0.1.17.tgz", + "integrity": "sha512-qTgRIUsU+b7RMls+Ji4xlDYq0rsUuNBpzVgb991UPnzrhFWFFkCtyk6I6tJqMtRfg7Vgn1stCghFEQiHmpqkew==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@napi-rs/simple-git-linux-x64-gnu": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-gnu/-/simple-git-linux-x64-gnu-0.1.16.tgz", - "integrity": "sha512-AZYYFY2V7hlcQASPEOWyOa3e1skzTct9QPzz0LiDM3f/hCFY/wBaU2M6NC5iG3d2Kr38heuyFS/+JqxLm5WaKA==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-gnu/-/simple-git-linux-x64-gnu-0.1.17.tgz", + "integrity": "sha512-xHlyUDJhjPUCR07JGrvMfLg5XSRVDsxgpo6B6zYQOSMcVgM7fjvyWNMBe508r4eD5YZKZyBPfSJUc5Ls9ToJNQ==", "cpu": [ "x64" ], @@ -750,9 +798,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-x64-musl": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-musl/-/simple-git-linux-x64-musl-0.1.16.tgz", - "integrity": "sha512-9TyMcYSBJwjT8jwjY9m24BZbu7ozyWTjsmYBYNtK3B0Um1Ov6jthSNneLVvouQ6x+k3Ow+00TiFh6bvmT00r8g==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-musl/-/simple-git-linux-x64-musl-0.1.17.tgz", + "integrity": "sha512-eaTr+WPeiuEegduE3O7VzHhHftGXmX1pzzILoOTbbdmeEuH1BHnGAr35XTu+1lUHUqE2JHef3d3PgBHeh844hA==", "cpu": [ "x64" ], @@ -765,9 +813,9 @@ } }, "node_modules/@napi-rs/simple-git-win32-arm64-msvc": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-arm64-msvc/-/simple-git-win32-arm64-msvc-0.1.16.tgz", - "integrity": "sha512-uslJ1WuAHCYJWui6xjsyT47SjX6KOHDtClmNO8hqKz1pmDSNY7AjyUY8HxvD1lK9bDnWwc4JYhikS9cxCqHybw==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-arm64-msvc/-/simple-git-win32-arm64-msvc-0.1.17.tgz", + "integrity": "sha512-v1F72stOCjapCd0Ha928m8X8i/IPhPQIXbYEGX0MEmaaAzbAJ3PTSSFpb0rFLShXaDFA2Wuw/jzlkPLESPdKVQ==", "cpu": [ "arm64" ], @@ -780,9 +828,9 @@ } }, "node_modules/@napi-rs/simple-git-win32-x64-msvc": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-x64-msvc/-/simple-git-win32-x64-msvc-0.1.16.tgz", - "integrity": "sha512-SoEaVeCZCDF1MP+M9bMSXsZWgEjk4On9GWADO5JOulvzR1bKjk0s9PMHwe/YztR9F0sJzrCxwtvBZowhSJsQPg==", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-x64-msvc/-/simple-git-win32-x64-msvc-0.1.17.tgz", + "integrity": "sha512-ziSqhCGE2eTUqpQKEutGobU2fH1t9fXwGF58dMFaPgTJIISaENvdnKu5FDJfA94vPbe3BMN64JoTmjBSglGFhQ==", "cpu": [ "x64" ], diff --git a/package.json b/package.json index 96e5164..2a7feaf 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "dependencies": { "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.8", - "@napi-rs/simple-git": "0.1.16", + "@napi-rs/simple-git": "0.1.17", "async-mutex": "^0.5.0", "chalk": "^5.3.0", "chokidar": "^3.6.0", From 7c5709b66008b565c3b298c7ec93c4cee432b91f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:15:34 -0700 Subject: [PATCH 18/92] chore(deps): bump preact-render-to-string from 6.5.7 to 6.5.9 (#1360) Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.5.7 to 6.5.9. - [Release notes](https://github.com/preactjs/preact-render-to-string/releases) - [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md) - [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.5.7...v6.5.9) --- updated-dependencies: - dependency-name: preact-render-to-string dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3af48a2..6961016 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "preact": "^10.23.2", - "preact-render-to-string": "^6.5.7", + "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", @@ -4764,9 +4764,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.7.tgz", - "integrity": "sha512-nACZDdv/ZZciuldVYMcfGqr61DKJeaAfPx96hn6OXoBGhgtU2yGQkA0EpTzWH4SvnwF0syLsL4WK7AIp3Ruc1g==", + "version": "6.5.9", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.9.tgz", + "integrity": "sha512-Fn9R89h6qrQeSRmsH2O2fWzqpVwsJgEL9UTly5nGEV2ldhVuG+9JhXdNJ6zreIkOZcBT20+AOMwlG1x72znJ+g==", "peerDependencies": { "preact": ">=10" } diff --git a/package.json b/package.json index 2a7feaf..7e1a839 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "preact": "^10.23.2", - "preact-render-to-string": "^6.5.7", + "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", From 437d65c8477575074ff2772ad6e3baef9a6f20cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:15:43 -0700 Subject: [PATCH 19/92] chore(deps): bump lightningcss from 1.25.1 to 1.26.0 (#1359) Bumps [lightningcss](https://github.com/parcel-bundler/lightningcss) from 1.25.1 to 1.26.0. - [Release notes](https://github.com/parcel-bundler/lightningcss/releases) - [Commits](https://github.com/parcel-bundler/lightningcss/compare/v1.25.1...v1.26.0) --- updated-dependencies: - dependency-name: lightningcss dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 100 +++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6961016..aa9758e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "hast-util-to-string": "^3.0.0", "is-absolute-url": "^4.0.1", "js-yaml": "^4.1.0", - "lightningcss": "^1.25.1", + "lightningcss": "^1.26.0", "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", @@ -3275,9 +3275,9 @@ } }, "node_modules/lightningcss": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.25.1.tgz", - "integrity": "sha512-V0RMVZzK1+rCHpymRv4URK2lNhIRyO8g7U7zOFwVAhJuat74HtkjIQpQRKNCwFEYkRGpafOpmXXLoaoBcyVtBg==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.26.0.tgz", + "integrity": "sha512-a/XZ5hdgifrofQJUArr5AiJjx26SwMam3SJUSMjgebZbESZ96i+6Qsl8tLi0kaUsdMzBWXh9sN1Oe6hp2/dkQw==", "dependencies": { "detect-libc": "^1.0.3" }, @@ -3289,21 +3289,22 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.25.1", - "lightningcss-darwin-x64": "1.25.1", - "lightningcss-freebsd-x64": "1.25.1", - "lightningcss-linux-arm-gnueabihf": "1.25.1", - "lightningcss-linux-arm64-gnu": "1.25.1", - "lightningcss-linux-arm64-musl": "1.25.1", - "lightningcss-linux-x64-gnu": "1.25.1", - "lightningcss-linux-x64-musl": "1.25.1", - "lightningcss-win32-x64-msvc": "1.25.1" + "lightningcss-darwin-arm64": "1.26.0", + "lightningcss-darwin-x64": "1.26.0", + "lightningcss-freebsd-x64": "1.26.0", + "lightningcss-linux-arm-gnueabihf": "1.26.0", + "lightningcss-linux-arm64-gnu": "1.26.0", + "lightningcss-linux-arm64-musl": "1.26.0", + "lightningcss-linux-x64-gnu": "1.26.0", + "lightningcss-linux-x64-musl": "1.26.0", + "lightningcss-win32-arm64-msvc": "1.26.0", + "lightningcss-win32-x64-msvc": "1.26.0" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.25.1.tgz", - "integrity": "sha512-G4Dcvv85bs5NLENcu/s1f7ehzE3D5ThnlWSDwE190tWXRQCQaqwcuHe+MGSVI/slm0XrxnaayXY+cNl3cSricw==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.26.0.tgz", + "integrity": "sha512-n4TIvHO1NY1ondKFYpL2ZX0bcC2y6yjXMD6JfyizgR8BCFNEeArINDzEaeqlfX9bXz73Bpz/Ow0nu+1qiDrBKg==", "cpu": [ "arm64" ], @@ -3320,9 +3321,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.25.1.tgz", - "integrity": "sha512-dYWuCzzfqRueDSmto6YU5SoGHvZTMU1Em9xvhcdROpmtOQLorurUZz8+xFxZ51lCO2LnYbfdjZ/gCqWEkwixNg==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.26.0.tgz", + "integrity": "sha512-Rf9HuHIDi1R6/zgBkJh25SiJHF+dm9axUZW/0UoYCW1/8HV0gMI0blARhH4z+REmWiU1yYT/KyNF3h7tHyRXUg==", "cpu": [ "x64" ], @@ -3339,9 +3340,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.25.1.tgz", - "integrity": "sha512-hXoy2s9A3KVNAIoKz+Fp6bNeY+h9c3tkcx1J3+pS48CqAt+5bI/R/YY4hxGL57fWAIquRjGKW50arltD6iRt/w==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.26.0.tgz", + "integrity": "sha512-C/io7POAxp6sZxFSVGezjajMlCKQ8KSwISLLGRq8xLQpQMokYrUoqYEwmIX8mLmF6C/CZPk0gFmRSzd8biWM0g==", "cpu": [ "x64" ], @@ -3358,9 +3359,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.25.1.tgz", - "integrity": "sha512-tWyMgHFlHlp1e5iW3EpqvH5MvsgoN7ZkylBbG2R2LWxnvH3FuWCJOhtGcYx9Ks0Kv0eZOBud789odkYLhyf1ng==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.26.0.tgz", + "integrity": "sha512-Aag9kqXqkyPSW+dXMgyWk66C984Nay2pY8Nws+67gHlDzV3cWh7TvFlzuaTaVFMVqdDTzN484LSK3u39zFBnzg==", "cpu": [ "arm" ], @@ -3377,9 +3378,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.25.1.tgz", - "integrity": "sha512-Xjxsx286OT9/XSnVLIsFEDyDipqe4BcLeB4pXQ/FEA5+2uWCCuAEarUNQumRucnj7k6ftkAHUEph5r821KBccQ==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.26.0.tgz", + "integrity": "sha512-iJmZM7fUyVjH+POtdiCtExG+67TtPUTer7K/5A8DIfmPfrmeGvzfRyBltGhQz13Wi15K1lf2cPYoRaRh6vcwNA==", "cpu": [ "arm64" ], @@ -3396,9 +3397,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.25.1.tgz", - "integrity": "sha512-IhxVFJoTW8wq6yLvxdPvyHv4NjzcpN1B7gjxrY3uaykQNXPHNIpChLB52+wfH+yS58zm1PL4LemUp8u9Cfp6Bw==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.26.0.tgz", + "integrity": "sha512-XxoEL++tTkyuvu+wq/QS8bwyTXZv2y5XYCMcWL45b8XwkiS8eEEEej9BkMGSRwxa5J4K+LDeIhLrS23CpQyfig==", "cpu": [ "arm64" ], @@ -3415,9 +3416,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.25.1.tgz", - "integrity": "sha512-RXIaru79KrREPEd6WLXfKfIp4QzoppZvD3x7vuTKkDA64PwTzKJ2jaC43RZHRt8BmyIkRRlmywNhTRMbmkPYpA==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.26.0.tgz", + "integrity": "sha512-1dkTfZQAYLj8MUSkd6L/+TWTG8V6Kfrzfa0T1fSlXCXQHrt1HC1/UepXHtKHDt/9yFwyoeayivxXAsApVxn6zA==", "cpu": [ "x64" ], @@ -3434,9 +3435,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.25.1.tgz", - "integrity": "sha512-TdcNqFsAENEEFr8fJWg0Y4fZ/nwuqTRsIr7W7t2wmDUlA8eSXVepeeONYcb+gtTj1RaXn/WgNLB45SFkz+XBZA==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.26.0.tgz", + "integrity": "sha512-yX3Rk9m00JGCUzuUhFEojY+jf/6zHs3XU8S8Vk+FRbnr4St7cjyMXdNjuA2LjiT8e7j8xHRCH8hyZ4H/btRE4A==", "cpu": [ "x64" ], @@ -3452,10 +3453,29 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.26.0.tgz", + "integrity": "sha512-X/597/cFnCogy9VItj/+7Tgu5VLbAtDF7KZDPdSw0MaL6FL940th1y3HiOzFIlziVvAtbo0RB3NAae1Oofr+Tw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.25.1.tgz", - "integrity": "sha512-9KZZkmmy9oGDSrnyHuxP6iMhbsgChUiu/NSgOx+U1I/wTngBStDf2i2aGRCHvFqj19HqqBEI4WuGVQBa2V6e0A==", + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.26.0.tgz", + "integrity": "sha512-pYS3EyGP3JRhfqEFYmfFDiZ9/pVNfy8jVIYtrx9TVNusVyDK3gpW1w/rbvroQ4bDJi7grdUtyrYU6V2xkY/bBw==", "cpu": [ "x64" ], diff --git a/package.json b/package.json index 7e1a839..a12cca2 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "hast-util-to-string": "^3.0.0", "is-absolute-url": "^4.0.1", "js-yaml": "^4.1.0", - "lightningcss": "^1.25.1", + "lightningcss": "^1.26.0", "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", From 6b499ed90c6e385a9f5385c7f8abf0e1294cbce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:18:00 -0700 Subject: [PATCH 20/92] chore(deps): bump @floating-ui/dom from 1.6.8 to 1.6.10 (#1358) Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.6.8 to 1.6.10. - [Release notes](https://github.com/floating-ui/floating-ui/releases) - [Changelog](https://github.com/floating-ui/floating-ui/blob/master/packages/dom/CHANGELOG.md) - [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.6.10/packages/dom) --- updated-dependencies: - dependency-name: "@floating-ui/dom" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa9758e..97813ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", - "@floating-ui/dom": "^1.6.8", + "@floating-ui/dom": "^1.6.10", "@napi-rs/simple-git": "0.1.17", "async-mutex": "^0.5.0", "chalk": "^5.3.0", @@ -579,18 +579,18 @@ } }, "node_modules/@floating-ui/dom": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", - "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", + "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.5" + "@floating-ui/utils": "^0.2.7" } }, "node_modules/@floating-ui/utils": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", - "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", diff --git a/package.json b/package.json index a12cca2..99c965b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "@clack/prompts": "^0.7.0", - "@floating-ui/dom": "^1.6.8", + "@floating-ui/dom": "^1.6.10", "@napi-rs/simple-git": "0.1.17", "async-mutex": "^0.5.0", "chalk": "^5.3.0", From 3b74453fe6768dc892574d739e7c30908c3833ca Mon Sep 17 00:00:00 2001 From: Eledah Date: Tue, 20 Aug 2024 19:58:52 +0330 Subject: [PATCH 21/92] docs: RTL showcase (#1362) --- docs/showcase.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/showcase.md b/docs/showcase.md index 5fd7133..2f92431 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -26,5 +26,6 @@ Want to see what Quartz can do? Here are some cool community gardens: - [Gatekeeper Wiki](https://www.gatekeeper.wiki) - [Ellie's Notes](https://ellie.wtf) - [🥷🏻🌳🍃 Computer Science & Thinkering Garden](https://notes.yxy.ninja) +- [Eledah's Crystalline](https://blog.eledah.ir/) If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/v4/docs/showcase.md)! From 647c12552569201dc1cf8c9b4f2ebb17fa2c1169 Mon Sep 17 00:00:00 2001 From: Elijah Kennedy Date: Fri, 23 Aug 2024 21:35:52 -0400 Subject: [PATCH 22/92] docs: added permalink description to supported frontmatter doc (#1369) --- docs/authoring content.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/authoring content.md b/docs/authoring content.md index d872a96..178f44a 100644 --- a/docs/authoring content.md +++ b/docs/authoring content.md @@ -29,6 +29,7 @@ Some common frontmatter fields that are natively supported by Quartz: - `title`: Title of the page. If it isn't provided, Quartz will use the name of the file as the title. - `description`: Description of the page used for link previews. +- `permalink`: A custom URL for the page that will remain constant even if the path to the file changes. - `aliases`: Other names for this note. This is a list of strings. - `tags`: Tags for this note. - `draft`: Whether to publish the page or not. This is one way to make [[private pages|pages private]] in Quartz. From f913332862907f77581f2bfcfb0878bebbc208da Mon Sep 17 00:00:00 2001 From: Tony Jackson Date: Fri, 23 Aug 2024 18:55:03 -0700 Subject: [PATCH 23/92] docs: Update Gitlab CI runner tag to use Gitlab runner (#1365) Co-authored-by: Tony Jackson --- docs/hosting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hosting.md b/docs/hosting.md index 853e30f..eaeea19 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -208,7 +208,7 @@ build: paths: - public tags: - - docker + - gitlab-org-docker pages: stage: deploy From 2be9c096a1d2c5a5bd43136d793fed9ea16f80f3 Mon Sep 17 00:00:00 2001 From: Aaron Pham Date: Sat, 24 Aug 2024 13:13:14 -0400 Subject: [PATCH 24/92] chore(features): remove implemented (#1350) --- docs/features/upcoming features.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/features/upcoming features.md b/docs/features/upcoming features.md index 11d9cbd..d45ebed 100644 --- a/docs/features/upcoming features.md +++ b/docs/features/upcoming features.md @@ -6,7 +6,6 @@ draft: true - static dead link detection - cursor chat extension -- https://giscus.app/ extension - sidenotes? https://github.com/capnfabs/paperesque - direct match in search using double quotes - https://help.obsidian.md/Advanced+topics/Using+Obsidian+URI From c4cd84dcc884469a0d84e2bec239b2fc3596c44f Mon Sep 17 00:00:00 2001 From: Andrew <80933354+ndrooo@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:13:55 -0400 Subject: [PATCH 25/92] fix: Add a wrapper element to dates in PageList. (#1345) * Add a wrapper span to dates in PageList. This means there is a placeholder when date is not specified, so the values in grid-template-columns always line up correctly. * Use a
instead -- better practice to stick to block elements. --- quartz/components/PageList.tsx | 12 +++++++----- quartz/components/styles/listPage.scss | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/quartz/components/PageList.tsx b/quartz/components/PageList.tsx index 8dc19b7..cc0124a 100644 --- a/quartz/components/PageList.tsx +++ b/quartz/components/PageList.tsx @@ -46,11 +46,13 @@ export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit, sort return (
  • - {page.dates && ( -

    - -

    - )} +
    + {page.dates && ( +

    + +

    + )} +

    diff --git a/quartz/components/styles/listPage.scss b/quartz/components/styles/listPage.scss index d51568d..44de70a 100644 --- a/quartz/components/styles/listPage.scss +++ b/quartz/components/styles/listPage.scss @@ -23,7 +23,7 @@ li.section-li { background-color: transparent; } - & > .meta { + & .meta { margin: 0 1em 0 0; opacity: 0.6; } From 46b63b68bf02491f841a794d72f3def6649ec72f Mon Sep 17 00:00:00 2001 From: Danny van Tol <19685217+dannyvtol@users.noreply.github.com> Date: Sat, 24 Aug 2024 21:56:17 +0200 Subject: [PATCH 26/92] fix: Link visibility in exampanded TOC while collapseByDefault is true (#1371) --- quartz/components/TableOfContents.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/components/TableOfContents.tsx b/quartz/components/TableOfContents.tsx index f3d8d7f..ec457cf 100644 --- a/quartz/components/TableOfContents.tsx +++ b/quartz/components/TableOfContents.tsx @@ -49,7 +49,7 @@ const TableOfContents: QuartzComponent = ({ -
    +
      {fileData.toc.map((tocEntry) => (
    • From 4c9e8601504f76dcc3c273ea8ad1862df432b7b4 Mon Sep 17 00:00:00 2001 From: Andrew <80933354+ndrooo@users.noreply.github.com> Date: Sat, 24 Aug 2024 16:33:30 -0400 Subject: [PATCH 27/92] a11y(darkmode): use a button for the theme toggle (#1335) * Use a ` ) } diff --git a/quartz/components/scripts/darkmode.inline.ts b/quartz/components/scripts/darkmode.inline.ts index 48e0aa1..038ae0f 100644 --- a/quartz/components/scripts/darkmode.inline.ts +++ b/quartz/components/scripts/darkmode.inline.ts @@ -11,7 +11,8 @@ const emitThemeChangeEvent = (theme: "light" | "dark") => { document.addEventListener("nav", () => { const switchTheme = (e: Event) => { - const newTheme = (e.target as HTMLInputElement)?.checked ? "dark" : "light" + const newTheme = + document.documentElement.getAttribute("saved-theme") === "dark" ? "light" : "dark" document.documentElement.setAttribute("saved-theme", newTheme) localStorage.setItem("theme", newTheme) emitThemeChangeEvent(newTheme) @@ -21,17 +22,13 @@ document.addEventListener("nav", () => { const newTheme = e.matches ? "dark" : "light" document.documentElement.setAttribute("saved-theme", newTheme) localStorage.setItem("theme", newTheme) - toggleSwitch.checked = e.matches emitThemeChangeEvent(newTheme) } // Darkmode toggle - const toggleSwitch = document.querySelector("#darkmode-toggle") as HTMLInputElement - toggleSwitch.addEventListener("change", switchTheme) - window.addCleanup(() => toggleSwitch.removeEventListener("change", switchTheme)) - if (currentTheme === "dark") { - toggleSwitch.checked = true - } + const themeButton = document.querySelector("#darkmode") as HTMLButtonElement + themeButton.addEventListener("click", switchTheme) + window.addCleanup(() => themeButton.removeEventListener("click", switchTheme)) // Listen for changes in prefers-color-scheme const colorSchemeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)") diff --git a/quartz/components/styles/darkmode.scss b/quartz/components/styles/darkmode.scss index 348c6f7..edf4e61 100644 --- a/quartz/components/styles/darkmode.scss +++ b/quartz/components/styles/darkmode.scss @@ -1,17 +1,15 @@ .darkmode { + cursor: pointer; + padding: 0; position: relative; + background: none; + border: none; width: 20px; height: 20px; margin: 0 10px; - - & > .toggle { - display: none; - box-sizing: border-box; - } + text-align: inherit; & svg { - cursor: pointer; - opacity: 0; position: absolute; width: 20px; height: 20px; @@ -29,20 +27,20 @@ color-scheme: light; } -:root[saved-theme="dark"] .toggle ~ label { +:root[saved-theme="dark"] .darkmode { & > #dayIcon { - opacity: 0; + display: none; } & > #nightIcon { - opacity: 1; + display: inline; } } -:root .toggle ~ label { +:root .darkmode { & > #dayIcon { - opacity: 1; + display: inline; } & > #nightIcon { - opacity: 0; + display: none; } } From bca74623a393c6957074e8adab90d056299e4c03 Mon Sep 17 00:00:00 2001 From: Aaron Pham Date: Sun, 25 Aug 2024 03:33:14 -0400 Subject: [PATCH 28/92] perf(graph): canvas implementation (#1328) * perf(graph): initial canvas layout include nodes and links drawn Signed-off-by: Aaron Pham * fix(graph): update persistent for nodeGfx Signed-off-by: Aaron Pham * chore(graph): add canvas element to avoid rerendering glitch Signed-off-by: Aaron Pham * fix(spa): only render graph once in global Signed-off-by: Aaron Pham * fix(graph): change svg as button render global graph on toggle Signed-off-by: Aaron Pham * fix(graph): fix anchor position and zIndex behaviour Signed-off-by: Aaron Pham * chore(graph): increase linkDistance Signed-off-by: Aaron Pham * refactor * fmt * pkg --------- Signed-off-by: Aaron Pham Co-authored-by: Jacky Zhao --- package-lock.json | 86 ++- package.json | 4 +- quartz/components/Graph.tsx | 51 +- quartz/components/scripts/graph.inline.ts | 654 ++++++++++++++-------- quartz/components/styles/graph.scss | 11 +- 5 files changed, 556 insertions(+), 250 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97813ea..d104192 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { "name": "@jackyzha0/quartz", - "version": "4.3.0", + "version": "4.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jackyzha0/quartz", - "version": "4.3.0", + "version": "4.3.1", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.10", "@napi-rs/simple-git": "0.1.17", + "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", "chalk": "^5.3.0", "chokidar": "^3.6.0", @@ -32,6 +33,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", + "pixi.js": "^8.3.3", "preact": "^10.23.2", "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", @@ -874,6 +876,12 @@ "node": ">= 8" } }, + "node_modules/@pixi/colord": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@pixi/colord/-/colord-2.9.6.tgz", + "integrity": "sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==", + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -902,6 +910,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@tweenjs/tween.js": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz", + "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==", + "license": "MIT" + }, "node_modules/@types/cli-spinner": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@types/cli-spinner/-/cli-spinner-0.2.3.tgz", @@ -911,6 +925,12 @@ "@types/node": "*" } }, + "node_modules/@types/css-font-loading-module": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz", + "integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==", + "license": "MIT" + }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", @@ -1172,6 +1192,12 @@ "@types/ms": "*" } }, + "node_modules/@types/earcut": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz", + "integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -1294,6 +1320,21 @@ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, + "node_modules/@webgpu/types": { + "version": "0.1.44", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.44.tgz", + "integrity": "sha512-JDpYJN5E/asw84LTYhKyvPpxGnD+bAKPtpW9Ilurf7cZpxaTbxkQcGwOd7jgB9BPBrTYQ+32ufo4HiuomTjHNQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -2194,6 +2235,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "license": "ISC" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2312,6 +2359,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3176,6 +3229,12 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/ismobilejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==", + "license": "MIT" + }, "node_modules/jackspeak": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", @@ -4698,6 +4757,12 @@ "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==", + "license": "MIT" + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -4774,6 +4839,23 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pixi.js": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.3.3.tgz", + "integrity": "sha512-dpucBKAqEm0K51MQKlXvyIJ40bcxniP82uz4ZPEQejGtPp0P+vueuG5DyArHCkC48mkVE2FEDvyYvBa45/JlQg==", + "license": "MIT", + "dependencies": { + "@pixi/colord": "^2.9.6", + "@types/css-font-loading-module": "^0.0.12", + "@types/earcut": "^2.1.4", + "@webgpu/types": "^0.1.40", + "@xmldom/xmldom": "^0.8.10", + "earcut": "^2.2.4", + "eventemitter3": "^5.0.1", + "ismobilejs": "^1.1.1", + "parse-svg-path": "^0.1.2" + } + }, "node_modules/preact": { "version": "10.23.2", "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", diff --git a/package.json b/package.json index 99c965b..5823535 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@jackyzha0/quartz", "description": "🌱 publish your digital garden and notes as a website", "private": true, - "version": "4.3.0", + "version": "4.3.1", "type": "module", "author": "jackyzha0 ", "license": "MIT", @@ -38,6 +38,7 @@ "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.10", "@napi-rs/simple-git": "0.1.17", + "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", "chalk": "^5.3.0", "chokidar": "^3.6.0", @@ -58,6 +59,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", + "pixi.js": "^8.3.3", "preact": "^10.23.2", "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", diff --git a/quartz/components/Graph.tsx b/quartz/components/Graph.tsx index f7ebcc9..ec3475d 100644 --- a/quartz/components/Graph.tsx +++ b/quartz/components/Graph.tsx @@ -65,31 +65,32 @@ export default ((opts?: GraphOptions) => {

      {i18n(cfg.locale).components.graph.title}

      - - - +
      diff --git a/quartz/components/scripts/graph.inline.ts b/quartz/components/scripts/graph.inline.ts index cda6fb5..6bf43aa 100644 --- a/quartz/components/scripts/graph.inline.ts +++ b/quartz/components/scripts/graph.inline.ts @@ -1,19 +1,56 @@ import type { ContentDetails } from "../../plugins/emitters/contentIndex" -import * as d3 from "d3" +import { + SimulationNodeDatum, + SimulationLinkDatum, + Simulation, + forceSimulation, + forceManyBody, + forceCenter, + forceLink, + forceCollide, + zoomIdentity, + select, + drag, + zoom, +} from "d3" +import { Text, Graphics, Application, Container, Circle } from "pixi.js" +import { Group as TweenGroup, Tween as Tweened } from "@tweenjs/tween.js" import { registerEscapeHandler, removeAllChildren } from "./util" import { FullSlug, SimpleSlug, getFullSlug, resolveRelative, simplifySlug } from "../../util/path" +import { D3Config } from "../Graph" + +type GraphicsInfo = { + color: string + gfx: Graphics + alpha: number + active: boolean +} type NodeData = { id: SimpleSlug text: string tags: string[] -} & d3.SimulationNodeDatum +} & SimulationNodeDatum -type LinkData = { +type SimpleLinkData = { source: SimpleSlug target: SimpleSlug } +type LinkData = { + source: NodeData + target: NodeData +} & SimulationLinkDatum + +type LinkRenderData = GraphicsInfo & { + simulationData: LinkData +} + +type NodeRenderData = GraphicsInfo & { + simulationData: NodeData + label: Text +} + const localStorageKey = "graph-visited" function getVisited(): Set { return new Set(JSON.parse(localStorage.getItem(localStorageKey) ?? "[]")) @@ -25,6 +62,11 @@ function addToVisited(slug: SimpleSlug) { localStorage.setItem(localStorageKey, JSON.stringify([...visited])) } +type TweenNode = { + update: (time: number) => void + stop: () => void +} + async function renderGraph(container: string, fullSlug: FullSlug) { const slug = simplifySlug(fullSlug) const visited = getVisited() @@ -45,7 +87,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) { removeTags, showTags, focusOnHover, - } = JSON.parse(graph.dataset["cfg"]!) + } = JSON.parse(graph.dataset["cfg"]!) as D3Config const data: Map = new Map( Object.entries(await fetchData).map(([k, v]) => [ @@ -53,10 +95,11 @@ async function renderGraph(container: string, fullSlug: FullSlug) { v, ]), ) - const links: LinkData[] = [] + const links: SimpleLinkData[] = [] const tags: SimpleSlug[] = [] - const validLinks = new Set(data.keys()) + + const tweens = new Map() for (const [source, details] of data.entries()) { const outgoing = details.links ?? [] @@ -100,263 +143,406 @@ async function renderGraph(container: string, fullSlug: FullSlug) { if (showTags) tags.forEach((tag) => neighbourhood.add(tag)) } + const nodes = [...neighbourhood].map((url) => { + const text = url.startsWith("tags/") ? "#" + url.substring(5) : (data.get(url)?.title ?? url) + return { + id: url, + text, + tags: data.get(url)?.tags ?? [], + } + }) const graphData: { nodes: NodeData[]; links: LinkData[] } = { - nodes: [...neighbourhood].map((url) => { - const text = url.startsWith("tags/") ? "#" + url.substring(5) : (data.get(url)?.title ?? url) - return { - id: url, - text: text, - tags: data.get(url)?.tags ?? [], - } - }), - links: links.filter((l) => neighbourhood.has(l.source) && neighbourhood.has(l.target)), + nodes, + links: links + .filter((l) => neighbourhood.has(l.source) && neighbourhood.has(l.target)) + .map((l) => ({ + source: nodes.find((n) => n.id === l.source)!, + target: nodes.find((n) => n.id === l.target)!, + })), } - const simulation: d3.Simulation = d3 - .forceSimulation(graphData.nodes) - .force("charge", d3.forceManyBody().strength(-100 * repelForce)) - .force( - "link", - d3 - .forceLink(graphData.links) - .id((d: any) => d.id) - .distance(linkDistance), - ) - .force("center", d3.forceCenter().strength(centerForce)) + // we virtualize the simulation and use pixi to actually render it + const simulation: Simulation = forceSimulation(graphData.nodes) + .force("charge", forceManyBody().strength(-100 * repelForce)) + .force("center", forceCenter().strength(centerForce)) + .force("link", forceLink(graphData.links).distance(linkDistance)) + .force("collide", forceCollide((n) => nodeRadius(n)).iterations(3)) - const height = Math.max(graph.offsetHeight, 250) const width = graph.offsetWidth + const height = Math.max(graph.offsetHeight, 250) - const svg = d3 - .select("#" + container) - .append("svg") - .attr("width", width) - .attr("height", height) - .attr("viewBox", [-width / 2 / scale, -height / 2 / scale, width / scale, height / scale]) - - // draw links between nodes - const link = svg - .append("g") - .selectAll("line") - .data(graphData.links) - .join("line") - .attr("class", "link") - .attr("stroke", "var(--lightgray)") - .attr("stroke-width", 1) - - // svg groups - const graphNode = svg.append("g").selectAll("g").data(graphData.nodes).enter().append("g") + // precompute style prop strings as pixi doesn't support css variables + const cssVars = [ + "--secondary", + "--tertiary", + "--gray", + "--light", + "--lightgray", + "--dark", + "--darkgray", + "--bodyFont", + ] as const + const computedStyleMap = cssVars.reduce( + (acc, key) => { + acc[key] = getComputedStyle(document.documentElement).getPropertyValue(key) + return acc + }, + {} as Record<(typeof cssVars)[number], string>, + ) // calculate color const color = (d: NodeData) => { const isCurrent = d.id === slug if (isCurrent) { - return "var(--secondary)" + return computedStyleMap["--secondary"] } else if (visited.has(d.id) || d.id.startsWith("tags/")) { - return "var(--tertiary)" + return computedStyleMap["--tertiary"] } else { - return "var(--gray)" + return computedStyleMap["--gray"] } } - const drag = (simulation: d3.Simulation) => { - function dragstarted(event: any, d: NodeData) { - if (!event.active) simulation.alphaTarget(1).restart() - d.fx = d.x - d.fy = d.y - } - - function dragged(event: any, d: NodeData) { - d.fx = event.x - d.fy = event.y - } - - function dragended(event: any, d: NodeData) { - if (!event.active) simulation.alphaTarget(0) - d.fx = null - d.fy = null - } - - const noop = () => {} - return d3 - .drag() - .on("start", enableDrag ? dragstarted : noop) - .on("drag", enableDrag ? dragged : noop) - .on("end", enableDrag ? dragended : noop) - } - function nodeRadius(d: NodeData) { - const numLinks = links.filter((l: any) => l.source.id === d.id || l.target.id === d.id).length + const numLinks = graphData.links.filter( + (l) => l.source.id === d.id || l.target.id === d.id, + ).length return 2 + Math.sqrt(numLinks) } - let connectedNodes: SimpleSlug[] = [] + let hoveredNodeId: string | null = null + let hoveredNeighbours: Set = new Set() + const linkRenderData: LinkRenderData[] = [] + const nodeRenderData: NodeRenderData[] = [] + function updateHoverInfo(newHoveredId: string | null) { + hoveredNodeId = newHoveredId - // draw individual nodes - const node = graphNode - .append("circle") - .attr("class", "node") - .attr("id", (d) => d.id) - .attr("r", nodeRadius) - .attr("fill", color) - .style("cursor", "pointer") - .on("click", (_, d) => { - const targ = resolveRelative(fullSlug, d.id) - window.spaNavigate(new URL(targ, window.location.toString())) - }) - .on("mouseover", function (_, d) { - const currentId = d.id - const linkNodes = d3 - .selectAll(".link") - .filter((d: any) => d.source.id === currentId || d.target.id === currentId) - - if (focusOnHover) { - // fade out non-neighbour nodes - connectedNodes = linkNodes.data().flatMap((d: any) => [d.source.id, d.target.id]) - - d3.selectAll(".link") - .transition() - .duration(200) - .style("opacity", 0.2) - d3.selectAll(".node") - .filter((d) => !connectedNodes.includes(d.id)) - .transition() - .duration(200) - .style("opacity", 0.2) - - d3.selectAll(".node") - .filter((d) => !connectedNodes.includes(d.id)) - .nodes() - .map((it) => d3.select(it.parentNode as HTMLElement).select("text")) - .forEach((it) => { - let opacity = parseFloat(it.style("opacity")) - it.transition() - .duration(200) - .attr("opacityOld", opacity) - .style("opacity", Math.min(opacity, 0.2)) - }) + if (newHoveredId === null) { + hoveredNeighbours = new Set() + for (const n of nodeRenderData) { + n.active = false } - // highlight links - linkNodes.transition().duration(200).attr("stroke", "var(--gray)").attr("stroke-width", 1) - - const bigFont = fontSize * 1.5 - - // show text for self - const parent = this.parentNode as HTMLElement - d3.select(parent) - .raise() - .select("text") - .transition() - .duration(200) - .attr("opacityOld", d3.select(parent).select("text").style("opacity")) - .style("opacity", 1) - .style("font-size", bigFont + "em") - }) - .on("mouseleave", function (_, d) { - if (focusOnHover) { - d3.selectAll(".link").transition().duration(200).style("opacity", 1) - d3.selectAll(".node").transition().duration(200).style("opacity", 1) - - d3.selectAll(".node") - .filter((d) => !connectedNodes.includes(d.id)) - .nodes() - .map((it) => d3.select(it.parentNode as HTMLElement).select("text")) - .forEach((it) => it.transition().duration(200).style("opacity", it.attr("opacityOld"))) + for (const l of linkRenderData) { + l.active = false } - const currentId = d.id - const linkNodes = d3 - .selectAll(".link") - .filter((d: any) => d.source.id === currentId || d.target.id === currentId) + } else { + hoveredNeighbours = new Set() + for (const l of linkRenderData) { + const linkData = l.simulationData + if (linkData.source.id === newHoveredId || linkData.target.id === newHoveredId) { + hoveredNeighbours.add(linkData.source.id) + hoveredNeighbours.add(linkData.target.id) + } - linkNodes.transition().duration(200).attr("stroke", "var(--lightgray)") + l.active = linkData.source.id === newHoveredId || linkData.target.id === newHoveredId + } - const parent = this.parentNode as HTMLElement - d3.select(parent) - .select("text") - .transition() - .duration(200) - .style("opacity", d3.select(parent).select("text").attr("opacityOld")) - .style("font-size", fontSize + "em") + for (const n of nodeRenderData) { + n.active = hoveredNeighbours.has(n.simulationData.id) + } + } + } + + let dragStartTime = 0 + let dragging = false + + function renderLinks() { + tweens.get("link")?.stop() + const tweenGroup = new TweenGroup() + + for (const l of linkRenderData) { + let alpha = 1 + + // if we are hovering over a node, we want to highlight the immediate neighbours + // with full alpha and the rest with default alpha + if (hoveredNodeId) { + alpha = l.active ? 1 : 0.2 + } + + l.color = l.active ? computedStyleMap["--gray"] : computedStyleMap["--lightgray"] + tweenGroup.add(new Tweened(l).to({ alpha }, 200)) + } + + tweenGroup.getAll().forEach((tw) => tw.start()) + tweens.set("link", { + update: tweenGroup.update.bind(tweenGroup), + stop() { + tweenGroup.getAll().forEach((tw) => tw.stop()) + }, }) - // @ts-ignore - .call(drag(simulation)) + } - // make tags hollow circles - node - .filter((d) => d.id.startsWith("tags/")) - .attr("stroke", color) - .attr("stroke-width", 2) - .attr("fill", "var(--light)") + function renderLabels() { + tweens.get("label")?.stop() + const tweenGroup = new TweenGroup() - // draw labels - const labels = graphNode - .append("text") - .attr("dx", 0) - .attr("dy", (d) => -nodeRadius(d) + "px") - .attr("text-anchor", "middle") - .text((d) => d.text) - .style("opacity", (opacityScale - 1) / 3.75) - .style("pointer-events", "none") - .style("font-size", fontSize + "em") - .raise() - // @ts-ignore - .call(drag(simulation)) + const defaultScale = 1 / scale + const activeScale = defaultScale * 1.1 + for (const n of nodeRenderData) { + const nodeId = n.simulationData.id + + if (hoveredNodeId === nodeId) { + tweenGroup.add( + new Tweened(n.label).to( + { + alpha: 1, + scale: { x: activeScale, y: activeScale }, + }, + 100, + ), + ) + } else { + tweenGroup.add( + new Tweened(n.label).to( + { + alpha: n.label.alpha, + scale: { x: defaultScale, y: defaultScale }, + }, + 100, + ), + ) + } + } + + tweenGroup.getAll().forEach((tw) => tw.start()) + tweens.set("label", { + update: tweenGroup.update.bind(tweenGroup), + stop() { + tweenGroup.getAll().forEach((tw) => tw.stop()) + }, + }) + } + + function renderNodes() { + tweens.get("hover")?.stop() + + const tweenGroup = new TweenGroup() + for (const n of nodeRenderData) { + let alpha = 1 + + // if we are hovering over a node, we want to highlight the immediate neighbours + if (hoveredNodeId !== null && focusOnHover) { + alpha = n.active ? 1 : 0.2 + } + + tweenGroup.add(new Tweened(n.gfx, tweenGroup).to({ alpha }, 200)) + } + + tweenGroup.getAll().forEach((tw) => tw.start()) + tweens.set("hover", { + update: tweenGroup.update.bind(tweenGroup), + stop() { + tweenGroup.getAll().forEach((tw) => tw.stop()) + }, + }) + } + + function renderPixiFromD3() { + renderNodes() + renderLinks() + renderLabels() + } + + tweens.forEach((tween) => tween.stop()) + tweens.clear() + + const app = new Application() + await app.init({ + width, + height, + antialias: true, + autoStart: false, + autoDensity: true, + backgroundAlpha: 0, + preference: "webgpu", + resolution: window.devicePixelRatio, + eventMode: "static", + }) + graph.appendChild(app.canvas) + + const stage = app.stage + stage.interactive = false + + const labelsContainer = new Container({ zIndex: 3 }) + const nodesContainer = new Container({ zIndex: 2 }) + const linkContainer = new Container({ zIndex: 1 }) + stage.addChild(nodesContainer, labelsContainer, linkContainer) + + for (const n of graphData.nodes) { + const nodeId = n.id + + const label = new Text({ + interactive: false, + eventMode: "none", + text: n.text, + alpha: 0, + anchor: { x: 0.5, y: 1.2 }, + style: { + fontSize: fontSize * 15, + fill: computedStyleMap["--dark"], + fontFamily: computedStyleMap["--bodyFont"], + }, + resolution: window.devicePixelRatio * 4, + }) + label.scale.set(1 / scale) + + let oldLabelOpacity = 0 + const isTagNode = nodeId.startsWith("tags/") + const gfx = new Graphics({ + interactive: true, + label: nodeId, + eventMode: "static", + hitArea: new Circle(0, 0, nodeRadius(n)), + cursor: "pointer", + }) + .circle(0, 0, nodeRadius(n)) + .fill({ color: isTagNode ? computedStyleMap["--light"] : color(n) }) + .stroke({ width: isTagNode ? 2 : 0, color: color(n) }) + .on("pointerover", (e) => { + updateHoverInfo(e.target.label) + oldLabelOpacity = label.alpha + if (!dragging) { + renderPixiFromD3() + } + }) + .on("pointerleave", () => { + updateHoverInfo(null) + label.alpha = oldLabelOpacity + if (!dragging) { + renderPixiFromD3() + } + }) + + nodesContainer.addChild(gfx) + labelsContainer.addChild(label) + + const nodeRenderDatum: NodeRenderData = { + simulationData: n, + gfx, + label, + color: color(n), + alpha: 1, + active: false, + } + + nodeRenderData.push(nodeRenderDatum) + } + + for (const l of graphData.links) { + const gfx = new Graphics({ interactive: false, eventMode: "none" }) + linkContainer.addChild(gfx) + + const linkRenderDatum: LinkRenderData = { + simulationData: l, + gfx, + color: computedStyleMap["--lightgray"], + alpha: 1, + active: false, + } + + linkRenderData.push(linkRenderDatum) + } + + let currentTransform = zoomIdentity + if (enableDrag) { + select(app.canvas).call( + drag() + .container(() => app.canvas) + .subject(() => graphData.nodes.find((n) => n.id === hoveredNodeId)) + .on("start", function dragstarted(event) { + if (!event.active) simulation.alphaTarget(1).restart() + event.subject.fx = event.subject.x + event.subject.fy = event.subject.y + event.subject.__initialDragPos = { + x: event.subject.x, + y: event.subject.y, + fx: event.subject.fx, + fy: event.subject.fy, + } + dragStartTime = Date.now() + dragging = true + }) + .on("drag", function dragged(event) { + const initPos = event.subject.__initialDragPos + event.subject.fx = initPos.x + (event.x - initPos.x) / currentTransform.k + event.subject.fy = initPos.y + (event.y - initPos.y) / currentTransform.k + }) + .on("end", function dragended(event) { + if (!event.active) simulation.alphaTarget(0) + event.subject.fx = null + event.subject.fy = null + dragging = false + + // if the time between mousedown and mouseup is short, we consider it a click + if (Date.now() - dragStartTime < 500) { + const node = graphData.nodes.find((n) => n.id === event.subject.id) as NodeData + const targ = resolveRelative(fullSlug, node.id) + window.spaNavigate(new URL(targ, window.location.toString())) + } + }), + ) + } else { + for (const node of nodeRenderData) { + node.gfx.on("click", () => { + const targ = resolveRelative(fullSlug, node.simulationData.id) + window.spaNavigate(new URL(targ, window.location.toString())) + }) + } + } - // set panning if (enableZoom) { - svg.call( - d3 - .zoom() + select(app.canvas).call( + zoom() .extent([ [0, 0], [width, height], ]) .scaleExtent([0.25, 4]) .on("zoom", ({ transform }) => { - link.attr("transform", transform) - node.attr("transform", transform) + currentTransform = transform + stage.scale.set(transform.k, transform.k) + stage.position.set(transform.x, transform.y) + + // zoom adjusts opacity of labels too const scale = transform.k * opacityScale - const scaledOpacity = Math.max((scale - 1) / 3.75, 0) - labels.attr("transform", transform).style("opacity", scaledOpacity) + let scaleOpacity = Math.max((scale - 1) / 3.75, 0) + const activeNodes = nodeRenderData.filter((n) => n.active).flatMap((n) => n.label) + + for (const label of labelsContainer.children) { + if (!activeNodes.includes(label)) { + label.alpha = scaleOpacity + } + } }), ) } - // progress the simulation - simulation.on("tick", () => { - link - .attr("x1", (d: any) => d.source.x) - .attr("y1", (d: any) => d.source.y) - .attr("x2", (d: any) => d.target.x) - .attr("y2", (d: any) => d.target.y) - node.attr("cx", (d: any) => d.x).attr("cy", (d: any) => d.y) - labels.attr("x", (d: any) => d.x).attr("y", (d: any) => d.y) - }) -} - -function renderGlobalGraph() { - const slug = getFullSlug(window) - const container = document.getElementById("global-graph-outer") - const sidebar = container?.closest(".sidebar") as HTMLElement - container?.classList.add("active") - if (sidebar) { - sidebar.style.zIndex = "1" - } - - renderGraph("global-graph-container", slug) - - function hideGlobalGraph() { - container?.classList.remove("active") - const graph = document.getElementById("global-graph-container") - if (sidebar) { - sidebar.style.zIndex = "unset" + function animate(time: number) { + for (const n of nodeRenderData) { + const { x, y } = n.simulationData + if (!x || !y) continue + n.gfx.position.set(x + width / 2, y + height / 2) + if (n.label) { + n.label.position.set(x + width / 2, y + height / 2) + } } - if (!graph) return - removeAllChildren(graph) + + for (const l of linkRenderData) { + const linkData = l.simulationData + l.gfx.clear() + l.gfx.moveTo(linkData.source.x! + width / 2, linkData.source.y! + height / 2) + l.gfx + .lineTo(linkData.target.x! + width / 2, linkData.target.y! + height / 2) + .stroke({ alpha: l.alpha, width: 1, color: l.color }) + } + + tweens.forEach((t) => t.update(time)) + app.renderer.render(stage) + requestAnimationFrame(animate) } - registerEscapeHandler(container, hideGlobalGraph) + const graphAnimationFrameHandle = requestAnimationFrame(animate) + window.addCleanup(() => cancelAnimationFrame(graphAnimationFrameHandle)) } document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { @@ -364,7 +550,39 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { addToVisited(simplifySlug(slug)) await renderGraph("graph-container", slug) + const container = document.getElementById("global-graph-outer") + const sidebar = container?.closest(".sidebar") as HTMLElement + + function renderGlobalGraph() { + const slug = getFullSlug(window) + container?.classList.add("active") + if (sidebar) { + sidebar.style.zIndex = "1" + } + + renderGraph("global-graph-container", slug) + registerEscapeHandler(container, hideGlobalGraph) + } + + function hideGlobalGraph() { + container?.classList.remove("active") + if (sidebar) { + sidebar.style.zIndex = "unset" + } + } + + async function shortcutHandler(e: HTMLElementEventMap["keydown"]) { + if (e.key === "g" && (e.ctrlKey || e.metaKey) && !e.shiftKey) { + e.preventDefault() + const globalGraphOpen = container?.classList.contains("active") + globalGraphOpen ? hideGlobalGraph() : renderGlobalGraph() + } + } + const containerIcon = document.getElementById("global-graph-icon") containerIcon?.addEventListener("click", renderGlobalGraph) window.addCleanup(() => containerIcon?.removeEventListener("click", renderGlobalGraph)) + + document.addEventListener("keydown", shortcutHandler) + window.addCleanup(() => document.removeEventListener("keydown", shortcutHandler)) }) diff --git a/quartz/components/styles/graph.scss b/quartz/components/styles/graph.scss index 3deaa1f..188907d 100644 --- a/quartz/components/styles/graph.scss +++ b/quartz/components/styles/graph.scss @@ -16,10 +16,13 @@ overflow: hidden; & > #global-graph-icon { + cursor: pointer; + background: none; + border: none; color: var(--dark); opacity: 0.5; - width: 18px; - height: 18px; + width: 24px; + height: 24px; position: absolute; padding: 0.2rem; margin: 0.3rem; @@ -59,8 +62,8 @@ top: 50%; left: 50%; transform: translate(-50%, -50%); - height: 60vh; - width: 50vw; + height: 80vh; + width: 80vw; @media all and (max-width: $fullPageWidth) { width: 90%; From 3b988aec61ce72400ef5ca5f700beeb0e3d54208 Mon Sep 17 00:00:00 2001 From: Iker Larrea <69987085+ikerls@users.noreply.github.com> Date: Mon, 26 Aug 2024 04:33:34 +0200 Subject: [PATCH 29/92] fix: Popover z-index issue on left sidebar (#1230) --- quartz/styles/base.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 3b3ead7..02b0f53 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -172,6 +172,7 @@ a { box-sizing: border-box; padding: 0 4rem; position: fixed; + z-index: 1; @media all and (max-width: $fullPageWidth) { position: initial; flex-direction: row; From 40f039983c29d5355950a80c19a1a13f220a3d72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:12:35 -0700 Subject: [PATCH 30/92] chore(deps-dev): bump tsx from 4.17.0 to 4.18.0 (#1377) Bumps [tsx](https://github.com/privatenumber/tsx) from 4.17.0 to 4.18.0. - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.17.0...v4.18.0) --- updated-dependencies: - dependency-name: tsx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d104192..b755c7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.17.0", + "tsx": "^4.18.0", "typescript": "^5.5.4" }, "engines": { @@ -5911,9 +5911,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.17.0.tgz", - "integrity": "sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.18.0.tgz", + "integrity": "sha512-a1jaKBSVQkd6yEc1/NI7G6yHFfefIcuf3QJST7ZEyn4oQnxLYrZR5uZAM8UrwUa3Ge8suiZHcNS1gNrEvmobqg==", "dev": true, "dependencies": { "esbuild": "~0.23.0", diff --git a/package.json b/package.json index 5823535..5a09299 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.17.0", + "tsx": "^4.18.0", "typescript": "^5.5.4" } } From 4e2aea8a5a414b3bcfac0168bea4f6afd032e8f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:12:45 -0700 Subject: [PATCH 31/92] chore(deps): bump @napi-rs/simple-git from 0.1.17 to 0.1.19 (#1376) Bumps [@napi-rs/simple-git](https://github.com/Brooooooklyn/simple-git) from 0.1.17 to 0.1.19. - [Release notes](https://github.com/Brooooooklyn/simple-git/releases) - [Commits](https://github.com/Brooooooklyn/simple-git/compare/v0.1.17...v0.1.19) --- updated-dependencies: - dependency-name: "@napi-rs/simple-git" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 120 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index b755c7d..81c66cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.10", - "@napi-rs/simple-git": "0.1.17", + "@napi-rs/simple-git": "0.1.19", "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", "chalk": "^5.3.0", @@ -611,33 +611,33 @@ } }, "node_modules/@napi-rs/simple-git": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.17.tgz", - "integrity": "sha512-lH8bYk2kqfbKsht/Gejd8K+y069ZXPHBfrlcj1ptS6xlJbHhncHxpFyy57W+PTuCcN+MPGVjs+3CiufG8EUrCQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.19.tgz", + "integrity": "sha512-jMxvwzkKzd3cXo2EB9GM2ic0eYo2rP/BS6gJt6HnWbsDO1O8GSD4k7o2Cpr2YERtMpGF/MGcDfsfj2EbQPtrXw==", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@napi-rs/simple-git-android-arm-eabi": "0.1.17", - "@napi-rs/simple-git-android-arm64": "0.1.17", - "@napi-rs/simple-git-darwin-arm64": "0.1.17", - "@napi-rs/simple-git-darwin-x64": "0.1.17", - "@napi-rs/simple-git-freebsd-x64": "0.1.17", - "@napi-rs/simple-git-linux-arm-gnueabihf": "0.1.17", - "@napi-rs/simple-git-linux-arm64-gnu": "0.1.17", - "@napi-rs/simple-git-linux-arm64-musl": "0.1.17", - "@napi-rs/simple-git-linux-powerpc64le-gnu": "0.1.17", - "@napi-rs/simple-git-linux-s390x-gnu": "0.1.17", - "@napi-rs/simple-git-linux-x64-gnu": "0.1.17", - "@napi-rs/simple-git-linux-x64-musl": "0.1.17", - "@napi-rs/simple-git-win32-arm64-msvc": "0.1.17", - "@napi-rs/simple-git-win32-x64-msvc": "0.1.17" + "@napi-rs/simple-git-android-arm-eabi": "0.1.19", + "@napi-rs/simple-git-android-arm64": "0.1.19", + "@napi-rs/simple-git-darwin-arm64": "0.1.19", + "@napi-rs/simple-git-darwin-x64": "0.1.19", + "@napi-rs/simple-git-freebsd-x64": "0.1.19", + "@napi-rs/simple-git-linux-arm-gnueabihf": "0.1.19", + "@napi-rs/simple-git-linux-arm64-gnu": "0.1.19", + "@napi-rs/simple-git-linux-arm64-musl": "0.1.19", + "@napi-rs/simple-git-linux-powerpc64le-gnu": "0.1.19", + "@napi-rs/simple-git-linux-s390x-gnu": "0.1.19", + "@napi-rs/simple-git-linux-x64-gnu": "0.1.19", + "@napi-rs/simple-git-linux-x64-musl": "0.1.19", + "@napi-rs/simple-git-win32-arm64-msvc": "0.1.19", + "@napi-rs/simple-git-win32-x64-msvc": "0.1.19" } }, "node_modules/@napi-rs/simple-git-android-arm-eabi": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm-eabi/-/simple-git-android-arm-eabi-0.1.17.tgz", - "integrity": "sha512-P+B95PKy46Dq9q1sr18wCn+Uj/WShMIyBBA+ezVHWJge6JSeGh4hLhKEpv3+Rk6S7ITCXxrr7Pn7U4o20nVqhQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm-eabi/-/simple-git-android-arm-eabi-0.1.19.tgz", + "integrity": "sha512-XryEH/hadZ4Duk/HS/HC/cA1j0RHmqUGey3MsCf65ZS0VrWMqChXM/xlTPWuY5jfCc/rPubHaqI7DZlbexnX/g==", "cpu": [ "arm" ], @@ -650,9 +650,9 @@ } }, "node_modules/@napi-rs/simple-git-android-arm64": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm64/-/simple-git-android-arm64-0.1.17.tgz", - "integrity": "sha512-qggMcxfNKiQsAa1pupFuC8fajvAz6QQcZirHxTPWUxQSEwUvliL8cyKM4QdJwSac0VEITTmHaegDSXsn43EvGg==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-android-arm64/-/simple-git-android-arm64-0.1.19.tgz", + "integrity": "sha512-ZQ0cPvY6nV9p7zrR9ZPo7hQBkDAcY/CHj3BjYNhykeUCiSNCrhvwX+WEeg5on8M1j4d5jcI/cwVG2FslfiByUg==", "cpu": [ "arm64" ], @@ -665,9 +665,9 @@ } }, "node_modules/@napi-rs/simple-git-darwin-arm64": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-arm64/-/simple-git-darwin-arm64-0.1.17.tgz", - "integrity": "sha512-LYgvP3Rw1lCkBW0Ud4xZFUZ2SI+Y2vvy9X/OEzlmqee5VPC1wiez2kZ62lD3ABU0Ta4Khv7W+eJsaXiTuvcq+Q==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-arm64/-/simple-git-darwin-arm64-0.1.19.tgz", + "integrity": "sha512-viZB5TYgjA1vH+QluhxZo0WKro3xBA+1xSzYx8mcxUMO5gnAoUMwXn0ZO/6Zy6pai+aGae+cj6XihGnrBRu3Pg==", "cpu": [ "arm64" ], @@ -680,9 +680,9 @@ } }, "node_modules/@napi-rs/simple-git-darwin-x64": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.17.tgz", - "integrity": "sha512-CyLbxyLILT47jdNDTCREdO0LELKWqfkbw9EV4gaFrLZVD1Dej+NnZogR4oDrg7N12pcgVWnleaK1hcBDs7SeLQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.19.tgz", + "integrity": "sha512-6dNkzSNUV5X9rsVYQbpZLyJu4Gtkl2vNJ3abBXHX/Etk0ILG5ZasO3ncznIANZQpqcbn/QPHr49J2QYAXGoKJA==", "cpu": [ "x64" ], @@ -695,9 +695,9 @@ } }, "node_modules/@napi-rs/simple-git-freebsd-x64": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-freebsd-x64/-/simple-git-freebsd-x64-0.1.17.tgz", - "integrity": "sha512-SHWa3o5EZWYh7UoLi2sO4uLjZd58UFHaMttw4O9PZPvFcdjz5LjC6CQclwZbLyPDPMGefalrkUeYTs+/VJ+XEA==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-freebsd-x64/-/simple-git-freebsd-x64-0.1.19.tgz", + "integrity": "sha512-sB9krVIchzd20FjI2ZZ8FDsTSsXLBdnwJ6CpeVyrhXHnoszfcqxt49ocZHujAS9lMpXq7i2Nv1EXJmCy4KdhwA==", "cpu": [ "x64" ], @@ -710,9 +710,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-arm-gnueabihf": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm-gnueabihf/-/simple-git-linux-arm-gnueabihf-0.1.17.tgz", - "integrity": "sha512-nQpwitNfSN4qGmDpWOlS3XqeE7NARxCvL+lxO0CtKih2iBuWIoU0wViVKdf9fb/Rm3xsQHcblMkliMnjcAOupg==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm-gnueabihf/-/simple-git-linux-arm-gnueabihf-0.1.19.tgz", + "integrity": "sha512-6HPn09lr9N1n5/XKfP8Np53g4fEXVxOFqNkS6rTH3Rm1lZHdazTRH62RggXLTguZwjcE+MvOLvoTIoR5kAS8+g==", "cpu": [ "arm" ], @@ -725,9 +725,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-arm64-gnu": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-gnu/-/simple-git-linux-arm64-gnu-0.1.17.tgz", - "integrity": "sha512-JD8nSLa9WY1kAppMufYqcqFYYjZKjZZFdZtlpz6Kn0kk4Qmm3Rvt1etnuQBwax9R2wG4n9YPYfpidDxic8rlNw==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-gnu/-/simple-git-linux-arm64-gnu-0.1.19.tgz", + "integrity": "sha512-G0gISckt4cVDp3oh5Z6PV3GHJrJO6Z8bIS+9xA7vTtKdqB1i5y0n3cSFLlzQciLzhr+CajFD27doW4lEyErQ/Q==", "cpu": [ "arm64" ], @@ -740,9 +740,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-arm64-musl": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-musl/-/simple-git-linux-arm64-musl-0.1.17.tgz", - "integrity": "sha512-PRdVIEvgdIuJhDvdneO3X7XfZwujU7MOyymwK3kR1RMJPlbwzxdQBA86am/jEkBP7d8Cx8RbREzJ6y/2hAHKOQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-arm64-musl/-/simple-git-linux-arm64-musl-0.1.19.tgz", + "integrity": "sha512-OwTRF+H4IZYxmDFRi1IrLMfqbdIpvHeYbJl2X94NVsLVOY+3NUHvEzL3fYaVx5urBaMnIK0DD3wZLbcueWvxbA==", "cpu": [ "arm64" ], @@ -755,9 +755,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-powerpc64le-gnu": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-powerpc64le-gnu/-/simple-git-linux-powerpc64le-gnu-0.1.17.tgz", - "integrity": "sha512-afbfsJMpQjtdLP3BRGj/hKpRqymxw2Lt+dmyoRej0zKxZnuPrws3Fi85RyYsT/6Tq0hSUAMeh5UtxGAOH3q8gA==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-powerpc64le-gnu/-/simple-git-linux-powerpc64le-gnu-0.1.19.tgz", + "integrity": "sha512-p7zuNNVyzpRvkCt2RIGv9FX/WPcPbZ6/FRUgUTZkA2WU33mrbvNqSi4AOqCCl6mBvEd+EOw5NU4lS9ORRJvAEg==", "cpu": [ "powerpc64le" ], @@ -770,9 +770,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-s390x-gnu": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-s390x-gnu/-/simple-git-linux-s390x-gnu-0.1.17.tgz", - "integrity": "sha512-qTgRIUsU+b7RMls+Ji4xlDYq0rsUuNBpzVgb991UPnzrhFWFFkCtyk6I6tJqMtRfg7Vgn1stCghFEQiHmpqkew==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-s390x-gnu/-/simple-git-linux-s390x-gnu-0.1.19.tgz", + "integrity": "sha512-6N2vwJUPLiak8GLrS0a3is0gSb0UwI2CHOOqtvQxPmv+JVI8kn3vKiUscsktdDb0wGEPeZ8PvZs0y8UWix7K4g==", "cpu": [ "s390x" ], @@ -785,9 +785,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-x64-gnu": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-gnu/-/simple-git-linux-x64-gnu-0.1.17.tgz", - "integrity": "sha512-xHlyUDJhjPUCR07JGrvMfLg5XSRVDsxgpo6B6zYQOSMcVgM7fjvyWNMBe508r4eD5YZKZyBPfSJUc5Ls9ToJNQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-gnu/-/simple-git-linux-x64-gnu-0.1.19.tgz", + "integrity": "sha512-61YfeO1J13WK7MalLgP3QlV6of2rWnVw1aqxWkAgy/lGxoOFSJ4Wid6ANVCEZk4tJpPX/XNeneqkUz5xpeb2Cw==", "cpu": [ "x64" ], @@ -800,9 +800,9 @@ } }, "node_modules/@napi-rs/simple-git-linux-x64-musl": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-musl/-/simple-git-linux-x64-musl-0.1.17.tgz", - "integrity": "sha512-eaTr+WPeiuEegduE3O7VzHhHftGXmX1pzzILoOTbbdmeEuH1BHnGAr35XTu+1lUHUqE2JHef3d3PgBHeh844hA==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-linux-x64-musl/-/simple-git-linux-x64-musl-0.1.19.tgz", + "integrity": "sha512-cCTWNpMJnN3PrUBItWcs3dQKCydsIasbrS3laMzq8k7OzF93Zrp2LWDTPlLCO9brbBVpBzy2Qk5Xg9uAfe/Ukw==", "cpu": [ "x64" ], @@ -815,9 +815,9 @@ } }, "node_modules/@napi-rs/simple-git-win32-arm64-msvc": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-arm64-msvc/-/simple-git-win32-arm64-msvc-0.1.17.tgz", - "integrity": "sha512-v1F72stOCjapCd0Ha928m8X8i/IPhPQIXbYEGX0MEmaaAzbAJ3PTSSFpb0rFLShXaDFA2Wuw/jzlkPLESPdKVQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-arm64-msvc/-/simple-git-win32-arm64-msvc-0.1.19.tgz", + "integrity": "sha512-sWavb1BjeLKKBA+PbTsRSSzVNfb7V/dOpaJvkgR5d2kWFn/AHmCZHSSj/3nyZdYf0BdDC+DIvqk3daAEZ6QMVw==", "cpu": [ "arm64" ], @@ -830,9 +830,9 @@ } }, "node_modules/@napi-rs/simple-git-win32-x64-msvc": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-x64-msvc/-/simple-git-win32-x64-msvc-0.1.17.tgz", - "integrity": "sha512-ziSqhCGE2eTUqpQKEutGobU2fH1t9fXwGF58dMFaPgTJIISaENvdnKu5FDJfA94vPbe3BMN64JoTmjBSglGFhQ==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@napi-rs/simple-git-win32-x64-msvc/-/simple-git-win32-x64-msvc-0.1.19.tgz", + "integrity": "sha512-FmNuPoK4+qwaSCkp8lm3sJlrxk374enW+zCE5ZksXlZzj/9BDJAULJb5QUJ7o9Y8A/G+d8LkdQLPBE2Jaxe5XA==", "cpu": [ "x64" ], diff --git a/package.json b/package.json index 5a09299..59c9e0b 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "dependencies": { "@clack/prompts": "^0.7.0", "@floating-ui/dom": "^1.6.10", - "@napi-rs/simple-git": "0.1.17", + "@napi-rs/simple-git": "0.1.19", "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", "chalk": "^5.3.0", From 5a26b582ed9874cde998d6a2f2da07386b8dea75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:12:51 -0700 Subject: [PATCH 32/92] chore(deps-dev): bump @types/node from 22.1.0 to 22.5.0 (#1375) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.1.0 to 22.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81c66cc..6bca604 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.1.0", + "@types/node": "^22.5.0", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", @@ -1263,12 +1263,12 @@ } }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", "dev": true, "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@types/pretty-time": { @@ -6350,9 +6350,9 @@ } }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unicorn-magic": { diff --git a/package.json b/package.json index 59c9e0b..2ccd05d 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.1.0", + "@types/node": "^22.5.0", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", From 9b75faafea510cf28f473dd91899d740da8b2273 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:13:00 -0700 Subject: [PATCH 33/92] chore(deps-dev): bump @types/yargs from 17.0.32 to 17.0.33 (#1374) Bumps [@types/yargs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/yargs) from 17.0.32 to 17.0.33. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/yargs) --- updated-dependencies: - dependency-name: "@types/yargs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6bca604..1d22cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,7 +80,7 @@ "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", - "@types/yargs": "^17.0.32", + "@types/yargs": "^17.0.33", "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.18.0", @@ -1301,9 +1301,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "dependencies": { "@types/yargs-parser": "*" diff --git a/package.json b/package.json index 2ccd05d..3b7f9af 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", - "@types/yargs": "^17.0.32", + "@types/yargs": "^17.0.33", "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.18.0", From d613a3d2f2f1cfa77bdc592c17882e260e2cea17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:13:09 -0700 Subject: [PATCH 34/92] chore(deps): bump unified from 11.0.4 to 11.0.5 (#1373) Bumps [unified](https://github.com/unifiedjs/unified) from 11.0.4 to 11.0.5. - [Release notes](https://github.com/unifiedjs/unified/releases) - [Changelog](https://github.com/unifiedjs/unified/blob/main/changelog.md) - [Commits](https://github.com/unifiedjs/unified/compare/11.0.4...11.0.5) --- updated-dependencies: - dependency-name: unified dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d22cce..1daed74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,7 @@ "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", - "unified": "^11.0.4", + "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2", "workerpool": "^9.1.3", @@ -6367,9 +6367,9 @@ } }, "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", diff --git a/package.json b/package.json index 3b7f9af..e164baf 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", - "unified": "^11.0.4", + "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2", "workerpool": "^9.1.3", From 6715079a8908e8807291415eb3dee506574b5459 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 28 Aug 2024 12:50:25 -0700 Subject: [PATCH 35/92] fix: only apply z-index on left sidebar --- quartz/styles/base.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 02b0f53..1b3d122 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -172,7 +172,6 @@ a { box-sizing: border-box; padding: 0 4rem; position: fixed; - z-index: 1; @media all and (max-width: $fullPageWidth) { position: initial; flex-direction: row; @@ -183,6 +182,7 @@ a { } & .sidebar.left { + z-index: 1; left: calc(calc(100vw - $pageWidth) / 2 - $sidePanelWidth); @media all and (max-width: $fullPageWidth) { gap: 0; From 84a9be65ce9c72aba2bc35aa7df4686d0a8082c4 Mon Sep 17 00:00:00 2001 From: bfahrenfort <59982409+bfahrenfort@users.noreply.github.com> Date: Sun, 1 Sep 2024 04:43:49 +1000 Subject: [PATCH 36/92] Add Projects & Privacy to showcase.md (#1381) --- docs/showcase.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/showcase.md b/docs/showcase.md index 2f92431..c33b2aa 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -27,5 +27,6 @@ Want to see what Quartz can do? Here are some cool community gardens: - [Ellie's Notes](https://ellie.wtf) - [🥷🏻🌳🍃 Computer Science & Thinkering Garden](https://notes.yxy.ninja) - [Eledah's Crystalline](https://blog.eledah.ir/) +- [🌓 Projects & Privacy - FOSS, tech, law](https://be-far.com) If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/v4/docs/showcase.md)! From 01fc26d2c0453b5dec70669b8cadd0622b64036c Mon Sep 17 00:00:00 2001 From: MarcRez33 <59151753+MarcRez33@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:25:30 +0200 Subject: [PATCH 37/92] fix: Reload graph after a theme change (closes #1380) (#1383) * FIX: Reload graph after a theme change * FIX: Reload graph after a theme change - comment updated * FIX: Reload graph after a theme change - comment updated * FIX: Reload graph after a theme change * fix: Reload graph after a theme change --- quartz/components/scripts/graph.inline.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/quartz/components/scripts/graph.inline.ts b/quartz/components/scripts/graph.inline.ts index 6bf43aa..5e8d48c 100644 --- a/quartz/components/scripts/graph.inline.ts +++ b/quartz/components/scripts/graph.inline.ts @@ -550,6 +550,19 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { addToVisited(simplifySlug(slug)) await renderGraph("graph-container", slug) + // Function to re-render the graph when the theme changes + const handleThemeChange = () => { + renderGraph("graph-container", slug) + } + + // event listener for theme change + document.addEventListener("themechange", handleThemeChange) + + // cleanup for the event listener + window.addCleanup(() => { + document.removeEventListener("themechange", handleThemeChange) + }) + const container = document.getElementById("global-graph-outer") const sidebar = container?.closest(".sidebar") as HTMLElement From d2414b3903c9f1353271ab8157e4be8997916294 Mon Sep 17 00:00:00 2001 From: Matt Vogel Date: Wed, 11 Sep 2024 03:29:07 -0400 Subject: [PATCH 38/92] feat(markdown): Roam Research flavour (#985) * feat: Roam Research flavor markdown * docs: Roam Research transformer * use markdownPlugins * fix roam matching * cleanup: Roam Plugin --------- Co-authored-by: Matt Vogel <> --- docs/features/Roam Research compatibility.md | 30 +++ docs/plugins/RoamFlavoredMarkdown.md | 26 +++ quartz/plugins/transformers/index.ts | 1 + quartz/plugins/transformers/roam.ts | 224 +++++++++++++++++++ 4 files changed, 281 insertions(+) create mode 100644 docs/features/Roam Research compatibility.md create mode 100644 docs/plugins/RoamFlavoredMarkdown.md create mode 100644 quartz/plugins/transformers/roam.ts diff --git a/docs/features/Roam Research compatibility.md b/docs/features/Roam Research compatibility.md new file mode 100644 index 0000000..aaeda8d --- /dev/null +++ b/docs/features/Roam Research compatibility.md @@ -0,0 +1,30 @@ +--- +title: "Roam Research Compatibility" +tags: + - feature/transformer +--- + +[Roam Research](https://roamresearch.com) is a note-taking tool that organizes your knowledge graph in a unique and interconnected way. Since the markdown exported from Roam Research includes specific `{{[[components]]}}` and formatting that may not be directly compatible with Quartz, we need to transform it. This is achieved with the [[RoamFlavoredMarkdown]] plugin. + +```typescript title="quartz.config.ts" +plugins: { + transformers: [ + // ... + Plugin.RoamFlavoredMarkdown(), + Plugin.ObsidianFlavoredMarkdown(), + // ... + ], +}, +``` + +## Usage + +By default, Quartz does not recognize markdown files exported from `Roam Research` as they contain unique identifiers and components specific to Roam. You are responsible for exporting your `Roam Research` notes as markdown files and then using this transformer to make them compatible with Quartz. This process ensures that your knowledge graph is seamlessly integrated into your static site, maintaining the rich interconnections between your notes. + +## Configuration + +This functionality is provided by the [[RoamFlavoredMarkdown]] plugin. See the plugin page for customization options. + +## Note + +As seen above placement of `Plugin.RoamFlavoredMarkdown()` within `quartz.config.ts` is very important. It must come before `Plugin.ObsidianFlavoredMarkdown()`. diff --git a/docs/plugins/RoamFlavoredMarkdown.md b/docs/plugins/RoamFlavoredMarkdown.md new file mode 100644 index 0000000..227dba3 --- /dev/null +++ b/docs/plugins/RoamFlavoredMarkdown.md @@ -0,0 +1,26 @@ +--- +title: RoamFlavoredMarkdown +tags: + - plugin/transformer +--- + +This plugin provides support for [Roam Research](https://roamresearch.com) compatibility. See [[Roam Research Compatibility]] for more information. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin accepts the following configuration options: + +- `orComponent`: If `true` (default), converts Roam `{{ or:ONE|TWO|THREE }}` shortcodes into html Dropdown options. +- `TODOComponent`: If `true` (default), converts Roam `{{[[TODO]]}}` shortcodes into html check boxes. +- `DONEComponent`: If `true` (default), converts Roam `{{[[DONE]]}}` shortcodes into checked html check boxes. +- `videoComponent`: If `true` (default), converts Roam `{{[[video]]:URL}}` shortcodes into embeded HTML video. +- `audioComponent`: If `true` (default), converts Roam `{{[[audio]]:URL}}` shortcodes into embeded HTML audio. +- `pdfComponent`: If `true` (default), converts Roam `{{[[pdf]]:URL}}` shortcodes into embeded HTML PDF viewer. +- `blockquoteComponent`: If `true` (default), converts Roam `{{[[>]]}}` shortcodes into quartz blockquotes. + +## API + +- Category: Transformer +- Function name: `Plugin.RoamFlavoredMarkdown()`. +- Source: [`quartz/plugins/transformers/roam.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/roam.ts). diff --git a/quartz/plugins/transformers/index.ts b/quartz/plugins/transformers/index.ts index 7908c86..8e2cd84 100644 --- a/quartz/plugins/transformers/index.ts +++ b/quartz/plugins/transformers/index.ts @@ -10,3 +10,4 @@ export { OxHugoFlavouredMarkdown } from "./oxhugofm" export { SyntaxHighlighting } from "./syntax" export { TableOfContents } from "./toc" export { HardLineBreaks } from "./linebreaks" +export { RoamFlavoredMarkdown } from "./roam" diff --git a/quartz/plugins/transformers/roam.ts b/quartz/plugins/transformers/roam.ts new file mode 100644 index 0000000..b3be8f5 --- /dev/null +++ b/quartz/plugins/transformers/roam.ts @@ -0,0 +1,224 @@ +import { QuartzTransformerPlugin } from "../types" +import { PluggableList } from "unified" +import { SKIP, visit } from "unist-util-visit" +import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace" +import { Root, Html, Paragraph, Text, Link, Parent } from "mdast" +import { Node } from "unist" +import { VFile } from "vfile" +import { BuildVisitor } from "unist-util-visit" + +export interface Options { + orComponent: boolean + TODOComponent: boolean + DONEComponent: boolean + videoComponent: boolean + audioComponent: boolean + pdfComponent: boolean + blockquoteComponent: boolean + tableComponent: boolean + attributeComponent: boolean +} + +const defaultOptions: Options = { + orComponent: true, + TODOComponent: true, + DONEComponent: true, + videoComponent: true, + audioComponent: true, + pdfComponent: true, + blockquoteComponent: true, + tableComponent: true, + attributeComponent: true, +} + +const orRegex = new RegExp(/{{or:(.*?)}}/, "g") +const TODORegex = new RegExp(/{{.*?\bTODO\b.*?}}/, "g") +const DONERegex = new RegExp(/{{.*?\bDONE\b.*?}}/, "g") +const videoRegex = new RegExp(/{{.*?\[\[video\]\].*?\:(.*?)}}/, "g") +const youtubeRegex = new RegExp( + /{{.*?\[\[video\]\].*?(https?:\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?)}}/, + "g", +) + +// const multimediaRegex = new RegExp(/{{.*?\b(video|audio)\b.*?\:(.*?)}}/, "g") + +const audioRegex = new RegExp(/{{.*?\[\[audio\]\].*?\:(.*?)}}/, "g") +const pdfRegex = new RegExp(/{{.*?\[\[pdf\]\].*?\:(.*?)}}/, "g") +const blockquoteRegex = new RegExp(/(\[\[>\]\])\s*(.*)/, "g") +const roamHighlightRegex = new RegExp(/\^\^(.+)\^\^/, "g") +const roamItalicRegex = new RegExp(/__(.+)__/, "g") +const tableRegex = new RegExp(/- {{.*?\btable\b.*?}}/, "g") /* TODO */ +const attributeRegex = new RegExp(/\b\w+(?:\s+\w+)*::/, "g") /* TODO */ + +function isSpecialEmbed(node: Paragraph): boolean { + if (node.children.length !== 2) return false + + const [textNode, linkNode] = node.children + return ( + textNode.type === "text" && + textNode.value.startsWith("{{[[") && + linkNode.type === "link" && + linkNode.children[0].type === "text" && + linkNode.children[0].value.endsWith("}}") + ) +} + +function transformSpecialEmbed(node: Paragraph, opts: Options): Html | null { + const [textNode, linkNode] = node.children as [Text, Link] + const embedType = textNode.value.match(/\{\{\[\[(.*?)\]\]:/)?.[1]?.toLowerCase() + const url = linkNode.url.slice(0, -2) // Remove the trailing '}}' + + switch (embedType) { + case "audio": + return opts.audioComponent + ? { + type: "html", + value: ``, + } + : null + case "video": + if (!opts.videoComponent) return null + // Check if it's a YouTube video + const youtubeMatch = url.match( + /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/, + ) + if (youtubeMatch) { + const videoId = youtubeMatch[1].split("&")[0] // Remove additional parameters + const playlistMatch = url.match(/[?&]list=([^#\&\?]*)/) + const playlistId = playlistMatch ? playlistMatch[1] : null + + return { + type: "html", + value: ``, + } + } else { + return { + type: "html", + value: ``, + } + } + case "pdf": + return opts.pdfComponent + ? { + type: "html", + value: ``, + } + : null + default: + return null + } +} + +export const RoamFlavoredMarkdown: QuartzTransformerPlugin | undefined> = ( + userOpts, +) => { + const opts = { ...defaultOptions, ...userOpts } + + return { + name: "RoamFlavoredMarkdown", + markdownPlugins() { + const plugins: PluggableList = [] + + plugins.push(() => { + return (tree: Root, file: VFile) => { + const replacements: [RegExp, ReplaceFunction][] = [] + + // Handle special embeds (audio, video, PDF) + if (opts.audioComponent || opts.videoComponent || opts.pdfComponent) { + visit(tree, "paragraph", ((node: Paragraph, index: number, parent: Parent | null) => { + if (isSpecialEmbed(node)) { + const transformedNode = transformSpecialEmbed(node, opts) + if (transformedNode && parent) { + parent.children[index] = transformedNode + } + } + }) as BuildVisitor) + } + + // Roam italic syntax + replacements.push([ + roamItalicRegex, + (_value: string, match: string) => ({ + type: "emphasis", + children: [{ type: "text", value: match }], + }), + ]) + + // Roam highlight syntax + replacements.push([ + roamHighlightRegex, + (_value: string, inner: string) => ({ + type: "html", + value: `${inner}`, + }), + ]) + + if (opts.orComponent) { + replacements.push([ + orRegex, + (match: string) => { + const matchResult = match.match(/{{or:(.*?)}}/) + if (matchResult === null) { + return { type: "html", value: "" } + } + const optionsString: string = matchResult[1] + const options: string[] = optionsString.split("|") + const selectHtml: string = `` + return { type: "html", value: selectHtml } + }, + ]) + } + + if (opts.TODOComponent) { + replacements.push([ + TODORegex, + () => ({ + type: "html", + value: ``, + }), + ]) + } + + if (opts.DONEComponent) { + replacements.push([ + DONERegex, + () => ({ + type: "html", + value: ``, + }), + ]) + } + + if (opts.blockquoteComponent) { + replacements.push([ + blockquoteRegex, + (_match: string, _marker: string, content: string) => ({ + type: "html", + value: `
      ${content.trim()}
      `, + }), + ]) + } + + mdastFindReplace(tree, replacements) + } + }) + + return plugins + }, + } +} From 93b2481261bb3f890ac1d6ccc91057f5a32a3e8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 03:29:36 -0400 Subject: [PATCH 39/92] chore(deps): bump pixi.js from 8.3.3 to 8.3.4 (#1394) Bumps [pixi.js](https://github.com/pixijs/pixijs) from 8.3.3 to 8.3.4. - [Release notes](https://github.com/pixijs/pixijs/releases) - [Commits](https://github.com/pixijs/pixijs/compare/v8.3.3...v8.3.4) --- updated-dependencies: - dependency-name: pixi.js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1daed74..03d2a8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "pixi.js": "^8.3.3", + "pixi.js": "^8.3.4", "preact": "^10.23.2", "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", @@ -4840,10 +4840,9 @@ } }, "node_modules/pixi.js": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.3.3.tgz", - "integrity": "sha512-dpucBKAqEm0K51MQKlXvyIJ40bcxniP82uz4ZPEQejGtPp0P+vueuG5DyArHCkC48mkVE2FEDvyYvBa45/JlQg==", - "license": "MIT", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.3.4.tgz", + "integrity": "sha512-b5qdoHMQy79JjTiOOAH/fDiK9dLKGAoxfBwkHIdsK5XKNxsFuII2MBbktvR9pVaAmTDobDkMPDoIBFKYYpDeOg==", "dependencies": { "@pixi/colord": "^2.9.6", "@types/css-font-loading-module": "^0.0.12", diff --git a/package.json b/package.json index e164baf..40c8dc7 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "pixi.js": "^8.3.3", + "pixi.js": "^8.3.4", "preact": "^10.23.2", "preact-render-to-string": "^6.5.9", "pretty-bytes": "^6.1.1", From 082cbb74c3b211fb407fd622ddabb6c0864eaa26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 03:29:51 -0400 Subject: [PATCH 40/92] chore(deps-dev): bump @types/node from 22.5.0 to 22.5.4 (#1403) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.0 to 22.5.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 03d2a8b..5cbfda0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.5.0", + "@types/node": "^22.5.4", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", @@ -1263,9 +1263,9 @@ } }, "node_modules/@types/node": { - "version": "22.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", - "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", "dev": true, "dependencies": { "undici-types": "~6.19.2" diff --git a/package.json b/package.json index 40c8dc7..318f41a 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.5.0", + "@types/node": "^22.5.4", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", From a145e320d0e886f611d1affdba19d03d1ea13c44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 03:30:28 -0400 Subject: [PATCH 41/92] chore(deps): bump hast-util-to-html from 9.0.1 to 9.0.2 (#1393) Bumps [hast-util-to-html](https://github.com/syntax-tree/hast-util-to-html) from 9.0.1 to 9.0.2. - [Release notes](https://github.com/syntax-tree/hast-util-to-html/releases) - [Commits](https://github.com/syntax-tree/hast-util-to-html/compare/9.0.1...9.0.2) --- updated-dependencies: - dependency-name: hast-util-to-html dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5cbfda0..19b7237 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "github-slugger": "^2.0.0", "globby": "^14.0.2", "gray-matter": "^4.0.3", - "hast-util-to-html": "^9.0.1", + "hast-util-to-html": "^9.0.2", "hast-util-to-jsx-runtime": "^2.3.0", "hast-util-to-string": "^3.0.0", "is-absolute-url": "^4.0.1", @@ -2831,15 +2831,14 @@ "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" }, "node_modules/hast-util-to-html": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.1.tgz", - "integrity": "sha512-hZOofyZANbyWo+9RP75xIDV/gq+OUKx+T46IlwERnKmfpwp81XBFbT9mi26ws+SJchA4RVUQwIBJpqEOBhMzEQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.2.tgz", + "integrity": "sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^9.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", diff --git a/package.json b/package.json index 318f41a..13a5339 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "github-slugger": "^2.0.0", "globby": "^14.0.2", "gray-matter": "^4.0.3", - "hast-util-to-html": "^9.0.1", + "hast-util-to-html": "^9.0.2", "hast-util-to-jsx-runtime": "^2.3.0", "hast-util-to-string": "^3.0.0", "is-absolute-url": "^4.0.1", From c89c76b40a2097cf6d349f753abc902739cd4374 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 03:30:44 -0400 Subject: [PATCH 42/92] chore(deps-dev): bump tsx from 4.18.0 to 4.19.0 (#1391) Bumps [tsx](https://github.com/privatenumber/tsx) from 4.18.0 to 4.19.0. - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.18.0...v4.19.0) --- updated-dependencies: - dependency-name: tsx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19b7237..33a76da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "@types/yargs": "^17.0.33", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.18.0", + "tsx": "^4.19.0", "typescript": "^5.5.4" }, "engines": { @@ -5909,9 +5909,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.18.0.tgz", - "integrity": "sha512-a1jaKBSVQkd6yEc1/NI7G6yHFfefIcuf3QJST7ZEyn4oQnxLYrZR5uZAM8UrwUa3Ge8suiZHcNS1gNrEvmobqg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", + "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", "dev": true, "dependencies": { "esbuild": "~0.23.0", diff --git a/package.json b/package.json index 13a5339..5f2ab8f 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "@types/yargs": "^17.0.33", "esbuild": "^0.19.9", "prettier": "^3.3.3", - "tsx": "^4.18.0", + "tsx": "^4.19.0", "typescript": "^5.5.4" } } From 6215dd556557f8894bc2553acb57b8bf4f49e37f Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 11 Sep 2024 14:45:04 -0700 Subject: [PATCH 43/92] docs: fix roam research docs --- docs/features/Roam Research compatibility.md | 16 +++++++--------- docs/plugins/RoamFlavoredMarkdown.md | 8 ++++---- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/features/Roam Research compatibility.md b/docs/features/Roam Research compatibility.md index aaeda8d..41ea885 100644 --- a/docs/features/Roam Research compatibility.md +++ b/docs/features/Roam Research compatibility.md @@ -4,7 +4,10 @@ tags: - feature/transformer --- -[Roam Research](https://roamresearch.com) is a note-taking tool that organizes your knowledge graph in a unique and interconnected way. Since the markdown exported from Roam Research includes specific `{{[[components]]}}` and formatting that may not be directly compatible with Quartz, we need to transform it. This is achieved with the [[RoamFlavoredMarkdown]] plugin. +[Roam Research](https://roamresearch.com) is a note-taking tool that organizes your knowledge graph in a unique and interconnected way. + +Quartz supports transforming the special Markdown syntax from Roam Research (like `{{[[components]]}}` and other formatting) into +regular Markdown via the [[RoamFlavoredMarkdown]] plugin. ```typescript title="quartz.config.ts" plugins: { @@ -17,14 +20,9 @@ plugins: { }, ``` -## Usage +> [!warning] +> As seen above placement of `Plugin.RoamFlavoredMarkdown()` within `quartz.config.ts` is very important. It must come before `Plugin.ObsidianFlavoredMarkdown()`. -By default, Quartz does not recognize markdown files exported from `Roam Research` as they contain unique identifiers and components specific to Roam. You are responsible for exporting your `Roam Research` notes as markdown files and then using this transformer to make them compatible with Quartz. This process ensures that your knowledge graph is seamlessly integrated into your static site, maintaining the rich interconnections between your notes. - -## Configuration +## Customization This functionality is provided by the [[RoamFlavoredMarkdown]] plugin. See the plugin page for customization options. - -## Note - -As seen above placement of `Plugin.RoamFlavoredMarkdown()` within `quartz.config.ts` is very important. It must come before `Plugin.ObsidianFlavoredMarkdown()`. diff --git a/docs/plugins/RoamFlavoredMarkdown.md b/docs/plugins/RoamFlavoredMarkdown.md index 227dba3..9d89477 100644 --- a/docs/plugins/RoamFlavoredMarkdown.md +++ b/docs/plugins/RoamFlavoredMarkdown.md @@ -11,13 +11,13 @@ This plugin provides support for [Roam Research](https://roamresearch.com) compa This plugin accepts the following configuration options: -- `orComponent`: If `true` (default), converts Roam `{{ or:ONE|TWO|THREE }}` shortcodes into html Dropdown options. -- `TODOComponent`: If `true` (default), converts Roam `{{[[TODO]]}}` shortcodes into html check boxes. -- `DONEComponent`: If `true` (default), converts Roam `{{[[DONE]]}}` shortcodes into checked html check boxes. +- `orComponent`: If `true` (default), converts Roam `{{ or:ONE|TWO|THREE }}` shortcodes into HTML Dropdown options. +- `TODOComponent`: If `true` (default), converts Roam `{{[[TODO]]}}` shortcodes into HTML check boxes. +- `DONEComponent`: If `true` (default), converts Roam `{{[[DONE]]}}` shortcodes into checked HTML check boxes. - `videoComponent`: If `true` (default), converts Roam `{{[[video]]:URL}}` shortcodes into embeded HTML video. - `audioComponent`: If `true` (default), converts Roam `{{[[audio]]:URL}}` shortcodes into embeded HTML audio. - `pdfComponent`: If `true` (default), converts Roam `{{[[pdf]]:URL}}` shortcodes into embeded HTML PDF viewer. -- `blockquoteComponent`: If `true` (default), converts Roam `{{[[>]]}}` shortcodes into quartz blockquotes. +- `blockquoteComponent`: If `true` (default), converts Roam `{{[[>]]}}` shortcodes into Quartz blockquotes. ## API From c36551310d223b204e39dc29e53723e03c238719 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 14:46:22 -0700 Subject: [PATCH 44/92] chore(deps): bump preact-render-to-string from 6.5.9 to 6.5.10 (#1390) Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.5.9 to 6.5.10. - [Release notes](https://github.com/preactjs/preact-render-to-string/releases) - [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md) - [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.5.9...v6.5.10) --- updated-dependencies: - dependency-name: preact-render-to-string dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33a76da..98809c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "micromorph": "^0.4.5", "pixi.js": "^8.3.4", "preact": "^10.23.2", - "preact-render-to-string": "^6.5.9", + "preact-render-to-string": "^6.5.10", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", @@ -4864,9 +4864,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "6.5.9", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.9.tgz", - "integrity": "sha512-Fn9R89h6qrQeSRmsH2O2fWzqpVwsJgEL9UTly5nGEV2ldhVuG+9JhXdNJ6zreIkOZcBT20+AOMwlG1x72znJ+g==", + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.10.tgz", + "integrity": "sha512-BJdypTQaBA5UbTF9NKZS3zP93Sw33tZOxNXIfuHofqOZFoMdsquNkVebs/HkEw0in/Qbi6Ep/Anngnj+VsHeBQ==", "peerDependencies": { "preact": ">=10" } diff --git a/package.json b/package.json index 5f2ab8f..52c87dd 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "micromorph": "^0.4.5", "pixi.js": "^8.3.4", "preact": "^10.23.2", - "preact-render-to-string": "^6.5.9", + "preact-render-to-string": "^6.5.10", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", From eb9bbd1666345e011da410ff7af67ede9fd00f47 Mon Sep 17 00:00:00 2001 From: bfahrenfort <59982409+bfahrenfort@users.noreply.github.com> Date: Sun, 15 Sep 2024 03:10:01 +1000 Subject: [PATCH 45/92] fix: constrain link icon size (#1409) --- quartz/plugins/transformers/links.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 38bc0dc..3e8dbde 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -67,6 +67,7 @@ export const CrawlLinks: QuartzTransformerPlugin> = (userOpts) properties: { "aria-hidden": "true", class: "external-icon", + style: "max-width:0.8em;max-height:0.8em", viewBox: "0 0 512 512", }, children: [ From cd3bb25626beca6e7e2149320773628f39d31af0 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Sun, 15 Sep 2024 17:25:31 +0200 Subject: [PATCH 46/92] fix: account for subtags in numerical tags (closes #1408) (#1410) --- quartz/plugins/transformers/ofm.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 0dea893..dd743b6 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -324,8 +324,8 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> replacements.push([ tagRegex, (_value: string, tag: string) => { - // Check if the tag only includes numbers - if (/^\d+$/.test(tag)) { + // Check if the tag only includes numbers and slashes + if (/^[\/\d]+$/.test(tag)) { return false } From 6ea359e55ee6333f27b0a8d59caebdb17b9acbf0 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 15 Sep 2024 16:42:07 -0700 Subject: [PATCH 47/92] perf: have more than 1ms granularity for rebuild detection --- quartz/build.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/quartz/build.ts b/quartz/build.ts index 342a27c..38efe36 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -39,7 +39,7 @@ type BuildData = { type FileEvent = "add" | "change" | "delete" function newBuildId() { - return new Date().toISOString() + return Math.random().toString(36).substring(2, 8) } async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) { @@ -162,17 +162,19 @@ async function partialRebuildFromEntrypoint( return } - const buildStart = new Date().getTime() - buildData.lastBuildMs = buildStart + const buildId = newBuildId() + ctx.buildId = buildId + buildData.lastBuildMs = new Date().getTime() const release = await mut.acquire() - if (buildData.lastBuildMs > buildStart) { + + // if there's another build after us, release and let them do it + if (ctx.buildId !== buildId) { release() return } const perf = new PerfTimer() console.log(chalk.yellow("Detected change, rebuilding...")) - ctx.buildId = newBuildId() // UPDATE DEP GRAPH const fp = joinSegments(argv.directory, toPosixPath(filepath)) as FilePath @@ -357,19 +359,19 @@ async function rebuildFromEntrypoint( toRemove.add(filePath) } - const buildStart = new Date().getTime() - buildData.lastBuildMs = buildStart + const buildId = newBuildId() + ctx.buildId = buildId + buildData.lastBuildMs = new Date().getTime() const release = await mut.acquire() // there's another build after us, release and let them do it - if (buildData.lastBuildMs > buildStart) { + if (ctx.buildId !== buildId) { release() return } const perf = new PerfTimer() console.log(chalk.yellow("Detected change, rebuilding...")) - ctx.buildId = newBuildId() try { const filesToRebuild = [...toRebuild].filter((fp) => !toRemove.has(fp)) @@ -405,10 +407,10 @@ async function rebuildFromEntrypoint( } } - release() clientRefresh() toRebuild.clear() toRemove.clear() + release() } export default async (argv: Argv, mut: Mutex, clientRefresh: () => void) => { From 50a78bafa53a6f99aa28911beb2d73e74c4127dd Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 15 Sep 2024 16:47:11 -0700 Subject: [PATCH 48/92] docs: clarify prod hosting --- docs/build.md | 4 ++++ quartz/build.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/build.md b/docs/build.md index 1447687..6005770 100644 --- a/docs/build.md +++ b/docs/build.md @@ -21,3 +21,7 @@ This will start a local web server to run your Quartz on your computer. Open a w > - `--serve`: run a local hot-reloading server to preview your Quartz > - `--port`: what port to run the local preview server on > - `--concurrency`: how many threads to use to parse notes + +> [!warning] Not to be used for production +> Serve mode is intended for local previews only. +> For production workloads, see the page on [[hosting]]. diff --git a/quartz/build.ts b/quartz/build.ts index 38efe36..67ec0da 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -163,7 +163,7 @@ async function partialRebuildFromEntrypoint( } const buildId = newBuildId() - ctx.buildId = buildId + ctx.buildId = buildId buildData.lastBuildMs = new Date().getTime() const release = await mut.acquire() @@ -360,7 +360,7 @@ async function rebuildFromEntrypoint( } const buildId = newBuildId() - ctx.buildId = buildId + ctx.buildId = buildId buildData.lastBuildMs = new Date().getTime() const release = await mut.acquire() From 16a9caa555a2d63b7ff8af0731fbfd3231d6225c Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 15 Sep 2024 18:05:02 -0700 Subject: [PATCH 50/92] perf: eagerly compute explorer nodes to avoid re-render in memoized value --- quartz/components/Explorer.tsx | 76 ++++++++++++++++-------------- quartz/components/ExplorerNode.tsx | 13 ++--- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/quartz/components/Explorer.tsx b/quartz/components/Explorer.tsx index ec7c48e..df876ab 100644 --- a/quartz/components/Explorer.tsx +++ b/quartz/components/Explorer.tsx @@ -7,6 +7,7 @@ import { ExplorerNode, FileNode, Options } from "./ExplorerNode" import { QuartzPluginData } from "../plugins/vfile" import { classNames } from "../util/lang" import { i18n } from "../i18n" +import { VNode } from "preact" // Options interface defined in `ExplorerNode` to avoid circular dependency const defaultOptions = { @@ -44,6 +45,7 @@ export default ((userOpts?: Partial) => { // memoized let fileTree: FileNode let jsonTree: string + let component: VNode let lastBuildId: string = "" function constructFileTree(allFiles: QuartzPluginData[]) { @@ -82,44 +84,46 @@ export default ((userOpts?: Partial) => { if (ctx.buildId !== lastBuildId) { lastBuildId = ctx.buildId constructFileTree(allFiles) + const tree = ExplorerNode({ node: fileTree, opts, fileData }) + component = ( +
      + +
      +
        + {tree} +
      • +
      +
      +
      + ) } - return ( -
      - -
      -
        - -
      • -
      -
      -
      - ) + return component } Explorer.css = explorerStyle diff --git a/quartz/components/ExplorerNode.tsx b/quartz/components/ExplorerNode.tsx index e57d677..3137a3f 100644 --- a/quartz/components/ExplorerNode.tsx +++ b/quartz/components/ExplorerNode.tsx @@ -224,15 +224,10 @@ export function ExplorerNode({ node, opts, fullPath, fileData }: ExplorerNodePro class="content" data-folderul={folderPath} > - {node.children.map((childNode, i) => ( - - ))} + {node.children.map((childNode) => + // eagerly render children so we can memoize properly + ExplorerNode({ node: childNode, opts, fileData, fullPath: folderPath }), + )}

  • From 9c060f3cf2f95f371b15967997d74486d6941051 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:55:23 -0400 Subject: [PATCH 51/92] chore(deps): bump vfile from 6.0.2 to 6.0.3 (#1421) Bumps [vfile](https://github.com/vfile/vfile) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/vfile/vfile/releases) - [Changelog](https://github.com/vfile/vfile/blob/main/changelog.md) - [Commits](https://github.com/vfile/vfile/compare/6.0.2...6.0.3) --- updated-dependencies: - dependency-name: vfile dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98809c6..12614b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "toml": "^3.0.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2", + "vfile": "^6.0.3", "workerpool": "^9.1.3", "ws": "^8.18.0", "yargs": "^17.7.2" @@ -6549,12 +6549,11 @@ } }, "node_modules/vfile": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", - "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { diff --git a/package.json b/package.json index 52c87dd..4608deb 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "toml": "^3.0.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2", + "vfile": "^6.0.3", "workerpool": "^9.1.3", "ws": "^8.18.0", "yargs": "^17.7.2" From dad0ae4e3f08288d1d9b36daa37f983e248507d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:55:42 -0400 Subject: [PATCH 52/92] chore(deps-dev): bump @types/node from 22.5.4 to 22.5.5 (#1420) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.4 to 22.5.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12614b6..daac613 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.5.4", + "@types/node": "^22.5.5", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", @@ -1263,9 +1263,9 @@ } }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", "dev": true, "dependencies": { "undici-types": "~6.19.2" diff --git a/package.json b/package.json index 4608deb..37460b8 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.5.4", + "@types/node": "^22.5.5", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.12", From 14cb50de9b77c6d508ef7489b6318f589cce321e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:56:00 -0400 Subject: [PATCH 53/92] chore(deps): bump preact from 10.23.2 to 10.24.0 (#1419) Bumps [preact](https://github.com/preactjs/preact) from 10.23.2 to 10.24.0. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.23.2...10.24.0) --- updated-dependencies: - dependency-name: preact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index daac613..bc0e63c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "pixi.js": "^8.3.4", - "preact": "^10.23.2", + "preact": "^10.24.0", "preact-render-to-string": "^6.5.10", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", @@ -4855,9 +4855,9 @@ } }, "node_modules/preact": { - "version": "10.23.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", - "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "version": "10.24.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.0.tgz", + "integrity": "sha512-aK8Cf+jkfyuZ0ZZRG9FbYqwmEiGQ4y/PUO4SuTWoyWL244nZZh7bd5h2APd4rSNDYTBNghg1L+5iJN3Skxtbsw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index 37460b8..5d7c1c9 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "pixi.js": "^8.3.4", - "preact": "^10.23.2", + "preact": "^10.24.0", "preact-render-to-string": "^6.5.10", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", From 9a6e4e2f8022894ee84077950e95ba01ff79b6b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:56:14 -0400 Subject: [PATCH 54/92] chore(deps-dev): bump typescript from 5.5.4 to 5.6.2 (#1418) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.5.4 to 5.6.2. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.5.4...v5.6.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index bc0e63c..dc1ad97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.19.0", - "typescript": "^5.5.4" + "typescript": "^5.6.2" }, "engines": { "node": "20 || >=22", @@ -6335,9 +6335,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 5d7c1c9..40772ff 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,6 @@ "esbuild": "^0.19.9", "prettier": "^3.3.3", "tsx": "^4.19.0", - "typescript": "^5.5.4" + "typescript": "^5.6.2" } } From 743ef712d514e857549ed67219ad20675d165e4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 22:24:03 -0400 Subject: [PATCH 55/92] chore(deps): bump preact-render-to-string from 6.5.10 to 6.5.11 (#1417) Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.5.10 to 6.5.11. - [Release notes](https://github.com/preactjs/preact-render-to-string/releases) - [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md) - [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.5.10...v6.5.11) --- updated-dependencies: - dependency-name: preact-render-to-string dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc1ad97..89287e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "micromorph": "^0.4.5", "pixi.js": "^8.3.4", "preact": "^10.24.0", - "preact-render-to-string": "^6.5.10", + "preact-render-to-string": "^6.5.11", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", @@ -4864,9 +4864,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.10.tgz", - "integrity": "sha512-BJdypTQaBA5UbTF9NKZS3zP93Sw33tZOxNXIfuHofqOZFoMdsquNkVebs/HkEw0in/Qbi6Ep/Anngnj+VsHeBQ==", + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz", + "integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==", "peerDependencies": { "preact": ">=10" } diff --git a/package.json b/package.json index 40772ff..b24f667 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "micromorph": "^0.4.5", "pixi.js": "^8.3.4", "preact": "^10.24.0", - "preact-render-to-string": "^6.5.10", + "preact-render-to-string": "^6.5.11", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", From 4aaeb768d87b9d4193fb1d37213f06e6387a8af3 Mon Sep 17 00:00:00 2001 From: Gustavo de Paula Date: Fri, 20 Sep 2024 13:23:19 -0300 Subject: [PATCH 56/92] update cabin url (#1428) --- quartz/plugins/emitters/componentResources.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/emitters/componentResources.ts b/quartz/plugins/emitters/componentResources.ts index d1d8c85..d36b51c 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -147,7 +147,7 @@ function addGlobalPageResources(ctx: BuildCtx, componentResources: ComponentReso } else if (cfg.analytics?.provider === "cabin") { componentResources.afterDOMLoaded.push(` const cabinScript = document.createElement("script") - cabinScript.src = "${cfg.analytics.host ?? "https://scripts.cabin.dev"}/cabin.js" + cabinScript.src = "${cfg.analytics.host ?? "https://scripts.withcabin.com"}/hello.js" cabinScript.defer = true cabinScript.async = true document.head.appendChild(cabinScript) From 9cefcd0dd1a503c727c8bbb2deb1b631329b3a42 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 20 Sep 2024 15:48:06 -0700 Subject: [PATCH 57/92] Revert "perf: eagerly compute explorer nodes to avoid re-render in memoized value" This reverts commit 16a9caa555a2d63b7ff8af0731fbfd3231d6225c. --- quartz/components/Explorer.tsx | 76 ++++++++++++++---------------- quartz/components/ExplorerNode.tsx | 13 +++-- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/quartz/components/Explorer.tsx b/quartz/components/Explorer.tsx index df876ab..ec7c48e 100644 --- a/quartz/components/Explorer.tsx +++ b/quartz/components/Explorer.tsx @@ -7,7 +7,6 @@ import { ExplorerNode, FileNode, Options } from "./ExplorerNode" import { QuartzPluginData } from "../plugins/vfile" import { classNames } from "../util/lang" import { i18n } from "../i18n" -import { VNode } from "preact" // Options interface defined in `ExplorerNode` to avoid circular dependency const defaultOptions = { @@ -45,7 +44,6 @@ export default ((userOpts?: Partial) => { // memoized let fileTree: FileNode let jsonTree: string - let component: VNode let lastBuildId: string = "" function constructFileTree(allFiles: QuartzPluginData[]) { @@ -84,46 +82,44 @@ export default ((userOpts?: Partial) => { if (ctx.buildId !== lastBuildId) { lastBuildId = ctx.buildId constructFileTree(allFiles) - const tree = ExplorerNode({ node: fileTree, opts, fileData }) - component = ( -
    - -
    -
      - {tree} -
    • -
    -
    -
    - ) } - return component + return ( +
    + +
    +
      + +
    • +
    +
    +
    + ) } Explorer.css = explorerStyle diff --git a/quartz/components/ExplorerNode.tsx b/quartz/components/ExplorerNode.tsx index 3137a3f..e57d677 100644 --- a/quartz/components/ExplorerNode.tsx +++ b/quartz/components/ExplorerNode.tsx @@ -224,10 +224,15 @@ export function ExplorerNode({ node, opts, fullPath, fileData }: ExplorerNodePro class="content" data-folderul={folderPath} > - {node.children.map((childNode) => - // eagerly render children so we can memoize properly - ExplorerNode({ node: childNode, opts, fileData, fullPath: folderPath }), - )} + {node.children.map((childNode, i) => ( + + ))}
    From 7d7e3349763b0c1ade94b8a6d13986e171861bc1 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Mon, 23 Sep 2024 22:40:12 +0200 Subject: [PATCH 58/92] feat: responsive design grid (#1354) * Responsive design grid * Addressed PR feedback * Bump Quartz version 4.3.1 => 4.4.0 * Moved page-header into center * Updated docs with new layouts * Sync updated version number with package-lock * Table of Content scrollbar auto * Reset node_modules * Updated layout images * Fixed tablet layout * Finilazed layout images --- docs/images/quartz layout.png | Bin 66230 -> 0 bytes docs/images/quartz-layout-desktop.png | Bin 0 -> 37098 bytes docs/images/quartz-layout-mobile.png | Bin 0 -> 36853 bytes docs/images/quartz-layout-tablet.png | Bin 0 -> 35554 bytes docs/layout.md | 27 ++++- package-lock.json | 4 +- package.json | 2 +- quartz/components/renderPage.tsx | 2 +- quartz/components/styles/backlinks.scss | 55 +++++++-- quartz/components/styles/explorer.scss | 25 +++- quartz/components/styles/graph.scss | 2 +- quartz/components/styles/listPage.scss | 2 +- quartz/components/styles/popover.scss | 2 +- quartz/components/styles/search.scss | 10 +- quartz/components/styles/toc.scss | 4 + quartz/styles/base.scss | 147 +++++++++++++++--------- quartz/styles/variables.scss | 57 ++++++++- 17 files changed, 247 insertions(+), 92 deletions(-) delete mode 100644 docs/images/quartz layout.png create mode 100644 docs/images/quartz-layout-desktop.png create mode 100644 docs/images/quartz-layout-mobile.png create mode 100644 docs/images/quartz-layout-tablet.png diff --git a/docs/images/quartz layout.png b/docs/images/quartz layout.png deleted file mode 100644 index 71ef3ac71edf91b81fc5cb7a051abf10e25dcd73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66230 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 I*Sd%PD+au@k^lez literal 0 HcmV?d00001 diff --git a/docs/images/quartz-layout-tablet.png b/docs/images/quartz-layout-tablet.png new file mode 100644 index 0000000000000000000000000000000000000000..6349f29758d7696c8b1e79fe5c51a36b1dabb57c GIT binary patch literal 35554 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 literal 0 HcmV?d00001 diff --git a/docs/layout.md b/docs/layout.md index 686b2f2..d8427c4 100644 --- a/docs/layout.md +++ b/docs/layout.md @@ -13,15 +13,19 @@ export interface FullPageLayout { beforeBody: QuartzComponent[] // laid out vertically pageBody: QuartzComponent // single component afterBody: QuartzComponent[] // laid out vertically - left: QuartzComponent[] // vertical on desktop, horizontal on mobile - right: QuartzComponent[] // vertical on desktop, horizontal on mobile + left: QuartzComponent[] // vertical on desktop and tablet, horizontal on mobile + right: QuartzComponent[] // vertical on desktop, horizontal on tablet and mobile footer: QuartzComponent // single component } ``` These correspond to following parts of the page: -![[quartz layout.png|800]] +| Layout | Preview | +| ------------------------------- | ----------------------------------- | +| Desktop (width > 1200px) | ![[quartz-layout-desktop.png\|800]] | +| Tablet (800px < width < 1200px) | ![[quartz-layout-tablet.png\|800]] | +| Mobile (width < 800px) | ![[quartz-layout-mobile.png\|800]] | > [!note] > There are two additional layout fields that are _not_ shown in the above diagram. @@ -33,6 +37,23 @@ Quartz **components**, like plugins, can take in additional properties as config See [a list of all the components](component.md) for all available components along with their configuration options. You can also checkout the guide on [[creating components]] if you're interested in further customizing the behaviour of Quartz. +### Layout breakpoints + +Quartz has different layouts depending on the width the screen viewing the website. + +The breakpoints for layouts can be configured in `variables.scss`. + +- `mobile`: screen width below this size will use mobile layout. +- `desktop`: screen width above this size will use desktop layout. +- Screen width between `mobile` and `desktop` width will use the tablet layout. + +```scss +$breakpoints: ( + mobile: 800px, + desktop: 1200px, +); +``` + ### Style Most meaningful style changes like colour scheme and font can be done simply through the [[configuration#General Configuration|general configuration]] options. However, if you'd like to make more involved style changes, you can do this by writing your own styles. Quartz 4, like Quartz 3, uses [Sass](https://sass-lang.com/guide/) for styling. diff --git a/package-lock.json b/package-lock.json index 89287e6..b53f28f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jackyzha0/quartz", - "version": "4.3.1", + "version": "4.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jackyzha0/quartz", - "version": "4.3.1", + "version": "4.4.0", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", diff --git a/package.json b/package.json index b24f667..44d7bb3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@jackyzha0/quartz", "description": "🌱 publish your digital garden and notes as a website", "private": true, - "version": "4.3.1", + "version": "4.4.0", "type": "module", "author": "jackyzha0 ", "license": "MIT", diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index ec5124f..f2dccea 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -242,8 +242,8 @@ export function renderPage(
    {RightComponent} +