From 76f295620c5e8ffc21a78698468ab38b2916a461 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Mon, 12 Feb 2024 08:51:47 -0800 Subject: [PATCH 001/217] feat: add transclude-src to transclude 'link to original' --- quartz/components/renderPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 4643d0a..33671d2 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -103,7 +103,7 @@ export function renderPage( { type: "element", tagName: "a", - properties: { href: inner.properties?.href, class: ["internal"] }, + properties: { href: inner.properties?.href, class: ["internal", "transclude-src"] }, children: [ { type: "text", value: i18n(cfg.locale).components.transcludes.linkToOriginal }, ], @@ -140,7 +140,7 @@ export function renderPage( { type: "element", tagName: "a", - properties: { href: inner.properties?.href, class: ["internal"] }, + properties: { href: inner.properties?.href, class: ["internal", "transclude-src"] }, children: [ { type: "text", value: i18n(cfg.locale).components.transcludes.linkToOriginal }, ], @@ -170,7 +170,7 @@ export function renderPage( { type: "element", tagName: "a", - properties: { href: inner.properties?.href, class: ["internal"] }, + properties: { href: inner.properties?.href, class: ["internal", "transclude-src"] }, children: [ { type: "text", value: i18n(cfg.locale).components.transcludes.linkToOriginal }, ], From 5dc4f21a4baf564ede85d8e702ef5b19c96657a3 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Mon, 12 Feb 2024 17:58:00 +0100 Subject: [PATCH 002/217] feat(i18n): localize the min read string for the nl-NL locale (#850) * Update min read translation * Added nl_BE to Dutch Added Flemish (nl_BE) to point to nl. * Removed period to match other translations --- quartz/i18n/index.ts | 1 + quartz/i18n/locales/nl-NL.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index a422acb..c4fa425 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -15,6 +15,7 @@ export const TRANSLATIONS = { "ja-JP": ja, "de-DE": de, "nl-NL": nl, + "nl-BE": nl, "ro-RO": ro, "ro-MD": ro, "es-ES": es, diff --git a/quartz/i18n/locales/nl-NL.ts b/quartz/i18n/locales/nl-NL.ts index 3ff3e8c..e239be0 100644 --- a/quartz/i18n/locales/nl-NL.ts +++ b/quartz/i18n/locales/nl-NL.ts @@ -54,7 +54,8 @@ export default { title: "Inhoudsopgave", }, contentMeta: { - readingTime: ({ minutes }) => `${minutes} min read`, + readingTime: ({ minutes }) => + minutes === 1 ? "1 minuut leestijd" : `${minutes} minuten leestijd`, }, }, pages: { From a7325eadc1483c181928425a4c7379427f21995a Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Mon, 12 Feb 2024 09:00:58 -0800 Subject: [PATCH 003/217] fix(analytics): umami custom host should be a string (closes #852) --- 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 290cb6f..67bc69c 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -120,7 +120,7 @@ function addGlobalPageResources( } else if (cfg.analytics?.provider === "umami") { componentResources.afterDOMLoaded.push(` const umamiScript = document.createElement("script") - umamiScript.src = ${cfg.analytics.host} ?? "https://analytics.umami.is/script.js" + umamiScript.src = "${cfg.analytics.host}" ?? "https://analytics.umami.is/script.js" umamiScript.setAttribute("data-website-id", "${cfg.analytics.websiteId}") umamiScript.async = true From 4a28d0e5d1b8fa866d0594a89ad72a751633dc8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:21:13 -0500 Subject: [PATCH 004/217] chore(deps-dev): bump tsx from 4.7.0 to 4.7.1 (#859) Bumps [tsx](https://github.com/privatenumber/tsx) from 4.7.0 to 4.7.1. - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/develop/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.7.0...v4.7.1) --- updated-dependencies: - dependency-name: tsx 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 e488124..891fcea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,7 +80,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.2.4", - "tsx": "^4.7.0", + "tsx": "^4.7.1", "typescript": "^5.3.3" }, "engines": { @@ -5647,9 +5647,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", + "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", "dev": true, "dependencies": { "esbuild": "~0.19.10", diff --git a/package.json b/package.json index 3235b5f..2d408b7 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@types/yargs": "^17.0.32", "esbuild": "^0.19.9", "prettier": "^3.2.4", - "tsx": "^4.7.0", + "tsx": "^4.7.1", "typescript": "^5.3.3" } } From 2c06e68ba6ccc5b079ca6ec96cc6e08c082d9fd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:21:30 -0500 Subject: [PATCH 005/217] chore(deps): bump preact from 10.19.3 to 10.19.4 (#858) Bumps [preact](https://github.com/preactjs/preact) from 10.19.3 to 10.19.4. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.19.3...10.19.4) --- updated-dependencies: - dependency-name: preact 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 891fcea..9a0d8cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.3", + "preact": "^10.19.4", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", @@ -4454,9 +4454,9 @@ } }, "node_modules/preact": { - "version": "10.19.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", - "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "version": "10.19.4", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.4.tgz", + "integrity": "sha512-dwaX5jAh0Ga8uENBX1hSOujmKWgx9RtL80KaKUFLc6jb4vCEAc3EeZ0rnQO/FO4VgjfPMfoLFWnNG8bHuZ9VLw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index 2d408b7..e11e6c4 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.3", + "preact": "^10.19.4", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", From a31e3f9458431883d8ee68961132b5cdb1ef2db6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:21:45 -0500 Subject: [PATCH 006/217] chore(deps): bump @floating-ui/dom from 1.6.1 to 1.6.3 (#857) Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.6.1 to 1.6.3. - [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.3/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 | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a0d8cb..7d1d973 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.1", + "@floating-ui/dom": "^1.6.3", "@napi-rs/simple-git": "0.1.16", "async-mutex": "^0.4.1", "chalk": "^5.3.0", @@ -486,12 +486,12 @@ } }, "node_modules/@floating-ui/dom": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz", - "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.1" + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" } }, "node_modules/@floating-ui/utils": { diff --git a/package.json b/package.json index e11e6c4..f89bb2a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@clack/prompts": "^0.7.0", - "@floating-ui/dom": "^1.6.1", + "@floating-ui/dom": "^1.6.3", "@napi-rs/simple-git": "0.1.16", "async-mutex": "^0.4.1", "chalk": "^5.3.0", From 880a9511b695f57b9b323be1f57b13d1598d42a9 Mon Sep 17 00:00:00 2001 From: Lin Date: Tue, 13 Feb 2024 09:11:16 +0100 Subject: [PATCH 007/217] fix: incorrect link resolution for transclusion in root index file (#853) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lauréline Nevin --- quartz/plugins/transformers/links.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 2d43be1..1e03876 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -8,6 +8,7 @@ import { simplifySlug, splitAnchor, transformLink, + joinSegments, } from "../../util/path" import path from "path" import { visit } from "unist-util-visit" @@ -107,7 +108,7 @@ export const CrawlLinks: QuartzTransformerPlugin | undefined> = // url.resolve is considered legacy // WHATWG equivalent https://nodejs.dev/en/api/v18/url/#urlresolvefrom-to - const url = new URL(dest, `https://base.com/${curSlug}`) + const url = new URL(dest, joinSegments(`https://base.com/`, curSlug)) const canonicalDest = url.pathname let [destCanonical, _destAnchor] = splitAnchor(canonicalDest) if (destCanonical.endsWith("/")) { From b87a701ff75946ff8150052e16916f041f065544 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 13 Feb 2024 01:27:27 -0800 Subject: [PATCH 008/217] fix: base.com not being resolved properly with joinSegments --- quartz/plugins/transformers/links.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 1e03876..f89d367 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -108,7 +108,7 @@ export const CrawlLinks: QuartzTransformerPlugin | undefined> = // url.resolve is considered legacy // WHATWG equivalent https://nodejs.dev/en/api/v18/url/#urlresolvefrom-to - const url = new URL(dest, joinSegments(`https://base.com/`, curSlug)) + const url = new URL(dest, "https://base.com/" + stripSlashes(curSlug, true)) const canonicalDest = url.pathname let [destCanonical, _destAnchor] = splitAnchor(canonicalDest) if (destCanonical.endsWith("/")) { From 21c6bbf3026cf9c06f6458bdb6614099d9a91adc Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Tue, 13 Feb 2024 23:53:44 -0500 Subject: [PATCH 009/217] chore(types): add additional hint for LSP support (#864) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/components/ArticleTitle.tsx | 4 ++-- quartz/components/Backlinks.tsx | 9 +++++++-- quartz/components/Body.tsx | 4 ++-- quartz/components/Breadcrumbs.tsx | 9 +++++++-- quartz/components/Darkmode.tsx | 4 ++-- quartz/components/DesktopOnly.tsx | 2 +- quartz/components/Explorer.tsx | 9 +++++++-- quartz/components/Footer.tsx | 4 ++-- quartz/components/Graph.tsx | 4 ++-- quartz/components/Head.tsx | 4 ++-- quartz/components/Header.tsx | 4 ++-- quartz/components/MobileOnly.tsx | 2 +- quartz/components/PageList.tsx | 4 ++-- quartz/components/PageTitle.tsx | 4 ++-- quartz/components/RecentNotes.tsx | 9 +++++++-- quartz/components/Search.tsx | 4 ++-- quartz/components/TableOfContents.tsx | 10 +++++++--- quartz/components/TagList.tsx | 4 ++-- 18 files changed, 59 insertions(+), 35 deletions(-) diff --git a/quartz/components/ArticleTitle.tsx b/quartz/components/ArticleTitle.tsx index 7768de6..318aeb2 100644 --- a/quartz/components/ArticleTitle.tsx +++ b/quartz/components/ArticleTitle.tsx @@ -1,7 +1,7 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { classNames } from "../util/lang" -function ArticleTitle({ fileData, displayClass }: QuartzComponentProps) { +const ArticleTitle: QuartzComponent = ({ fileData, displayClass }: QuartzComponentProps) => { const title = fileData.frontmatter?.title if (title) { return

{title}

diff --git a/quartz/components/Backlinks.tsx b/quartz/components/Backlinks.tsx index 573c1c3..aa412a2 100644 --- a/quartz/components/Backlinks.tsx +++ b/quartz/components/Backlinks.tsx @@ -1,10 +1,15 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import style from "./styles/backlinks.scss" import { resolveRelative, simplifySlug } from "../util/path" import { i18n } from "../i18n" import { classNames } from "../util/lang" -function Backlinks({ fileData, allFiles, displayClass, cfg }: QuartzComponentProps) { +const Backlinks: QuartzComponent = ({ + fileData, + allFiles, + displayClass, + cfg, +}: QuartzComponentProps) => { const slug = simplifySlug(fileData.slug!) const backlinkFiles = allFiles.filter((file) => file.links?.includes(slug)) return ( diff --git a/quartz/components/Body.tsx b/quartz/components/Body.tsx index fbb8572..96b6278 100644 --- a/quartz/components/Body.tsx +++ b/quartz/components/Body.tsx @@ -1,9 +1,9 @@ // @ts-ignore import clipboardScript from "./scripts/clipboard.inline" import clipboardStyle from "./styles/clipboard.scss" -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" -function Body({ children }: QuartzComponentProps) { +const Body: QuartzComponent = ({ children }: QuartzComponentProps) => { return
{children}
} diff --git a/quartz/components/Breadcrumbs.tsx b/quartz/components/Breadcrumbs.tsx index eab8a34..b1a924a 100644 --- a/quartz/components/Breadcrumbs.tsx +++ b/quartz/components/Breadcrumbs.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import breadcrumbsStyle from "./styles/breadcrumbs.scss" import { FullSlug, SimpleSlug, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" @@ -54,7 +54,11 @@ export default ((opts?: Partial) => { // computed index of folder name to its associated file data let folderIndex: Map | undefined - function Breadcrumbs({ fileData, allFiles, displayClass }: QuartzComponentProps) { + const Breadcrumbs: QuartzComponent = ({ + fileData, + allFiles, + displayClass, + }: QuartzComponentProps) => { // Hide crumbs on root if enabled if (options.hideOnRoot && fileData.slug === "index") { return <> @@ -121,5 +125,6 @@ export default ((opts?: Partial) => { ) } Breadcrumbs.css = breadcrumbsStyle + return Breadcrumbs }) satisfies QuartzComponentConstructor diff --git a/quartz/components/Darkmode.tsx b/quartz/components/Darkmode.tsx index 62d3c23..8ed7c99 100644 --- a/quartz/components/Darkmode.tsx +++ b/quartz/components/Darkmode.tsx @@ -3,11 +3,11 @@ // see: https://v8.dev/features/modules#defer import darkmodeScript from "./scripts/darkmode.inline" import styles from "./styles/darkmode.scss" -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { i18n } from "../i18n" import { classNames } from "../util/lang" -function Darkmode({ displayClass, cfg }: QuartzComponentProps) { +const Darkmode: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { return (
diff --git a/quartz/components/DesktopOnly.tsx b/quartz/components/DesktopOnly.tsx index a11f23f..fe2a27f 100644 --- a/quartz/components/DesktopOnly.tsx +++ b/quartz/components/DesktopOnly.tsx @@ -3,7 +3,7 @@ import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } fro export default ((component?: QuartzComponent) => { if (component) { const Component = component - function DesktopOnly(props: QuartzComponentProps) { + const DesktopOnly: QuartzComponent = (props: QuartzComponentProps) => { return } diff --git a/quartz/components/Explorer.tsx b/quartz/components/Explorer.tsx index f701734..cffc079 100644 --- a/quartz/components/Explorer.tsx +++ b/quartz/components/Explorer.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import explorerStyle from "./styles/explorer.scss" // @ts-ignore @@ -75,7 +75,12 @@ export default ((userOpts?: Partial) => { jsonTree = JSON.stringify(folders) } - function Explorer({ cfg, allFiles, displayClass, fileData }: QuartzComponentProps) { + const Explorer: QuartzComponent = ({ + cfg, + allFiles, + displayClass, + fileData, + }: QuartzComponentProps) => { constructFileTree(allFiles) return (
diff --git a/quartz/components/Footer.tsx b/quartz/components/Footer.tsx index de472f7..076c378 100644 --- a/quartz/components/Footer.tsx +++ b/quartz/components/Footer.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import style from "./styles/footer.scss" import { version } from "../../package.json" import { i18n } from "../i18n" @@ -8,7 +8,7 @@ interface Options { } export default ((opts?: Options) => { - function Footer({ displayClass, cfg }: QuartzComponentProps) { + const Footer: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { const year = new Date().getFullYear() const links = opts?.links ?? [] return ( diff --git a/quartz/components/Graph.tsx b/quartz/components/Graph.tsx index 9fce9bd..40ab43a 100644 --- a/quartz/components/Graph.tsx +++ b/quartz/components/Graph.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" // @ts-ignore import script from "./scripts/graph.inline" import style from "./styles/graph.scss" @@ -54,7 +54,7 @@ const defaultOptions: GraphOptions = { } export default ((opts?: GraphOptions) => { - function Graph({ displayClass, cfg }: QuartzComponentProps) { + const Graph: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { const localGraph = { ...defaultOptions.localGraph, ...opts?.localGraph } const globalGraph = { ...defaultOptions.globalGraph, ...opts?.globalGraph } return ( diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index 8292acc..a3c0800 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -1,10 +1,10 @@ import { i18n } from "../i18n" import { FullSlug, joinSegments, pathToRoot } from "../util/path" import { JSResourceToScriptElement } from "../util/resources" -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" export default (() => { - function Head({ cfg, fileData, externalResources }: QuartzComponentProps) { + const Head: QuartzComponent = ({ cfg, fileData, externalResources }: QuartzComponentProps) => { const title = fileData.frontmatter?.title ?? i18n(cfg.locale).propertyDefaults.title const description = fileData.description?.trim() ?? i18n(cfg.locale).propertyDefaults.description diff --git a/quartz/components/Header.tsx b/quartz/components/Header.tsx index 5281f72..eba17ae 100644 --- a/quartz/components/Header.tsx +++ b/quartz/components/Header.tsx @@ -1,6 +1,6 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" -function Header({ children }: QuartzComponentProps) { +const Header: QuartzComponent = ({ children }: QuartzComponentProps) => { return children.length > 0 ?
{children}
: null } diff --git a/quartz/components/MobileOnly.tsx b/quartz/components/MobileOnly.tsx index 5a19095..7d2108d 100644 --- a/quartz/components/MobileOnly.tsx +++ b/quartz/components/MobileOnly.tsx @@ -3,7 +3,7 @@ import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } fro export default ((component?: QuartzComponent) => { if (component) { const Component = component - function MobileOnly(props: QuartzComponentProps) { + const MobileOnly: QuartzComponent = (props: QuartzComponentProps) => { return } diff --git a/quartz/components/PageList.tsx b/quartz/components/PageList.tsx index 644e354..62b77b1 100644 --- a/quartz/components/PageList.tsx +++ b/quartz/components/PageList.tsx @@ -1,7 +1,7 @@ import { FullSlug, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" import { Date, getDate } from "./Date" -import { QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentProps } from "./types" import { GlobalConfiguration } from "../cfg" export function byDateAndAlphabetical( @@ -29,7 +29,7 @@ type Props = { limit?: number } & QuartzComponentProps -export function PageList({ cfg, fileData, allFiles, limit }: Props) { +export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit }: Props) => { let list = allFiles.sort(byDateAndAlphabetical(cfg)) if (limit) { list = list.slice(0, limit) diff --git a/quartz/components/PageTitle.tsx b/quartz/components/PageTitle.tsx index d129602..2362f10 100644 --- a/quartz/components/PageTitle.tsx +++ b/quartz/components/PageTitle.tsx @@ -1,9 +1,9 @@ import { pathToRoot } from "../util/path" -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { classNames } from "../util/lang" import { i18n } from "../i18n" -function PageTitle({ fileData, cfg, displayClass }: QuartzComponentProps) { +const PageTitle: QuartzComponent = ({ fileData, cfg, displayClass }: QuartzComponentProps) => { const title = cfg?.pageTitle ?? i18n(cfg.locale).propertyDefaults.title const baseDir = pathToRoot(fileData.slug!) return ( diff --git a/quartz/components/RecentNotes.tsx b/quartz/components/RecentNotes.tsx index f8f6de4..549b025 100644 --- a/quartz/components/RecentNotes.tsx +++ b/quartz/components/RecentNotes.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { FullSlug, SimpleSlug, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" import { byDateAndAlphabetical } from "./PageList" @@ -24,7 +24,12 @@ const defaultOptions = (cfg: GlobalConfiguration): Options => ({ }) export default ((userOpts?: Partial) => { - function RecentNotes({ allFiles, fileData, displayClass, cfg }: QuartzComponentProps) { + const RecentNotes: QuartzComponent = ({ + allFiles, + fileData, + displayClass, + cfg, + }: QuartzComponentProps) => { const opts = { ...defaultOptions(cfg), ...userOpts } const pages = allFiles.filter(opts.filter).sort(opts.sort) const remaining = Math.max(0, pages.length - opts.limit) diff --git a/quartz/components/Search.tsx b/quartz/components/Search.tsx index a07dbc4..01e5a35 100644 --- a/quartz/components/Search.tsx +++ b/quartz/components/Search.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import style from "./styles/search.scss" // @ts-ignore import script from "./scripts/search.inline" @@ -14,7 +14,7 @@ const defaultOptions: SearchOptions = { } export default ((userOpts?: Partial) => { - function Search({ displayClass, cfg }: QuartzComponentProps) { + const Search: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { const opts = { ...defaultOptions, ...userOpts } const searchPlaceholder = i18n(cfg.locale).components.search.searchBarPlaceholder return ( diff --git a/quartz/components/TableOfContents.tsx b/quartz/components/TableOfContents.tsx index 2abc74b..77ff0eb 100644 --- a/quartz/components/TableOfContents.tsx +++ b/quartz/components/TableOfContents.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import legacyStyle from "./styles/legacyToc.scss" import modernStyle from "./styles/toc.scss" import { classNames } from "../util/lang" @@ -15,7 +15,11 @@ const defaultOptions: Options = { layout: "modern", } -function TableOfContents({ fileData, displayClass, cfg }: QuartzComponentProps) { +const TableOfContents: QuartzComponent = ({ + fileData, + displayClass, + cfg, +}: QuartzComponentProps) => { if (!fileData.toc) { return null } @@ -56,7 +60,7 @@ function TableOfContents({ fileData, displayClass, cfg }: QuartzComponentProps) TableOfContents.css = modernStyle TableOfContents.afterDOMLoaded = script -function LegacyTableOfContents({ fileData, cfg }: QuartzComponentProps) { +const LegacyTableOfContents: QuartzComponent = ({ fileData, cfg }: QuartzComponentProps) => { if (!fileData.toc) { return null } diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx index e5dd1a3..04a483b 100644 --- a/quartz/components/TagList.tsx +++ b/quartz/components/TagList.tsx @@ -1,8 +1,8 @@ import { pathToRoot, slugTag } from "../util/path" -import { QuartzComponentConstructor, QuartzComponentProps } from "./types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { classNames } from "../util/lang" -function TagList({ fileData, displayClass }: QuartzComponentProps) { +const TagList: QuartzComponent = ({ fileData, displayClass }: QuartzComponentProps) => { const tags = fileData.frontmatter?.tags const baseDir = pathToRoot(fileData.slug!) if (tags && tags.length > 0) { From 2041341d9fd9a3b674d7fa7286ad5b6e99ce80e5 Mon Sep 17 00:00:00 2001 From: Aaron Bull Schaefer Date: Wed, 14 Feb 2024 09:41:44 -0800 Subject: [PATCH 010/217] docs: workaround for shallow clones on Cloudflare Pages (#868) Rather than recommend a different hosting provider, Cloudflare Pages users that prioritize the `git` method for their `CreatedModifiedDate` configuration can preface the build command with a means of fetching the required repository history. See: - https://gohugo.io/methods/page/gitinfo/#hosting-considerations --- docs/hosting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hosting.md b/docs/hosting.md index e6340d2..bae7ed8 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -30,7 +30,7 @@ Press "Save and deploy" and Cloudflare should have a deployed version of your si To add a custom domain, check out [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/custom-domains/). > [!warning] -> Cloudflare Pages only allows shallow `git` clones so if you rely on `git` for timestamps, it is recommended you either add dates to your frontmatter (see [[authoring content#Syntax]]) or use another hosting provider. +> Cloudflare Pages performs a shallow clone by default, so if you rely on `git` for timestamps, it is recommended that you add `git fetch --unshallow &&` to the beginning of the build command (e.g., `git fetch --unshallow && npx quartz build`). ## GitHub Pages From 6c8023463d0e4ea68be3216c454775fd87d3e370 Mon Sep 17 00:00:00 2001 From: David Fischer Date: Wed, 14 Feb 2024 21:41:13 +0100 Subject: [PATCH 011/217] Add support for image popovers (#854) * feat(popover): Add support for images * fix: run prettier * feat(popover): use switch logic for content types & adjust styles * feat(popover): Add content type data tag for popover-inner class --- docs/features/popover previews.md | 2 ++ quartz/components/scripts/popover.inline.ts | 40 +++++++++++++++------ quartz/components/styles/popover.scss | 11 ++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/docs/features/popover previews.md b/docs/features/popover previews.md index f882224..0666047 100644 --- a/docs/features/popover previews.md +++ b/docs/features/popover previews.md @@ -8,6 +8,8 @@ By default, Quartz only fetches previews for pages inside your vault due to [COR When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover. +Similar to Obsidian, [[quartz layout.png|images referenced using wikilinks]] can also be viewed as popups. + ## Configuration - Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`. diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index 0251834..d0346b0 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -37,29 +37,47 @@ async function mouseEnterHandler( targetUrl.hash = "" targetUrl.search = "" - const contents = await fetch(`${targetUrl}`) - .then((res) => res.text()) - .catch((err) => { - console.error(err) - }) + const response = await fetch(`${targetUrl}`).catch((err) => { + console.error(err) + }) // bailout if another popover exists if (hasAlreadyBeenFetched()) { return } - if (!contents) return - const html = p.parseFromString(contents, "text/html") - normalizeRelativeURLs(html, targetUrl) - const elts = [...html.getElementsByClassName("popover-hint")] - if (elts.length === 0) return + if (!response) return + const contentType = response.headers.get("Content-Type") + const contentTypeCategory = contentType?.split("/")[0] ?? "text" const popoverElement = document.createElement("div") popoverElement.classList.add("popover") const popoverInner = document.createElement("div") popoverInner.classList.add("popover-inner") popoverElement.appendChild(popoverInner) - elts.forEach((elt) => popoverInner.appendChild(elt)) + + popoverInner.dataset.contentType = contentTypeCategory + + switch (contentTypeCategory) { + case "image": + const img = document.createElement("img") + + response.blob().then((blob) => { + img.src = URL.createObjectURL(blob) + }) + img.alt = targetUrl.pathname + + popoverInner.appendChild(img) + break + default: + const contents = await response.text() + const html = p.parseFromString(contents, "text/html") + normalizeRelativeURLs(html, targetUrl) + const elts = [...html.getElementsByClassName("popover-hint")] + if (elts.length === 0) return + + elts.forEach((elt) => popoverInner.appendChild(elt)) + } setPosition(popoverElement) link.appendChild(popoverElement) diff --git a/quartz/components/styles/popover.scss b/quartz/components/styles/popover.scss index e46292a..141b89d 100644 --- a/quartz/components/styles/popover.scss +++ b/quartz/components/styles/popover.scss @@ -38,6 +38,17 @@ white-space: normal; } + & > .popover-inner[data-content-type="image"] { + padding: 0; + max-height: 100%; + + img { + margin: 0; + border-radius: 0; + display: block; + } + } + h1 { font-size: 1.5rem; } From 78a408c96a221629ce1a8b70a17ed4981aad1336 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Fri, 16 Feb 2024 00:50:33 +0000 Subject: [PATCH 012/217] feat: implement getDependencyGraph for FolderPage (#849) --- quartz/plugins/emitters/folderPage.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/quartz/plugins/emitters/folderPage.tsx b/quartz/plugins/emitters/folderPage.tsx index 690fa56..bf69d29 100644 --- a/quartz/plugins/emitters/folderPage.tsx +++ b/quartz/plugins/emitters/folderPage.tsx @@ -38,12 +38,21 @@ export const FolderPage: QuartzEmitterPlugin> = (userOpt getQuartzComponents() { return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer] }, - async getDependencyGraph(_ctx, _content, _resources) { + async getDependencyGraph(_ctx, content, _resources) { // Example graph: - // nested/file.md --> nested/file.html - // \-------> nested/index.html - // TODO implement - return new DepGraph() + // nested/file.md --> nested/index.html + // nested/file2.md ------^ + const graph = new DepGraph() + + content.map(([_tree, vfile]) => { + const slug = vfile.data.slug + const folderName = path.dirname(slug ?? "") as SimpleSlug + if (slug && folderName !== "." && folderName !== "tags") { + graph.addEdge(vfile.data.filePath!, joinSegments(folderName, "index.html") as FilePath) + } + }) + + return graph }, async emit(ctx, content, resources): Promise { const fps: FilePath[] = [] From 823d9529224d70056be9dbac29dbbc66f75ae5e8 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Fri, 16 Feb 2024 00:50:48 +0000 Subject: [PATCH 013/217] feat: implement getDependencyGraph for AliasRedirects emitter (#860) --- quartz/plugins/emitters/aliases.ts | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/quartz/plugins/emitters/aliases.ts b/quartz/plugins/emitters/aliases.ts index fb25a44..af3578e 100644 --- a/quartz/plugins/emitters/aliases.ts +++ b/quartz/plugins/emitters/aliases.ts @@ -9,9 +9,30 @@ export const AliasRedirects: QuartzEmitterPlugin = () => ({ getQuartzComponents() { return [] }, - async getDependencyGraph(_ctx, _content, _resources) { - // TODO implement - return new DepGraph() + async getDependencyGraph(ctx, content, _resources) { + const graph = new DepGraph() + + const { argv } = ctx + for (const [_tree, file] of content) { + const dir = path.posix.relative(argv.directory, path.dirname(file.data.filePath!)) + const aliases = file.data.frontmatter?.aliases ?? [] + const slugs = aliases.map((alias) => path.posix.join(dir, alias) as FullSlug) + const permalink = file.data.frontmatter?.permalink + if (typeof permalink === "string") { + slugs.push(permalink as FullSlug) + } + + for (let slug of slugs) { + // fix any slugs that have trailing slash + if (slug.endsWith("/")) { + slug = joinSegments(slug, "index") as FullSlug + } + + graph.addEdge(file.data.filePath!, joinSegments(argv.output, slug + ".html") as FilePath) + } + } + + return graph }, async emit(ctx, content, _resources): Promise { const { argv } = ctx From 5af707ea20e8106857750e1d6a0e43cf18679749 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:45:01 +0000 Subject: [PATCH 014/217] fix/feat(fast rebuild): re-render transclusions in normal and fastRebuild mode (#842) * Re-render transclusions in normal watch mode * Include transclusions in ContentPage getDependencyGraph * Address PR comments --- quartz/components/renderPage.tsx | 26 +++++-------- quartz/plugins/emitters/contentPage.tsx | 49 +++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 33671d2..5394d6f 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -3,10 +3,9 @@ import { QuartzComponent, QuartzComponentProps } from "./types" import HeaderConstructor from "./Header" import BodyConstructor from "./Body" import { JSResourceToScriptElement, StaticResources } from "../util/resources" -import { FullSlug, RelativeURL, joinSegments, normalizeHastElement } from "../util/path" +import { clone, FullSlug, RelativeURL, joinSegments, normalizeHastElement } from "../util/path" import { visit } from "unist-util-visit" import { Root, Element, ElementContent } from "hast" -import { QuartzPluginData } from "../plugins/vfile" import { GlobalConfiguration } from "../cfg" import { i18n } from "../i18n" @@ -52,18 +51,6 @@ export function pageResources( } } -let pageIndex: Map | undefined = undefined -function getOrComputeFileIndex(allFiles: QuartzPluginData[]): Map { - if (!pageIndex) { - pageIndex = new Map() - for (const file of allFiles) { - pageIndex.set(file.slug!, file) - } - } - - return pageIndex -} - export function renderPage( cfg: GlobalConfiguration, slug: FullSlug, @@ -71,14 +58,18 @@ export function renderPage( components: RenderComponents, pageResources: StaticResources, ): string { + // make a deep copy of the tree so we don't remove the transclusion references + // for the file cached in contentMap in build.ts + const root = clone(componentData.tree) as Root + // process transcludes in componentData - visit(componentData.tree as Root, "element", (node, _index, _parent) => { + visit(root, "element", (node, _index, _parent) => { if (node.tagName === "blockquote") { const classNames = (node.properties?.className ?? []) as string[] if (classNames.includes("transclude")) { const inner = node.children[0] as Element const transcludeTarget = inner.properties["data-slug"] as FullSlug - const page = getOrComputeFileIndex(componentData.allFiles).get(transcludeTarget) + const page = componentData.allFiles.find((f) => f.slug === transcludeTarget) if (!page) { return } @@ -181,6 +172,9 @@ export function renderPage( } }) + // set componentData.tree to the edited html that has transclusions rendered + componentData.tree = root + const { head: Head, header, diff --git a/quartz/plugins/emitters/contentPage.tsx b/quartz/plugins/emitters/contentPage.tsx index e531b36..904a8a8 100644 --- a/quartz/plugins/emitters/contentPage.tsx +++ b/quartz/plugins/emitters/contentPage.tsx @@ -1,16 +1,56 @@ +import path from "path" +import { visit } from "unist-util-visit" +import { Root } from "hast" +import { VFile } from "vfile" import { QuartzEmitterPlugin } from "../types" import { QuartzComponentProps } from "../../components/types" import HeaderConstructor from "../../components/Header" import BodyConstructor from "../../components/Body" import { pageResources, renderPage } from "../../components/renderPage" import { FullPageLayout } from "../../cfg" -import { FilePath, joinSegments, pathToRoot } from "../../util/path" +import { Argv } from "../../util/ctx" +import { FilePath, isRelativeURL, joinSegments, pathToRoot } from "../../util/path" import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout" import { Content } from "../../components" import chalk from "chalk" import { write } from "./helpers" import DepGraph from "../../depgraph" +// get all the dependencies for the markdown file +// eg. images, scripts, stylesheets, transclusions +const parseDependencies = (argv: Argv, hast: Root, file: VFile): string[] => { + const dependencies: string[] = [] + + visit(hast, "element", (elem): void => { + let ref: string | null = null + + if ( + ["script", "img", "audio", "video", "source", "iframe"].includes(elem.tagName) && + elem?.properties?.src + ) { + ref = elem.properties.src.toString() + } else if (["a", "link"].includes(elem.tagName) && elem?.properties?.href) { + // transclusions will create a tags with relative hrefs + ref = elem.properties.href.toString() + } + + // if it is a relative url, its a local file and we need to add + // it to the dependency graph. otherwise, ignore + if (ref === null || !isRelativeURL(ref)) { + return + } + + let fp = path.join(file.data.filePath!, path.relative(argv.directory, ref)).replace(/\\/g, "/") + // markdown files have the .md extension stripped in hrefs, add it back here + if (!fp.split("/").pop()?.includes(".")) { + fp += ".md" + } + dependencies.push(fp) + }) + + return dependencies +} + export const ContentPage: QuartzEmitterPlugin> = (userOpts) => { const opts: FullPageLayout = { ...sharedPageComponents, @@ -29,13 +69,16 @@ export const ContentPage: QuartzEmitterPlugin> = (userOp return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer] }, async getDependencyGraph(ctx, content, _resources) { - // TODO handle transclusions const graph = new DepGraph() - for (const [_tree, file] of content) { + for (const [tree, file] of content) { const sourcePath = file.data.filePath! const slug = file.data.slug! graph.addEdge(sourcePath, joinSegments(ctx.argv.output, slug + ".html") as FilePath) + + parseDependencies(ctx.argv, tree as Root, file).forEach((dep) => { + graph.addEdge(dep as FilePath, sourcePath) + }) } return graph From fa2ea2896f0977253733334199d28e509351e621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Silviu=20Loren=C8=9B?= <124451350+smilorent@users.noreply.github.com> Date: Sat, 17 Feb 2024 20:23:45 +0200 Subject: [PATCH 015/217] feat: add user-defined config for syntax highlighting plugin (#869) * feat: add user-defined options to syntax highlighting plugin * feat: add default syntax highlighting config to `quartz.config.ts` * chore: refactor according to @aarnphm's review Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * chore: run Prettier on `quartz/plugins/transformers/syntax.ts` * Update quartz/plugins/transformers/syntax.ts Co-authored-by: Jacky Zhao * Update syntax.ts --------- Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Co-authored-by: Jacky Zhao --- quartz.config.ts | 11 ++++++- quartz/plugins/transformers/syntax.ts | 47 +++++++++++++++++---------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/quartz.config.ts b/quartz.config.ts index 4e36e94..8c479ac 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -53,7 +53,16 @@ const config: QuartzConfig = { priority: ["frontmatter", "filesystem"], }), Plugin.Latex({ renderEngine: "katex" }), - Plugin.SyntaxHighlighting(), + Plugin.SyntaxHighlighting({ + // uses themes bundled with Shikiji, see https://shikiji.netlify.app/themes + theme: { + light: "github-light", + dark: "github-dark", + }, + // set this to 'true' to use the background color of the Shikiji theme + // if set to 'false', will use Quartz theme colors for background + keepBackground: false, + }), Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), Plugin.GitHubFlavoredMarkdown(), Plugin.TableOfContents(), diff --git a/quartz/plugins/transformers/syntax.ts b/quartz/plugins/transformers/syntax.ts index e847729..f11734e 100644 --- a/quartz/plugins/transformers/syntax.ts +++ b/quartz/plugins/transformers/syntax.ts @@ -1,20 +1,33 @@ import { QuartzTransformerPlugin } from "../types" -import rehypePrettyCode, { Options as CodeOptions } from "rehype-pretty-code" +import rehypePrettyCode, { Options as CodeOptions, Theme as CodeTheme } from "rehype-pretty-code" -export const SyntaxHighlighting: QuartzTransformerPlugin = () => ({ - name: "SyntaxHighlighting", - htmlPlugins() { - return [ - [ - rehypePrettyCode, - { - keepBackground: false, - theme: { - dark: "github-dark", - light: "github-light", - }, - } satisfies Partial, - ], - ] +interface Theme extends Record { + light: CodeTheme + dark: CodeTheme +} + +interface Options { + theme?: Theme + keepBackground?: boolean +} + +const defaultOptions: Options = { + theme: { + light: "github-light", + dark: "github-dark", }, -}) + keepBackground: false, +} + +export const SyntaxHighlighting: QuartzTransformerPlugin = ( + userOpts?: Partial, +) => { + const opts: Partial = { ...defaultOptions, ...userOpts } + + return { + name: "SyntaxHighlighting", + htmlPlugins() { + return [[rehypePrettyCode, opts]] + }, + } +} From 06e3f8b93d5fbe96e7a05e4eb6be97b6a2d7ead0 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 17 Feb 2024 10:34:46 -0800 Subject: [PATCH 016/217] fix(style): introduce semiBoldWeight and various improvements to reduce CLS --- quartz/components/Head.tsx | 12 ++++++------ quartz/components/styles/explorer.scss | 4 ++-- quartz/plugins/emitters/componentResources.ts | 9 ++++----- quartz/styles/base.scss | 2 +- quartz/styles/callouts.scss | 2 +- quartz/styles/variables.scss | 1 + 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index a3c0800..3cb6bea 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -21,6 +21,12 @@ export default (() => { {title} + {cfg.theme.cdnCaching && ( + <> + + + + )} @@ -30,12 +36,6 @@ export default (() => { - {cfg.theme.cdnCaching && ( - <> - - - - )} {css.map((href) => ( ))} diff --git a/quartz/components/styles/explorer.scss b/quartz/components/styles/explorer.scss index 34f180c..55ea8aa 100644 --- a/quartz/components/styles/explorer.scss +++ b/quartz/components/styles/explorer.scss @@ -87,7 +87,7 @@ svg { color: var(--secondary); font-family: var(--headerFont); font-size: 0.95rem; - font-weight: $boldWeight; + font-weight: $semiBoldWeight; line-height: 1.5rem; display: inline-block; } @@ -112,7 +112,7 @@ svg { font-size: 0.95rem; display: inline-block; color: var(--secondary); - font-weight: $boldWeight; + font-weight: $semiBoldWeight; margin: 0; line-height: 1.5rem; pointer-events: none; diff --git a/quartz/plugins/emitters/componentResources.ts b/quartz/plugins/emitters/componentResources.ts index 67bc69c..0468416 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -196,10 +196,6 @@ export const ComponentResources: QuartzEmitterPlugin = (opts?: Partial< const cfg = ctx.cfg.configuration // component specific scripts and styles const componentResources = getComponentResources(ctx) - // important that this goes *after* component scripts - // as the "nav" event gets triggered here and we should make sure - // that everyone else had the chance to register a listener for it - let googleFontsStyleSheet = "" if (fontOrigin === "local") { // let the user do it themselves in css @@ -247,12 +243,15 @@ export const ComponentResources: QuartzEmitterPlugin = (opts?: Partial< } } + // important that this goes *after* component scripts + // as the "nav" event gets triggered here and we should make sure + // that everyone else had the chance to register a listener for it addGlobalPageResources(ctx, resources, componentResources) const stylesheet = joinStyles( ctx.cfg.configuration.theme, - ...componentResources.css, googleFontsStyleSheet, + ...componentResources.css, styles, ) const [prescript, postscript] = await Promise.all([ diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index f0e7c14..6c8f836 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -54,7 +54,7 @@ ul, } a { - font-weight: $boldWeight; + font-weight: $semiBoldWeight; text-decoration: none; transition: color 0.2s ease; color: var(--secondary); diff --git a/quartz/styles/callouts.scss b/quartz/styles/callouts.scss index 7fa52c5..b1fd180 100644 --- a/quartz/styles/callouts.scss +++ b/quartz/styles/callouts.scss @@ -157,6 +157,6 @@ } .callout-title-inner { - font-weight: $boldWeight; + font-weight: $semiBoldWeight; } } diff --git a/quartz/styles/variables.scss b/quartz/styles/variables.scss index 8384b9c..e45cc91 100644 --- a/quartz/styles/variables.scss +++ b/quartz/styles/variables.scss @@ -5,4 +5,5 @@ $sidePanelWidth: 380px; $topSpacing: 6rem; $fullPageWidth: $pageWidth + 2 * $sidePanelWidth; $boldWeight: 700; +$semiBoldWeight: 600; $normalWeight: 400; From a6690c6503ca6b2957a4476671c7239212b81b1a Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 17 Feb 2024 10:57:59 -0800 Subject: [PATCH 017/217] fix(style): bold should use semibold --- quartz/styles/base.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 6c8f836..92798a2 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -53,6 +53,10 @@ ul, } } +strong { + font-weight: $semiBoldWeight; +} + a { font-weight: $semiBoldWeight; text-decoration: none; From aa24a62ae77ed1bd3edd4b617cd76d7a056c7f1c Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 17 Feb 2024 11:12:35 -0800 Subject: [PATCH 018/217] fix(breadcrumbs): calculate trailing slash for tag hierarchies (closes #873) --- quartz/components/Breadcrumbs.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/quartz/components/Breadcrumbs.tsx b/quartz/components/Breadcrumbs.tsx index b1a924a..9ccfb9a 100644 --- a/quartz/components/Breadcrumbs.tsx +++ b/quartz/components/Breadcrumbs.tsx @@ -1,6 +1,6 @@ import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import breadcrumbsStyle from "./styles/breadcrumbs.scss" -import { FullSlug, SimpleSlug, resolveRelative } from "../util/path" +import { FullSlug, SimpleSlug, joinSegments, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" import { classNames } from "../util/lang" @@ -82,8 +82,12 @@ export default ((opts?: Partial) => { // Split slug into hierarchy/parts const slugParts = fileData.slug?.split("/") if (slugParts) { + // is tag breadcrumb? + const isTagPath = slugParts[0] === "tags" + // full path until current part let currentPath = "" + for (let i = 0; i < slugParts.length - 1; i++) { let curPathSegment = slugParts[i] @@ -97,10 +101,15 @@ export default ((opts?: Partial) => { } // Add current slug to full path - currentPath += slugParts[i] + "/" + currentPath = joinSegments(currentPath, slugParts[i]) + const includeTrailingSlash = !isTagPath || i < 1 // Format and add current crumb - const crumb = formatCrumb(curPathSegment, fileData.slug!, currentPath as SimpleSlug) + const crumb = formatCrumb( + curPathSegment, + fileData.slug!, + (currentPath + (includeTrailingSlash ? "/" : "")) as SimpleSlug, + ) crumbs.push(crumb) } From 8c5c5f9130c65fcc48412a24b0a6c98b254f1934 Mon Sep 17 00:00:00 2001 From: makondratev <69584771+makondratev@users.noreply.github.com> Date: Sun, 18 Feb 2024 21:54:37 +0300 Subject: [PATCH 019/217] feat(i18n): add Russian (#886) --- quartz/i18n/index.ts | 2 + quartz/i18n/locales/ru-RU.ts | 95 ++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 quartz/i18n/locales/ru-RU.ts diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index c4fa425..1e4853f 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -8,6 +8,7 @@ import ro from "./locales/ro-RO" import es from "./locales/es-ES" import ar from "./locales/ar-SA" import uk from "./locales/uk-UA" +import ru from "./locales/ru-RU" export const TRANSLATIONS = { "en-US": en, @@ -40,6 +41,7 @@ export const TRANSLATIONS = { "ar-DZ": ar, "ar-MR": ar, "uk-UA": uk, + "ru-RU": ru, } as const export const defaultTranslation = "en-US" diff --git a/quartz/i18n/locales/ru-RU.ts b/quartz/i18n/locales/ru-RU.ts new file mode 100644 index 0000000..8ead3ca --- /dev/null +++ b/quartz/i18n/locales/ru-RU.ts @@ -0,0 +1,95 @@ +import { Translation } from "./definition" + +export default { + propertyDefaults: { + title: "Без названия", + description: "Описание отсутствует", + }, + components: { + callout: { + note: "Заметка", + abstract: "Резюме", + info: "Инфо", + todo: "Сделать", + tip: "Подсказка", + success: "Успех", + question: "Вопрос", + warning: "Предупреждение", + failure: "Неудача", + danger: "Опасность", + bug: "Баг", + example: "Пример", + quote: "Цитата", + }, + backlinks: { + title: "Обратные ссылки", + noBacklinksFound: "Обратные ссылки отсутствуют", + }, + themeToggle: { + lightMode: "Светлый режим", + darkMode: "Тёмный режим", + }, + explorer: { + title: "Проводник", + }, + footer: { + createdWith: "Создано с помощью", + }, + graph: { + title: "Вид графа", + }, + recentNotes: { + title: "Недавние заметки", + seeRemainingMore: ({ remaining }) => + `Посмотреть оставш${getForm(remaining, "уюся", "иеся", "иеся")} ${remaining} →`, + }, + transcludes: { + transcludeOf: ({ targetSlug }) => `Переход из ${targetSlug}`, + linkToOriginal: "Ссылка на оригинал", + }, + search: { + title: "Поиск", + searchBarPlaceholder: "Найти что-нибудь", + }, + tableOfContents: { + title: "Оглавление", + }, + contentMeta: { + readingTime: ({ minutes }) => `время чтения ~${minutes} мин.`, + }, + }, + pages: { + rss: { + recentNotes: "Недавние заметки", + lastFewNotes: ({ count }) => + `Последн${getForm(count, "яя", "ие", "ие")} ${count} замет${getForm(count, "ка", "ки", "ок")}`, + }, + error: { + title: "Страница не найдена", + notFound: "Эта страница приватная или не существует", + }, + folderContent: { + folder: "Папка", + itemsUnderFolder: ({ count }) => + `в этой папке ${count} элемент${getForm(count, "", "а", "ов")}`, + }, + tagContent: { + tag: "Тег", + tagIndex: "Индекс тегов", + itemsUnderTag: ({ count }) => `с этим тегом ${count} элемент${getForm(count, "", "а", "ов")}`, + showingFirst: ({ count }) => + `Показыва${getForm(count, "ется", "ются", "ются")} ${count} тег${getForm(count, "", "а", "ов")}`, + totalTags: ({ count }) => `Всего ${count} тег${getForm(count, "", "а", "ов")}`, + }, + }, +} as const satisfies Translation + +function getForm(number: number, form1: string, form2: string, form5: string): string { + const remainder100 = number % 100 + const remainder10 = remainder100 % 10 + + if (remainder100 >= 10 && remainder100 <= 20) return form5 + if (remainder10 > 1 && remainder10 < 5) return form2 + if (remainder10 == 1) return form1 + return form5 +} From b1a105371bffdea6ca10a010292248ef9aff3ce2 Mon Sep 17 00:00:00 2001 From: JONG HWAN KIM <99215801+JongDeug@users.noreply.github.com> Date: Mon, 19 Feb 2024 07:37:59 +0900 Subject: [PATCH 020/217] feat(i18n): add Korean (#889) * feat(i18n): add Korean * feat(i18n): add Korean --- quartz/i18n/index.ts | 2 + quartz/i18n/locales/ko-KR.ts | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 quartz/i18n/locales/ko-KR.ts diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index 1e4853f..5224f66 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -9,6 +9,7 @@ import es from "./locales/es-ES" import ar from "./locales/ar-SA" import uk from "./locales/uk-UA" import ru from "./locales/ru-RU" +import ko from "./locales/ko-KR" export const TRANSLATIONS = { "en-US": en, @@ -42,6 +43,7 @@ export const TRANSLATIONS = { "ar-MR": ar, "uk-UA": uk, "ru-RU": ru, + "ko-KR": ko, } as const export const defaultTranslation = "en-US" diff --git a/quartz/i18n/locales/ko-KR.ts b/quartz/i18n/locales/ko-KR.ts new file mode 100644 index 0000000..ed859a9 --- /dev/null +++ b/quartz/i18n/locales/ko-KR.ts @@ -0,0 +1,81 @@ +import { Translation } from "./definition" + +export default { + propertyDefaults: { + title: "제목 없음", + description: "설명 없음", + }, + components: { + callout: { + note: "노트", + abstract: "개요", + info: "정보", + todo: "할일", + tip: "팁", + success: "성공", + question: "질문", + warning: "주의", + failure: "실패", + danger: "위험", + bug: "버그", + example: "예시", + quote: "인용", + }, + backlinks: { + title: "백링크", + noBacklinksFound: "백링크가 없습니다.", + }, + themeToggle: { + lightMode: "라이트 모드", + darkMode: "다크 모드", + }, + explorer: { + title: "탐색기", + }, + footer: { + createdWith: "Created with", + }, + graph: { + title: "그래프 뷰", + }, + recentNotes: { + title: "최근 게시글", + seeRemainingMore: ({ remaining }) => `${remaining}건 더보기 →`, + }, + transcludes: { + transcludeOf: ({ targetSlug }) => `${targetSlug}의 포함`, + linkToOriginal: "원본 링크", + }, + search: { + title: "검색", + searchBarPlaceholder: "검색어를 입력하세요", + }, + tableOfContents: { + title: "목차", + }, + contentMeta: { + readingTime: ({ minutes }) => `${minutes} min read`, + }, + }, + pages: { + rss: { + recentNotes: "최근 게시글", + lastFewNotes: ({ count }) => `최근 ${count} 건`, + }, + error: { + title: "Not Found", + notFound: "페이지가 존재하지 않거나 비공개 설정이 되어 있습니다.", + }, + folderContent: { + folder: "폴더", + itemsUnderFolder: ({ count }) => `${count}건의 페이지`, + }, + tagContent: { + tag: "태그", + tagIndex: "태그 목록", + itemsUnderTag: ({ count }) => `${count}건의 페이지`, + showingFirst: ({ count }) => `처음 ${count}개의 태그`, + totalTags: ({ count }) => `총 ${count}개의 태그를 찾았습니다.`, + }, + }, +} as const satisfies Translation From 739c2e2cc8db456514f81def7fa8c519656fdaa7 Mon Sep 17 00:00:00 2001 From: s-crypt <41712656+s-crypt@users.noreply.github.com> Date: Sun, 18 Feb 2024 20:26:04 -0800 Subject: [PATCH 021/217] perf(cdn): CDNJS instead of JSDelivr (#891) --- docs/advanced/making plugins.md | 4 ++-- quartz/plugins/transformers/latex.ts | 4 ++-- quartz/plugins/transformers/ofm.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/advanced/making plugins.md b/docs/advanced/making plugins.md index 565f5bd..d9ed9e3 100644 --- a/docs/advanced/making plugins.md +++ b/docs/advanced/making plugins.md @@ -84,10 +84,10 @@ export const Latex: QuartzTransformerPlugin = (opts?: Options) => { externalResources() { if (engine === "katex") { return { - css: ["https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"], + css: ["https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css"], js: [ { - src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js", + src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/contrib/copy-tex.min.js", loadTime: "afterDOMReady", contentType: "external", }, diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts index ab10a4f..c9f6bff 100644 --- a/quartz/plugins/transformers/latex.ts +++ b/quartz/plugins/transformers/latex.ts @@ -26,12 +26,12 @@ export const Latex: QuartzTransformerPlugin = (opts?: Options) => { return { css: [ // base css - "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css", + "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css", ], js: [ { // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md - src: "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/copy-tex.min.js", + src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/copy-tex.min.js", loadTime: "afterDOMReady", contentType: "external", }, diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index e110e40..6aad230 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -619,7 +619,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin let mermaidImport = undefined document.addEventListener('nav', async () => { if (document.querySelector("code.mermaid")) { - mermaidImport ||= await import('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs') + mermaidImport ||= await import('https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs') const mermaid = mermaidImport.default const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' mermaid.initialize({ From efd46f84de2d8dcc630b96de5454027bfbbf5f6e Mon Sep 17 00:00:00 2001 From: Eiko Wagenknecht Date: Mon, 19 Feb 2024 09:08:36 +0100 Subject: [PATCH 022/217] fix(frontmatter): delimiters parameter was not passed (#885) * fix: delimiters parameter was not passed Signed-off-by: Eiko Wagenknecht * fix: remove unneeded undefined --------- Signed-off-by: Eiko Wagenknecht --- quartz/plugins/transformers/frontmatter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index 9371df8..7073d43 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -8,12 +8,12 @@ import { QuartzPluginData } from "../vfile" import { i18n } from "../../i18n" export interface Options { - delims: string | string[] + delimiters: string | [string, string] language: "yaml" | "toml" } const defaultOptions: Options = { - delims: "---", + delimiters: "---", language: "yaml", } From d9e8ffc78c54a59047df56d8000b2f6289eb9be0 Mon Sep 17 00:00:00 2001 From: Leonardo Ledda <35930217+LeddaZ@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:50:01 +0100 Subject: [PATCH 023/217] feat(i18n): Add Italian (#893) Signed-off-by: Leonardo Ledda --- quartz/i18n/index.ts | 2 + quartz/i18n/locales/it-IT.ts | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 quartz/i18n/locales/it-IT.ts diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index 5224f66..3861bf7 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -1,6 +1,7 @@ import { Translation, CalloutTranslation } from "./locales/definition" import en from "./locales/en-US" import fr from "./locales/fr-FR" +import it from "./locales/it-IT" import ja from "./locales/ja-JP" import de from "./locales/de-DE" import nl from "./locales/nl-NL" @@ -14,6 +15,7 @@ import ko from "./locales/ko-KR" export const TRANSLATIONS = { "en-US": en, "fr-FR": fr, + "it-IT": it, "ja-JP": ja, "de-DE": de, "nl-NL": nl, diff --git a/quartz/i18n/locales/it-IT.ts b/quartz/i18n/locales/it-IT.ts new file mode 100644 index 0000000..a0cc042 --- /dev/null +++ b/quartz/i18n/locales/it-IT.ts @@ -0,0 +1,83 @@ +import { Translation } from "./definition" + +export default { + propertyDefaults: { + title: "Senza titolo", + description: "Nessuna descrizione", + }, + components: { + callout: { + note: "Nota", + abstract: "Astratto", + info: "Info", + todo: "Da fare", + tip: "Consiglio", + success: "Completato", + question: "Domanda", + warning: "Attenzione", + failure: "Errore", + danger: "Pericolo", + bug: "Bug", + example: "Esempio", + quote: "Citazione", + }, + backlinks: { + title: "Link entranti", + noBacklinksFound: "Nessun link entrante", + }, + themeToggle: { + lightMode: "Tema chiaro", + darkMode: "Tema scuro", + }, + explorer: { + title: "Esplora", + }, + footer: { + createdWith: "Creato con", + }, + graph: { + title: "Vista grafico", + }, + recentNotes: { + title: "Note recenti", + seeRemainingMore: ({ remaining }) => `Vedi ${remaining} altro →`, + }, + transcludes: { + transcludeOf: ({ targetSlug }) => `Transclusione di ${targetSlug}`, + linkToOriginal: "Link all'originale", + }, + search: { + title: "Cerca", + searchBarPlaceholder: "Cerca qualcosa", + }, + tableOfContents: { + title: "Tabella dei contenuti", + }, + contentMeta: { + readingTime: ({ minutes }) => `${minutes} minuti`, + }, + }, + pages: { + rss: { + recentNotes: "Note recenti", + lastFewNotes: ({ count }) => `Ultime ${count} note`, + }, + error: { + title: "Non trovato", + notFound: "Questa pagina è privata o non esiste.", + }, + folderContent: { + folder: "Cartella", + itemsUnderFolder: ({ count }) => + count === 1 ? "1 oggetto in questa cartella" : `${count} oggetti in questa cartella.`, + }, + tagContent: { + tag: "Etichetta", + tagIndex: "Indice etichette", + itemsUnderTag: ({ count }) => + count === 1 ? "1 oggetto con questa etichetta" : `${count} oggetti con questa etichetta.`, + showingFirst: ({ count }) => `Prime ${count} etichette.`, + totalTags: ({ count }) => `Trovate ${count} etichette totali.`, + }, + }, +} as const satisfies Translation From 3e09b05468c372e85518ff76d8d6d9a415f61fac Mon Sep 17 00:00:00 2001 From: kon-foo <25391223+kon-foo@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:50:40 +0100 Subject: [PATCH 024/217] docs: add self-hosting section (#883) * Add Self-Hosting section Add Nginx section * run prettier --- docs/hosting.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/hosting.md b/docs/hosting.md index bae7ed8..eeb9308 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -228,3 +228,25 @@ pages: When `.gitlab-ci.yaml` is committed, GitLab will build and deploy the website as a GitLab Page. You can find the url under `Deploy > Pages` in the sidebar. By default, the page is private and only visible when logged in to a GitLab account with access to the repository but can be opened in the settings under `Deploy` -> `Pages`. + +## Self-Hosting + +Copy the `public` directory to your web server and configure it to serve the files. You can use any web server to host your site. Since Quartz generates links that do not include the `.html` extension, you need to let your web server know how to deal with it. + +### Using Nginx + +Here's an example of how to do this with Nginx: + +```nginx title="nginx.conf" +server { + listen 80; + server_name example.com; + root /path/to/quartz/public; + index index.html; + error_page 404 /404.html; + + location / { + try_files $uri $uri.html $uri/ =404; + } +} +``` From e85ea490003870c5a6c004bb2e6bd6d76769a2ce Mon Sep 17 00:00:00 2001 From: KylinDC Date: Tue, 20 Feb 2024 02:31:09 +0800 Subject: [PATCH 025/217] feat(i18n): add Simplified Chinese (#896) --- quartz/i18n/index.ts | 2 + quartz/i18n/locales/zh-CN.ts | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 quartz/i18n/locales/zh-CN.ts diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index 3861bf7..38d3562 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -11,6 +11,7 @@ import ar from "./locales/ar-SA" import uk from "./locales/uk-UA" import ru from "./locales/ru-RU" import ko from "./locales/ko-KR" +import zh from "./locales/zh-CN" export const TRANSLATIONS = { "en-US": en, @@ -46,6 +47,7 @@ export const TRANSLATIONS = { "uk-UA": uk, "ru-RU": ru, "ko-KR": ko, + "zh-CN": zh, } as const export const defaultTranslation = "en-US" diff --git a/quartz/i18n/locales/zh-CN.ts b/quartz/i18n/locales/zh-CN.ts new file mode 100644 index 0000000..43d0111 --- /dev/null +++ b/quartz/i18n/locales/zh-CN.ts @@ -0,0 +1,81 @@ +import { Translation } from "./definition" + +export default { + propertyDefaults: { + title: "无题", + description: "无描述", + }, + components: { + callout: { + note: "笔记", + abstract: "摘要", + info: "提示", + todo: "待办", + tip: "提示", + success: "成功", + question: "问题", + warning: "警告", + failure: "失败", + danger: "危险", + bug: "错误", + example: "示例", + quote: "引用", + }, + backlinks: { + title: "反向链接", + noBacklinksFound: "无法找到反向链接", + }, + themeToggle: { + lightMode: "亮色模式", + darkMode: "暗色模式", + }, + explorer: { + title: "探索", + }, + footer: { + createdWith: "Created with", + }, + graph: { + title: "关系图谱", + }, + recentNotes: { + title: "最近的笔记", + seeRemainingMore: ({ remaining }) => `查看更多${remaining}篇笔记 →`, + }, + transcludes: { + transcludeOf: ({ targetSlug }) => `包含${targetSlug}`, + linkToOriginal: "指向原始笔记的链接", + }, + search: { + title: "搜索", + searchBarPlaceholder: "搜索些什么", + }, + tableOfContents: { + title: "目录", + }, + contentMeta: { + readingTime: ({ minutes }) => `${minutes}分钟阅读`, + }, + }, + pages: { + rss: { + recentNotes: "最近的笔记", + lastFewNotes: ({ count }) => `最近的${count}条笔记`, + }, + error: { + title: "无法找到", + notFound: "私有笔记或笔记不存在。", + }, + folderContent: { + folder: "文件夹", + itemsUnderFolder: ({ count }) => `此文件夹下有${count}条笔记。`, + }, + tagContent: { + tag: "标签", + tagIndex: "标签索引", + itemsUnderTag: ({ count }) => `此标签下有${count}条笔记。`, + showingFirst: ({ count }) => `显示前${count}个标签。`, + totalTags: ({ count }) => `总共有${count}个标签。`, + }, + }, +} as const satisfies Translation From a67a8d7aa9da06d8f87d0f48bac630728a4ea394 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:58:15 +0000 Subject: [PATCH 026/217] feat: implement getDependencyGraph for TagPage (#872) * feat: implement getDependencyGraph for TagPage * Only add file to dg if it has at least 1 tag --- quartz/plugins/emitters/tagPage.tsx | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/quartz/plugins/emitters/tagPage.tsx b/quartz/plugins/emitters/tagPage.tsx index 332c758..3eb6975 100644 --- a/quartz/plugins/emitters/tagPage.tsx +++ b/quartz/plugins/emitters/tagPage.tsx @@ -35,9 +35,26 @@ export const TagPage: QuartzEmitterPlugin> = (userOpts) getQuartzComponents() { return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer] }, - async getDependencyGraph(ctx, _content, _resources) { - // TODO implement - return new DepGraph() + async getDependencyGraph(ctx, content, _resources) { + const graph = new DepGraph() + + for (const [_tree, file] of content) { + const sourcePath = file.data.filePath! + const tags = (file.data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes) + // if the file has at least one tag, it is used in the tag index page + if (tags.length > 0) { + tags.push("index") + } + + for (const tag of tags) { + graph.addEdge( + sourcePath, + joinSegments(ctx.argv.output, "tags", tag + ".html") as FilePath, + ) + } + } + + return graph }, async emit(ctx, content, resources): Promise { const fps: FilePath[] = [] From 0493942c79f8528ca8bef6cd8e2f634275f03119 Mon Sep 17 00:00:00 2001 From: kon-foo <25391223+kon-foo@users.noreply.github.com> Date: Mon, 19 Feb 2024 20:04:27 +0100 Subject: [PATCH 027/217] fix: remove assets via globs to avoid volume mount lock (#877) * Fix docker volume lock issue by altering asset cleanup method Modified build process to prevent the deletion of the output directory. * Add fsOps utility for filesystem operations * Use cleanDirectory in build process to fix volume lock issue * applied prettier * handle ENOENT error when output dir does not exist * remove native function in favor of rimraf * use path.join to concatenate paths --- quartz/build.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/build.ts b/quartz/build.ts index 452a2f1..3d95f31 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -60,7 +60,7 @@ async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) { const release = await mut.acquire() perf.addEvent("clean") - await rimraf(output) + await rimraf(path.join(output, "*"), { glob: true }) console.log(`Cleaned output directory \`${output}\` in ${perf.timeSince("clean")}`) perf.addEvent("glob") @@ -375,7 +375,7 @@ async function rebuildFromEntrypoint( // TODO: we can probably traverse the link graph to figure out what's safe to delete here // instead of just deleting everything - await rimraf(argv.output) + await rimraf(path.join(argv.output, ".*"), { glob: true }) await emitContent(ctx, filteredContent) console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`)) } catch (err) { From 637e336cdaa8cf8eb918257c236c53ccc5dc5ae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:46:27 -0800 Subject: [PATCH 028/217] chore(deps-dev): bump @types/node from 20.11.16 to 20.11.19 (#899) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.16 to 20.11.19. - [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 7d1d973..4d0ef1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.16", + "@types/node": "^20.11.19", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", @@ -1088,9 +1088,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", - "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", + "version": "20.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", + "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" diff --git a/package.json b/package.json index f89bb2a..2a56735 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.16", + "@types/node": "^20.11.19", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", From f1619620d5cd285b4a4dabf69a9dd1d95de2f36c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:47:00 -0800 Subject: [PATCH 029/217] chore(deps): bump globby from 14.0.0 to 14.0.1 (#897) Bumps [globby](https://github.com/sindresorhus/globby) from 14.0.0 to 14.0.1. - [Release notes](https://github.com/sindresorhus/globby/releases) - [Commits](https://github.com/sindresorhus/globby/compare/v14.0.0...v14.0.1) --- updated-dependencies: - dependency-name: globby 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 4d0ef1a..e2ae90e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "esbuild-sass-plugin": "^2.16.1", "flexsearch": "0.7.43", "github-slugger": "^2.0.0", - "globby": "^14.0.0", + "globby": "^14.0.1", "gray-matter": "^4.0.3", "hast-util-to-html": "^9.0.0", "hast-util-to-jsx-runtime": "^2.3.0", @@ -743,9 +743,9 @@ } }, "node_modules/@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "engines": { "node": ">=18" }, @@ -2301,11 +2301,11 @@ } }, "node_modules/globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dependencies": { - "@sindresorhus/merge-streams": "^1.0.0", + "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", diff --git a/package.json b/package.json index 2a56735..d469d7b 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "esbuild-sass-plugin": "^2.16.1", "flexsearch": "0.7.43", "github-slugger": "^2.0.0", - "globby": "^14.0.0", + "globby": "^14.0.1", "gray-matter": "^4.0.3", "hast-util-to-html": "^9.0.0", "hast-util-to-jsx-runtime": "^2.3.0", From 779c501d9eb6393539f0be7653dbdc09f1b9ebe9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:47:07 -0800 Subject: [PATCH 030/217] chore(deps): bump preact from 10.19.4 to 10.19.5 (#898) Bumps [preact](https://github.com/preactjs/preact) from 10.19.4 to 10.19.5. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.19.4...10.19.5) --- updated-dependencies: - dependency-name: preact 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 e2ae90e..4a8b583 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.4", + "preact": "^10.19.5", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", @@ -4454,9 +4454,9 @@ } }, "node_modules/preact": { - "version": "10.19.4", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.4.tgz", - "integrity": "sha512-dwaX5jAh0Ga8uENBX1hSOujmKWgx9RtL80KaKUFLc6jb4vCEAc3EeZ0rnQO/FO4VgjfPMfoLFWnNG8bHuZ9VLw==", + "version": "10.19.5", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.5.tgz", + "integrity": "sha512-OPELkDmSVbKjbFqF9tgvOowiiQ9TmsJljIzXRyNE8nGiis94pwv1siF78rQkAP1Q1738Ce6pellRg/Ns/CtHqQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index d469d7b..54c67fb 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.4", + "preact": "^10.19.5", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", From b6cf3df84f452c22ac9ddaf452b0ecbe0828086f Mon Sep 17 00:00:00 2001 From: Eiko Wagenknecht Date: Mon, 19 Feb 2024 22:49:07 +0100 Subject: [PATCH 031/217] fix: correctly parse falsy js as title (#900) --- quartz/plugins/transformers/frontmatter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index 7073d43..79aa5f3 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -57,9 +57,9 @@ export const FrontMatter: QuartzTransformerPlugin | undefined> }, }) - if (data.title) { + if (data.title != null && data.title.toString() !== "") { data.title = data.title.toString() - } else if (data.title === null || data.title === undefined) { + } else { data.title = file.stem ?? i18n(cfg.configuration.locale).propertyDefaults.title } From fc5fa48bf18ec0bc0b7a7e31a086428664117e04 Mon Sep 17 00:00:00 2001 From: JONG HWAN KIM <99215801+JongDeug@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:36:54 +0900 Subject: [PATCH 032/217] feat(i18n): change itemsUnderFolder, itemsUnderTag translation of ko-KR (#905) * feat(i18n): add Korean * feat(i18n): add Korean * feat(i18n): change itemsUnderFolder, itemsUnderTag translation of ko-KR --- quartz/i18n/locales/ko-KR.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/i18n/locales/ko-KR.ts b/quartz/i18n/locales/ko-KR.ts index ed859a9..ea735b0 100644 --- a/quartz/i18n/locales/ko-KR.ts +++ b/quartz/i18n/locales/ko-KR.ts @@ -68,12 +68,12 @@ export default { }, folderContent: { folder: "폴더", - itemsUnderFolder: ({ count }) => `${count}건의 페이지`, + itemsUnderFolder: ({ count }) => `${count}건의 항목`, }, tagContent: { tag: "태그", tagIndex: "태그 목록", - itemsUnderTag: ({ count }) => `${count}건의 페이지`, + itemsUnderTag: ({ count }) => `${count}건의 항목`, showingFirst: ({ count }) => `처음 ${count}개의 태그`, totalTags: ({ count }) => `총 ${count}개의 태그를 찾았습니다.`, }, From 3b266ee7d0d414d2af7d291f249b0153af51aa2e Mon Sep 17 00:00:00 2001 From: Eiko Wagenknecht Date: Tue, 20 Feb 2024 15:45:10 +0100 Subject: [PATCH 033/217] fix: add space and missing dot for listing pages (#907) --- quartz/components/pages/TagContent.tsx | 9 ++++++--- quartz/i18n/locales/de-DE.ts | 4 ++-- quartz/i18n/locales/en-US.ts | 4 ++-- quartz/i18n/locales/es-ES.ts | 4 ++-- quartz/i18n/locales/fr-FR.ts | 4 ++-- quartz/i18n/locales/it-IT.ts | 4 ++-- quartz/i18n/locales/nl-NL.ts | 2 +- quartz/i18n/locales/uk-UA.ts | 4 ++-- 8 files changed, 19 insertions(+), 16 deletions(-) diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx index 19452ec..22f6bb2 100644 --- a/quartz/components/pages/TagContent.tsx +++ b/quartz/components/pages/TagContent.tsx @@ -66,9 +66,12 @@ function TagContent(props: QuartzComponentProps) {

{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })} {pages.length > numPages && ( - - {i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })} - + <> + {" "} + + {i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })} + + )}

diff --git a/quartz/i18n/locales/de-DE.ts b/quartz/i18n/locales/de-DE.ts index e382194..64c9ba9 100644 --- a/quartz/i18n/locales/de-DE.ts +++ b/quartz/i18n/locales/de-DE.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Ordner", itemsUnderFolder: ({ count }) => - count === 1 ? "1 Datei in diesem Ordner" : `${count} Dateien in diesem Ordner.`, + count === 1 ? "1 Datei in diesem Ordner." : `${count} Dateien in diesem Ordner.`, }, tagContent: { tag: "Tag", tagIndex: "Tag-Übersicht", itemsUnderTag: ({ count }) => - count === 1 ? "1 Datei mit diesem Tag" : `${count} Dateien mit diesem Tag.`, + count === 1 ? "1 Datei mit diesem Tag." : `${count} Dateien mit diesem Tag.`, showingFirst: ({ count }) => `Die ersten ${count} Tags werden angezeigt.`, totalTags: ({ count }) => `${count} Tags insgesamt.`, }, diff --git a/quartz/i18n/locales/en-US.ts b/quartz/i18n/locales/en-US.ts index 4a308d7..ac283fd 100644 --- a/quartz/i18n/locales/en-US.ts +++ b/quartz/i18n/locales/en-US.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Folder", itemsUnderFolder: ({ count }) => - count === 1 ? "1 item under this folder" : `${count} items under this folder.`, + count === 1 ? "1 item under this folder." : `${count} items under this folder.`, }, tagContent: { tag: "Tag", tagIndex: "Tag Index", itemsUnderTag: ({ count }) => - count === 1 ? "1 item with this tag" : `${count} items with this tag.`, + count === 1 ? "1 item with this tag." : `${count} items with this tag.`, showingFirst: ({ count }) => `Showing first ${count} tags.`, totalTags: ({ count }) => `Found ${count} total tags.`, }, diff --git a/quartz/i18n/locales/es-ES.ts b/quartz/i18n/locales/es-ES.ts index f59d201..37a2a79 100644 --- a/quartz/i18n/locales/es-ES.ts +++ b/quartz/i18n/locales/es-ES.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Carpeta", itemsUnderFolder: ({ count }) => - count === 1 ? "1 artículo en esta carpeta" : `${count} artículos en esta carpeta.`, + count === 1 ? "1 artículo en esta carpeta." : `${count} artículos en esta carpeta.`, }, tagContent: { tag: "Etiqueta", tagIndex: "Índice de Etiquetas", itemsUnderTag: ({ count }) => - count === 1 ? "1 artículo con esta etiqueta" : `${count} artículos con esta etiqueta.`, + count === 1 ? "1 artículo con esta etiqueta." : `${count} artículos con esta etiqueta.`, showingFirst: ({ count }) => `Mostrando las primeras ${count} etiquetas.`, totalTags: ({ count }) => `Se encontraron ${count} etiquetas en total.`, }, diff --git a/quartz/i18n/locales/fr-FR.ts b/quartz/i18n/locales/fr-FR.ts index 8b72292..b485d2b 100644 --- a/quartz/i18n/locales/fr-FR.ts +++ b/quartz/i18n/locales/fr-FR.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Dossier", itemsUnderFolder: ({ count }) => - count === 1 ? "1 élément sous ce dossier" : `${count} éléments sous ce dossier.`, + count === 1 ? "1 élément sous ce dossier." : `${count} éléments sous ce dossier.`, }, tagContent: { tag: "Étiquette", tagIndex: "Index des étiquettes", itemsUnderTag: ({ count }) => - count === 1 ? "1 élément avec cette étiquette" : `${count} éléments avec cette étiquette.`, + count === 1 ? "1 élément avec cette étiquette." : `${count} éléments avec cette étiquette.`, showingFirst: ({ count }) => `Affichage des premières ${count} étiquettes.`, totalTags: ({ count }) => `Trouvé ${count} étiquettes au total.`, }, diff --git a/quartz/i18n/locales/it-IT.ts b/quartz/i18n/locales/it-IT.ts index a0cc042..ca8818a 100644 --- a/quartz/i18n/locales/it-IT.ts +++ b/quartz/i18n/locales/it-IT.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Cartella", itemsUnderFolder: ({ count }) => - count === 1 ? "1 oggetto in questa cartella" : `${count} oggetti in questa cartella.`, + count === 1 ? "1 oggetto in questa cartella." : `${count} oggetti in questa cartella.`, }, tagContent: { tag: "Etichetta", tagIndex: "Indice etichette", itemsUnderTag: ({ count }) => - count === 1 ? "1 oggetto con questa etichetta" : `${count} oggetti con questa etichetta.`, + count === 1 ? "1 oggetto con questa etichetta." : `${count} oggetti con questa etichetta.`, showingFirst: ({ count }) => `Prime ${count} etichette.`, totalTags: ({ count }) => `Trovate ${count} etichette totali.`, }, diff --git a/quartz/i18n/locales/nl-NL.ts b/quartz/i18n/locales/nl-NL.ts index e239be0..d075d58 100644 --- a/quartz/i18n/locales/nl-NL.ts +++ b/quartz/i18n/locales/nl-NL.ts @@ -70,7 +70,7 @@ export default { folderContent: { folder: "Map", itemsUnderFolder: ({ count }) => - count === 1 ? "1 item in deze map" : `${count} items in deze map.`, + count === 1 ? "1 item in deze map." : `${count} items in deze map.`, }, tagContent: { tag: "Label", diff --git a/quartz/i18n/locales/uk-UA.ts b/quartz/i18n/locales/uk-UA.ts index c997a69..b636938 100644 --- a/quartz/i18n/locales/uk-UA.ts +++ b/quartz/i18n/locales/uk-UA.ts @@ -69,13 +69,13 @@ export default { folderContent: { folder: "Папка", itemsUnderFolder: ({ count }) => - count === 1 ? "У цій папці 1 елемент" : `Елементів у цій папці: ${count}.`, + count === 1 ? "У цій папці 1 елемент." : `Елементів у цій папці: ${count}.`, }, tagContent: { tag: "Тег", tagIndex: "Індекс тегу", itemsUnderTag: ({ count }) => - count === 1 ? "1 елемент з цим тегом" : `Елементів з цим тегом: ${count}.`, + count === 1 ? "1 елемент з цим тегом." : `Елементів з цим тегом: ${count}.`, showingFirst: ({ count }) => `Показ перших ${count} тегів.`, totalTags: ({ count }) => `Всього знайдено тегів: ${count}.`, }, From 1c3f3d03e1682cd435363e354acae6dc936baef3 Mon Sep 17 00:00:00 2001 From: Eiko Wagenknecht Date: Tue, 20 Feb 2024 18:06:53 +0100 Subject: [PATCH 034/217] fix(toc): correct type for minEntries param (#909) --- quartz/plugins/transformers/toc.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/toc.ts b/quartz/plugins/transformers/toc.ts index 4c31d20..bfc2f98 100644 --- a/quartz/plugins/transformers/toc.ts +++ b/quartz/plugins/transformers/toc.ts @@ -6,7 +6,7 @@ import Slugger from "github-slugger" export interface Options { maxDepth: 1 | 2 | 3 | 4 | 5 | 6 - minEntries: 1 + minEntries: number showByDefault: boolean collapseByDefault: boolean } @@ -52,7 +52,7 @@ export const TableOfContents: QuartzTransformerPlugin | undefin } }) - if (toc.length > opts.minEntries) { + if (toc.length > 0 && toc.length > opts.minEntries) { file.data.toc = toc.map((entry) => ({ ...entry, depth: entry.depth - highestDepth, From 7dd596ebcece8badf18586186c9712b364fab42e Mon Sep 17 00:00:00 2001 From: kon-foo <25391223+kon-foo@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:18:44 +0100 Subject: [PATCH 035/217] docs: Fix in explorer.md (#911) --- docs/features/explorer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/explorer.md b/docs/features/explorer.md index b5fd379..a2acb86 100644 --- a/docs/features/explorer.md +++ b/docs/features/explorer.md @@ -42,7 +42,7 @@ When passing in your own options, you can omit any or all of these fields if you Want to customize it even more? -- Removing table of contents: remove `Component.Explorer()` from `quartz.layout.ts` +- Removing explorer: remove `Component.Explorer()` from `quartz.layout.ts` - (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout - Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]] - Component: From 916aedce40864a485724d9df78879e8d130beab3 Mon Sep 17 00:00:00 2001 From: Aster Hu Date: Wed, 21 Feb 2024 22:04:36 -0500 Subject: [PATCH 036/217] docs: Add Aster's notebook to showcase.md (#912) --- docs/showcase.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/showcase.md b/docs/showcase.md index cdef5fc..0509e93 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: - [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/) - [Data Dictionary 🧠](https://glossary.airbyte.com/) - [sspaeti.com's Second Brain](https://brain.sspaeti.com/) +- [🪴Aster's notebook](https://notes.asterhu.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 345c347a56070d0b0d2b72656df891eec6a1f7ab Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Thu, 22 Feb 2024 20:51:07 -0500 Subject: [PATCH 037/217] chore: passing additional buildCtx to componentData (#914) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/components/types.ts | 2 ++ quartz/plugins/emitters/404.tsx | 1 + quartz/plugins/emitters/contentPage.tsx | 1 + quartz/plugins/emitters/folderPage.tsx | 1 + quartz/plugins/emitters/tagPage.tsx | 1 + 5 files changed, 6 insertions(+) diff --git a/quartz/components/types.ts b/quartz/components/types.ts index d322ea9..a6b90d3 100644 --- a/quartz/components/types.ts +++ b/quartz/components/types.ts @@ -3,8 +3,10 @@ import { StaticResources } from "../util/resources" import { QuartzPluginData } from "../plugins/vfile" import { GlobalConfiguration } from "../cfg" import { Node } from "hast" +import { BuildCtx } from "../util/ctx" export type QuartzComponentProps = { + ctx: BuildCtx externalResources: StaticResources fileData: QuartzPluginData cfg: GlobalConfiguration diff --git a/quartz/plugins/emitters/404.tsx b/quartz/plugins/emitters/404.tsx index f9d7a86..e4605cf 100644 --- a/quartz/plugins/emitters/404.tsx +++ b/quartz/plugins/emitters/404.tsx @@ -46,6 +46,7 @@ export const NotFoundPage: QuartzEmitterPlugin = () => { frontmatter: { title: notFound, tags: [] }, }) const componentData: QuartzComponentProps = { + ctx, fileData: vfile.data, externalResources, cfg, diff --git a/quartz/plugins/emitters/contentPage.tsx b/quartz/plugins/emitters/contentPage.tsx index 904a8a8..f493802 100644 --- a/quartz/plugins/emitters/contentPage.tsx +++ b/quartz/plugins/emitters/contentPage.tsx @@ -97,6 +97,7 @@ export const ContentPage: QuartzEmitterPlugin> = (userOp const externalResources = pageResources(pathToRoot(slug), resources) const componentData: QuartzComponentProps = { + ctx, fileData: file.data, externalResources, cfg, diff --git a/quartz/plugins/emitters/folderPage.tsx b/quartz/plugins/emitters/folderPage.tsx index bf69d29..d892b28 100644 --- a/quartz/plugins/emitters/folderPage.tsx +++ b/quartz/plugins/emitters/folderPage.tsx @@ -95,6 +95,7 @@ export const FolderPage: QuartzEmitterPlugin> = (userOpt const externalResources = pageResources(pathToRoot(slug), resources) const [tree, file] = folderDescriptions[folder] const componentData: QuartzComponentProps = { + ctx, fileData: file.data, externalResources, cfg, diff --git a/quartz/plugins/emitters/tagPage.tsx b/quartz/plugins/emitters/tagPage.tsx index 3eb6975..6f65ae4 100644 --- a/quartz/plugins/emitters/tagPage.tsx +++ b/quartz/plugins/emitters/tagPage.tsx @@ -99,6 +99,7 @@ export const TagPage: QuartzEmitterPlugin> = (userOpts) const externalResources = pageResources(pathToRoot(slug), resources) const [tree, file] = tagDescriptions[tag] const componentData: QuartzComponentProps = { + ctx, fileData: file.data, externalResources, cfg, From 96c7076fb5333882dd354c5f156232217d4fab13 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Thu, 22 Feb 2024 22:16:40 -0500 Subject: [PATCH 038/217] feat(popover): add support for PDF (#913) * feat(popover): add support for PDF Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> * chore: split pdf by ';' Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> * fix: remove unnecessary check Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --------- Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/components/scripts/popover.inline.ts | 17 +++++++++++--- quartz/components/styles/popover.scss | 25 +++++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index d0346b0..dee0a78 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -47,8 +47,8 @@ async function mouseEnterHandler( } if (!response) return - const contentType = response.headers.get("Content-Type") - const contentTypeCategory = contentType?.split("/")[0] ?? "text" + const [contentType] = response.headers.get("Content-Type")!.split(";") + const [contentTypeCategory, typeInfo] = contentType.split("/") const popoverElement = document.createElement("div") popoverElement.classList.add("popover") @@ -56,7 +56,7 @@ async function mouseEnterHandler( popoverInner.classList.add("popover-inner") popoverElement.appendChild(popoverInner) - popoverInner.dataset.contentType = contentTypeCategory + popoverInner.dataset.contentType = contentType ?? undefined switch (contentTypeCategory) { case "image": @@ -69,6 +69,17 @@ async function mouseEnterHandler( popoverInner.appendChild(img) break + case "application": + switch (typeInfo) { + case "pdf": + const pdf = document.createElement("iframe") + pdf.src = targetUrl.toString() + popoverInner.appendChild(pdf) + break + default: + break + } + break default: const contents = await response.text() const html = p.parseFromString(contents, "text/html") diff --git a/quartz/components/styles/popover.scss b/quartz/components/styles/popover.scss index 141b89d..b1694f9 100644 --- a/quartz/components/styles/popover.scss +++ b/quartz/components/styles/popover.scss @@ -38,14 +38,25 @@ white-space: normal; } - & > .popover-inner[data-content-type="image"] { - padding: 0; - max-height: 100%; + & > .popover-inner[data-content-type] { + &[data-content-type*="pdf"], + &[data-content-type*="image"] { + padding: 0; + max-height: 100%; + } - img { - margin: 0; - border-radius: 0; - display: block; + &[data-content-type*="image"] { + img { + margin: 0; + border-radius: 0; + display: block; + } + } + + &[data-content-type*="pdf"] { + iframe { + width: 100%; + } } } From 129e878b29dc53a1327d88089fa5876b0b1cc764 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Fri, 23 Feb 2024 00:55:35 -0500 Subject: [PATCH 039/217] chore(img): return targetUrl as given href (#916) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/components/scripts/popover.inline.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index dee0a78..972d3c6 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -61,10 +61,7 @@ async function mouseEnterHandler( switch (contentTypeCategory) { case "image": const img = document.createElement("img") - - response.blob().then((blob) => { - img.src = URL.createObjectURL(blob) - }) + img.src = targetUrl.toString() img.alt = targetUrl.pathname popoverInner.appendChild(img) From fb66ae283848deec6b2be405642bd63f0c113e61 Mon Sep 17 00:00:00 2001 From: KylinDC Date: Fri, 23 Feb 2024 13:56:26 +0800 Subject: [PATCH 040/217] deps(highlighting): migrate to shiki as shikiji has been archived (#918) --- package-lock.json | 34 +++++++++++++++++----------------- package.json | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a8b583..dc020fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "rehype-autolink-headings": "^7.1.0", "rehype-katex": "^7.0.0", "rehype-mathjax": "^6.0.0", - "rehype-pretty-code": "^0.12.6", + "rehype-pretty-code": "^0.13.0", "rehype-raw": "^7.0.0", "rehype-slug": "^6.0.0", "remark": "^15.0.1", @@ -54,7 +54,7 @@ "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", - "shikiji": "^0.10.2", + "shiki": "^1.1.6", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", @@ -742,6 +742,11 @@ "node": ">=14" } }, + "node_modules/@shikijs/core": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.6.tgz", + "integrity": "sha512-kt9hhvrWTm0EPtRDIsoAZnSsFlIDBVBBI5CQewpA/NZCPin+MOKRXg+JiWc4y+8fZ/v0HzfDhu/UC+OTZGMt7A==" + }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", @@ -4708,11 +4713,11 @@ } }, "node_modules/rehype-pretty-code": { - "version": "0.12.6", - "resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.12.6.tgz", - "integrity": "sha512-AW18s4eXwnb4PGwL0Y8BoUzBJr23epWNXndCKaZ52S4kl/4tsgM+406oCp5NdtPZsB0ItpaY+hCMv3kw58DLrA==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.13.0.tgz", + "integrity": "sha512-+22dz1StXlF7dlMyOySNaVxgcGhMI4BCxq0JxJJPWYGiKsI6cu5jyuIKGHXHvH18D8sv1rdKtvsY9UEfN3++SQ==", "dependencies": { - "@types/hast": "^3.0.3", + "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.0", "parse-numeric-range": "^1.3.0", "rehype-parse": "^9.0.0", @@ -4723,7 +4728,7 @@ "node": ">=18" }, "peerDependencies": { - "shikiji": "^0.7.0 || ^0.8.0 || ^0.9.0 || ^0.10.0" + "shiki": "^1.0.0" } }, "node_modules/rehype-raw": { @@ -5321,19 +5326,14 @@ "node": ">=8" } }, - "node_modules/shikiji": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.10.2.tgz", - "integrity": "sha512-wtZg3T0vtYV2PnqusWQs3mDaJBdCPWxFDrBM/SE5LfrX92gjUvfEMlc+vJnoKY6Z/S44OWaCRzNIsdBRWcTAiw==", + "node_modules/shiki": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.6.tgz", + "integrity": "sha512-j4pcpvaQWHb42cHeV+W6P+X/VcK7Y2ctvEham6zB8wsuRQroT6cEMIkiUmBU2Nqg2qnHZDH6ZyRdVldcy0l6xw==", "dependencies": { - "shikiji-core": "0.10.2" + "@shikijs/core": "1.1.6" } }, - "node_modules/shikiji-core": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/shikiji-core/-/shikiji-core-0.10.2.tgz", - "integrity": "sha512-9Of8HMlF96usXJHmCL3Gd0Fcf0EcyJUF9m8EoAKKd98mHXi0La2AZl1h6PegSFGtiYcBDK/fLuKbDa1l16r1fA==" - }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", diff --git a/package.json b/package.json index 54c67fb..094e62a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "rehype-autolink-headings": "^7.1.0", "rehype-katex": "^7.0.0", "rehype-mathjax": "^6.0.0", - "rehype-pretty-code": "^0.12.6", + "rehype-pretty-code": "^0.13.0", "rehype-raw": "^7.0.0", "rehype-slug": "^6.0.0", "remark": "^15.0.1", @@ -79,7 +79,7 @@ "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", - "shikiji": "^0.10.2", + "shiki": "^1.1.6", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", From be9b6b3a1e2038ea0a985ebd37fb18a661bddd04 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 09:32:08 -0800 Subject: [PATCH 041/217] fix(docs): make docs accurate to callout behaviour (closes #920) --- docs/features/callouts.md | 63 +++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/docs/features/callouts.md b/docs/features/callouts.md index d739792..3fefda2 100644 --- a/docs/features/callouts.md +++ b/docs/features/callouts.md @@ -55,50 +55,41 @@ By default, custom callouts are handled by applying the `note` style. To make fa > > > > > [!example] You can even use multiple layers of nesting. -> [!EXAMPLE] Examples -> -> Aliases: example +> [!note] +> Aliases: "note" -> [!note] Notes -> -> Aliases: note +> [!abstract] +> Aliases: "abstract", "summary", "tldr" -> [!abstract] Summaries -> -> Aliases: abstract, summary, tldr +> [!info] +> Aliases: "info" -> [!info] Info -> -> Aliases: info, todo +> [!todo] +> Aliases: "todo" -> [!tip] Hint -> -> Aliases: tip, hint, important +> [!tip] +> Aliases: "tip", "hint", "important" -> [!success] Success -> -> Aliases: success, check, done +> [!success] +> Aliases: "success", "check", "done" -> [!question] Question -> -> Aliases: question, help, faq +> [!question] +> Aliases: "question", "help", "faq" -> [!warning] Warning -> -> Aliases: warning, caution, attention +> [!warning] +> Aliases: "warning", "attention", "caution" -> [!failure] Failure -> -> Aliases: failure, fail, missing +> [!failure] +> Aliases: "failure", "missing", "fail" -> [!danger] Error -> -> Aliases: danger, error +> [!danger] +> Aliases: "danger", "error" -> [!bug] Bug -> -> Aliases: bug +> [!bug] +> Aliases: "bug" -> [!quote] Quote -> -> Aliases: quote, cite +> [!example] +> Aliases: "example" + +> [!quote] +> Aliases: "quote", "cite" From 421718958fc47db0f1a7b53f51e0c7063db744b3 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 11:20:35 -0800 Subject: [PATCH 042/217] fix(callouts): use user provided title instead of canonical for default title --- quartz/plugins/transformers/ofm.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 6aad230..fab7cf8 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -412,12 +412,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin children: [ { type: "text", - value: useDefaultTitle - ? capitalize( - i18n(cfg.locale).components.callout[calloutType as ValidCallout] ?? - calloutType, - ) - : titleContent + " ", + value: useDefaultTitle ? capitalize(typeString) : titleContent + " ", }, ...restOfTitle, ], From 1929241a62b67ebd9cc9831e372ab321874d03d1 Mon Sep 17 00:00:00 2001 From: Eiko Wagenknecht Date: Fri, 23 Feb 2024 21:07:53 +0100 Subject: [PATCH 043/217] docs: update plugin documentation (#888) * docs: first few plugins documented * docs: move plugin info * docs: move plugin docs to tag based system * docs: update latex example code snippet * docs: fix spelling of latex in title * docs: add missing linebreak * docs: remove plugin tag from feature pages * docs: shorten titles * docs: refine wording * docs: move plugin details for frontmatter * docs: add features/* tags * docs: update latex example * docs: make references more explicit * docs: add stubs for the remaining plugins * docs: more descriptions * docs: fix feature tags * docs: descriptions * docs: new plugin pages * docs: update configuration page * docs: more plugin work * docs: run prettier * docs: remove comments in config file and add link to docs * docs: minor fixes * docs: run prettier * docs: spelling * docs: update docs/plugins/AliasRedirects.md Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * docs: update docs/plugins/Assets.md Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * docs: update docs/plugins/CNAME.md Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * docs: update docs/plugins/Static.md Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * docs: update docs * docs: update docs/features/Mermaid diagrams.md Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> * docs: update docs/plugins/RemoveDrafts.md Co-authored-by: Jacky Zhao * docs: update docs/plugins/Assets.md Co-authored-by: Jacky Zhao * docs: update docs/configuration.md Co-authored-by: Jacky Zhao * docs: update docs/configuration.md Co-authored-by: Jacky Zhao * docs: update docs/configuration.md Co-authored-by: Jacky Zhao * docs: some updates * docs: work in review comments --------- Signed-off-by: Eiko Wagenknecht Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Co-authored-by: Jacky Zhao --- docs/advanced/making plugins.md | 12 ++++--- docs/authoring content.md | 4 +++ docs/configuration.md | 44 +++++++++++++++++------- docs/features/Latex.md | 13 ++++--- docs/features/Mermaid diagrams.md | 8 ++++- docs/features/Obsidian compatibility.md | 28 ++++----------- docs/features/OxHugo compatibility.md | 18 +++------- docs/features/RSS Feed.md | 6 ++-- docs/features/callouts.md | 9 ++--- docs/features/folder and tag listings.md | 21 +++++------ docs/features/private pages.md | 6 ++-- docs/features/syntax highlighting.md | 6 ++-- docs/features/table of contents.md | 22 ++++-------- docs/features/wikilinks.md | 2 +- docs/index.md | 2 +- docs/plugins/AliasRedirects.md | 37 ++++++++++++++++++++ docs/plugins/Assets.md | 20 +++++++++++ docs/plugins/CNAME.md | 22 ++++++++++++ docs/plugins/ComponentResources.md | 18 ++++++++++ docs/plugins/ContentIndex.md | 26 ++++++++++++++ docs/plugins/ContentPage.md | 18 ++++++++++ docs/plugins/CrawlLinks.md | 30 ++++++++++++++++ docs/plugins/CreatedModifiedDate.md | 25 ++++++++++++++ docs/plugins/Description.md | 22 ++++++++++++ docs/plugins/ExplicitPublish.md | 18 ++++++++++ docs/plugins/FolderPage.md | 22 ++++++++++++ docs/plugins/Frontmatter.md | 24 +++++++++++++ docs/plugins/GitHubFlavoredMarkdown.md | 23 +++++++++++++ docs/plugins/HardLineBreaks.md | 18 ++++++++++ docs/plugins/Latex.md | 20 +++++++++++ docs/plugins/NotFoundPage.md | 18 ++++++++++ docs/plugins/ObsidianFlavoredMarkdown.md | 34 ++++++++++++++++++ docs/plugins/OxHugoFlavoredMarkdown.md | 29 ++++++++++++++++ docs/plugins/RemoveDrafts.md | 18 ++++++++++ docs/plugins/Static.md | 21 +++++++++++ docs/plugins/SyntaxHighlighting.md | 23 +++++++++++++ docs/plugins/TableOfContents.md | 26 ++++++++++++++ docs/plugins/TagPage.md | 20 +++++++++++ docs/plugins/index.md | 3 ++ docs/tags/plugin.md | 3 ++ quartz.config.ts | 10 +++--- 41 files changed, 641 insertions(+), 108 deletions(-) create mode 100644 docs/plugins/AliasRedirects.md create mode 100644 docs/plugins/Assets.md create mode 100644 docs/plugins/CNAME.md create mode 100644 docs/plugins/ComponentResources.md create mode 100644 docs/plugins/ContentIndex.md create mode 100644 docs/plugins/ContentPage.md create mode 100644 docs/plugins/CrawlLinks.md create mode 100644 docs/plugins/CreatedModifiedDate.md create mode 100644 docs/plugins/Description.md create mode 100644 docs/plugins/ExplicitPublish.md create mode 100644 docs/plugins/FolderPage.md create mode 100644 docs/plugins/Frontmatter.md create mode 100644 docs/plugins/GitHubFlavoredMarkdown.md create mode 100644 docs/plugins/HardLineBreaks.md create mode 100644 docs/plugins/Latex.md create mode 100644 docs/plugins/NotFoundPage.md create mode 100644 docs/plugins/ObsidianFlavoredMarkdown.md create mode 100644 docs/plugins/OxHugoFlavoredMarkdown.md create mode 100644 docs/plugins/RemoveDrafts.md create mode 100644 docs/plugins/Static.md create mode 100644 docs/plugins/SyntaxHighlighting.md create mode 100644 docs/plugins/TableOfContents.md create mode 100644 docs/plugins/TagPage.md create mode 100644 docs/plugins/index.md create mode 100644 docs/tags/plugin.md diff --git a/docs/advanced/making plugins.md b/docs/advanced/making plugins.md index d9ed9e3..b2bacf0 100644 --- a/docs/advanced/making plugins.md +++ b/docs/advanced/making plugins.md @@ -53,12 +53,12 @@ All transformer plugins must define at least a `name` field to register the plug Normally for both `remark` and `rehype`, you can find existing plugins that you can use to . If you'd like to create your own `remark` or `rehype` plugin, checkout the [guide to creating a plugin](https://unifiedjs.com/learn/guide/create-a-plugin/) using `unified` (the underlying AST parser and transformer library). -A good example of a transformer plugin that borrows from the `remark` and `rehype` ecosystems is the [[Latex]] plugin: +A good example of a transformer plugin that borrows from the `remark` and `rehype` ecosystems is the [[plugins/Latex|Latex]] plugin: ```ts title="quartz/plugins/transformers/latex.ts" import remarkMath from "remark-math" import rehypeKatex from "rehype-katex" -import rehypeMathjax from "rehype-mathjax/svg.js" +import rehypeMathjax from "rehype-mathjax/svg" import { QuartzTransformerPlugin } from "../types" interface Options { @@ -84,10 +84,14 @@ export const Latex: QuartzTransformerPlugin = (opts?: Options) => { externalResources() { if (engine === "katex") { return { - css: ["https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css"], + css: [ + // base css + "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css", + ], js: [ { - src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/contrib/copy-tex.min.js", + // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md + src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/copy-tex.min.js", loadTime: "afterDOMReady", contentType: "external", }, diff --git a/docs/authoring content.md b/docs/authoring content.md index c259e50..d872a96 100644 --- a/docs/authoring content.md +++ b/docs/authoring content.md @@ -38,3 +38,7 @@ Some common frontmatter fields that are natively supported by Quartz: When your Quartz is at a point you're happy with, you can save your changes to GitHub. First, make sure you've [[setting up your GitHub repository|already setup your GitHub repository]] and then do `npx quartz sync`. + +## Customization + +Frontmatter parsing for `title`, `tags`, `aliases` and `cssclasses` is a functionality of the [[Frontmatter]] plugin, `date` is handled by the [[CreatedModifiedDate]] plugin and `description` by the [[Description]] plugin. See the plugin pages for customization options. diff --git a/docs/configuration.md b/docs/configuration.md index 366430c..6c76654 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -30,12 +30,12 @@ This part of the configuration concerns anything that can affect the whole site. - `{ provider: 'umami', host: '', websiteId: '' }`: use [Umami](https://umami.is/); - `locale`: used for [[i18n]] and date formatting - `baseUrl`: this is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes. - - This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz` + - This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`. - Note that Quartz 4 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter _where_ you end up actually deploying it. - `ignorePatterns`: a list of [glob]() patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. - `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. - `theme`: configure how the site looks. - - `cdnCaching`: Whether to use Google CDN to cache the fonts (generally will be faster). Disable this if you want Quartz to be self-contained. Default to `true` + - `cdnCaching`: If `true` (default), use Google CDN to cache the fonts. This will generally will be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. - `header`: Font to use for headers - `code`: Font for inline and block quotes. @@ -56,7 +56,7 @@ You can think of Quartz plugins as a series of transformations over content. ![[quartz transform pipeline.png]] -```ts +```ts title="quartz.config.ts" plugins: { transformers: [...], filters: [...], @@ -64,22 +64,40 @@ plugins: { } ``` -- [[making plugins#Transformers|Transformers]] **map** over content (e.g. parsing frontmatter, generating a description) -- [[making plugins#Filters|Filters]] **filter** content (e.g. filtering out drafts) -- [[making plugins#Emitters|Emitters]] **reduce** over content (e.g. creating an RSS feed or pages that list all files with a specific tag) +- [[tags/plugin/transformer|Transformers]] **map** over content (e.g. parsing frontmatter, generating a description) +- [[tags/plugin/filter|Filters]] **filter** content (e.g. filtering out drafts) +- [[tags/plugin/emitter|Emitters]] **reduce** over content (e.g. creating an RSS feed or pages that list all files with a specific tag) -By adding, removing, and reordering plugins from the `tranformers`, `filters`, and `emitters` fields, you can customize the behaviour of Quartz. +You can customize the behaviour of Quartz by adding, removing and reordering plugins in the `transformers`, `filters` and `emitters` fields. > [!note] -> Each node is modified by every transformer _in order_. Some transformers are position-sensitive so you may need to take special note of whether it needs come before or after any other particular plugins. +> Each node is modified by every transformer _in order_. Some transformers are position sensitive, so you may need to pay particular attention to whether they need to come before or after certain other plugins. -Additionally, plugins may also have their own configuration settings that you can pass in. For example, the [[Latex]] plugin allows you to pass in a field specifying the `renderEngine` to choose between Katex and MathJax. +You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/transformer|Transformer]], you would add the following line: -```ts +```ts title="quartz.config.ts" transformers: [ - Plugin.FrontMatter(), // uses default options - Plugin.Latex({ renderEngine: "katex" }), // specify some options + ... + Plugin.ExplicitPublish(), + ... +], +``` + +To remove a plugin, you should remove all occurrences of it in the `quartz.config.ts`. + +To customize plugins further, some plugins may also have their own configuration settings that you can pass in. If you do not pass in a configuration, the plugin will use its default settings. + +For example, the [[plugins/Latex|Latex]] plugin allows you to pass in a field specifying the `renderEngine` to choose between Katex and MathJax. + +```ts title="quartz.config.ts" +transformers: [ + Plugin.FrontMatter(), // use default options + Plugin.Latex({ renderEngine: "katex" }), // set some custom options ] ``` -If you'd like to make your own plugins, read the guide on [[making plugins]] for more information. +Some plugins are included by default in the[ `quartz.config.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz.config.ts), but there are more available. + +You can see a list of all plugins and their configuration options [[tags/plugin|here]]. + +If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide. diff --git a/docs/features/Latex.md b/docs/features/Latex.md index 3c8f6ff..e019190 100644 --- a/docs/features/Latex.md +++ b/docs/features/Latex.md @@ -1,6 +1,7 @@ --- +title: LaTeX tags: - - plugin/transformer + - feature/transformer --- Quartz uses [Katex](https://katex.org/) by default to typeset both inline and block math expressions at build time. @@ -38,6 +39,9 @@ a & b & c \end{bmatrix} $$ +> [!warn] +> Due to limitations in the [underlying parsing library](https://github.com/remarkjs/remark-math), block math in Quartz requires the `$$` delimiters to be on newlines like above. + ### Inline Math Similarly, inline math can be rendered by delimiting math expression with a single `$`. For example, `$e^{i\pi} = -1$` produces $e^{i\pi} = -1$ @@ -53,11 +57,6 @@ For example: - Incorrect: `I have $1 and you have $2` produces I have $1 and you have $2 - Correct: `I have \$1 and you have \$2` produces I have \$1 and you have \$2 -## MathJax - -In `quartz.config.ts`, you can configure Quartz to use [MathJax SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html) by replacing `Plugin.Latex({ renderEngine: 'katex' })` with `Plugin.Latex({ renderEngine: 'mathjax' })` - ## Customization -- Removing Latex support: remove all instances of `Plugin.Latex()` from `quartz.config.ts`. -- Plugin: `quartz/plugins/transformers/latex.ts` +Latex parsing is a functionality of the [[plugins/Latex|Latex]] plugin. See the plugin page for customization options. diff --git a/docs/features/Mermaid diagrams.md b/docs/features/Mermaid diagrams.md index f14a558..9cc4089 100644 --- a/docs/features/Mermaid diagrams.md +++ b/docs/features/Mermaid diagrams.md @@ -1,9 +1,15 @@ +--- +title: "Mermaid Diagrams" +tags: + - feature/transformer +--- + Quartz supports Mermaid which allows you to add diagrams and charts to your notes. Mermaid supports a range of diagrams, such as [flow charts](https://mermaid.js.org/syntax/flowchart.html), [sequence diagrams](https://mermaid.js.org/syntax/sequenceDiagram.html), and [timelines](https://mermaid.js.org/syntax/timeline.html). This is enabled as a part of [[Obsidian compatibility]] and can be configured and enabled/disabled from that plugin. By default, Quartz will render Mermaid diagrams to match the site theme. > [!warning] -> Wondering why Mermaid diagrams may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is _after_ `Plugin.SyntaxHighlighting()`. +> Wondering why Mermaid diagrams may not be showing up even if you have them enabled? You may need to reorder your plugins so that [[ObsidianFlavoredMarkdown]] is _after_ [[SyntaxHighlighting]]. ## Syntax diff --git a/docs/features/Obsidian compatibility.md b/docs/features/Obsidian compatibility.md index 1254370..e469f48 100644 --- a/docs/features/Obsidian compatibility.md +++ b/docs/features/Obsidian compatibility.md @@ -1,33 +1,17 @@ --- +title: "Obsidian Compatibility" tags: - - plugin/transformer + - feature/transformer --- Quartz was originally designed as a tool to publish Obsidian vaults as websites. Even as the scope of Quartz has widened over time, it hasn't lost the ability to seamlessly interoperate with Obsidian. -By default, Quartz ships with `Plugin.ObsidianFlavoredMarkdown` which is a transformer plugin that adds support for [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown). This includes support for features like [[wikilinks]] and [[Mermaid diagrams]]. +By default, Quartz ships with the [[ObsidianFlavoredMarkdown]] plugin, which is a transformer plugin that adds support for [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown). This includes support for features like [[wikilinks]] and [[Mermaid diagrams]]. -It also ships with support for [frontmatter parsing](https://help.obsidian.md/Editing+and+formatting/Properties) with the same fields that Obsidian uses through the `Plugin.FrontMatter` transformer plugin. +It also ships with support for [frontmatter parsing](https://help.obsidian.md/Editing+and+formatting/Properties) with the same fields that Obsidian uses through the [[Frontmatter]] transformer plugin. -Finally, Quartz also provides `Plugin.CrawlLinks` which allows you to customize Quartz's link resolution behaviour to match Obsidian. +Finally, Quartz also provides [[CrawlLinks]] plugin, which allows you to customize Quartz's link resolution behaviour to match Obsidian. ## Configuration -- Frontmatter parsing: - - Disabling: remove all instances of `Plugin.FrontMatter()` from `quartz.config.ts`. - - Customize default values for frontmatter: edit `quartz/plugins/transformers/frontmatter.ts` -- Obsidian Flavored Markdown: - - Disabling: remove all instances of `Plugin.ObsidianFlavoredMarkdown()` from `quartz.config.ts` - - Customizing features: `Plugin.ObsidianFlavoredMarkdown` has several other options to toggle on and off: - - `comments`: whether to enable `%%` style Obsidian comments. Defaults to `true` - - `highlight`: whether to enable `==` style highlights. Defaults to `true` - - `wikilinks`: whether to enable turning [[wikilinks]] into regular links. Defaults to `true` - - `callouts`: whether to enable [[callouts]]. Defaults to `true` - - `mermaid`: whether to enable [[Mermaid diagrams]]. Defaults to `true` - - `parseTags`: whether to try and parse tags in the content body. Defaults to `true` - - `parseArrows`: whether to try and parse arrows in the content body. Defaults to `true`. - - `enableInHtmlEmbed`: whether to try and parse Obsidian flavoured markdown in raw HTML. Defaults to `false` - - `enableYouTubeEmbed`: whether to enable embedded YouTube videos using external image Markdown syntax. Defaults to `false` -- Link resolution behaviour: - - Disabling: remove all instances of `Plugin.CrawlLinks()` from `quartz.config.ts` - - Changing link resolution preference: set `markdownLinkResolution` to one of `absolute`, `relative` or `shortest` +This functionality is provided by the [[ObsidianFlavoredMarkdown]], [[Frontmatter]] and [[CrawlLinks]] plugins. See the plugin pages for customization options. diff --git a/docs/features/OxHugo compatibility.md b/docs/features/OxHugo compatibility.md index 3143eb1..e220511 100644 --- a/docs/features/OxHugo compatibility.md +++ b/docs/features/OxHugo compatibility.md @@ -1,11 +1,12 @@ --- +title: "OxHugo Compatibility" tags: - - plugin/transformer + - feature/transformer --- [org-roam](https://www.orgroam.com/) is a plain-text personal knowledge management system for [emacs](https://en.wikipedia.org/wiki/Emacs). [ox-hugo](https://github.com/kaushalmodi/ox-hugo) is org exporter backend that exports `org-mode` files to [Hugo](https://gohugo.io/) compatible Markdown. -Because the Markdown generated by ox-hugo is not pure Markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by `Plugin.OxHugoFlavouredMarkdown`. Even though this [[making plugins|plugin]] was written with `ox-hugo` in mind, it should work for any Hugo specific Markdown. +Because the Markdown generated by ox-hugo is not pure Markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by the [[OxHugoFlavoredMarkdown]] plugin. Even though this plugin was written with `ox-hugo` in mind, it should work for any Hugo specific Markdown. ```typescript title="quartz.config.ts" plugins: { @@ -25,15 +26,4 @@ Quartz by default doesn't understand `org-roam` files as they aren't Markdown. Y ## Configuration -- Link resolution - - `wikilinks`: Whether to replace `{{ relref }}` with Quartz [[wikilinks]] - - `removePredefinedAnchor`: Whether to remove [pre-defined anchor set by ox-hugo](https://ox-hugo.scripter.co/doc/anchors/). -- Image handling - - `replaceFigureWithMdImg`: Whether to replace `
` with `![]()` -- Formatting - - `removeHugoShortcode`: Whether to remove hugo shortcode syntax (`{{}}`) - - `replaceOrgLatex`: Whether to replace org-mode formatting for latex fragments with what `Plugin.Latex` supports. - -> [!warning] -> -> While you can use `Plugin.OxHugoFlavoredMarkdown` and `Plugin.ObsidianFlavoredMarkdown` together, it's not recommended because it might mutate the file in unexpected ways. Use with caution. +This functionality is provided by the [[OxHugoFlavoredMarkdown]] plugin. See the plugin page for customization options. diff --git a/docs/features/RSS Feed.md b/docs/features/RSS Feed.md index bfeb399..ed4138d 100644 --- a/docs/features/RSS Feed.md +++ b/docs/features/RSS Feed.md @@ -1,7 +1,5 @@ -Quartz creates an RSS feed for all the content on your site by generating an `index.xml` file that RSS readers can subscribe to. Because of the RSS spec, this requires the `baseUrl` property in your [[configuration]] to be set properly for RSS readers to pick it up properly. +Quartz emits an RSS feed for all the content on your site by generating an `index.xml` file that RSS readers can subscribe to. Because of the RSS spec, this requires the `baseUrl` property in your [[configuration]] to be set properly for RSS readers to pick it up properly. ## Configuration -- Remove RSS feed: set the `enableRSS` field of `Plugin.ContentIndex` in `quartz.config.ts` to be `false`. -- Change number of entries: set the `rssLimit` field of `Plugin.ContentIndex` to be the desired value. It defaults to latest 10 items. -- Use rich HTML output in RSS: set `rssFullHtml` field of `Plugin.ContentIndex` to be `true`. +This functionality is provided by the [[ContentIndex]] plugin. See the plugin page for customization options. diff --git a/docs/features/callouts.md b/docs/features/callouts.md index 3fefda2..4caeeb4 100644 --- a/docs/features/callouts.md +++ b/docs/features/callouts.md @@ -1,7 +1,7 @@ --- title: Callouts tags: - - plugin/transformer + - feature/transformer --- Quartz supports the same Admonition-callout syntax as Obsidian. @@ -19,12 +19,13 @@ This includes See [documentation on supported types and syntax here](https://help.obsidian.md/Editing+and+formatting/Callouts). > [!warning] -> Wondering why callouts may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is _after_ `Plugin.SyntaxHighlighting()`. +> Wondering why callouts may not be showing up even if you have them enabled? You may need to reorder your plugins so that [[ObsidianFlavoredMarkdown]] is _after_ [[SyntaxHighlighting]]. ## Customization -- Disable callouts: simply pass `callouts: false` to the plugin: `Plugin.ObsidianFlavoredMarkdown({ callouts: false })` -- Editing icons: `quartz/styles/callouts.scss` +The callouts are a functionality of the [[ObsidianFlavoredMarkdown]] plugin. See the plugin page for how to enable or disable them. + +You can edit the icons by customizing `quartz/styles/callouts.scss`. ### Add custom callouts diff --git a/docs/features/folder and tag listings.md b/docs/features/folder and tag listings.md index dfde7c2..d330f14 100644 --- a/docs/features/folder and tag listings.md +++ b/docs/features/folder and tag listings.md @@ -1,18 +1,20 @@ --- title: Folder and Tag Listings tags: - - plugin/emitter + - feature/emitter --- -Quartz creates listing pages for any folders and tags you have. +Quartz emits listing pages for any folders and tags you have. ## Folder Listings Quartz will generate an index page for all the pages under that folder. This includes any content that is multiple levels deep. -Additionally, Quartz will also generate pages for subfolders. Say you have a note in a nested folder `content/abc/def/note.md`. Then, Quartz would generate a page for all the notes under `abc` _and_ a page for all the notes under `abc/def`. +Additionally, Quartz will also generate pages for subfolders. Say you have a note in a nested folder `content/abc/def/note.md`. Then Quartz would generate a page for all the notes under `abc` _and_ a page for all the notes under `abc/def`. -By default, Quartz will title the page `Folder: ` and no description. You can override this by creating an `index.md` file in the folder with the `title` [[authoring content#Syntax|frontmatter]] field. Any content you write in this file will also be used in the description of the folder. +You can link to the folder listing by referencing its name, plus a trailing slash, like this: `[[advanced/]]` (results in [[advanced/]]). + +By default, Quartz will title the page `Folder: ` and no description. You can override this by creating an `index.md` file in the folder with the `title` [[authoring content#Syntax|frontmatter]] field. Any content you write in this file will also be used in the folder description. For example, for the folder `content/posts`, you can add another file `content/posts/index.md` to add a specific description for it. @@ -20,13 +22,12 @@ For example, for the folder `content/posts`, you can add another file `content/p Quartz will also create an index page for each unique tag in your vault and render a list of all notes with that tag. -Quartz also supports tag hierarchies as well (e.g. `plugin/emitter`) and will also render a separate tag page for each layer of the tag hierarchy. It will also create a default global tag index page at `/tags` that displays a list of all the tags in your Quartz. +Quartz also supports tag hierarchies as well (e.g. `plugin/emitter`) and will also render a separate tag page for each level of the tag hierarchy. It will also create a default global tag index page at `/tags` that displays a list of all the tags in your Quartz. -Like folder listings, you can also provide a description and title for a tag page by creating a file for each tag. For example, if you wanted to create a custom description for the #component tag, you would create a file at `content/tags/component.md` with a title and description. +You can link to the tag listing by referencing its name with a `tag/` prefix, like this: `[[tags/plugin]]` (results in [[tags/plugin]]). + +As with folder listings, you can also provide a description and title for a tag page by creating a file for each tag. For example, if you wanted to create a custom description for the #component tag, you would create a file at `content/tags/component.md` with a title and description. ## Customization -The layout for both the folder and content pages can be customized. By default, they use the `defaultListPageLayout` in `quartz.layouts.ts`. If you'd like to make more involved changes to the layout and don't mind editing some [[creating components|Quartz components]], you can take a look at `quartz/components/pages/FolderContent.tsx` and `quartz/components/pages/TagContent.tsx` respectively. - -- Removing folder listings: remove `Plugin.FolderPage()` from `emitters` in `quartz.config.ts` -- Removing tag listings: remove `Plugin.TagPage()` from `emitters` in `quartz.config.ts` +The folder listings are a functionality of the [[FolderPage]] plugin, the tag listings of the [[TagPage]] plugin. See the plugin pages for customization options. diff --git a/docs/features/private pages.md b/docs/features/private pages.md index 638c628..1e8f8aa 100644 --- a/docs/features/private pages.md +++ b/docs/features/private pages.md @@ -1,16 +1,16 @@ --- title: Private Pages tags: - - plugin/filter + - feature/filter --- There may be some notes you want to avoid publishing as a website. Quartz supports this through two mechanisms which can be used in conjunction: ## Filter Plugins -[[making plugins#Filters|Filter plugins]] are plugins that filter out content based off of certain criteria. By default, Quartz uses the `Plugin.RemoveDrafts` plugin which filters out any note that has `draft: true` in the frontmatter. +[[making plugins#Filters|Filter plugins]] are plugins that filter out content based off of certain criteria. By default, Quartz uses the [[RemoveDrafts]] plugin which filters out any note that has `draft: true` in the frontmatter. -If you'd like to only publish a select number of notes, you can instead use `Plugin.ExplicitPublish` which will filter out all notes except for any that have `publish: true` in the frontmatter. +If you'd like to only publish a select number of notes, you can instead use [[ExplicitPublish]] which will filter out all notes except for any that have `publish: true` in the frontmatter. > [!warning] > Regardless of the filter plugin used, **all non-markdown files will be emitted and available publically in the final build.** This includes files such as images, voice recordings, PDFs, etc. One way to prevent this and still be able to embed local images is to create a folder specifically for public media and add the following two patterns to the ignorePatterns array. diff --git a/docs/features/syntax highlighting.md b/docs/features/syntax highlighting.md index 68436c2..16fef25 100644 --- a/docs/features/syntax highlighting.md +++ b/docs/features/syntax highlighting.md @@ -1,7 +1,7 @@ --- title: Syntax Highlighting tags: - - plugin/transformer + - feature/transformer --- Syntax highlighting in Quartz is completely done at build-time. This means that Quartz only ships pre-calculated CSS to highlight the right words so there is no heavy client-side bundle that does the syntax highlighting. @@ -130,6 +130,4 @@ const [name, setName] = useState('Taylor'); ## Customization -- Removing syntax highlighting: delete all usages of `Plugin.SyntaxHighlighting()` from `quartz.config.ts`. -- Style: By default, Quartz uses derivatives of the GitHub light and dark themes. You can customize the colours in the `quartz/styles/syntax.scss` file. -- Plugin: `quartz/plugins/transformers/syntax.ts` +Syntax highlighting is a functionality of the [[SyntaxHighlighting]] plugin. See the plugin page for customization options. diff --git a/docs/features/table of contents.md b/docs/features/table of contents.md index 0298ffa..4ecccc9 100644 --- a/docs/features/table of contents.md +++ b/docs/features/table of contents.md @@ -2,25 +2,17 @@ title: "Table of Contents" tags: - component - - plugin/transformer + - feature/transformer --- -Quartz can automatically generate a table of contents from a list of headings on each page. It will also show you your current scroll position on the site by marking headings you've scrolled through with a different colour. +Quartz can automatically generate a table of contents (TOC) from a list of headings on each page. It will also show you your current scrolling position on the page by highlighting headings you've scrolled through with a different color. -By default, it will show all headers from H1 (`# Title`) all the way to H3 (`### Title`) and will only show the table of contents if there is more than 1 header on the page. -You can also hide the table of contents on a page by adding `enableToc: false` to the frontmatter for that page. +You can hide the TOC on a page by adding `enableToc: false` to the frontmatter for that page. -> [!info] -> This feature requires both `Plugin.TableOfContents` in your `quartz.config.ts` and `Component.TableOfContents` in your `quartz.layout.ts` to function correctly. +By default, the TOC shows all headings from H1 (`# Title`) to H3 (`### Title`) and is only displayed if there is more than one heading on the page. ## Customization -- Removing table of contents: remove all instances of `Plugin.TableOfContents()` from `quartz.config.ts`. and `Component.TableOfContents()` from `quartz.layout.ts` -- Changing the max depth: pass in a parameter to `Plugin.TableOfContents({ maxDepth: 4 })` -- Changing the minimum number of entries in the Table of Contents before it renders: pass in a parameter to `Plugin.TableOfContents({ minEntries: 3 })` -- Collapse the table of content by default: pass in a parameter to `Plugin.TableOfContents({ collapseByDefault: true })` -- Component: `quartz/components/TableOfContents.tsx` -- Style: - - Modern (default): `quartz/components/styles/toc.scss` - - Legacy Quartz 3 style: `quartz/components/styles/legacyToc.scss` -- Script: `quartz/components/scripts/toc.inline.ts` +The table of contents is a functionality of the [[TableOfContents]] plugin. See the plugin page for more customization options. + +It also needs the `TableOfContents` component, which is displayed in the right sidebar by default. You can change this by customizing the [[layout]]. The TOC component can be configured with the `layout` parameter, which can either be `modern` (default) or `legacy`. diff --git a/docs/features/wikilinks.md b/docs/features/wikilinks.md index 1b00532..ad4f2d7 100644 --- a/docs/features/wikilinks.md +++ b/docs/features/wikilinks.md @@ -4,7 +4,7 @@ title: Wikilinks Wikilinks were pioneered by earlier internet wikis to make it easier to write links across pages without needing to write Markdown or HTML links each time. -Quartz supports Wikilinks by default and these links are resolved by Quartz using `Plugin.CrawlLinks`. See the [Obsidian Help page on Internal Links](https://help.obsidian.md/Linking+notes+and+files/Internal+links) for more information on Wikilink syntax. +Quartz supports Wikilinks by default and these links are resolved by Quartz using the [[CrawlLinks]] plugin. See the [Obsidian Help page on Internal Links](https://help.obsidian.md/Linking+notes+and+files/Internal+links) for more information on Wikilink syntax. This is enabled as a part of [[Obsidian compatibility]] and can be configured and enabled/disabled from that plugin. diff --git a/docs/index.md b/docs/index.md index f25b6e2..87cf024 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,7 +31,7 @@ If you prefer instructions in a video format you can try following Nicole van de ## 🔧 Features -- [[Obsidian compatibility]], [[full-text search]], [[graph view]], note transclusion, [[wikilinks]], [[backlinks]], [[Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], [[i18n|internationalization]] and [many more](./features) right out of the box +- [[Obsidian compatibility]], [[full-text search]], [[graph view]], note transclusion, [[wikilinks]], [[backlinks]], [[features/Latex|Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], [[i18n|internationalization]] and [many more](./features) right out of the box - Hot-reload for both configuration and content - Simple JSX layouts and [[creating components|page components]] - [[SPA Routing|Ridiculously fast page loads]] and tiny bundle sizes diff --git a/docs/plugins/AliasRedirects.md b/docs/plugins/AliasRedirects.md new file mode 100644 index 0000000..3a33ce6 --- /dev/null +++ b/docs/plugins/AliasRedirects.md @@ -0,0 +1,37 @@ +--- +title: AliasRedirects +tags: + - plugin/emitter +--- + +This plugin emits HTML redirect pages for aliases and permalinks defined in the frontmatter of content files. + +For example, A `foo.md` has the following frontmatter + +```md title="foo.md" +--- +title: "Foo" +alias: + - "bar" +--- +``` + +The target `host.me/bar` will be redirected to `host.me/foo` + +Note that these are permanent redirect. + +The emitter supports the following aliases: + +- `aliases` +- `alias` + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.AliasRedirects()`. +- Source: [`quartz/plugins/emitters/aliases.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/aliases.ts). diff --git a/docs/plugins/Assets.md b/docs/plugins/Assets.md new file mode 100644 index 0000000..eb03994 --- /dev/null +++ b/docs/plugins/Assets.md @@ -0,0 +1,20 @@ +--- +title: Assets +tags: + - plugin/emitter +--- + +This plugin emits all non-Markdown static assets in your content folder (like images, videos, HTML, etc). The plugin respects the `ignorePatterns` in the global [[configuration]]. + +Note that all static assets will then be accessible through its path on your generated site, i.e: `host.me/path/to/static.pdf` + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.Assets()`. +- Source: [`quartz/plugins/emitters/assets.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/assets.ts). diff --git a/docs/plugins/CNAME.md b/docs/plugins/CNAME.md new file mode 100644 index 0000000..1cc0b5c --- /dev/null +++ b/docs/plugins/CNAME.md @@ -0,0 +1,22 @@ +--- +title: CNAME +tags: + - plugin/emitter +--- + +This plugin emits a `CNAME` record that points your subdomain to the default domain of your site. + +If you want to use a custom domain name like `quartz.example.com` for the site, then this is needed. + +See [[Hosting]] for more information. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.CNAME()`. +- Source: [`quartz/plugins/emitters/cname.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/cname.ts). diff --git a/docs/plugins/ComponentResources.md b/docs/plugins/ComponentResources.md new file mode 100644 index 0000000..739c170 --- /dev/null +++ b/docs/plugins/ComponentResources.md @@ -0,0 +1,18 @@ +--- +title: ComponentResources +tags: + - plugin/emitter +--- + +This plugin manages and emits the static resources required for the Quartz framework. This includes CSS stylesheets and JavaScript scripts that enhance the functionality and aesthetics of the generated site. See also the `cdnCaching` option in the `theme` section of the [[configuration]]. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.ComponentResources()`. +- Source: [`quartz/plugins/emitters/componentResources.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/componentResources.ts). diff --git a/docs/plugins/ContentIndex.md b/docs/plugins/ContentIndex.md new file mode 100644 index 0000000..af235b0 --- /dev/null +++ b/docs/plugins/ContentIndex.md @@ -0,0 +1,26 @@ +--- +title: ContentIndex +tags: + - plugin/emitter +--- + +This plugin emits both RSS and an XML sitemap for your site. The [[RSS Feed]] allows users to subscribe to content on your site and the sitemap allows search engines to better index your site. The plugin also emits a `contentIndex.json` file which is used by dynamic frontend components like search and graph. + +This plugin emits a comprehensive index of the site's content, generating additional resources such as a sitemap, an RSS feed, and a + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin accepts the following configuration options: + +- `enableSiteMap`: If `true` (default), generates a sitemap XML file (`sitemap.xml`) listing all site URLs for search engines in content discovery. +- `enableRSS`: If `true` (default), produces an RSS feed (`index.xml`) with recent content updates. +- `rssLimit`: Defines the maximum number of entries to include in the RSS feed, helping to focus on the most recent or relevant content. Defaults to `10`. +- `rssFullHtml`: If `true`, the RSS feed includes full HTML content. Otherwise it includes just summaries. +- `includeEmptyFiles`: If `true` (default), content files with no body text are included in the generated index and resources. + +## API + +- Category: Emitter +- Function name: `Plugin.ContentIndex()`. +- Source: [`quartz/plugins/emitters/contentIndex.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/contentIndex.ts). diff --git a/docs/plugins/ContentPage.md b/docs/plugins/ContentPage.md new file mode 100644 index 0000000..5d9016f --- /dev/null +++ b/docs/plugins/ContentPage.md @@ -0,0 +1,18 @@ +--- +title: ContentPage +tags: + - plugin/emitter +--- + +This plugin is a core component of the Quartz framework. It generates the HTML pages for each piece of Markdown content. It emits the full-page [[layout]], including headers, footers, and body content, among others. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.ContentPage()`. +- Source: [`quartz/plugins/emitters/contentPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/contentPage.tsx). diff --git a/docs/plugins/CrawlLinks.md b/docs/plugins/CrawlLinks.md new file mode 100644 index 0000000..15a0d66 --- /dev/null +++ b/docs/plugins/CrawlLinks.md @@ -0,0 +1,30 @@ +--- +title: CrawlLinks +tags: + - plugin/transformer +--- + +This plugin parses links and processes them to point to the right places. It is also needed for embedded links (like images). See [[Obsidian 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: + +- `markdownLinkResolution`: Sets the strategy for resolving Markdown paths, can be `"absolute"` (default), `"relative"` or `"shortest"`. You should use the same setting here as in [[Obsidian compatibility|Obsidian]]. + - `absolute`: Path relative to the root of the content folder. + - `relative`: Path relative to the file you are linking from. + - `shortest`: Name of the file. If this isn't enough to identify the file, use the full absolute path. +- `prettyLinks`: If `true` (default), simplifies links by removing folder paths, making them more user friendly (e.g. `folder/deeply/nested/note` becomes `note`). +- `openLinksInNewTab`: If `true`, configures external links to open in a new tab. Defaults to `false`. +- `lazyLoad`: If `true`, adds lazy loading to resource elements (`img`, `video`, etc.) to improve page load performance. Defaults to `false`. +- `externalLinkIcon`: Adds an icon next to external links when `true` (default) to visually distinguishing them from internal links. + +> [!warning] +> Removing this plugin is _not_ recommended and will likely break the page. + +## API + +- Category: Transformer +- Function name: `Plugin.CrawlLinks()`. +- Source: [`quartz/plugins/transformers/links.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/links.ts). diff --git a/docs/plugins/CreatedModifiedDate.md b/docs/plugins/CreatedModifiedDate.md new file mode 100644 index 0000000..6a0f137 --- /dev/null +++ b/docs/plugins/CreatedModifiedDate.md @@ -0,0 +1,25 @@ +--- +title: "CreatedModifiedDate" +tags: + - plugin/transformer +--- + +This plugin determines the created, modified, and published dates for a document using three potential data sources: frontmatter metadata, Git history, and the filesystem. See [[authoring content#Syntax]] 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: + +- `priority`: The data sources to consult for date information. Highest priority first. Possible values are `"frontmatter"`, `"git"`, and `"filesystem"`. Defaults to `"frontmatter", "git", "filesystem"]`. + +> [!warning] +> If you rely on `git` for dates, make sure `defaultDateType` is set to `modified` in `quartz.config.ts`. +> +> Depending on how you [[hosting|host]] your Quartz, the `filesystem` dates of your local files may not match the final dates. In these cases, it may be better to use `git` or `frontmatter` to guarantee correct dates. + +## API + +- Category: Transformer +- Function name: `Plugin.CreatedModifiedDate()`. +- Source: [`quartz/plugins/transformers/lastmod.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/lastmod.ts). diff --git a/docs/plugins/Description.md b/docs/plugins/Description.md new file mode 100644 index 0000000..6849b3c --- /dev/null +++ b/docs/plugins/Description.md @@ -0,0 +1,22 @@ +--- +title: Description +tags: + - plugin/transformer +--- + +This plugin generates descriptions that are used as metadata for the HTML `head`, the [[RSS Feed]] and in [[folder and tag listings]] if there is no main body content, the description is used as the text between the title and the listing. + +If the frontmatter contains a `description` property, it is used (see [[authoring content#Syntax]]). Otherwise, the plugin will do its best to use the first few sentences of the content to reach the target description length. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin accepts the following configuration options: + +- `descriptionLength`: the maximum length of the generated description. Default is 150 characters. The cut off happens after the first _sentence_ that ends after the given length. + +## API + +- Category: Transformer +- Function name: `Plugin.Description()`. +- Source: [`quartz/plugins/transformers/description.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/description.ts). diff --git a/docs/plugins/ExplicitPublish.md b/docs/plugins/ExplicitPublish.md new file mode 100644 index 0000000..7ef2dd4 --- /dev/null +++ b/docs/plugins/ExplicitPublish.md @@ -0,0 +1,18 @@ +--- +title: ExplicitPublish +tags: + - plugin/filter +--- + +This plugin filters content based on an explicit `publish` flag in the frontmatter, allowing only content that is explicitly marked for publication to pass through. It's the opt-in version of [[RemoveDrafts]]. See [[private pages]] for more information. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.ExplicitPublish()`. +- Source: [`quartz/plugins/filters/explicit.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/explicit.ts). diff --git a/docs/plugins/FolderPage.md b/docs/plugins/FolderPage.md new file mode 100644 index 0000000..92a700a --- /dev/null +++ b/docs/plugins/FolderPage.md @@ -0,0 +1,22 @@ +--- +title: FolderPage +tags: + - plugin/emitter +--- + +This plugin generates index pages for folders, creating a listing page for each folder that contains multiple content files. See [[folder and tag listings]] for more information. + +Example: [[advanced/|Advanced]] + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts`. For the content, the `FolderContent` component is used. If you want to modify the layout, you must edit it directly (`quartz/components/pages/FolderContent.tsx`). + +## API + +- Category: Emitter +- Function name: `Plugin.FolderPage()`. +- Source: [`quartz/plugins/emitters/folderPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/folderPage.tsx). diff --git a/docs/plugins/Frontmatter.md b/docs/plugins/Frontmatter.md new file mode 100644 index 0000000..960417a --- /dev/null +++ b/docs/plugins/Frontmatter.md @@ -0,0 +1,24 @@ +--- +title: "Frontmatter" +tags: + - plugin/transformer +--- + +This plugin parses the frontmatter of the page using the [gray-matter](https://github.com/jonschlinkert/gray-matter) library. See [[authoring content#Syntax]], [[Obsidian compatibility]] and [[OxHugo 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: + +- `delimiters`: the delimiters to use for the frontmatter. Can have one value (e.g. `"---"`) or separate values for opening and closing delimiters (e.g. `["---", "~~~"]`). Defaults to `"---"`. +- `language`: the language to use for parsing the frontmatter. Can be `yaml` (default) or `toml`. + +> [!warning] +> This plugin must not be removed, otherwise Quartz will break. + +## API + +- Category: Transformer +- Function name: `Plugin.Frontmatter()`. +- Source: [`quartz/plugins/transformers/frontmatter.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/frontmatter.ts). diff --git a/docs/plugins/GitHubFlavoredMarkdown.md b/docs/plugins/GitHubFlavoredMarkdown.md new file mode 100644 index 0000000..2ea8f8d --- /dev/null +++ b/docs/plugins/GitHubFlavoredMarkdown.md @@ -0,0 +1,23 @@ +--- +title: GitHubFlavoredMarkdown +tags: + - plugin/transformer +--- + +This plugin enhances Markdown processing to support GitHub Flavored Markdown (GFM) which adds features like autolink literals, footnotes, strikethrough, tables and tasklists. + +In addition, this plugin adds optional features for typographic refinement (such as converting straight quotes to curly quotes, dashes to en-dashes/em-dashes, and ellipses) and automatic heading links as a symbol that appears next to the heading on hover. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin accepts the following configuration options: + +- `enableSmartyPants`: When true, enables typographic enhancements. Default is true. +- `linkHeadings`: When true, automatically adds links to headings. Default is true. + +## API + +- Category: Transformer +- Function name: `Plugin.GitHubFlavoredMarkdown()`. +- Source: [`quartz/plugins/transformers/gfm.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/gfm.ts). diff --git a/docs/plugins/HardLineBreaks.md b/docs/plugins/HardLineBreaks.md new file mode 100644 index 0000000..d35d74c --- /dev/null +++ b/docs/plugins/HardLineBreaks.md @@ -0,0 +1,18 @@ +--- +title: HardLineBreaks +tags: + - plugin/transformer +--- + +This plugin automatically converts single line breaks in Markdown text into hard line breaks in the HTML output. This plugin is not enabled by default as this doesn't follow the semantics of actual Markdown but you may enable it if you'd like parity with [[Obsidian compatibility|Obsidian]]. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Transformer +- Function name: `Plugin.HardLineBreaks()`. +- Source: [`quartz/plugins/transformers/linebreaks.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/linebreaks.ts). diff --git a/docs/plugins/Latex.md b/docs/plugins/Latex.md new file mode 100644 index 0000000..8a8999e --- /dev/null +++ b/docs/plugins/Latex.md @@ -0,0 +1,20 @@ +--- +title: "Latex" +tags: + - plugin/transformer +--- + +This plugin adds LaTeX support to Quartz. See [[features/Latex|Latex]] 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: + +- `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. + +## API + +- Category: Transformer +- Function name: `Plugin.Latex()`. +- Source: [`quartz/plugins/transformers/latex.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/latex.ts). diff --git a/docs/plugins/NotFoundPage.md b/docs/plugins/NotFoundPage.md new file mode 100644 index 0000000..082f864 --- /dev/null +++ b/docs/plugins/NotFoundPage.md @@ -0,0 +1,18 @@ +--- +title: NotFoundPage +tags: + - plugin/emitter +--- + +This plugin emits a 404 (Not Found) page for broken or non-existent URLs. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.NotFoundPage()`. +- Source: [`quartz/plugins/emitters/404.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/404.tsx). diff --git a/docs/plugins/ObsidianFlavoredMarkdown.md b/docs/plugins/ObsidianFlavoredMarkdown.md new file mode 100644 index 0000000..7700a5c --- /dev/null +++ b/docs/plugins/ObsidianFlavoredMarkdown.md @@ -0,0 +1,34 @@ +--- +title: ObsidianFlavoredMarkdown +tags: + - plugin/transformer +--- + +This plugin provides support for [[Obsidian compatibility]]. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin accepts the following configuration options: + +- `comments`: If `true` (default), enables parsing of `%%` style Obsidian comment blocks. +- `highlight`: If `true` (default), enables parsing of `==` style highlights within content. +- `wikilinks`:If `true` (default), turns [[wikilinks]] into regular links. +- `callouts`: If `true` (default), adds support for [[callouts|callout]] blocks for emphasizing content. +- `mermaid`: If `true` (default), enables [[Mermaid diagrams|Mermaid diagram]] rendering within Markdown files. +- `parseTags`: If `true` (default), parses and links tags within the content. +- `parseArrows`: If `true` (default), transforms arrow symbols into their HTML character equivalents. +- `parseBlockReferences`: If `true` (default), handles block references, linking to specific content blocks. +- `enableInHtmlEmbed`: If `true`, allows embedding of content directly within HTML. Defaults to `false`. +- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos using external image Markdown syntax. +- `enableVideoEmbed`: If `true` (default), enables the embedding of video files. +- `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`. + +> [!warning] +> Don't remove this plugin if you're using [[Obsidian compatibility|Obsidian]] to author the content! + +## API + +- Category: Transformer +- Function name: `Plugin.ObsidianFlavoredMarkdown()`. +- Source: [`quartz/plugins/transformers/toc.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/toc.ts). diff --git a/docs/plugins/OxHugoFlavoredMarkdown.md b/docs/plugins/OxHugoFlavoredMarkdown.md new file mode 100644 index 0000000..523a215 --- /dev/null +++ b/docs/plugins/OxHugoFlavoredMarkdown.md @@ -0,0 +1,29 @@ +--- +title: OxHugoFlavoredMarkdown +tags: + - plugin/transformer +--- + +This plugin provides support for [ox-hugo](https://github.com/kaushalmodi/ox-hugo) compatibility. See [[OxHugo 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: + +- `wikilinks`: If `true` (default), converts Hugo `{{ relref }}` shortcodes to Quartz [[wikilinks]]. +- `removePredefinedAnchor`: If `true` (default), strips predefined anchors from headings. +- `removeHugoShortcode`: If `true` (default), removes Hugo shortcode syntax (`{{}}`) from the content. +- `replaceFigureWithMdImg`: If `true` (default), replaces `
` with `![]()`. +- `replaceOrgLatex`: If `true` (default), converts Org-mode [[features/Latex|Latex]] fragments to Quartz-compatible LaTeX wrapped in `$` (for inline) and `$$` (for block equations). + +> [!warning] +> While you can use this together with [[ObsidianFlavoredMarkdown]], it's not recommended because it might mutate the file in unexpected ways. Use with caution. +> +> If you use `toml` frontmatter, make sure to configure the [[Frontmatter]] plugin accordingly. See [[OxHugo compatibility]] for an example. + +## API + +- Category: Transformer +- Function name: `Plugin.OxHugoFlavoredMarkdown()`. +- Source: [`quartz/plugins/transformers/oxhugofm.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/oxhugofm.ts). diff --git a/docs/plugins/RemoveDrafts.md b/docs/plugins/RemoveDrafts.md new file mode 100644 index 0000000..729ac86 --- /dev/null +++ b/docs/plugins/RemoveDrafts.md @@ -0,0 +1,18 @@ +--- +title: RemoveDrafts +tags: + - plugin/filter +--- + +This plugin filters out content from your vault, so that only finalized content is made available. This prevents [[private pages]] from being published. By default, it filters out all pages with `draft: true` in the frontmatter and leaves all other pages intact. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Filter +- Function name: `Plugin.RemoveDrafts()`. +- Source: [`quartz/plugins/filters/draft.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/draft.ts). diff --git a/docs/plugins/Static.md b/docs/plugins/Static.md new file mode 100644 index 0000000..c660eab --- /dev/null +++ b/docs/plugins/Static.md @@ -0,0 +1,21 @@ +--- +title: Static +tags: + - plugin/emitter +--- + +This plugin emits all static resources needed by Quartz. This is used, for example, for fonts and images that need a stable position, such as banners and icons. The plugin respects the `ignorePatterns` in the global [[configuration]]. + +> [!important] +> This is different from [[Assets]]. The resources from the [[Static]] plugin are located under `quartz/static`, whereas [[Assets]] renders all static resources under `content` and is used for images, videos, audio, etc. that are directly referenced by your markdown content. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +## API + +- Category: Emitter +- Function name: `Plugin.Static()`. +- Source: [`quartz/plugins/emitters/static.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/static.ts). diff --git a/docs/plugins/SyntaxHighlighting.md b/docs/plugins/SyntaxHighlighting.md new file mode 100644 index 0000000..8bf581e --- /dev/null +++ b/docs/plugins/SyntaxHighlighting.md @@ -0,0 +1,23 @@ +--- +title: "SyntaxHighlighting" +tags: + - plugin/transformer +--- + +This plugin is used to add syntax highlighting to code blocks in Quartz. See [[syntax highlighting]] 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: + +- `theme`: a separate id of one of the [themes bundled with Shikiji](https://shikiji.netlify.app/themes). One for light mode and one for dark mode. Defaults to `theme: { light: "github-light", dark: "github-dark" }`. +- `keepBackground`: If set to `true`, the background of the Shikiji theme will be used. With `false` (default) the Quartz theme color for background will be used instead. + +In addition, you can further override the colours in the `quartz/styles/syntax.scss` file. + +## API + +- Category: Transformer +- Function name: `Plugin.SyntaxHighlighting()`. +- Source: [`quartz/plugins/transformers/syntax.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/syntax.ts). diff --git a/docs/plugins/TableOfContents.md b/docs/plugins/TableOfContents.md new file mode 100644 index 0000000..d443d0e --- /dev/null +++ b/docs/plugins/TableOfContents.md @@ -0,0 +1,26 @@ +--- +title: TableOfContents +tags: + - plugin/transformer +--- + +This plugin generates a table of contents (TOC) for Markdown documents. See [[table of contents]] 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: + +- `maxDepth`: Limits the depth of headings included in the TOC, ranging from `1` (top level headings only) to `6` (all heading levels). Default is `3`. +- `minEntries`: The minimum number of heading entries required for the TOC to be displayed. Default is `1`. +- `showByDefault`: If `true` (default), the TOC should be displayed by default. Can be overridden by frontmatter settings. +- `collapseByDefault`: If `true`, the TOC will start in a collapsed state. Default is `false`. + +> [!warning] +> This plugin needs the `Component.TableOfContents` component in `quartz.layout.ts` to determine where to display the TOC. Without it, nothing will be displayed. They should always be added or removed together. + +## API + +- Category: Transformer +- Function name: `Plugin.TableOfContents()`. +- Source: [`quartz/plugins/transformers/toc.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/toc.ts). diff --git a/docs/plugins/TagPage.md b/docs/plugins/TagPage.md new file mode 100644 index 0000000..4dabfd0 --- /dev/null +++ b/docs/plugins/TagPage.md @@ -0,0 +1,20 @@ +--- +title: TagPage +tags: + - plugin/emitter +--- + +This plugin emits dedicated pages for each tag used in the content. See [[folder and tag listings]] for more information. + +> [!note] +> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page. + +This plugin has no configuration options. + +The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts`. For the content, the `TagContent` component is used. If you want to modify the layout, you must edit it directly (`quartz/components/pages/TagContent.tsx`). + +## API + +- Category: Emitter +- Function name: `Plugin.AliasRedirects()`. +- Source: [`quartz/plugins/emitters/tagPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/tagPage.tsx). diff --git a/docs/plugins/index.md b/docs/plugins/index.md new file mode 100644 index 0000000..298ff16 --- /dev/null +++ b/docs/plugins/index.md @@ -0,0 +1,3 @@ +--- +title: Plugins +--- diff --git a/docs/tags/plugin.md b/docs/tags/plugin.md new file mode 100644 index 0000000..298ff16 --- /dev/null +++ b/docs/tags/plugin.md @@ -0,0 +1,3 @@ +--- +title: Plugins +--- diff --git a/quartz.config.ts b/quartz.config.ts index 8c479ac..2cdadb7 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -1,6 +1,11 @@ import { QuartzConfig } from "./quartz/cfg" import * as Plugin from "./quartz/plugins" +/** + * Quartz 4.0 Configuration + * + * See https://quartz.jzhao.xyz/configuration for more information. + */ const config: QuartzConfig = { configuration: { pageTitle: "🪴 Quartz 4.0", @@ -48,19 +53,14 @@ const config: QuartzConfig = { transformers: [ Plugin.FrontMatter(), Plugin.CreatedModifiedDate({ - // you can add 'git' here for last modified from Git - // if you do rely on git for dates, ensure defaultDateType is 'modified' priority: ["frontmatter", "filesystem"], }), Plugin.Latex({ renderEngine: "katex" }), Plugin.SyntaxHighlighting({ - // uses themes bundled with Shikiji, see https://shikiji.netlify.app/themes theme: { light: "github-light", dark: "github-dark", }, - // set this to 'true' to use the background color of the Shikiji theme - // if set to 'false', will use Quartz theme colors for background keepBackground: false, }), Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), From 6be1ed1ea2ab6602f1d77d98cd9972aa391a5e7f Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 17:45:41 -0800 Subject: [PATCH 044/217] docs(latex): mhchem --- docs/features/Latex.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/features/Latex.md b/docs/features/Latex.md index e019190..b2bdb2d 100644 --- a/docs/features/Latex.md +++ b/docs/features/Latex.md @@ -57,6 +57,15 @@ For example: - Incorrect: `I have $1 and you have $2` produces I have $1 and you have $2 - Correct: `I have \$1 and you have \$2` produces I have \$1 and you have \$2 +### Using mhchem + +Add the following import to the top of `quartz/plugins/transformers/latex.ts` (before all the other +imports): + +```ts title="quartz/plugins/transformers/latex.ts" +import "katex/contrib/mhchem" +``` + ## Customization Latex parsing is a functionality of the [[plugins/Latex|Latex]] plugin. See the plugin page for customization options. From a6417c447af8f0ff203ffb8730e53e4a7dfafb23 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Sat, 24 Feb 2024 02:40:42 +0000 Subject: [PATCH 045/217] fix(fast rebuild): handle added an deleted markdown correctly (#921) * Handle added files correctly * Handle deletes properly * addGraph renamed to mergeGraph --- quartz/build.ts | 33 +++++++++++++++++++++------------ quartz/depgraph.test.ts | 22 ++++++++++++++++++++++ quartz/depgraph.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/quartz/build.ts b/quartz/build.ts index 3d95f31..d72b8dd 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -185,9 +185,14 @@ async function partialRebuildFromEntrypoint( const emitterGraph = (await emitter.getDependencyGraph?.(ctx, processedFiles, staticResources)) ?? null - // emmiter may not define a dependency graph. nothing to update if so if (emitterGraph) { - dependencies[emitter.name]?.updateIncomingEdgesForNode(emitterGraph, fp) + const existingGraph = dependencies[emitter.name] + if (existingGraph !== null) { + existingGraph.mergeGraph(emitterGraph) + } else { + // might be the first time we're adding a mardown file + dependencies[emitter.name] = emitterGraph + } } } break @@ -224,7 +229,6 @@ async function partialRebuildFromEntrypoint( // EMIT perf.addEvent("rebuild") let emittedFiles = 0 - const destinationsToDelete = new Set() for (const emitter of cfg.plugins.emitters) { const depGraph = dependencies[emitter.name] @@ -264,11 +268,6 @@ async function partialRebuildFromEntrypoint( // and supply [a.md, b.md] to the emitter const upstreams = [...depGraph.getLeafNodeAncestors(fp)] as FilePath[] - if (action === "delete" && upstreams.length === 1) { - // if there's only one upstream, the destination is solely dependent on this file - destinationsToDelete.add(upstreams[0]) - } - const upstreamContent = upstreams // filter out non-markdown files .filter((file) => contentMap.has(file)) @@ -291,14 +290,24 @@ async function partialRebuildFromEntrypoint( console.log(`Emitted ${emittedFiles} files to \`${argv.output}\` in ${perf.timeSince("rebuild")}`) // CLEANUP - // delete files that are solely dependent on this file - await rimraf([...destinationsToDelete]) + const destinationsToDelete = new Set() for (const file of toRemove) { // remove from cache contentMap.delete(file) - // remove the node from dependency graphs - Object.values(dependencies).forEach((depGraph) => depGraph?.removeNode(file)) + Object.values(dependencies).forEach((depGraph) => { + // remove the node from dependency graphs + depGraph?.removeNode(file) + // remove any orphan nodes. eg if a.md is deleted, a.html is orphaned and should be removed + const orphanNodes = depGraph?.removeOrphanNodes() + orphanNodes?.forEach((node) => { + // only delete files that are in the output directory + if (node.startsWith(argv.output)) { + destinationsToDelete.add(node) + } + }) + }) } + await rimraf([...destinationsToDelete]) toRemove.clear() release() diff --git a/quartz/depgraph.test.ts b/quartz/depgraph.test.ts index 43eb402..062f13e 100644 --- a/quartz/depgraph.test.ts +++ b/quartz/depgraph.test.ts @@ -39,6 +39,28 @@ describe("DepGraph", () => { }) }) + describe("mergeGraph", () => { + test("merges two graphs", () => { + const graph = new DepGraph() + graph.addEdge("A.md", "A.html") + + const other = new DepGraph() + other.addEdge("B.md", "B.html") + + graph.mergeGraph(other) + + const expected = { + nodes: ["A.md", "A.html", "B.md", "B.html"], + edges: [ + ["A.md", "A.html"], + ["B.md", "B.html"], + ], + } + + assert.deepStrictEqual(graph.export(), expected) + }) + }) + describe("updateIncomingEdgesForNode", () => { test("merges when node exists", () => { // A.md -> B.md -> B.html diff --git a/quartz/depgraph.ts b/quartz/depgraph.ts index 1efad07..3d048cd 100644 --- a/quartz/depgraph.ts +++ b/quartz/depgraph.ts @@ -39,12 +39,26 @@ export default class DepGraph { } } + // Remove node and all edges connected to it removeNode(node: T): void { if (this._graph.has(node)) { + // first remove all edges so other nodes don't have references to this node + for (const target of this._graph.get(node)!.outgoing) { + this.removeEdge(node, target) + } + for (const source of this._graph.get(node)!.incoming) { + this.removeEdge(source, node) + } this._graph.delete(node) } } + forEachNode(callback: (node: T) => void): void { + for (const node of this._graph.keys()) { + callback(node) + } + } + hasEdge(from: T, to: T): boolean { return Boolean(this._graph.get(from)?.outgoing.has(to)) } @@ -92,6 +106,15 @@ export default class DepGraph { // DEPENDENCY ALGORITHMS + // Add all nodes and edges from other graph to this graph + mergeGraph(other: DepGraph): void { + other.forEachEdge(([source, target]) => { + this.addNode(source) + this.addNode(target) + this.addEdge(source, target) + }) + } + // For the node provided: // If node does not exist, add it // If an incoming edge was added in other, it is added in this graph @@ -112,6 +135,24 @@ export default class DepGraph { }) } + // Remove all nodes that do not have any incoming or outgoing edges + // A node may be orphaned if the only node pointing to it was removed + removeOrphanNodes(): Set { + let orphanNodes = new Set() + + this.forEachNode((node) => { + if (this.inDegree(node) === 0 && this.outDegree(node) === 0) { + orphanNodes.add(node) + } + }) + + orphanNodes.forEach((node) => { + this.removeNode(node) + }) + + return orphanNodes + } + // Get all leaf nodes (i.e. destination paths) reachable from the node provided // Eg. if the graph is A -> B -> C // D ---^ From 2c74b05d1be573ca953f5331ab8f99c70dbf3a59 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 18:48:19 -0800 Subject: [PATCH 046/217] fix(ci): autotag --- .github/workflows/ci.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9b1622c..9ef2786 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -47,7 +47,7 @@ jobs: run: npx quartz build --bundleInfo - name: Create release tag - uses: Klemensas/action-autotag@stable + uses: phish108/autotag-action@v1.1.55 with: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - tag_prefix: "v" + github-token: ${{ secrets.GITHUB_TOKEN}} + with-v: "true" From ea7122dd5a45db6b749045a626de5a0096819edd Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 18:52:28 -0800 Subject: [PATCH 047/217] pkg: bump to 4.2.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc020fc..50ab837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jackyzha0/quartz", - "version": "4.2.2", + "version": "4.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jackyzha0/quartz", - "version": "4.2.2", + "version": "4.2.3", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", diff --git a/package.json b/package.json index 094e62a..787c37d 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.2.2", + "version": "4.2.3", "type": "module", "author": "jackyzha0 ", "license": "MIT", From d0c0daa4aa6fc4db4be2371f460f22eb3764c457 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 19:00:47 -0800 Subject: [PATCH 048/217] ci: fix autotag --- .github/workflows/ci.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9ef2786..1037f5e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -46,8 +46,14 @@ jobs: - name: Ensure Quartz builds, check bundle info run: npx quartz build --bundleInfo + - name: Get package version + run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV + - name: Create release tag - uses: phish108/autotag-action@v1.1.55 + uses: pkgdeps/git-tag-action@v2 with: - github-token: ${{ secrets.GITHUB_TOKEN}} - with-v: "true" + github_token: ${{ secrets.GITHUB_TOKEN }} + github_repo: ${{ github.repository }} + version: ${{ env.PACKAGE_VERSION }} + git_commit_sha: ${{ github.sha }} + git_tag_prefix: "v" From c53fd5b56fb5a4a09df0a6dc8ff115b510f25d25 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 19:04:38 -0800 Subject: [PATCH 049/217] ci: tag as a separate step --- .github/workflows/ci.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1037f5e..edd52b9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -46,6 +46,12 @@ jobs: - name: Ensure Quartz builds, check bundle info run: npx quartz build --bundleInfo + publish-tag: + if: ${{ github.repository == 'jackyzha0/quartz' }} + run-on: ubuntu-latest + permissions: + contents: write + steps: - name: Get package version run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV From b88d3d292beaa0cd03e72a4fc1b84c7bc1d39e9e Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 19:05:26 -0800 Subject: [PATCH 050/217] ci: fix typo in runs-on --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index edd52b9..9bf34a9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -48,7 +48,7 @@ jobs: publish-tag: if: ${{ github.repository == 'jackyzha0/quartz' }} - run-on: ubuntu-latest + runs-on: ubuntu-latest permissions: contents: write steps: From 67647d9167c4f8aefc25a864f14248d88d33eac5 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Fri, 23 Feb 2024 19:08:39 -0800 Subject: [PATCH 051/217] ci: also checkout and install node before tagging --- .github/workflows/ci.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9bf34a9..56107cf 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -52,9 +52,15 @@ jobs: permissions: contents: write steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18 - name: Get package version run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV - - name: Create release tag uses: pkgdeps/git-tag-action@v2 with: From 2f10da776689a1dc83ed74d53af9d1615d705dc3 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Sun, 25 Feb 2024 12:00:26 -0500 Subject: [PATCH 052/217] docs: fix tag page oops (#925) --- docs/plugins/TagPage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/TagPage.md b/docs/plugins/TagPage.md index 4dabfd0..cd7dee6 100644 --- a/docs/plugins/TagPage.md +++ b/docs/plugins/TagPage.md @@ -16,5 +16,5 @@ The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts` ## API - Category: Emitter -- Function name: `Plugin.AliasRedirects()`. +- Function name: `Plugin.TagPage()`. - Source: [`quartz/plugins/emitters/tagPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/tagPage.tsx). From d6e79d1ea6ace4e70b1813a63c5060c89681a2ad Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Sun, 25 Feb 2024 19:58:21 -0500 Subject: [PATCH 053/217] chore(types): update correct annotations for pages (#928) --- quartz/components/pages/404.tsx | 4 ++-- quartz/components/pages/Content.tsx | 4 ++-- quartz/components/pages/FolderContent.tsx | 4 ++-- quartz/components/pages/TagContent.tsx | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/quartz/components/pages/404.tsx b/quartz/components/pages/404.tsx index 276d5e5..4ef1b91 100644 --- a/quartz/components/pages/404.tsx +++ b/quartz/components/pages/404.tsx @@ -1,7 +1,7 @@ import { i18n } from "../../i18n" -import { QuartzComponentConstructor, QuartzComponentProps } from "../types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types" -function NotFound({ cfg }: QuartzComponentProps) { +const NotFound: QuartzComponent = ({ cfg }: QuartzComponentProps) => { return (

404

diff --git a/quartz/components/pages/Content.tsx b/quartz/components/pages/Content.tsx index 2e6416f..8222d78 100644 --- a/quartz/components/pages/Content.tsx +++ b/quartz/components/pages/Content.tsx @@ -1,7 +1,7 @@ import { htmlToJsx } from "../../util/jsx" -import { QuartzComponentConstructor, QuartzComponentProps } from "../types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types" -function Content({ fileData, tree }: QuartzComponentProps) { +const Content: QuartzComponent = ({ fileData, tree }: QuartzComponentProps) => { const content = htmlToJsx(fileData.filePath!, tree) const classes: string[] = fileData.frontmatter?.cssclasses ?? [] const classString = ["popover-hint", ...classes].join(" ") diff --git a/quartz/components/pages/FolderContent.tsx b/quartz/components/pages/FolderContent.tsx index d3f28dd..55f1e42 100644 --- a/quartz/components/pages/FolderContent.tsx +++ b/quartz/components/pages/FolderContent.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "../types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types" import path from "path" import style from "../styles/listPage.scss" @@ -22,7 +22,7 @@ const defaultOptions: FolderContentOptions = { export default ((opts?: Partial) => { const options: FolderContentOptions = { ...defaultOptions, ...opts } - function FolderContent(props: QuartzComponentProps) { + const FolderContent: QuartzComponent = (props: QuartzComponentProps) => { const { tree, fileData, allFiles, cfg } = props const folderSlug = stripSlashes(simplifySlug(fileData.slug!)) const allPagesInFolder = allFiles.filter((file) => { diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx index 22f6bb2..1dd9124 100644 --- a/quartz/components/pages/TagContent.tsx +++ b/quartz/components/pages/TagContent.tsx @@ -1,4 +1,4 @@ -import { QuartzComponentConstructor, QuartzComponentProps } from "../types" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types" import style from "../styles/listPage.scss" import { PageList } from "../PageList" import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path" @@ -8,7 +8,7 @@ import { htmlToJsx } from "../../util/jsx" import { i18n } from "../../i18n" const numPages = 10 -function TagContent(props: QuartzComponentProps) { +const TagContent: QuartzComponent = (props: QuartzComponentProps) => { const { tree, fileData, allFiles, cfg } = props const slug = fileData.slug From 6b90d03ca66e9b4b7096dd04ff74b1503a9bb7ca Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:53:45 -0500 Subject: [PATCH 054/217] chore(type): export attribute for theme key (#933) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/util/theme.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/quartz/util/theme.ts b/quartz/util/theme.ts index bd0da5f..49cc9cc 100644 --- a/quartz/util/theme.ts +++ b/quartz/util/theme.ts @@ -9,6 +9,11 @@ export interface ColorScheme { highlight: string } +interface Colors { + lightMode: ColorScheme + darkMode: ColorScheme +} + export interface Theme { typography: { header: string @@ -16,12 +21,11 @@ export interface Theme { code: string } cdnCaching: boolean - colors: { - lightMode: ColorScheme - darkMode: ColorScheme - } + colors: Colors } +export type ThemeKey = keyof Colors + const DEFAULT_SANS_SERIF = '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif' const DEFAULT_MONO = "ui-monospace, SFMono-Regular, SF Mono, Menlo, monospace" From 4957eaa2d02c3987d825487f46e5a74bfbba7601 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:17:42 -0500 Subject: [PATCH 055/217] chore(deps): bump preact from 10.19.5 to 10.19.6 (#935) Bumps [preact](https://github.com/preactjs/preact) from 10.19.5 to 10.19.6. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.19.5...10.19.6) --- updated-dependencies: - dependency-name: preact 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 50ab837..9ee42ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.5", + "preact": "^10.19.6", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", @@ -4459,9 +4459,9 @@ } }, "node_modules/preact": { - "version": "10.19.5", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.5.tgz", - "integrity": "sha512-OPELkDmSVbKjbFqF9tgvOowiiQ9TmsJljIzXRyNE8nGiis94pwv1siF78rQkAP1Q1738Ce6pellRg/Ns/CtHqQ==", + "version": "10.19.6", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.6.tgz", + "integrity": "sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index 787c37d..492377b 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", - "preact": "^10.19.5", + "preact": "^10.19.6", "preact-render-to-string": "^6.3.1", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", From 66a5855fad8ece898cf64460a74e0f7ef6f3b23f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 13:54:15 -0800 Subject: [PATCH 056/217] chore(deps): bump chokidar from 3.5.3 to 3.6.0 (#937) Bumps [chokidar](https://github.com/paulmillr/chokidar) from 3.5.3 to 3.6.0. - [Release notes](https://github.com/paulmillr/chokidar/releases) - [Commits](https://github.com/paulmillr/chokidar/compare/3.5.3...3.6.0) --- updated-dependencies: - dependency-name: chokidar 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 | 17 +++++++---------- package.json | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ee42ff..7e71a1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@napi-rs/simple-git": "0.1.16", "async-mutex": "^0.4.1", "chalk": "^5.3.0", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "cli-spinner": "^0.2.10", "d3": "^7.8.5", "esbuild-sass-plugin": "^2.16.1", @@ -1344,15 +1344,9 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1365,6 +1359,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } diff --git a/package.json b/package.json index 492377b..ef623a0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "@napi-rs/simple-git": "0.1.16", "async-mutex": "^0.4.1", "chalk": "^5.3.0", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "cli-spinner": "^0.2.10", "d3": "^7.8.5", "esbuild-sass-plugin": "^2.16.1", From b9dee0775cda4bb29da1a5fb5b000ddcd4dc1f6e Mon Sep 17 00:00:00 2001 From: kon-foo <25391223+kon-foo@users.noreply.github.com> Date: Mon, 26 Feb 2024 22:55:47 +0100 Subject: [PATCH 057/217] docs: Clarifications in the Explorer Docs (#938) add example to filter by tags. --- docs/features/explorer.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/features/explorer.md b/docs/features/explorer.md index a2acb86..95878f7 100644 --- a/docs/features/explorer.md +++ b/docs/features/explorer.md @@ -61,7 +61,7 @@ export class FileNode { children: FileNode[] // children of current node name: string // last part of slug displayName: string // what actually should be displayed in the explorer - file: QuartzPluginData | null // set if node is a file, see `QuartzPluginData` for more detail + file: QuartzPluginData | null // if node is a file, this is the file's metadata. See `QuartzPluginData` for more detail depth: number // depth of current node ... // rest of implementation @@ -167,6 +167,19 @@ Component.Explorer({ You can customize this by changing the entries of the `omit` set. Simply add all folder or file names you want to remove. +### Remove files by tag + +You can access the frontmatter of a file by `node.file?.frontmatter?`. This allows you to filter out files based on their frontmatter, for example by their tags. + +```ts title="quartz.layout.ts" +Component.Explorer({ + filterFn: (node) => { + // exclude files with the tag "explorerexclude" + return node.file?.frontmatter?.tags?.includes("explorerexclude") !== true + }, +}) +``` + ### Show every element in explorer To override the default filter function that removes the `tags` folder from the explorer, you can set the filter function to `undefined`. From f200a0be22405f1a5b03ddbc173d6174bff3a0ba Mon Sep 17 00:00:00 2001 From: kon-foo <25391223+kon-foo@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:05:28 +0100 Subject: [PATCH 058/217] fix: correct umami host for self-hosted (#939) * fixed umami script path for self-hosted version * Update quartz/plugins/emitters/componentResources.ts Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> --------- Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> --- 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 0468416..1b6e13a 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -120,7 +120,7 @@ function addGlobalPageResources( } else if (cfg.analytics?.provider === "umami") { componentResources.afterDOMLoaded.push(` const umamiScript = document.createElement("script") - umamiScript.src = "${cfg.analytics.host}" ?? "https://analytics.umami.is/script.js" + umamiScript.src = "${cfg.analytics.host ?? "https://analytics.umami.is"}/script.js" umamiScript.setAttribute("data-website-id", "${cfg.analytics.websiteId}") umamiScript.async = true From 1c42b6365cab71e1400e94178d39a7592aa47726 Mon Sep 17 00:00:00 2001 From: HakuGuen <80277109+HakuGuen@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:14:20 -0800 Subject: [PATCH 059/217] feat(i18n): add Vietnamese translation (#950) --- quartz/i18n/index.ts | 2 + quartz/i18n/locales/vi-VN.ts | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 quartz/i18n/locales/vi-VN.ts diff --git a/quartz/i18n/index.ts b/quartz/i18n/index.ts index 38d3562..b97368d 100644 --- a/quartz/i18n/index.ts +++ b/quartz/i18n/index.ts @@ -12,6 +12,7 @@ import uk from "./locales/uk-UA" import ru from "./locales/ru-RU" import ko from "./locales/ko-KR" import zh from "./locales/zh-CN" +import vi from "./locales/vi-VN" export const TRANSLATIONS = { "en-US": en, @@ -48,6 +49,7 @@ export const TRANSLATIONS = { "ru-RU": ru, "ko-KR": ko, "zh-CN": zh, + "vi-VN": vi, } as const export const defaultTranslation = "en-US" diff --git a/quartz/i18n/locales/vi-VN.ts b/quartz/i18n/locales/vi-VN.ts new file mode 100644 index 0000000..b72ced4 --- /dev/null +++ b/quartz/i18n/locales/vi-VN.ts @@ -0,0 +1,83 @@ +import { Translation } from "./definition" + +export default { + propertyDefaults: { + title: "Không có tiêu đề", + description: "Không có mô tả được cung cấp", + }, + components: { + callout: { + note: "Ghi Chú", + abstract: "Tóm Tắt", + info: "Thông tin", + todo: "Cần Làm", + tip: "Gợi Ý", + success: "Thành Công", + question: "Nghi Vấn", + warning: "Cảnh Báo", + failure: "Thất Bại", + danger: "Nguy Hiểm", + bug: "Lỗi", + example: "Ví Dụ", + quote: "Trích Dẫn", + }, + backlinks: { + title: "Liên Kết Ngược", + noBacklinksFound: "Không có liên kết ngược được tìm thấy", + }, + themeToggle: { + lightMode: "Sáng", + darkMode: "Tối", + }, + explorer: { + title: "Trong bài này", + }, + footer: { + createdWith: "Được tạo bởi", + }, + graph: { + title: "Biểu Đồ", + }, + recentNotes: { + title: "Bài viết gần đây", + seeRemainingMore: ({ remaining }) => `Xem ${remaining} thêm →`, + }, + transcludes: { + transcludeOf: ({ targetSlug }) => `Bao gồm ${targetSlug}`, + linkToOriginal: "Liên Kết Gốc", + }, + search: { + title: "Tìm Kiếm", + searchBarPlaceholder: "Tìm kiếm thông tin", + }, + tableOfContents: { + title: "Bảng Nội Dung", + }, + contentMeta: { + readingTime: ({ minutes }) => `đọc ${minutes} phút`, + }, + }, + pages: { + rss: { + recentNotes: "Những bài gần đây", + lastFewNotes: ({ count }) => `${count} Bài gần đây`, + }, + error: { + title: "Không Tìm Thấy", + notFound: "Trang này được bảo mật hoặc không tồn tại.", + }, + folderContent: { + folder: "Thư Mục", + itemsUnderFolder: ({ count }) => + count === 1 ? "1 mục trong thư mục này." : `${count} mục trong thư mục này.`, + }, + tagContent: { + tag: "Thẻ", + tagIndex: "Thẻ Mục Lục", + itemsUnderTag: ({ count }) => + count === 1 ? "1 mục gắn thẻ này." : `${count} mục gắn thẻ này.`, + showingFirst: ({ count }) => `Hiển thị trước ${count} thẻ.`, + totalTags: ({ count }) => `Tìm thấy ${count} thẻ tổng cộng.`, + }, + }, +} as const satisfies Translation From 018c6358c4c00be319ccc00df84f9be02e7845b4 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:39:29 -0500 Subject: [PATCH 060/217] fix(callout): reorder the plugins to render latex on callout title (closes #952) (#934) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz.config.ts b/quartz.config.ts index 2cdadb7..a2eb605 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -55,6 +55,7 @@ const config: QuartzConfig = { Plugin.CreatedModifiedDate({ priority: ["frontmatter", "filesystem"], }), + Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), Plugin.Latex({ renderEngine: "katex" }), Plugin.SyntaxHighlighting({ theme: { @@ -63,7 +64,6 @@ const config: QuartzConfig = { }, keepBackground: false, }), - Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), Plugin.GitHubFlavoredMarkdown(), Plugin.TableOfContents(), Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }), From 566f3cf9f81a597c28f6bdc4deef912ac95e8f34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:27:54 -0800 Subject: [PATCH 061/217] chore(deps): bump remark-smartypants from 2.0.0 to 2.1.0 (#755) Bumps [remark-smartypants](https://github.com/silvenon/remark-smartypants) from 2.0.0 to 2.1.0. - [Release notes](https://github.com/silvenon/remark-smartypants/releases) - [Commits](https://github.com/silvenon/remark-smartypants/compare/v2.0.0...v2.1.0) --- updated-dependencies: - dependency-name: remark-smartypants 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 | 26 ++++++-------------------- package.json | 2 +- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e71a1d..c720b7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "remark-math": "^6.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0", - "remark-smartypants": "^2.0.0", + "remark-smartypants": "^2.1.0", "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", @@ -4866,32 +4866,18 @@ } }, "node_modules/remark-smartypants": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", - "integrity": "sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.1.0.tgz", + "integrity": "sha512-qoF6Vz3BjU2tP6OfZqHOvCU0ACmu/6jhGaINSQRI9mM7wCxNQTKB3JUAN4SVoN2ybElEDTxBIABRep7e569iJw==", "dependencies": { "retext": "^8.1.0", - "retext-smartypants": "^5.1.0", - "unist-util-visit": "^4.1.0" + "retext-smartypants": "^5.2.0", + "unist-util-visit": "^5.0.0" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/remark-smartypants/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remark-stringify": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", diff --git a/package.json b/package.json index ef623a0..38b0ca6 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "remark-math": "^6.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0", - "remark-smartypants": "^2.0.0", + "remark-smartypants": "^2.1.0", "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", From 2a7e61ae2a0d0e1a479923f5664635d110e470c3 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 3 Mar 2024 12:31:55 -0800 Subject: [PATCH 062/217] feat: support transcluding codeblocks and blockquotes (closes #940) --- quartz/plugins/transformers/ofm.ts | 36 ++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index fab7cf8..237d683 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -1,5 +1,5 @@ import { QuartzTransformerPlugin } from "../types" -import { Blockquote, Root, Html, BlockContent, DefinitionContent, Paragraph, Code } from "mdast" +import { Root, Html, BlockContent, DefinitionContent, Paragraph, Code } from "mdast" import { Element, Literal, Root as HtmlRoot } from "hast" import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace" import { slug as slugAnchor } from "github-slugger" @@ -17,7 +17,6 @@ import { toHtml } from "hast-util-to-html" import { PhrasingContent } from "mdast-util-find-and-replace/lib" import { capitalize } from "../../util/lang" import { PluggableList } from "unified" -import { ValidCallout, i18n } from "../../i18n" export interface Options { comments: boolean @@ -528,12 +527,35 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin last.value = last.value.slice(0, -matches[0].length) const block = matches[0].slice(1) - if (!Object.keys(file.data.blocks!).includes(block)) { - node.properties = { - ...node.properties, - id: block, + if (last.value === "") { + // this is an inline block ref but the actual block + // is the previous element above it + let idx = (index ?? 1) - 1 + while (idx >= 0) { + const element = parent?.children.at(idx) + if (!element) break + if (element.type !== "element") { + idx -= 1 + } else { + if (!Object.keys(file.data.blocks!).includes(block)) { + element.properties = { + ...element.properties, + id: block, + } + file.data.blocks![block] = element + } + return + } + } + } else { + // normal paragraph transclude + if (!Object.keys(file.data.blocks!).includes(block)) { + node.properties = { + ...node.properties, + id: block, + } + file.data.blocks![block] = node } - file.data.blocks![block] = node } } } From bd05950c2db1335b68c8e1701385219e681a4241 Mon Sep 17 00:00:00 2001 From: sventec Date: Sun, 3 Mar 2024 19:40:42 -0500 Subject: [PATCH 063/217] fix(docs): correct ExplicitPublish as filters instead of transformers (#953) --- docs/configuration.md | 4 ++-- docs/plugins/ExplicitPublish.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 6c76654..500e4c1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -73,10 +73,10 @@ You can customize the behaviour of Quartz by adding, removing and reordering plu > [!note] > Each node is modified by every transformer _in order_. Some transformers are position sensitive, so you may need to pay particular attention to whether they need to come before or after certain other plugins. -You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/transformer|Transformer]], you would add the following line: +You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/filter|Filter]]), you would add the following line: ```ts title="quartz.config.ts" -transformers: [ +filters: [ ... Plugin.ExplicitPublish(), ... diff --git a/docs/plugins/ExplicitPublish.md b/docs/plugins/ExplicitPublish.md index 7ef2dd4..7c7aceb 100644 --- a/docs/plugins/ExplicitPublish.md +++ b/docs/plugins/ExplicitPublish.md @@ -13,6 +13,6 @@ This plugin has no configuration options. ## API -- Category: Emitter +- Category: Filter - Function name: `Plugin.ExplicitPublish()`. - Source: [`quartz/plugins/filters/explicit.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/explicit.ts). From bcb5b2df09cb8c8fc0736ec476b2486f9b4643be Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Mon, 4 Mar 2024 18:52:28 +0100 Subject: [PATCH 064/217] feat(frontmatter): configure max length for description (#946) * Sentence length check * Replace external links with domain name. * Updated documentation. * Updated replacement values. * Updated Regex based on feedback. * Check description for undefined * Updated external url transform regex. * Updated formatting --- docs/plugins/Description.md | 1 + quartz/plugins/transformers/description.ts | 43 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/docs/plugins/Description.md b/docs/plugins/Description.md index 6849b3c..526bb01 100644 --- a/docs/plugins/Description.md +++ b/docs/plugins/Description.md @@ -14,6 +14,7 @@ If the frontmatter contains a `description` property, it is used (see [[authorin This plugin accepts the following configuration options: - `descriptionLength`: the maximum length of the generated description. Default is 150 characters. The cut off happens after the first _sentence_ that ends after the given length. +- `replaceExternalLinks`: If `true` (default), replace external links with their domain and path in the description (e.g. `https://domain.tld/some_page/another_page?query=hello&target=world` is replaced with `domain.tld/some_page/another_page`). ## API diff --git a/quartz/plugins/transformers/description.ts b/quartz/plugins/transformers/description.ts index 884d5b1..0f8cd8d 100644 --- a/quartz/plugins/transformers/description.ts +++ b/quartz/plugins/transformers/description.ts @@ -5,12 +5,19 @@ import { escapeHTML } from "../../util/escape" export interface Options { descriptionLength: number + replaceExternalLinks: boolean } const defaultOptions: Options = { descriptionLength: 150, + replaceExternalLinks: true, } +const urlRegex = new RegExp( + /(https?:\/\/)?(?([\da-z\.-]+)\.([a-z\.]{2,6})(:\d+)?)(?[\/\w\.-]*)(\?[\/\w\.=&;-]*)?/, + "g", +) + export const Description: QuartzTransformerPlugin | undefined> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } return { @@ -19,19 +26,39 @@ export const Description: QuartzTransformerPlugin | undefined> return [ () => { return async (tree: HTMLRoot, file) => { - const frontMatterDescription = file.data.frontmatter?.description - const text = escapeHTML(toString(tree)) + let frontMatterDescription = file.data.frontmatter?.description + let text = escapeHTML(toString(tree)) + + if (opts.replaceExternalLinks) { + frontMatterDescription = frontMatterDescription?.replace( + urlRegex, + "$" + "$", + ) + text = text.replace(urlRegex, "$" + "$") + } const desc = frontMatterDescription ?? text - const sentences = desc.replace(/\s+/g, " ").split(".") + const sentences = desc.replace(/\s+/g, " ").split(/\.\s/) let finalDesc = "" let sentenceIdx = 0 const len = opts.descriptionLength - while (finalDesc.length < len) { - const sentence = sentences[sentenceIdx] - if (!sentence) break - finalDesc += sentence + "." - sentenceIdx++ + + if (sentences[0] !== undefined && sentences[0].length >= len) { + const firstSentence = sentences[0].split(" ") + while (finalDesc.length < len) { + const sentence = firstSentence[sentenceIdx] + if (!sentence) break + finalDesc += sentence + " " + sentenceIdx++ + } + finalDesc = finalDesc.trimEnd() + "..." + } else { + while (finalDesc.length < len) { + const sentence = sentences[sentenceIdx] + if (!sentence) break + finalDesc += sentence.endsWith(".") ? sentence : sentence + "." + sentenceIdx++ + } } file.data.description = finalDesc From cec3662c748ff6abbe8570632e9287085a2a51fc Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:09:20 -0500 Subject: [PATCH 065/217] feat(graph): focusOnHover (#954) by default, globalGraph will enable focusOnHover, similar to Obsidian. --------- Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/components/Graph.tsx | 3 +++ quartz/components/scripts/graph.inline.ts | 27 ++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/quartz/components/Graph.tsx b/quartz/components/Graph.tsx index 40ab43a..f7ebcc9 100644 --- a/quartz/components/Graph.tsx +++ b/quartz/components/Graph.tsx @@ -17,6 +17,7 @@ export interface D3Config { opacityScale: number removeTags: string[] showTags: boolean + focusOnHover?: boolean } interface GraphOptions { @@ -37,6 +38,7 @@ const defaultOptions: GraphOptions = { opacityScale: 1, showTags: true, removeTags: [], + focusOnHover: false, }, globalGraph: { drag: true, @@ -50,6 +52,7 @@ const defaultOptions: GraphOptions = { opacityScale: 1, showTags: true, removeTags: [], + focusOnHover: true, }, } diff --git a/quartz/components/scripts/graph.inline.ts b/quartz/components/scripts/graph.inline.ts index c991e16..1c9bb5d 100644 --- a/quartz/components/scripts/graph.inline.ts +++ b/quartz/components/scripts/graph.inline.ts @@ -44,6 +44,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) { opacityScale, removeTags, showTags, + focusOnHover, } = JSON.parse(graph.dataset["cfg"]!) const data: Map = new Map( @@ -189,6 +190,8 @@ async function renderGraph(container: string, fullSlug: FullSlug) { return 2 + Math.sqrt(numLinks) } + let connectedNodes: SimpleSlug[] = [] + // draw individual nodes const node = graphNode .append("circle") @@ -202,17 +205,25 @@ async function renderGraph(container: string, fullSlug: FullSlug) { window.spaNavigate(new URL(targ, window.location.toString())) }) .on("mouseover", function (_, d) { - const neighbours: SimpleSlug[] = data.get(slug)?.links ?? [] - const neighbourNodes = d3 - .selectAll(".node") - .filter((d) => neighbours.includes(d.id)) const currentId = d.id const linkNodes = d3 .selectAll(".link") .filter((d: any) => d.source.id === currentId || d.target.id === currentId) - // highlight neighbour nodes - neighbourNodes.transition().duration(200).attr("fill", color) + 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) + } // highlight links linkNodes.transition().duration(200).attr("stroke", "var(--gray)").attr("stroke-width", 1) @@ -231,6 +242,10 @@ async function renderGraph(container: string, fullSlug: FullSlug) { .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) + } const currentId = d.id const linkNodes = d3 .selectAll(".link") From a13d8e84b250a0e0bcb5d34e52f161e796e3a2fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 12:54:21 -0800 Subject: [PATCH 066/217] chore(deps): bump lightningcss from 1.23.0 to 1.24.0 (#961) Bumps [lightningcss](https://github.com/parcel-bundler/lightningcss) from 1.23.0 to 1.24.0. - [Release notes](https://github.com/parcel-bundler/lightningcss/releases) - [Commits](https://github.com/parcel-bundler/lightningcss/compare/v1.23.0...v1.24.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 | 80 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index c720b7f..f001d87 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.23.0", + "lightningcss": "^1.24.0", "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", @@ -3032,9 +3032,9 @@ } }, "node_modules/lightningcss": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.23.0.tgz", - "integrity": "sha512-SEArWKMHhqn/0QzOtclIwH5pXIYQOUEkF8DgICd/105O+GCgd7jxjNod/QPnBCSWvpRHQBGVz5fQ9uScby03zA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.24.0.tgz", + "integrity": "sha512-y36QEEDVx4IM7/yIZNsZJMRREIu26WzTsauIysf5s76YeCmlSbRZS7aC97IGPuoFRnyZ5Wx43OBsQBFB5Ne7ng==", "dependencies": { "detect-libc": "^1.0.3" }, @@ -3046,21 +3046,21 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.23.0", - "lightningcss-darwin-x64": "1.23.0", - "lightningcss-freebsd-x64": "1.23.0", - "lightningcss-linux-arm-gnueabihf": "1.23.0", - "lightningcss-linux-arm64-gnu": "1.23.0", - "lightningcss-linux-arm64-musl": "1.23.0", - "lightningcss-linux-x64-gnu": "1.23.0", - "lightningcss-linux-x64-musl": "1.23.0", - "lightningcss-win32-x64-msvc": "1.23.0" + "lightningcss-darwin-arm64": "1.24.0", + "lightningcss-darwin-x64": "1.24.0", + "lightningcss-freebsd-x64": "1.24.0", + "lightningcss-linux-arm-gnueabihf": "1.24.0", + "lightningcss-linux-arm64-gnu": "1.24.0", + "lightningcss-linux-arm64-musl": "1.24.0", + "lightningcss-linux-x64-gnu": "1.24.0", + "lightningcss-linux-x64-musl": "1.24.0", + "lightningcss-win32-x64-msvc": "1.24.0" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.23.0.tgz", - "integrity": "sha512-kl4Pk3Q2lnE6AJ7Qaij47KNEfY2/UXRZBT/zqGA24B8qwkgllr/j7rclKOf1axcslNXvvUdztjo4Xqh39Yq1aA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.24.0.tgz", + "integrity": "sha512-rTNPkEiynOu4CfGdd5ZfVOQe2gd2idfQd4EfX1l2ZUUwd+2SwSdbb7cG4rlwfnZckbzCAygm85xkpekRE5/wFw==", "cpu": [ "arm64" ], @@ -3077,9 +3077,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.23.0.tgz", - "integrity": "sha512-KeRFCNoYfDdcolcFXvokVw+PXCapd2yHS1Diko1z1BhRz/nQuD5XyZmxjWdhmhN/zj5sH8YvWsp0/lPLVzqKpg==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.24.0.tgz", + "integrity": "sha512-4KCeF2RJjzp9xdGY8zIH68CUtptEg8uz8PfkHvsIdrP4t9t5CIgfDBhiB8AmuO75N6SofdmZexDZIKdy9vA7Ww==", "cpu": [ "x64" ], @@ -3096,9 +3096,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.23.0.tgz", - "integrity": "sha512-xhnhf0bWPuZxcqknvMDRFFo2TInrmQRWZGB0f6YoAsZX8Y+epfjHeeOIGCfAmgF0DgZxHwYc8mIR5tQU9/+ROA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.24.0.tgz", + "integrity": "sha512-FJAYlek1wXuVTsncNU0C6YD41q126dXcIUm97KAccMn9C4s/JfLSqGWT2gIzAblavPFkyGG2gIADTWp3uWfN1g==", "cpu": [ "x64" ], @@ -3115,9 +3115,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.23.0.tgz", - "integrity": "sha512-fBamf/bULvmWft9uuX+bZske236pUZEoUlaHNBjnueaCTJ/xd8eXgb0cEc7S5o0Nn6kxlauMBnqJpF70Bgq3zg==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.24.0.tgz", + "integrity": "sha512-N55K6JqzMx7C0hYUu1YmWqhkHwzEJlkQRMA6phY65noO0I1LOAvP4wBIoFWrzRE+O6zL0RmXJ2xppqyTbk3sYw==", "cpu": [ "arm" ], @@ -3134,9 +3134,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.23.0.tgz", - "integrity": "sha512-RS7sY77yVLOmZD6xW2uEHByYHhQi5JYWmgVumYY85BfNoVI3DupXSlzbw+b45A9NnVKq45+oXkiN6ouMMtTwfg==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.24.0.tgz", + "integrity": "sha512-MqqUB2TpYtFWeBvvf5KExDdClU3YGLW5bHKs50uKKootcvG9KoS7wYwd5UichS+W3mYLc5yXUPGD1DNWbLiYKw==", "cpu": [ "arm64" ], @@ -3153,9 +3153,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.23.0.tgz", - "integrity": "sha512-cU00LGb6GUXCwof6ACgSMKo3q7XYbsyTj0WsKHLi1nw7pV0NCq8nFTn6ZRBYLoKiV8t+jWl0Hv8KkgymmK5L5g==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.24.0.tgz", + "integrity": "sha512-5wn4d9tFwa5bS1ao9mLexYVJdh3nn09HNIipsII6ZF7z9ZA5J4dOEhMgKoeCl891axTGTUYd8Kxn+Hn3XUSYRQ==", "cpu": [ "arm64" ], @@ -3172,9 +3172,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.23.0.tgz", - "integrity": "sha512-q4jdx5+5NfB0/qMbXbOmuC6oo7caPnFghJbIAV90cXZqgV8Am3miZhC4p+sQVdacqxfd+3nrle4C8icR3p1AYw==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.24.0.tgz", + "integrity": "sha512-3j5MdTh+LSDF3o6uDwRjRUgw4J+IfDCVtdkUrJvKxL79qBLUujXY7CTe5X3IQDDLKEe/3wu49r8JKgxr0MfjbQ==", "cpu": [ "x64" ], @@ -3191,9 +3191,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.23.0.tgz", - "integrity": "sha512-G9Ri3qpmF4qef2CV/80dADHKXRAQeQXpQTLx7AiQrBYQHqBjB75oxqj06FCIe5g4hNCqLPnM9fsO4CyiT1sFSQ==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.24.0.tgz", + "integrity": "sha512-HI+rNnvaLz0o36z6Ki0gyG5igVGrJmzczxA5fznr6eFTj3cHORoR/j2q8ivMzNFR4UKJDkTWUH5LMhacwOHWBA==", "cpu": [ "x64" ], @@ -3210,9 +3210,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.23.0.tgz", - "integrity": "sha512-1rcBDJLU+obPPJM6qR5fgBUiCdZwZLafZM5f9kwjFLkb/UBNIzmae39uCSmh71nzPCTXZqHbvwu23OWnWEz+eg==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.24.0.tgz", + "integrity": "sha512-oeije/t7OZ5N9vSs6amyW/34wIYoBCpE6HUlsSKcP2SR1CVgx9oKEM00GtQmtqNnYiMIfsSm7+ppMb4NLtD5vg==", "cpu": [ "x64" ], diff --git a/package.json b/package.json index 38b0ca6..25d0331 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "hast-util-to-string": "^3.0.0", "is-absolute-url": "^4.0.1", "js-yaml": "^4.1.0", - "lightningcss": "^1.23.0", + "lightningcss": "^1.24.0", "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.1.0", "mdast-util-to-string": "^4.0.0", From 059dd1260e3762659530649972a220c9238bf6ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 12:55:02 -0800 Subject: [PATCH 067/217] chore(deps): bump preact-render-to-string from 6.3.1 to 6.4.0 (#960) Bumps [preact-render-to-string](https://github.com/developit/preact-render-to-string) from 6.3.1 to 6.4.0. - [Release notes](https://github.com/developit/preact-render-to-string/releases) - [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md) - [Commits](https://github.com/developit/preact-render-to-string/compare/v6.3.1...6.4.0) --- updated-dependencies: - dependency-name: preact-render-to-string 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 f001d87..b6613e4 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.19.6", - "preact-render-to-string": "^6.3.1", + "preact-render-to-string": "^6.4.0", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", @@ -4465,9 +4465,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.3.1.tgz", - "integrity": "sha512-NQ28WrjLtWY6lKDlTxnFpKHZdpjfF+oE6V4tZ0rTrunHrtZp6Dm0oFrcJalt/5PNeqJz4j1DuZDS0Y6rCBoqDA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.4.0.tgz", + "integrity": "sha512-pzDwezZaLbK371OiJjXDsZJwVOALzFX5M1wEh2Kr0pEApq5AV6bRH/DFbA/zNA7Lck/duyREPQLLvzu2G6hEQQ==", "dependencies": { "pretty-format": "^3.8.0" }, diff --git a/package.json b/package.json index 25d0331..7b8c9be 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "preact": "^10.19.6", - "preact-render-to-string": "^6.3.1", + "preact-render-to-string": "^6.4.0", "pretty-bytes": "^6.1.1", "pretty-time": "^1.1.0", "reading-time": "^1.5.0", From 83ab39c7bd00c7bdfddc303b765b73ae774e3aab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 12:55:44 -0800 Subject: [PATCH 068/217] chore(deps): bump shiki from 1.1.6 to 1.1.7 (#959) Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.1.6 to 1.1.7. - [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.1.7/packages/shiki) --- updated-dependencies: - dependency-name: shiki 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 b6613e4..8164782 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", - "shiki": "^1.1.6", + "shiki": "^1.1.7", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", @@ -743,9 +743,9 @@ } }, "node_modules/@shikijs/core": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.6.tgz", - "integrity": "sha512-kt9hhvrWTm0EPtRDIsoAZnSsFlIDBVBBI5CQewpA/NZCPin+MOKRXg+JiWc4y+8fZ/v0HzfDhu/UC+OTZGMt7A==" + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.7.tgz", + "integrity": "sha512-gTYLUIuD1UbZp/11qozD3fWpUTuMqPSf3svDMMrL0UmlGU7D9dPw/V1FonwAorCUJBltaaESxq90jrSjQyGixg==" }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", @@ -5310,11 +5310,11 @@ } }, "node_modules/shiki": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.6.tgz", - "integrity": "sha512-j4pcpvaQWHb42cHeV+W6P+X/VcK7Y2ctvEham6zB8wsuRQroT6cEMIkiUmBU2Nqg2qnHZDH6ZyRdVldcy0l6xw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.7.tgz", + "integrity": "sha512-9kUTMjZtcPH3i7vHunA6EraTPpPOITYTdA5uMrvsJRexktqP0s7P3s9HVK80b4pP42FRVe03D7fT3NmJv2yYhw==", "dependencies": { - "@shikijs/core": "1.1.6" + "@shikijs/core": "1.1.7" } }, "node_modules/signal-exit": { diff --git a/package.json b/package.json index 7b8c9be..a5fc32f 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "rfdc": "^1.3.1", "rimraf": "^5.0.5", "serve-handler": "^6.1.5", - "shiki": "^1.1.6", + "shiki": "^1.1.7", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", From 73a890ab126786cba2e0cef701601672c9b28ee2 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:37:28 -0500 Subject: [PATCH 069/217] =?UTF-8?q?revert:=20"fix(callout):=20reorder=20th?= =?UTF-8?q?e=20plugins=20to=20render=20latex=20on=20callout=E2=80=A6=20(#9?= =?UTF-8?q?65)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 018c6358c4c00be319ccc00df84f9be02e7845b4. --- quartz.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz.config.ts b/quartz.config.ts index a2eb605..2cdadb7 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -55,7 +55,6 @@ const config: QuartzConfig = { Plugin.CreatedModifiedDate({ priority: ["frontmatter", "filesystem"], }), - Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), Plugin.Latex({ renderEngine: "katex" }), Plugin.SyntaxHighlighting({ theme: { @@ -64,6 +63,7 @@ const config: QuartzConfig = { }, keepBackground: false, }), + Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }), Plugin.GitHubFlavoredMarkdown(), Plugin.TableOfContents(), Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }), From 5163504517791cb327423fff9291c91c519b27b6 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Wed, 6 Mar 2024 06:53:35 +0100 Subject: [PATCH 070/217] fix: transclude all subsections for embedded call (closes #963) (#964) --- quartz/components/renderPage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 5394d6f..9309e67 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -106,8 +106,9 @@ export function renderPage( blockRef = blockRef.slice(1) let startIdx = undefined let endIdx = undefined + let headerRegex = /h[1-6]/ for (const [i, el] of page.htmlAst.children.entries()) { - if (el.type === "element" && el.tagName.match(/h[1-6]/)) { + if (el.type === "element" && el.tagName.match(headerRegex)) { if (endIdx) { break } @@ -116,6 +117,7 @@ export function renderPage( endIdx = i } else if (el.properties?.id === blockRef) { startIdx = i + headerRegex = new RegExp(`h[1-${el.tagName.slice(-1)}]`) } } } From a506cedd7a28f9443c34487e2997e58e919b09b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:59:37 -0800 Subject: [PATCH 071/217] chore(deps-dev): bump @types/node from 20.11.19 to 20.11.24 (#958) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.19 to 20.11.24. - [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 8164782..b3e7ece 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.19", + "@types/node": "^20.11.24", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", @@ -1093,9 +1093,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", "dev": true, "dependencies": { "undici-types": "~5.26.4" diff --git a/package.json b/package.json index a5fc32f..a0feb96 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.19", + "@types/node": "^20.11.24", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", From 0ca8a2ac7ca5686598d360b247caf8c13d5036d5 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Tue, 5 Mar 2024 22:17:58 -0800 Subject: [PATCH 072/217] chore: transclude subsection without dynamic regex construction --- quartz/components/renderPage.tsx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 9309e67..7a97edb 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -19,6 +19,7 @@ interface RenderComponents { footer: QuartzComponent } +const headerRegex = new RegExp(/h[1-6]/) export function pageResources( baseDir: FullSlug | RelativeURL, staticResources: StaticResources, @@ -105,20 +106,23 @@ export function renderPage( // header transclude blockRef = blockRef.slice(1) let startIdx = undefined + let startDepth = undefined let endIdx = undefined - let headerRegex = /h[1-6]/ for (const [i, el] of page.htmlAst.children.entries()) { - if (el.type === "element" && el.tagName.match(headerRegex)) { - if (endIdx) { - break - } + // skip non-headers + if (!(el.type === "element" && el.tagName.match(headerRegex))) continue + const depth = Number(el.tagName.substring(1)) - if (startIdx !== undefined) { - endIdx = i - } else if (el.properties?.id === blockRef) { + // lookin for our blockref + if (startIdx === undefined || startDepth === undefined) { + // skip until we find the blockref that matches + if (el.properties?.id === blockRef) { startIdx = i - headerRegex = new RegExp(`h[1-${el.tagName.slice(-1)}]`) + startDepth = Number(el.tagName.substring(1)) } + } else if (depth <= startDepth) { + // looking for new header that is same level or higher + endIdx = i } } From e13cafe070885b0bc5c2642324342a8e957006b2 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Wed, 6 Mar 2024 18:45:31 +0100 Subject: [PATCH 073/217] feat: support youtube playlist iframe (#968) * feat: support youtube playlist iframe * chore: updated Youtube embed documentation to include playlists --- docs/plugins/ObsidianFlavoredMarkdown.md | 2 +- quartz/plugins/transformers/ofm.ts | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/plugins/ObsidianFlavoredMarkdown.md b/docs/plugins/ObsidianFlavoredMarkdown.md index 7700a5c..c424086 100644 --- a/docs/plugins/ObsidianFlavoredMarkdown.md +++ b/docs/plugins/ObsidianFlavoredMarkdown.md @@ -20,7 +20,7 @@ This plugin accepts the following configuration options: - `parseArrows`: If `true` (default), transforms arrow symbols into their HTML character equivalents. - `parseBlockReferences`: If `true` (default), handles block references, linking to specific content blocks. - `enableInHtmlEmbed`: If `true`, allows embedding of content directly within HTML. Defaults to `false`. -- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos using external image Markdown syntax. +- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax. - `enableVideoEmbed`: If `true` (default), enables the embedding of video files. - `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`. diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 237d683..48428af 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -123,6 +123,7 @@ const tagRegex = new RegExp( ) const blockReferenceRegex = new RegExp(/\^([-_A-Za-z0-9]+)$/, "g") const ytLinkRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/ +const ytPlaylistLinkRegex = /[?&]list=([^#?&]*)/ const videoExtensionRegex = new RegExp(/\.(mp4|webm|ogg|avi|mov|flv|wmv|mkv|mpg|mpeg|3gp|m4v)$/) const wikilinkImageEmbedRegex = new RegExp( /^(?(?!^\d*x?\d*$).*?)?(\|?\s*?(?\d+)(x(?\d+))?)?$/, @@ -574,7 +575,9 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin if (node.tagName === "img" && typeof node.properties.src === "string") { const match = node.properties.src.match(ytLinkRegex) const videoId = match && match[2].length == 11 ? match[2] : null + const playlistId = node.properties.src.match(ytPlaylistLinkRegex)?.[1] if (videoId) { + // YouTube video (with optional playlist) node.tagName = "iframe" node.properties = { class: "external-embed", @@ -582,7 +585,20 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin frameborder: 0, width: "600px", height: "350px", - src: `https://www.youtube.com/embed/${videoId}`, + src: playlistId + ? `https://www.youtube.com/embed/${videoId}?list=${playlistId}` + : `https://www.youtube.com/embed/${videoId}`, + } + } else if (playlistId) { + // YouTube playlist only. + node.tagName = "iframe" + node.properties = { + class: "external-embed", + allow: "fullscreen", + frameborder: 0, + width: "600px", + height: "350px", + src: `https://www.youtube.com/embed/videoseries?list=${playlistId}`, } } } From 001c166825575d28a07257a969081fa74668c2b5 Mon Sep 17 00:00:00 2001 From: Matt Vogel Date: Wed, 6 Mar 2024 20:25:39 -0500 Subject: [PATCH 074/217] fix(tag): move hash to sass styling only (#930) --- quartz/components/PageList.tsx | 2 +- quartz/components/RecentNotes.tsx | 2 +- quartz/components/TagList.tsx | 3 +-- quartz/plugins/transformers/ofm.ts | 2 +- quartz/styles/base.scss | 5 +++++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/quartz/components/PageList.tsx b/quartz/components/PageList.tsx index 62b77b1..1e5d232 100644 --- a/quartz/components/PageList.tsx +++ b/quartz/components/PageList.tsx @@ -63,7 +63,7 @@ export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit }: Pr class="internal tag-link" href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)} > - #{tag} + {tag} ))} diff --git a/quartz/components/RecentNotes.tsx b/quartz/components/RecentNotes.tsx index 549b025..d99878d 100644 --- a/quartz/components/RecentNotes.tsx +++ b/quartz/components/RecentNotes.tsx @@ -63,7 +63,7 @@ export default ((userOpts?: Partial) => { class="internal tag-link" href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)} > - #{tag} + {tag} ))} diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx index 04a483b..ba48098 100644 --- a/quartz/components/TagList.tsx +++ b/quartz/components/TagList.tsx @@ -9,12 +9,11 @@ const TagList: QuartzComponent = ({ fileData, displayClass }: QuartzComponentPro return (