From 9d2024b11c7c24ec8112b5019504fc44b4e1a297 Mon Sep 17 00:00:00 2001
From: Jacky Zhao <j.zhao2k19@gmail.com>
Date: Tue, 13 Jun 2023 05:41:42 +0000
Subject: [PATCH] taglist, mermaid
---
/dev/null | 10 --
quartz/plugins/transformers/latex.ts | 3
quartz/resources.tsx | 28 +++++++
quartz/components/index.ts | 4
quartz/plugins/transformers/ofm.ts | 35 ++++++++
quartz/plugins/transformers/toc.ts | 4
quartz/components/Head.tsx | 3
quartz/components/TableOfContents.tsx | 45 +++++++---
quartz/path.ts | 6 -
quartz/components/TagList.tsx | 42 ++++++++++
quartz/plugins/emitters/contentPage.tsx | 8 +-
quartz.config.ts | 2
12 files changed, 149 insertions(+), 41 deletions(-)
diff --git a/quartz.config.ts b/quartz.config.ts
index d1fe184..5868449 100644
--- a/quartz.config.ts
+++ b/quartz.config.ts
@@ -58,7 +58,7 @@
Plugin.ContentPage({
head: Component.Head(),
header: [Component.PageTitle(), Component.Spacer(), Component.Darkmode()],
- body: [Component.ArticleTitle(), Component.ReadingTime(), Component.TableOfContents(), Component.Content()]
+ body: [Component.ArticleTitle(), Component.ReadingTime(), Component.TagList(), Component.TableOfContents(), Component.Content()]
})
]
},
diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx
index 16125da..cc9dd77 100644
--- a/quartz/components/Head.tsx
+++ b/quartz/components/Head.tsx
@@ -1,4 +1,5 @@
import { resolveToRoot } from "../path"
+import { JSResourceToScriptElement } from "../resources"
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
function Head({ fileData, externalResources }: QuartzComponentProps) {
@@ -25,7 +26,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
{css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" spa-preserve />)}
- {js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} {...resource} spa-preserve />)}
+ {js.filter(resource => resource.loadTime === "beforeDOMReady").map(res => JSResourceToScriptElement(res, true))}
</head>
}
diff --git a/quartz/components/TableOfContents.tsx b/quartz/components/TableOfContents.tsx
index 531c61d..19f26ef 100644
--- a/quartz/components/TableOfContents.tsx
+++ b/quartz/components/TableOfContents.tsx
@@ -1,21 +1,38 @@
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import style from "./styles/toc.scss"
-function TableOfContents({ fileData }: QuartzComponentProps) {
- if (!fileData.toc) {
- return null
- }
- return <details class="toc" open>
- <summary><h3>Table of Contents</h3></summary>
- <ul>
- {fileData.toc.map(tocEntry => <li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
- <a href={`#${tocEntry.slug}`}>{tocEntry.text}</a>
- </li>)}
- </ul>
- </details>
+interface Options {
+ layout: 'modern' | 'quartz-3'
}
-TableOfContents.css = style
+const defaultOptions: Options = {
+ layout: 'quartz-3'
+}
-export default (() => TableOfContents) satisfies QuartzComponentConstructor
+export default ((opts?: Partial<Options>) => {
+ const layout = opts?.layout ?? defaultOptions.layout
+ if (layout === "modern") {
+ return function() {
+ return null // TODO (make this look like nextra)
+ }
+ } else {
+ function TableOfContents({ fileData }: QuartzComponentProps) {
+ if (!fileData.toc) {
+ return null
+ }
+
+ return <details class="toc" open>
+ <summary><h3>Table of Contents</h3></summary>
+ <ul>
+ {fileData.toc.map(tocEntry => <li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
+ <a href={`#${tocEntry.slug}`}>{tocEntry.text}</a>
+ </li>)}
+ </ul>
+ </details>
+ }
+
+ TableOfContents.css = style
+ return TableOfContents
+ }
+}) satisfies QuartzComponentConstructor
diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx
new file mode 100644
index 0000000..a462e95
--- /dev/null
+++ b/quartz/components/TagList.tsx
@@ -0,0 +1,42 @@
+import { resolveToRoot } from "../path"
+import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
+import { slug as slugAnchor } from 'github-slugger'
+
+function TagList({ fileData }: QuartzComponentProps) {
+ const tags = fileData.frontmatter?.tags
+ const slug = fileData.slug!
+ const baseDir = resolveToRoot(slug)
+ if (tags) {
+ return <ul class="tags">{tags.map(tag => {
+ const display = `#${tag}`
+ const linkDest = baseDir + `/tags/${slugAnchor(tag)}`
+ return <li>
+ <a href={linkDest}>{display}</a>
+ </li>
+ })}</ul>
+ } else {
+ return null
+ }
+}
+
+TagList.css = `
+.tags {
+ list-style: none;
+ display: flex;
+ padding-left: 0;
+ gap: 0.4rem;
+
+ & > li {
+ display: inline-block;
+ margin: 0;
+
+ & > a {
+ border-radius: 8px;
+ border: var(--lightgray) 1px solid;
+ padding: 0.2rem 0.5rem;
+ }
+ }
+}
+`
+
+export default (() => TagList) satisfies QuartzComponentConstructor
diff --git a/quartz/components/index.ts b/quartz/components/index.ts
index 5fde7c3..72350fe 100644
--- a/quartz/components/index.ts
+++ b/quartz/components/index.ts
@@ -6,6 +6,7 @@
import ReadingTime from "./ReadingTime"
import Spacer from "./Spacer"
import TableOfContents from "./TableOfContents"
+import TagList from "./TagList"
export {
ArticleTitle,
@@ -15,5 +16,6 @@
PageTitle,
ReadingTime,
Spacer,
- TableOfContents
+ TableOfContents,
+ TagList
}
diff --git a/quartz/path.ts b/quartz/path.ts
index bece770..87f1a9d 100644
--- a/quartz/path.ts
+++ b/quartz/path.ts
@@ -1,7 +1,5 @@
import path from 'path'
-import SlugAnchor from 'github-slugger'
-
-export const slugAnchor = new SlugAnchor()
+import { slug as slugAnchor } from 'github-slugger'
function slugSegment(s: string): string {
return s.replace(/\s/g, '-')
@@ -9,7 +7,7 @@
export function slugify(s: string): string {
const [fp, anchor] = s.split("#", 2)
- const sluggedAnchor = anchor === undefined ? "" : "#" + slugAnchor.slug(anchor)
+ const sluggedAnchor = anchor === undefined ? "" : "#" + slugAnchor(anchor)
const withoutFileExt = fp.replace(new RegExp(path.extname(fp) + '$'), '')
const rawSlugSegments = withoutFileExt.split(path.sep)
const slugParts: string = rawSlugSegments
diff --git a/quartz/plugins/emitters/contentPage.tsx b/quartz/plugins/emitters/contentPage.tsx
index 9b789ef..039b5cc 100644
--- a/quartz/plugins/emitters/contentPage.tsx
+++ b/quartz/plugins/emitters/contentPage.tsx
@@ -1,4 +1,4 @@
-import { StaticResources } from "../../resources"
+import { JSResourceToScriptElement, StaticResources } from "../../resources"
import { EmitCallback, QuartzEmitterPlugin } from "../types"
import { ProcessedContent } from "../vfile"
import { render } from "preact-render-to-string"
@@ -37,9 +37,9 @@
const pageResources: StaticResources = {
css: [baseDir + "/index.css", ...resources.css],
js: [
- { src: baseDir + "/prescript.js", loadTime: "beforeDOMReady" },
+ { src: baseDir + "/prescript.js", loadTime: "beforeDOMReady", contentType: "external" },
...resources.js,
- { src: baseDir + "/postscript.js", loadTime: "afterDOMReady", type: 'module' }
+ { src: baseDir + "/postscript.js", loadTime: "afterDOMReady", moduleType: 'module', contentType: "external" }
]
}
@@ -63,7 +63,7 @@
</Body>
</div>
</body>
- {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} {...resource} />)}
+ {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))}
</html>
const fp = file.data.slug + ".html"
diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts
index 86af69f..3140ab4 100644
--- a/quartz/plugins/transformers/latex.ts
+++ b/quartz/plugins/transformers/latex.ts
@@ -23,7 +23,8 @@
{
// fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md
src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
- loadTime: "afterDOMReady"
+ loadTime: "afterDOMReady",
+ contentType: 'external'
}
]
}
diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts
index 1733b94..1b4e07a 100644
--- a/quartz/plugins/transformers/ofm.ts
+++ b/quartz/plugins/transformers/ofm.ts
@@ -1,6 +1,6 @@
import { PluggableList } from "unified"
import { QuartzTransformerPlugin } from "../types"
-import { Root, HTML, BlockContent, DefinitionContent } from 'mdast'
+import { Root, HTML, BlockContent, DefinitionContent, Code } from 'mdast'
import { findAndReplace } from "mdast-util-find-and-replace"
import { slugify } from "../../path"
import rehypeRaw from "rehype-raw"
@@ -11,12 +11,14 @@
highlight: boolean
wikilinks: boolean
callouts: boolean
+ mermaid: boolean
}
const defaultOptions: Options = {
highlight: true,
wikilinks: true,
- callouts: true
+ callouts: true,
+ mermaid: false,
}
const icons = {
@@ -246,11 +248,38 @@
}
})
}
+
+ if (opts.mermaid) {
+ plugins.push(() => {
+ return (tree: Root, _file) => {
+ visit(tree, 'code', (node: Code) => {
+ if (node.lang === 'mermaid') {
+ node.data = {
+ hProperties: {
+ className: 'mermaid'
+ }
+ }
+ }
+ })
+ }
+ })
+ }
+
return plugins
},
-
htmlPlugins() {
return [rehypeRaw]
+ },
+ externalResources: {
+ js: [{
+ script: `
+import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
+mermaid.initialize({ startOnLoad: true });
+ `,
+ loadTime: 'afterDOMReady',
+ moduleType: 'module',
+ contentType: 'inline'
+ }]
}
}
}
diff --git a/quartz/plugins/transformers/toc.ts b/quartz/plugins/transformers/toc.ts
index 2141a87..172f082 100644
--- a/quartz/plugins/transformers/toc.ts
+++ b/quartz/plugins/transformers/toc.ts
@@ -2,7 +2,7 @@
import { Root } from "mdast"
import { visit } from "unist-util-visit"
import { toString } from "mdast-util-to-string"
-import { slugAnchor } from "../../path"
+import { slug as slugAnchor } from 'github-slugger'
export interface Options {
maxDepth: 1 | 2 | 3 | 4 | 5 | 6,
@@ -40,7 +40,7 @@
toc.push({
depth: node.depth,
text,
- slug: slugAnchor.slug(text)
+ slug: slugAnchor(text)
})
}
})
diff --git a/quartz/resources.ts b/quartz/resources.ts
deleted file mode 100644
index 9de0b19..0000000
--- a/quartz/resources.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export interface JSResource {
- src: string
- loadTime: 'beforeDOMReady' | 'afterDOMReady'
- type?: 'module'
-}
-
-export interface StaticResources {
- css: string[],
- js: JSResource[]
-}
diff --git a/quartz/resources.tsx b/quartz/resources.tsx
new file mode 100644
index 0000000..78ae10b
--- /dev/null
+++ b/quartz/resources.tsx
@@ -0,0 +1,28 @@
+import { randomUUID } from "crypto"
+import { JSX } from "preact/jsx-runtime"
+
+export type JSResource = {
+ loadTime: 'beforeDOMReady' | 'afterDOMReady'
+ moduleType?: 'module'
+} & ({
+ src: string
+ contentType: 'external'
+} | {
+ script: string
+ contentType: 'inline'
+})
+
+export function JSResourceToScriptElement(resource: JSResource, preserve?: boolean): JSX.Element {
+ const scriptType = resource.moduleType ?? 'application/javascript'
+ if (resource.contentType === 'external') {
+ return <script key={resource.src} src={resource.src} type={scriptType} spa-preserve={preserve} />
+ } else {
+ const content = resource.script
+ return <script key={randomUUID()} type={scriptType} spa-preserve={preserve}>{content}</script>
+ }
+}
+
+export interface StaticResources {
+ css: string[],
+ js: JSResource[]
+}
--
Gitblit v1.10.0