From 78e13bcb40af99210c0c3c80becd9e2a5858a8fa Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 26 Apr 2025 11:04:23 -0700 Subject: [PATCH 1/9] chore: add ci to preview all prs (#1947) * add ci to preview all prs * only on this repo * fmt --- .github/workflows/preview.yaml | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/preview.yaml diff --git a/.github/workflows/preview.yaml b/.github/workflows/preview.yaml new file mode 100644 index 000000000..80a8a41cb --- /dev/null +++ b/.github/workflows/preview.yaml @@ -0,0 +1,46 @@ +name: Build Preview Deployment + +on: + pull_request: + types: [opened, synchronize] + workflow_dispatch: + +jobs: + build-preview: + if: ${{ github.repository == 'jackyzha0/quartz' }} + runs-on: ubuntu-latest + name: Build Preview + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - run: npm ci + + - name: Check types and style + run: npm run check + + - name: Build Quartz + run: npx quartz build -d docs -v + + - name: Publish to Cloudflare Pages + uses: AdrianGonz97/refined-cf-pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + githubToken: ${{ secrets.GITHUB_TOKEN }} + projectName: quartz + directory: public From 4bd714b7be4a5d891ab187a94e64e537cb43809e Mon Sep 17 00:00:00 2001 From: Stephen Tse Date: Sat, 26 Apr 2025 11:05:51 -0700 Subject: [PATCH 2/9] fix(callout): Grid-based callout collapsible animation (#1944) * Fixed broken nested callout maxHeight calculation * Implemented grid-based callout collapsible --- quartz/components/scripts/callout.inline.ts | 29 ++++----------- quartz/plugins/transformers/ofm.ts | 39 +++++++++++++-------- quartz/styles/callouts.scss | 14 ++++++-- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/quartz/components/scripts/callout.inline.ts b/quartz/components/scripts/callout.inline.ts index 3b7e16df3..242ce514e 100644 --- a/quartz/components/scripts/callout.inline.ts +++ b/quartz/components/scripts/callout.inline.ts @@ -1,25 +1,10 @@ function toggleCallout(this: HTMLElement) { const outerBlock = this.parentElement! outerBlock.classList.toggle("is-collapsed") + const content = outerBlock.getElementsByClassName("callout-content")[0] as HTMLElement + if (!content) return const collapsed = outerBlock.classList.contains("is-collapsed") - const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight - outerBlock.style.maxHeight = height + "px" - - // walk and adjust height of all parents - let current = outerBlock - let parent = outerBlock.parentElement - while (parent) { - if (!parent.classList.contains("callout")) { - return - } - - const collapsed = parent.classList.contains("is-collapsed") - const height = collapsed ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight - parent.style.maxHeight = height + "px" - - current = parent - parent = parent.parentElement - } + content.style.gridTemplateRows = collapsed ? "0fr" : "1fr" } function setupCallout() { @@ -27,15 +12,15 @@ function setupCallout() { `callout is-collapsible`, ) as HTMLCollectionOf for (const div of collapsible) { - const title = div.firstElementChild - if (!title) continue + const title = div.getElementsByClassName("callout-title")[0] as HTMLElement + const content = div.getElementsByClassName("callout-content")[0] as HTMLElement + if (!title || !content) continue title.addEventListener("click", toggleCallout) window.addCleanup(() => title.removeEventListener("click", toggleCallout)) const collapsed = div.classList.contains("is-collapsed") - const height = collapsed ? title.scrollHeight : div.scrollHeight - div.style.maxHeight = height + "px" + content.style.gridTemplateRows = collapsed ? "0fr" : "1fr" } } diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 983fd7327..e958027ea 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -464,6 +464,30 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> }) } + // For the rest of the MD callout elements other than the title, wrap them with + // two nested HTML
s (use some hacked mdhast component to achieve this) of + // class `callout-content` and `callout-content-inner` respectively for + // grid-based collapsible animation. + if (calloutContent.length > 0) { + node.children = [ + node.children[0], + { + data: { hProperties: { className: ["callout-content"] }, hName: "div" }, + type: "blockquote", + children: [ + { + data: { + hProperties: { className: ["callout-content-inner"] }, + hName: "div", + }, + type: "blockquote", + children: [...calloutContent], + }, + ], + }, + ] + } + // replace first line of blockquote with title and rest of the paragraph text node.children.splice(0, 1, ...blockquoteContent) @@ -485,21 +509,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> "data-callout-metadata": calloutMetaData, }, } - - // Add callout-content class to callout body if it has one. - if (calloutContent.length > 0) { - const contentData: BlockContent | DefinitionContent = { - data: { - hProperties: { - className: "callout-content", - }, - hName: "div", - }, - type: "blockquote", - children: [...calloutContent], - } - node.children = [node.children[0], contentData] - } } }) } diff --git a/quartz/styles/callouts.scss b/quartz/styles/callouts.scss index d6f65aadc..02921aed1 100644 --- a/quartz/styles/callouts.scss +++ b/quartz/styles/callouts.scss @@ -7,11 +7,19 @@ border-radius: 5px; padding: 0 1rem; overflow-y: hidden; - transition: max-height 0.3s ease; box-sizing: border-box; - & > .callout-content > :first-child { - margin-top: 0; + & > .callout-content { + display: grid; + transition: grid-template-rows 0.3s ease; + + & > .callout-content-inner { + overflow: hidden; + + & > :first-child { + margin-top: 0; + } + } } --callout-icon-note: url('data:image/svg+xml; utf8, '); From 9e58857746b74ef3e122139f7db09509435bebc8 Mon Sep 17 00:00:00 2001 From: dralagen Date: Sat, 26 Apr 2025 20:06:59 +0200 Subject: [PATCH 3/9] feat(favicon): add plugin to expose favicon from icon.png (#1942) * feat(favicon): add plugin to expose favicon from icon.png * chore(favicon): clean up formatting and remove unnecessary line breaks --- quartz.config.ts | 1 + quartz/plugins/emitters/favicon.ts | 16 ++++++++++++++++ quartz/plugins/emitters/index.ts | 1 + 3 files changed, 18 insertions(+) create mode 100644 quartz/plugins/emitters/favicon.ts diff --git a/quartz.config.ts b/quartz.config.ts index efe96485c..b3db3d60d 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -86,6 +86,7 @@ const config: QuartzConfig = { }), Plugin.Assets(), Plugin.Static(), + Plugin.Favicon(), Plugin.NotFoundPage(), // Comment out CustomOgImages to speed up build time Plugin.CustomOgImages(), diff --git a/quartz/plugins/emitters/favicon.ts b/quartz/plugins/emitters/favicon.ts new file mode 100644 index 000000000..c58322c63 --- /dev/null +++ b/quartz/plugins/emitters/favicon.ts @@ -0,0 +1,16 @@ +import sharp from "sharp" +import { joinSegments, QUARTZ, FilePath } from "../../util/path" +import { QuartzEmitterPlugin } from "../types" + +export const Favicon: QuartzEmitterPlugin = () => ({ + name: "Favicon", + async *emit({ argv }) { + const iconPath = joinSegments(QUARTZ, "static", "icon.png") + const dest = joinSegments(argv.output, "favicon.ico") as FilePath + + await sharp(iconPath).resize(48, 48).toFormat("png").toFile(dest) + + yield dest + }, + async *partialEmit() {}, +}) diff --git a/quartz/plugins/emitters/index.ts b/quartz/plugins/emitters/index.ts index 842ffb083..d2de2ed1e 100644 --- a/quartz/plugins/emitters/index.ts +++ b/quartz/plugins/emitters/index.ts @@ -5,6 +5,7 @@ export { ContentIndex as ContentIndex } from "./contentIndex" export { AliasRedirects } from "./aliases" export { Assets } from "./assets" export { Static } from "./static" +export { Favicon } from "./favicon" export { ComponentResources } from "./componentResources" export { NotFoundPage } from "./404" export { CNAME } from "./cname" From 2acdec323fe37c4d3675ada7d14832fe9d90954b Mon Sep 17 00:00:00 2001 From: Stephen Tse Date: Sat, 26 Apr 2025 11:13:56 -0700 Subject: [PATCH 4/9] fix(explorer): Prevent html from being scrollable when mobile explorer is open (#1895) * Fixed html page being scrollable when mobile explorer is open * Prettier code * Addressed comment --- quartz/components/scripts/explorer.inline.ts | 22 +++++++++++++++++++- quartz/components/styles/explorer.scss | 20 +++--------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/quartz/components/scripts/explorer.inline.ts b/quartz/components/scripts/explorer.inline.ts index b431c53c5..9c8341169 100644 --- a/quartz/components/scripts/explorer.inline.ts +++ b/quartz/components/scripts/explorer.inline.ts @@ -23,11 +23,18 @@ let currentExplorerState: Array function toggleExplorer(this: HTMLElement) { const nearestExplorer = this.closest(".explorer") as HTMLElement if (!nearestExplorer) return - nearestExplorer.classList.toggle("collapsed") + const explorerCollapsed = nearestExplorer.classList.toggle("collapsed") nearestExplorer.setAttribute( "aria-expanded", nearestExplorer.getAttribute("aria-expanded") === "true" ? "false" : "true", ) + + if (!explorerCollapsed) { + // Stop from being scrollable when mobile explorer is open + document.documentElement.classList.add("mobile-no-scroll") + } else { + document.documentElement.classList.remove("mobile-no-scroll") + } } function toggleFolder(evt: MouseEvent) { @@ -270,12 +277,25 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { if (mobileExplorer.checkVisibility()) { explorer.classList.add("collapsed") explorer.setAttribute("aria-expanded", "false") + + // Allow to be scrollable when mobile explorer is collapsed + document.documentElement.classList.remove("mobile-no-scroll") } mobileExplorer.classList.remove("hide-until-loaded") } }) +window.addEventListener("resize", function () { + // Desktop explorer opens by default, and it stays open when the window is resized + // to mobile screen size. Applies `no-scroll` to in this edge case. + const explorer = document.querySelector(".explorer") + if (explorer && !explorer.classList.contains("collapsed")) { + document.documentElement.classList.add("mobile-no-scroll") + return + } +}) + function setFolderState(folderElement: HTMLElement, collapsed: boolean) { return collapsed ? folderElement.classList.remove("open") : folderElement.classList.add("open") } diff --git a/quartz/components/styles/explorer.scss b/quartz/components/styles/explorer.scss index 55c43722f..002b086a7 100644 --- a/quartz/components/styles/explorer.scss +++ b/quartz/components/styles/explorer.scss @@ -263,22 +263,8 @@ li:has(> .folder-outer:not(.open)) > .folder-container > svg { } } -.no-scroll { - opacity: 0; - overflow: hidden; -} - -html:has(.no-scroll) { - overflow: hidden; -} - -@media all and not ($mobile) { - .no-scroll { - opacity: 1 !important; - overflow: auto !important; - } - - html:has(.no-scroll) { - overflow: auto !important; +.mobile-no-scroll { + @media all and ($mobile) { + overflow: hidden; } } From 00e860d8e687d2cd77f425b7ba77b3b591458127 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Mon, 28 Apr 2025 13:19:29 -0700 Subject: [PATCH 5/9] ci: fix fork preview --- .../{preview.yaml => build-preview.yaml} | 11 ++---- .github/workflows/deploy-preview.yaml | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) rename .github/workflows/{preview.yaml => build-preview.yaml} (72%) create mode 100644 .github/workflows/deploy-preview.yaml diff --git a/.github/workflows/preview.yaml b/.github/workflows/build-preview.yaml similarity index 72% rename from .github/workflows/preview.yaml rename to .github/workflows/build-preview.yaml index 80a8a41cb..9a4455d7c 100644 --- a/.github/workflows/preview.yaml +++ b/.github/workflows/build-preview.yaml @@ -36,11 +36,8 @@ jobs: - name: Build Quartz run: npx quartz build -d docs -v - - name: Publish to Cloudflare Pages - uses: AdrianGonz97/refined-cf-pages-action@v1 + - name: Upload build artifact + uses: actions/upload-artifact@v4 with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - githubToken: ${{ secrets.GITHUB_TOKEN }} - projectName: quartz - directory: public + name: preview-build + path: public diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml new file mode 100644 index 000000000..20a9ac3a3 --- /dev/null +++ b/.github/workflows/deploy-preview.yaml @@ -0,0 +1,37 @@ +name: Upload Preview Deployment +on: + workflow_run: + workflows: ["Build Preview Deployment"] + types: + - completed + +permissions: + actions: read + deployments: write + contents: read + pull-requests: write + +jobs: + deploy-preview: + if: ${{ github.repository == 'jackyzha0/quartz' && github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + name: Deploy Preview to Cloudflare Pages + steps: + - name: Download build artifact + uses: actions/download-artifact@v4 + id: preview-build-artifact + with: + name: preview-build + path: build + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Deploy to Cloudflare Pages + uses: AdrianGonz97/refined-cf-pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + githubToken: ${{ secrets.GITHUB_TOKEN }} + projectName: YOUR_PROJECT_NAME + deploymentName: Preview + directory: ${{ steps.preview-build-artifact.outputs.download-path }} From 32d3fc0ce8945c7d9aace2235a0f6f9663895b58 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Mon, 28 Apr 2025 14:35:51 -0700 Subject: [PATCH 6/9] chore(ci): fix proj name --- .github/workflows/deploy-preview.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml index 20a9ac3a3..3a1432ac9 100644 --- a/.github/workflows/deploy-preview.yaml +++ b/.github/workflows/deploy-preview.yaml @@ -32,6 +32,6 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} githubToken: ${{ secrets.GITHUB_TOKEN }} - projectName: YOUR_PROJECT_NAME - deploymentName: Preview + projectName: quartz + deploymentName: Branch Preview directory: ${{ steps.preview-build-artifact.outputs.download-path }} From 4d07ac93b44f0c751009ff1dda8323ee3b4c9900 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 14:41:04 -0700 Subject: [PATCH 7/9] chore(deps-dev): bump the production-dependencies group with 2 updates (#1952) Bumps the production-dependencies group with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [esbuild](https://github.com/evanw/esbuild). Updates `@types/node` from 22.14.1 to 22.15.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `esbuild` from 0.25.2 to 0.25.3 - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md) - [Commits](https://github.com/evanw/esbuild/compare/v0.25.2...v0.25.3) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.15.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: production-dependencies - dependency-name: esbuild dependency-version: 0.25.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 216 +++++++++++++++++++++++----------------------- package.json | 4 +- 2 files changed, 110 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 227e756da..0c9943f1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,12 +81,12 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.14.1", + "@types/node": "^22.15.3", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.18.1", "@types/yargs": "^17.0.33", - "esbuild": "^0.25.2", + "esbuild": "^0.25.3", "prettier": "^3.5.3", "tsx": "^4.19.3", "typescript": "^5.8.3" @@ -210,9 +210,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", "cpu": [ "ppc64" ], @@ -226,9 +226,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", "cpu": [ "arm" ], @@ -242,9 +242,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", "cpu": [ "arm64" ], @@ -258,9 +258,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", "cpu": [ "x64" ], @@ -274,9 +274,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", "cpu": [ "arm64" ], @@ -290,9 +290,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", "cpu": [ "x64" ], @@ -306,9 +306,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", "cpu": [ "arm64" ], @@ -322,9 +322,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", "cpu": [ "x64" ], @@ -338,9 +338,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", "cpu": [ "arm" ], @@ -354,9 +354,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", "cpu": [ "arm64" ], @@ -370,9 +370,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", "cpu": [ "ia32" ], @@ -386,9 +386,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", "cpu": [ "loong64" ], @@ -402,9 +402,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", "cpu": [ "mips64el" ], @@ -418,9 +418,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", "cpu": [ "ppc64" ], @@ -434,9 +434,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", "cpu": [ "riscv64" ], @@ -450,9 +450,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", "cpu": [ "s390x" ], @@ -466,9 +466,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", "cpu": [ "x64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", "cpu": [ "arm64" ], @@ -498,9 +498,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", "cpu": [ "arm64" ], @@ -530,9 +530,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", "cpu": [ "x64" ], @@ -546,9 +546,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", "cpu": [ "x64" ], @@ -562,9 +562,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", "cpu": [ "arm64" ], @@ -578,9 +578,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", "cpu": [ "ia32" ], @@ -594,9 +594,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", "cpu": [ "x64" ], @@ -1942,9 +1942,9 @@ } }, "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "version": "22.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", + "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2942,9 +2942,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -2954,31 +2954,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" } }, "node_modules/esbuild-sass-plugin": { diff --git a/package.json b/package.json index ddcb5f2a0..b137cc7d9 100644 --- a/package.json +++ b/package.json @@ -104,12 +104,12 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.14.1", + "@types/node": "^22.15.3", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.18.1", "@types/yargs": "^17.0.33", - "esbuild": "^0.25.2", + "esbuild": "^0.25.3", "prettier": "^3.5.3", "tsx": "^4.19.3", "typescript": "^5.8.3" From 8d5b13ee03533f72954037608001d5d8b3029d0f Mon Sep 17 00:00:00 2001 From: Stephen Tse Date: Mon, 28 Apr 2025 14:58:06 -0700 Subject: [PATCH 8/9] fix(fonts): Fixed page title fonts not downloadable to local (#1898) * Fixed url parser regex not working for Google Fonts subset API * Prettier no --- quartz/util/theme.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/quartz/util/theme.ts b/quartz/util/theme.ts index 4a064255f..ff4453b9f 100644 --- a/quartz/util/theme.ts +++ b/quartz/util/theme.ts @@ -107,6 +107,13 @@ export interface GoogleFontFile { extension: string } +const fontMimeMap: Record = { + truetype: "ttf", + woff: "woff", + woff2: "woff2", + opentype: "otf", +} + export async function processGoogleFonts( stylesheet: string, baseUrl: string, @@ -114,14 +121,16 @@ export async function processGoogleFonts( processedStylesheet: string fontFiles: GoogleFontFile[] }> { - const fontSourceRegex = /url\((https:\/\/fonts.gstatic.com\/s\/[^)]+\.(woff2|ttf))\)/g + const fontSourceRegex = + /url\((https:\/\/fonts.gstatic.com\/.+(?:\/|(?:kit=))(.+?)[.&].+?)\)\sformat\('(\w+?)'\);/g const fontFiles: GoogleFontFile[] = [] let processedStylesheet = stylesheet let match while ((match = fontSourceRegex.exec(stylesheet)) !== null) { const url = match[1] - const [filename, extension] = url.split("/").pop()!.split(".") + const filename = match[2] + const extension = fontMimeMap[match[3].toLowerCase()] const staticUrl = `https://${baseUrl}/static/fonts/${filename}.${extension}` processedStylesheet = processedStylesheet.replace(url, staticUrl) From 6ba9c7c02aa75e58849f334514719e31be1cf522 Mon Sep 17 00:00:00 2001 From: dralagen Date: Tue, 29 Apr 2025 07:00:28 +0200 Subject: [PATCH 9/9] doc(favicon): add documentation of favicon plugin (#1948) * doc(favicon): add documentation of favicon plugin * doc(favicon): add missing link to configuration page * fix(favicon): build on public folder don't created --- docs/plugins/Favicon.md | 19 +++++++++++++++++++ quartz/plugins/emitters/favicon.ts | 14 ++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 docs/plugins/Favicon.md diff --git a/docs/plugins/Favicon.md b/docs/plugins/Favicon.md new file mode 100644 index 000000000..a6d4d4e1b --- /dev/null +++ b/docs/plugins/Favicon.md @@ -0,0 +1,19 @@ +--- +title: Favicon +tags: + - plugin/emitter +--- + +This plugin emits a `favicon.ico` into the `public` folder. It creates the favicon from `icon.png` located in the `quartz/static` folder. +The plugin resizes `icon.png` to 48x48px to make it as small as possible. + +> [!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.Favicon()`. +- Source: [`quartz/plugins/emitters/favicon.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/favicon.ts). diff --git a/quartz/plugins/emitters/favicon.ts b/quartz/plugins/emitters/favicon.ts index c58322c63..b05f9309d 100644 --- a/quartz/plugins/emitters/favicon.ts +++ b/quartz/plugins/emitters/favicon.ts @@ -1,16 +1,22 @@ import sharp from "sharp" -import { joinSegments, QUARTZ, FilePath } from "../../util/path" +import { joinSegments, QUARTZ, FullSlug } from "../../util/path" import { QuartzEmitterPlugin } from "../types" +import { write } from "./helpers" +import { BuildCtx } from "../../util/ctx" export const Favicon: QuartzEmitterPlugin = () => ({ name: "Favicon", async *emit({ argv }) { const iconPath = joinSegments(QUARTZ, "static", "icon.png") - const dest = joinSegments(argv.output, "favicon.ico") as FilePath - await sharp(iconPath).resize(48, 48).toFormat("png").toFile(dest) + const faviconContent = sharp(iconPath).resize(48, 48).toFormat("png") - yield dest + yield write({ + ctx: { argv } as BuildCtx, + slug: "favicon" as FullSlug, + ext: ".ico", + content: faviconContent, + }) }, async *partialEmit() {}, })