From 5b13ff21992a61eb8b03670ae1742a72703c2afe Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Wed, 5 Mar 2025 18:16:17 -0800 Subject: [PATCH] feat: support emitters defining external resources, emit link from contentindex directly --- docs/advanced/making plugins.md | 2 -- quartz/components/Head.tsx | 11 +++++++++-- quartz/components/renderPage.tsx | 1 + .../emitters/{contentIndex.ts => contentIndex.tsx} | 14 ++++++++++++++ quartz/plugins/index.ts | 6 +++++- quartz/plugins/transformers/latex.ts | 2 -- quartz/plugins/types.ts | 4 +++- quartz/util/resources.tsx | 2 ++ 8 files changed, 34 insertions(+), 8 deletions(-) rename quartz/plugins/emitters/{contentIndex.ts => contentIndex.tsx} (94%) diff --git a/docs/advanced/making plugins.md b/docs/advanced/making plugins.md index 3042737..8ed533f 100644 --- a/docs/advanced/making plugins.md +++ b/docs/advanced/making plugins.md @@ -99,8 +99,6 @@ export const Latex: QuartzTransformerPlugin = (opts?: Options) => { }, ], } - } else { - return {} } }, } diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index a1fb0f6..09156c9 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -127,7 +127,7 @@ export default (() => { } } - const { css, js } = externalResources + const { css, js, additionalHead } = externalResources const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`) const path = url.pathname as FullSlug @@ -177,7 +177,7 @@ export default (() => { )} - + {/* OG/Twitter meta tags */} @@ -213,6 +213,13 @@ export default (() => { {js .filter((resource) => resource.loadTime === "beforeDOMReady") .map((res) => JSResourceToScriptElement(res, true))} + {additionalHead.map((resource) => { + if (typeof resource === "function") { + return resource(fileData) + } else { + return resource + } + })} ) } diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 3914411..9cebaa8 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -54,6 +54,7 @@ export function pageResources( }, ...staticResources.js, ], + additionalHead: staticResources.additionalHead, } if (fileData.hasMermaidDiagram) { diff --git a/quartz/plugins/emitters/contentIndex.ts b/quartz/plugins/emitters/contentIndex.tsx similarity index 94% rename from quartz/plugins/emitters/contentIndex.ts rename to quartz/plugins/emitters/contentIndex.tsx index 5d76e08..bd609b4 100644 --- a/quartz/plugins/emitters/contentIndex.ts +++ b/quartz/plugins/emitters/contentIndex.tsx @@ -182,6 +182,20 @@ export const ContentIndex: QuartzEmitterPlugin> = (opts) => { return emitted }, + externalResources: (ctx) => { + if (opts?.enableRSS) { + return { + additionalHead: [ + , + ], + } + } + }, getQuartzComponents: () => [], } } diff --git a/quartz/plugins/index.ts b/quartz/plugins/index.ts index df9fd1d..c41157c 100644 --- a/quartz/plugins/index.ts +++ b/quartz/plugins/index.ts @@ -6,9 +6,10 @@ export function getStaticResourcesFromPlugins(ctx: BuildCtx) { const staticResources: StaticResources = { css: [], js: [], + additionalHead: [], } - for (const transformer of ctx.cfg.plugins.transformers) { + for (const transformer of [...ctx.cfg.plugins.transformers, ...ctx.cfg.plugins.emitters]) { const res = transformer.externalResources ? transformer.externalResources(ctx) : {} if (res?.js) { staticResources.js.push(...res.js) @@ -16,6 +17,9 @@ export function getStaticResourcesFromPlugins(ctx: BuildCtx) { if (res?.css) { staticResources.css.push(...res.css) } + if (res?.additionalHead) { + staticResources.additionalHead.push(...res.additionalHead) + } } // if serving locally, listen for rebuilds and reload the page diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts index 26913ba..40939d5 100644 --- a/quartz/plugins/transformers/latex.ts +++ b/quartz/plugins/transformers/latex.ts @@ -59,8 +59,6 @@ export const Latex: QuartzTransformerPlugin> = (opts) => { }, ], } - default: - return { css: [], js: [] } } }, } diff --git a/quartz/plugins/types.ts b/quartz/plugins/types.ts index 667799f..283a999 100644 --- a/quartz/plugins/types.ts +++ b/quartz/plugins/types.ts @@ -13,6 +13,7 @@ export interface PluginTypes { } type OptionType = object | undefined +type ExternalResourcesFn = (ctx: BuildCtx) => Partial | undefined export type QuartzTransformerPlugin = ( opts?: Options, ) => QuartzTransformerPluginInstance @@ -21,7 +22,7 @@ export type QuartzTransformerPluginInstance = { textTransform?: (ctx: BuildCtx, src: string) => string markdownPlugins?: (ctx: BuildCtx) => PluggableList htmlPlugins?: (ctx: BuildCtx) => PluggableList - externalResources?: (ctx: BuildCtx) => Partial + externalResources?: ExternalResourcesFn } export type QuartzFilterPlugin = ( @@ -44,4 +45,5 @@ export type QuartzEmitterPluginInstance = { content: ProcessedContent[], resources: StaticResources, ): Promise> + externalResources?: ExternalResourcesFn } diff --git a/quartz/util/resources.tsx b/quartz/util/resources.tsx index 72ae9e6..2ec8561 100644 --- a/quartz/util/resources.tsx +++ b/quartz/util/resources.tsx @@ -1,5 +1,6 @@ import { randomUUID } from "crypto" import { JSX } from "preact/jsx-runtime" +import { QuartzPluginData } from "../plugins/vfile" export type JSResource = { loadTime: "beforeDOMReady" | "afterDOMReady" @@ -62,4 +63,5 @@ export function CSSResourceToStyleElement(resource: CSSResource, preserve?: bool export interface StaticResources { css: CSSResource[] js: JSResource[] + additionalHead: (JSX.Element | ((pageData: QuartzPluginData) => JSX.Element))[] }