2 files added
9 files modified
| | |
| | | --- |
| | | title: 🪴 Quartz 3.3 |
| | | title: Welcome to Quartz |
| | | enableToc: false |
| | | --- |
| | | |
| | |
| | | "preact-render-to-string": "^6.0.3", |
| | | "pretty-time": "^1.1.0", |
| | | "rehype-katex": "^6.0.3", |
| | | "rehype-pretty-code": "^0.9.6", |
| | | "rehype-raw": "^6.1.1", |
| | | "remark": "^14.0.2", |
| | | "remark-frontmatter": "^4.0.1", |
| | |
| | | "require-from-string": "^2.0.2", |
| | | "rimraf": "^5.0.1", |
| | | "serve-handler": "^6.1.5", |
| | | "shiki": "^0.14.2", |
| | | "to-vfile": "^7.2.4", |
| | | "unified": "^10.1.2", |
| | | "unist-util-visit": "^4.1.2", |
| | |
| | | "node": ">=8" |
| | | } |
| | | }, |
| | | "node_modules/ansi-sequence-parser": { |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", |
| | | "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" |
| | | }, |
| | | "node_modules/ansi-styles": { |
| | | "version": "4.3.0", |
| | | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", |
| | |
| | | "node": ">=8" |
| | | } |
| | | }, |
| | | "node_modules/hash-obj": { |
| | | "version": "4.0.0", |
| | | "resolved": "https://registry.npmjs.org/hash-obj/-/hash-obj-4.0.0.tgz", |
| | | "integrity": "sha512-FwO1BUVWkyHasWDW4S8o0ssQXjvyghLV2rfVhnN36b2bbcj45eGiuzdn9XOvOpjV3TKQD7Gm2BWNXdE9V4KKYg==", |
| | | "dependencies": { |
| | | "is-obj": "^3.0.0", |
| | | "sort-keys": "^5.0.0", |
| | | "type-fest": "^1.0.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/hash-obj/node_modules/type-fest": { |
| | | "version": "1.4.0", |
| | | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", |
| | | "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", |
| | | "engines": { |
| | | "node": ">=10" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/hast-util-from-dom": { |
| | | "version": "4.2.0", |
| | | "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz", |
| | |
| | | "node": ">=0.12.0" |
| | | } |
| | | }, |
| | | "node_modules/is-obj": { |
| | | "version": "3.0.0", |
| | | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", |
| | | "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", |
| | | "engines": { |
| | | "node": ">=12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/is-plain-obj": { |
| | | "version": "4.1.0", |
| | | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", |
| | |
| | | "js-yaml": "bin/js-yaml.js" |
| | | } |
| | | }, |
| | | "node_modules/jsonc-parser": { |
| | | "version": "3.2.0", |
| | | "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", |
| | | "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" |
| | | }, |
| | | "node_modules/katex": { |
| | | "version": "0.16.7", |
| | | "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.7.tgz", |
| | |
| | | "url": "https://github.com/sponsors/wooorm" |
| | | } |
| | | }, |
| | | "node_modules/parse-numeric-range": { |
| | | "version": "1.3.0", |
| | | "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", |
| | | "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" |
| | | }, |
| | | "node_modules/parse5": { |
| | | "version": "7.1.2", |
| | | "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", |
| | |
| | | "url": "https://opencollective.com/unified" |
| | | } |
| | | }, |
| | | "node_modules/rehype-pretty-code": { |
| | | "version": "0.9.6", |
| | | "resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.9.6.tgz", |
| | | "integrity": "sha512-l94QKT6w00AIJp1FsbVnbKmcEckKdYkJQfstgiSI4GTt/hSdDrnQRz6rP8r01x1rXNFC2exMG4WY0X7fOpVQGw==", |
| | | "dependencies": { |
| | | "hash-obj": "^4.0.0", |
| | | "parse-numeric-range": "^1.3.0" |
| | | }, |
| | | "engines": { |
| | | "node": "^12.16.0 || >=13.2.0" |
| | | }, |
| | | "peerDependencies": { |
| | | "shiki": "*" |
| | | } |
| | | }, |
| | | "node_modules/rehype-raw": { |
| | | "version": "6.1.1", |
| | | "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", |
| | |
| | | "node": ">=8" |
| | | } |
| | | }, |
| | | "node_modules/shiki": { |
| | | "version": "0.14.2", |
| | | "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz", |
| | | "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==", |
| | | "dependencies": { |
| | | "ansi-sequence-parser": "^1.1.0", |
| | | "jsonc-parser": "^3.2.0", |
| | | "vscode-oniguruma": "^1.7.0", |
| | | "vscode-textmate": "^8.0.0" |
| | | } |
| | | }, |
| | | "node_modules/signal-exit": { |
| | | "version": "4.0.2", |
| | | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", |
| | |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/sort-keys": { |
| | | "version": "5.0.0", |
| | | "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", |
| | | "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", |
| | | "dependencies": { |
| | | "is-plain-obj": "^4.0.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/source-map-js": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", |
| | |
| | | "url": "https://opencollective.com/unified" |
| | | } |
| | | }, |
| | | "node_modules/vscode-oniguruma": { |
| | | "version": "1.7.0", |
| | | "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", |
| | | "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" |
| | | }, |
| | | "node_modules/vscode-textmate": { |
| | | "version": "8.0.0", |
| | | "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", |
| | | "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" |
| | | }, |
| | | "node_modules/web-namespaces": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", |
| | |
| | | "preact-render-to-string": "^6.0.3", |
| | | "pretty-time": "^1.1.0", |
| | | "rehype-katex": "^6.0.3", |
| | | "rehype-pretty-code": "^0.9.6", |
| | | "rehype-raw": "^6.1.1", |
| | | "remark": "^14.0.2", |
| | | "remark-frontmatter": "^4.0.1", |
| | |
| | | "require-from-string": "^2.0.2", |
| | | "rimraf": "^5.0.1", |
| | | "serve-handler": "^6.1.5", |
| | | "shiki": "^0.14.2", |
| | | "to-vfile": "^7.2.4", |
| | | "unified": "^10.1.2", |
| | | "unist-util-visit": "^4.1.2", |
| | |
| | | import { buildQuartz } from "./quartz" |
| | | import Head from "./quartz/components/Head" |
| | | import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, ObsidianFlavoredMarkdown, RemoveDrafts, ResolveLinks } from "./quartz/plugins" |
| | | import Header from "./quartz/components/Header" |
| | | import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, ObsidianFlavoredMarkdown, RemoveDrafts, ResolveLinks, SyntaxHighlighting } from "./quartz/plugins" |
| | | |
| | | export default buildQuartz({ |
| | | configuration: { |
| | |
| | | new CreatedModifiedDate({ |
| | | priority: ['frontmatter', 'filesystem'] // you can add 'git' here for last modified from Git but this makes the build slower |
| | | }), |
| | | new SyntaxHighlighting(), |
| | | new GitHubFlavoredMarkdown(), |
| | | new ObsidianFlavoredMarkdown(), |
| | | new ResolveLinks(), |
| | |
| | | ], |
| | | emitters: [ |
| | | new ContentPage({ |
| | | Head: Head |
| | | Head: Head, |
| | | Header: Header |
| | | }) |
| | | ] |
| | | }, |
| | |
| | | format: "cjs", |
| | | jsx: "automatic", |
| | | jsxImportSource: "preact", |
| | | external: ["@napi-rs/simple-git"], |
| | | external: ["@napi-rs/simple-git", "shiki"], |
| | | plugins: [sassPlugin({ |
| | | type: 'css-text' |
| | | })] |
| New file |
| | |
| | | import { resolveToRoot } from "../path" |
| | | |
| | | export interface HeaderProps { |
| | | title: string |
| | | slug: string |
| | | } |
| | | |
| | | export default function({ title, slug }: HeaderProps) { |
| | | const baseDir = resolveToRoot(slug) |
| | | return <header> |
| | | <h1><a href={baseDir}>{title}</a></h1> |
| | | </header> |
| | | |
| | | } |
| | |
| | | import { render } from "preact-render-to-string" |
| | | import { ComponentType } from "preact" |
| | | import { HeadProps } from "../../components/Head" |
| | | |
| | | import styles from '../../styles/base.scss' |
| | | import { googleFontHref, templateThemeStyles } from "../../theme" |
| | | import { GlobalConfiguration } from "../../cfg" |
| | | import { HeaderProps } from "../../components/Header" |
| | | |
| | | import styles from '../../styles/base.scss' |
| | | |
| | | interface Options { |
| | | Head: ComponentType<HeadProps> |
| | | Header: ComponentType<HeaderProps> |
| | | } |
| | | |
| | | export class ContentPage extends QuartzEmitterPlugin { |
| | |
| | | resources.css.push(googleFontHref(cfg.theme)) |
| | | |
| | | for (const [tree, file] of content) { |
| | | |
| | | // @ts-ignore (preact makes it angry) |
| | | const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' }) |
| | | |
| | | const { Head } = this.opts |
| | | const title = file.data.frontmatter?.title |
| | | const { Head, Header } = this.opts |
| | | const doc = <html> |
| | | <Head |
| | | title={file.data.frontmatter?.title ?? "Untitled"} |
| | | title={title ?? "Untitled"} |
| | | description={file.data.description ?? "No description provided"} |
| | | slug={file.data.slug!} |
| | | externalResources={resources} /> |
| | | <body> |
| | | <div id="quartz-root" class="page"> |
| | | <header> |
| | | <h1>{file.data.frontmatter?.title}</h1> |
| | | </header> |
| | | <Header title={cfg.siteTitle} slug={file.data.slug!} /> |
| | | <article> |
| | | {file.data.slug !== "index" && <h1>{title}</h1>} |
| | | {content} |
| | | </article> |
| | | </div> |
| | |
| | | export { Description } from './description' |
| | | export { ResolveLinks } from './links' |
| | | export { ObsidianFlavoredMarkdown } from './ofm' |
| | | export { SyntaxHighlighting } from './syntax' |
| New file |
| | |
| | | import { PluggableList } from "unified" |
| | | import { QuartzTransformerPlugin } from "../types" |
| | | import rehypePrettyCode, { Options as CodeOptions } from "rehype-pretty-code" |
| | | |
| | | export class SyntaxHighlighting extends QuartzTransformerPlugin { |
| | | name = "SyntaxHighlighting" |
| | | |
| | | markdownPlugins(): PluggableList { |
| | | return [] |
| | | } |
| | | |
| | | htmlPlugins(): PluggableList { |
| | | return [[rehypePrettyCode, { |
| | | theme: 'css-variables', |
| | | onVisitLine(node) { |
| | | if (node.children.length === 0) { |
| | | node.children = [{ type: 'text', value: ' ' }] |
| | | } |
| | | }, |
| | | onVisitHighlightedLine(node) { |
| | | node.properties.className.push('highlighted') |
| | | }, |
| | | onVisitHighlightedWord(node) { |
| | | node.properties.className = ['word'] |
| | | }, |
| | | } satisfies Partial<CodeOptions>]] |
| | | } |
| | | } |
| | |
| | | margin-bottom: -0.8rem; |
| | | color: var(--darkgray); |
| | | } |
| | | } |
| | | |
| | | & pre { |
| | | font-family: var(--codeFont); |
| | | padding: 0.5rem 0; |
| | | border-radius: 5px; |
| | | overflow-x: scroll; |
| | | border: 1px solid var(--lightgray); |
| | | pre { |
| | | font-family: var(--codeFont); |
| | | padding: 0.5rem; |
| | | border-radius: 5px; |
| | | overflow-x: scroll; |
| | | border: 1px solid var(--lightgray); |
| | | |
| | | & > code { |
| | | background: none; |
| | | padding: 0; |
| | | font-size: 0.9rem; |
| | | counter-reset: line; |
| | | counter-increment: line 0; |
| | | display: grid; |
| | | & > code { |
| | | background: none; |
| | | padding: 0; |
| | | font-size: 0.9rem; |
| | | counter-reset: line; |
| | | counter-increment: line 0; |
| | | display: grid; |
| | | |
| | | & .line { |
| | | padding: 0 0.75rem; |
| | | box-sizing: border-box; |
| | | border-left: 3px solid transparent; |
| | | & .line { |
| | | padding: 0 0.25rem; |
| | | box-sizing: border-box; |
| | | border-left: 3px solid transparent; |
| | | |
| | | &.highlighted { |
| | | background-color: var(--highlight); |
| | | border-left: 3px solid var(--secondary); |
| | | } |
| | | &.highlighted { |
| | | background-color: var(--highlight); |
| | | border-left: 3px solid var(--secondary); |
| | | } |
| | | |
| | | &::before { |
| | | content: counter(line); |
| | | counter-increment: line; |
| | | width: 1rem; |
| | | margin-right: 1rem; |
| | | display: inline-block; |
| | | text-align: right; |
| | | color: rgba(115, 138, 148, 0.4); |
| | | } |
| | | &::before { |
| | | content: counter(line); |
| | | counter-increment: line; |
| | | width: 1rem; |
| | | margin-right: 1rem; |
| | | display: inline-block; |
| | | text-align: right; |
| | | color: rgba(115, 138, 148, 0.4); |
| | | } |
| | | } |
| | | } |
| | |
| | | // npx convert-sh-theme https://raw.githubusercontent.com/shikijs/shiki/main/packages/shiki/themes/github-light.json |
| | | body { |
| | | :root { |
| | | --shiki-color-text: #24292e; |
| | | --shiki-color-background: #f8f8f8; |
| | | --shiki-token-constant: #005cc5; |
| | |
| | | } |
| | | |
| | | // npx convert-sh-theme https://raw.githubusercontent.com/shikijs/shiki/main/packages/shiki/themes/github-dark.json |
| | | :root[saved-theme="dark"] body { |
| | | :root[saved-theme="dark"] { |
| | | --shiki-color-text: #e1e4e8 !important; |
| | | --shiki-color-background: #24292e !important; |
| | | --shiki-token-constant: #79b8ff !important; |