Merge branch 'v4' of https://github.com/jackyzha0/quartz into markdown-parser-rework-rework

This commit is contained in:
saberzero1 2024-10-22 21:00:27 +02:00
commit 58667195c1
No known key found for this signature in database
GPG Key ID: 41AEE99107640F10
15 changed files with 306 additions and 15 deletions

View File

@ -63,6 +63,18 @@ type Options = {
category: string category: string
categoryId: string categoryId: string
// Url to folder with custom themes
// defaults to 'https://${cfg.baseUrl}/static/giscus'
themeUrl?: string
// filename for light theme .css file
// defaults to 'light'
lightTheme?: string
// filename for dark theme .css file
// defaults to 'dark'
darkTheme?: string
// how to map pages -> discussions // how to map pages -> discussions
// defaults to 'url' // defaults to 'url'
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname" mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
@ -81,3 +93,24 @@ type Options = {
} }
} }
``` ```
#### Custom CSS theme
Quartz supports custom theme for Giscus. To use a custom CSS theme, place the `.css` file inside the `quartz/static` folder and set the configuration values.
For example, if you have a light theme `light-theme.css`, a dark theme `dark-theme.css`, and your Quartz site is hosted at `https://example.com/`:
```ts
afterBody: [
Component.Comments({
provider: 'giscus',
options: {
// Other options
themeUrl: "https://example.com/static/giscus", // corresponds to quartz/static/giscus/
lightTheme: "light-theme", // corresponds to light-theme.css in quartz/static/giscus/
darkTheme: "dark-theme", // corresponds to dark-theme.css quartz/static/giscus/
}
}),
],
```

View File

@ -20,8 +20,9 @@ Want to see what Quartz can do? Here are some cool community gardens:
- [Sideny's 3D Artist's Handbook](https://sidney-eliot.github.io/3d-artists-handbook/) - [Sideny's 3D Artist's Handbook](https://sidney-eliot.github.io/3d-artists-handbook/)
- [Brandon Boswell's Garden](https://brandonkboswell.com) - [Brandon Boswell's Garden](https://brandonkboswell.com)
- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/) - [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/)
- [Simon's Second Brain: Crafted, Curated, Connected, Compounded](https://brain.ssp.sh/)
- [Data Engineering Vault: A Second Brain Knowledge Network](https://vault.ssp.sh/)
- [Data Dictionary 🧠](https://glossary.airbyte.com/) - [Data Dictionary 🧠](https://glossary.airbyte.com/)
- [sspaeti.com's Second Brain](https://brain.sspaeti.com/)
- [🪴Aster's notebook](https://notes.asterhu.com) - [🪴Aster's notebook](https://notes.asterhu.com)
- [Gatekeeper Wiki](https://www.gatekeeper.wiki) - [Gatekeeper Wiki](https://www.gatekeeper.wiki)
- [Ellie's Notes](https://ellie.wtf) - [Ellie's Notes](https://ellie.wtf)

View File

@ -457,7 +457,25 @@ export async function handleUpdate(argv) {
await popContentFolder(contentFolder) await popContentFolder(contentFolder)
console.log("Ensuring dependencies are up to date") console.log("Ensuring dependencies are up to date")
const res = spawnSync("npm", ["i"], { stdio: "inherit" })
/*
On Windows, if the command `npm` is really `npm.cmd', this call fails
as it will be unable to find `npm`. This is often the case on systems
where `npm` is installed via a package manager.
This means `npx quartz update` will not actually update dependencies
on Windows, without a manual `npm i` from the caller.
However, by spawning a shell, we are able to call `npm.cmd`.
See: https://nodejs.org/api/child_process.html#spawning-bat-and-cmd-files-on-windows
*/
const opts = { stdio: "inherit" }
if (process.platform === "win32") {
opts.shell = true
}
const res = spawnSync("npm", ["i"], opts)
if (res.status === 0) { if (res.status === 0) {
console.log(chalk.green("Done!")) console.log(chalk.green("Done!"))
} else { } else {

View File

@ -10,6 +10,9 @@ type Options = {
repoId: string repoId: string
category: string category: string
categoryId: string categoryId: string
themeUrl?: string
lightTheme?: string
darkTheme?: string
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname" mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict?: boolean strict?: boolean
reactionsEnabled?: boolean reactionsEnabled?: boolean
@ -34,6 +37,11 @@ export default ((opts: Options) => {
data-strict={boolToStringBool(opts.options.strict ?? true)} data-strict={boolToStringBool(opts.options.strict ?? true)}
data-reactions-enabled={boolToStringBool(opts.options.reactionsEnabled ?? true)} data-reactions-enabled={boolToStringBool(opts.options.reactionsEnabled ?? true)}
data-input-position={opts.options.inputPosition ?? "bottom"} data-input-position={opts.options.inputPosition ?? "bottom"}
data-light-theme={opts.options.lightTheme ?? "light"}
data-dark-theme={opts.options.darkTheme ?? "dark"}
data-theme-url={
opts.options.themeUrl ?? `https://${cfg.baseUrl ?? "example.com"}/static/giscus`
}
></div> ></div>
) )
} }

View File

@ -13,7 +13,7 @@ const changeTheme = (e: CustomEventMap["themechange"]) => {
{ {
giscus: { giscus: {
setConfig: { setConfig: {
theme: theme, theme: getThemeUrl(getThemeName(theme)),
}, },
}, },
}, },
@ -21,12 +21,36 @@ const changeTheme = (e: CustomEventMap["themechange"]) => {
) )
} }
const getThemeName = (theme: string) => {
if (theme !== "dark" && theme !== "light") {
return theme
}
const giscusContainer = document.querySelector(".giscus") as GiscusElement
if (!giscusContainer) {
return theme
}
const darkGiscus = giscusContainer.dataset.darkTheme ?? "dark"
const lightGiscus = giscusContainer.dataset.lightTheme ?? "light"
return theme === "dark" ? darkGiscus : lightGiscus
}
const getThemeUrl = (theme: string) => {
const giscusContainer = document.querySelector(".giscus") as GiscusElement
if (!giscusContainer) {
return `https://giscus.app/themes/${theme}.css`
}
return `${giscusContainer.dataset.themeUrl ?? "https://giscus.app/themes"}/${theme}.css`
}
type GiscusElement = Omit<HTMLElement, "dataset"> & { type GiscusElement = Omit<HTMLElement, "dataset"> & {
dataset: DOMStringMap & { dataset: DOMStringMap & {
repo: `${string}/${string}` repo: `${string}/${string}`
repoId: string repoId: string
category: string category: string
categoryId: string categoryId: string
themeUrl: string
lightTheme: string
darkTheme: string
mapping: "url" | "title" | "og:title" | "specific" | "number" | "pathname" mapping: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict: string strict: string
reactionsEnabled: string reactionsEnabled: string
@ -57,7 +81,7 @@ document.addEventListener("nav", () => {
const theme = document.documentElement.getAttribute("saved-theme") const theme = document.documentElement.getAttribute("saved-theme")
if (theme) { if (theme) {
giscusScript.setAttribute("data-theme", theme) giscusScript.setAttribute("data-theme", getThemeUrl(getThemeName(theme)))
} }
giscusContainer.appendChild(giscusScript) giscusContainer.appendChild(giscusScript)

View File

@ -37,7 +37,7 @@
display: none; display: none;
} }
height: auto; height: auto;
@media all and ($desktop) { @media all and not ($desktop) {
height: 250px; height: 250px;
} }
} }

View File

@ -65,7 +65,7 @@
height: 80vh; height: 80vh;
width: 80vw; width: 80vw;
@media all and ($desktop) { @media all and not ($desktop) {
width: 90%; width: 90%;
} }
} }

View File

@ -64,7 +64,7 @@
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@media all and ($desktop) { @media all and not ($desktop) {
width: 90%; width: 90%;
} }

View File

@ -1,12 +1,20 @@
@use "../../styles/variables.scss" as *;
.toc { .toc {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&.desktop-only { &.desktop-only {
display: flex;
max-height: 40%; max-height: 40%;
} }
} }
@media all and not ($mobile) {
.toc {
display: flex;
}
}
button#toc { button#toc {
background-color: transparent; background-color: transparent;
border: none; border: none;

View File

@ -3,7 +3,7 @@ import { QuartzFilterPlugin } from "../types"
export const RemoveDrafts: QuartzFilterPlugin<{}> = () => ({ export const RemoveDrafts: QuartzFilterPlugin<{}> = () => ({
name: "RemoveDrafts", name: "RemoveDrafts",
shouldPublish(_ctx, [_tree, vfile]) { shouldPublish(_ctx, [_tree, vfile]) {
const draftFlag: boolean = vfile.data?.frontmatter?.draft || false const draftFlag: boolean = vfile.data?.frontmatter?.draft === true
return !draftFlag return !draftFlag
}, },
}) })

View File

@ -3,6 +3,6 @@ import { QuartzFilterPlugin } from "../types"
export const ExplicitPublish: QuartzFilterPlugin = () => ({ export const ExplicitPublish: QuartzFilterPlugin = () => ({
name: "ExplicitPublish", name: "ExplicitPublish",
shouldPublish(_ctx, [_tree, vfile]) { shouldPublish(_ctx, [_tree, vfile]) {
return vfile.data?.frontmatter?.publish ?? false return vfile.data?.frontmatter?.publish === true
}, },
}) })

View File

@ -0,0 +1,99 @@
/*! MIT License
* Copyright (c) 2018 GitHub Inc.
* https://github.com/primer/primitives/blob/main/LICENSE
*/
main {
--color-prettylights-syntax-comment: #8b949e;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #c9d1d9;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #c9d1d9;
--color-prettylights-syntax-markup-bold: #c9d1d9;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #c9d1d9;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-brackethighlighter-angle: #8b949e;
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-btn-text: #d4d4d4; /* --darkgray */
--color-btn-bg: #161618; /* --light */
--color-btn-border: rgb(240, 246, 252 / 10%); /* --dark */
--color-btn-shadow: 0 0 transparent;
--color-btn-inset-shadow: 0 0 transparent;
--color-btn-hover-bg: #30363d;
--color-btn-hover-border: #8b949e;
--color-btn-active-bg: hsl(212deg 12% 18% / 100%);
--color-btn-active-border: #6e7681;
--color-btn-selected-bg: #161b22;
--color-btn-primary-text: #fff;
--color-btn-primary-bg: #84a59d; /* --tertiary */
--color-btn-primary-border: rgb(240, 246, 252 / 10%); /* --dark */
--color-btn-primary-shadow: 0 0 transparent;
--color-btn-primary-inset-shadow: 0 0 transparent;
--color-btn-primary-hover-bg: #7b97aa; /* --secondary */
--color-btn-primary-hover-border: rgb(240, 246, 252 / 10%); /* --dark */
--color-btn-primary-selected-bg: #7b97aa; /* --secondary */
--color-btn-primary-selected-shadow: 0 0 transparent;
--color-btn-primary-disabled-text: rgba(33, 32, 32, 0.5);
--color-btn-primary-disabled-bg: rgb(35 134 54 / 60%);
--color-btn-primary-disabled-border: rgb(240 246 252 / 10%);
--color-action-list-item-default-hover-bg: rgb(177 186 196 / 12%);
--color-segmented-control-bg: rgb(110 118 129 / 10%);
--color-segmented-control-button-bg: #0d1117;
--color-segmented-control-button-selected-border: #6e7681;
--color-fg-default: #ebebec; /* --dark */
--color-fg-muted: #d4d4d4; /* --darkgray */
--color-fg-subtle: #d4d4d4; /* --darkgray */
--color-canvas-default: #0d1117;
--color-canvas-overlay: #161b22;
--color-canvas-inset: #010409;
--color-canvas-subtle: #161b22;
--color-border-default: #30363d;
--color-border-muted: #21262d;
--color-neutral-muted: rgb(110 118 129 / 40%);
--color-accent-fg: #2f81f7;
--color-accent-emphasis: #1f6feb;
--color-accent-muted: rgb(56 139 253 / 40%);
--color-accent-subtle: rgb(56 139 253 / 10%);
--color-success-fg: #3fb950;
--color-attention-fg: #d29922;
--color-attention-muted: rgb(187 128 9 / 40%);
--color-attention-subtle: rgb(187 128 9 / 15%);
--color-danger-fg: #f85149;
--color-danger-muted: rgb(248 81 73 / 40%);
--color-danger-subtle: rgb(248 81 73 / 10%);
--color-primer-shadow-inset: 0 0 transparent;
--color-scale-gray-7: #21262d;
--color-scale-blue-8: #0c2d6b;
/*! Extensions from @primer/css/alerts/flash.scss */
--color-social-reaction-bg-hover: var(--color-scale-gray-7);
--color-social-reaction-bg-reacted-hover: var(--color-scale-blue-8);
}
main .pagination-loader-container {
background-image: url("https://github.com/images/modules/pulls/progressive-disclosure-line-dark.svg");
}
main .gsc-loading-image {
background-image: url("https://github.githubassets.com/images/mona-loading-dark.gif");
}

View File

@ -0,0 +1,99 @@
/*! MIT License
* Copyright (c) 2018 GitHub Inc.
* https://github.com/primer/primitives/blob/main/LICENSE
*/
main {
--color-prettylights-syntax-comment: #6e7781;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #8250df;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-btn-text: #4e4e4e; /* --darkgray */
--color-btn-bg: #faf8f8; /* --light */
--color-btn-border: rgb(43, 43, 43 / 15%); /* --dark */
--color-btn-shadow: 0 1px 0 rgb(31 35 40 / 4%);
--color-btn-inset-shadow: inset 0 1px 0 rgb(255 255 255 / 25%);
--color-btn-hover-bg: #f3f4f6;
--color-btn-hover-border: rgb(43, 43, 43 / 15%); /* --dark */
--color-btn-active-bg: hsl(220deg 14% 93% / 100%);
--color-btn-active-border: rgb(31 35 40 / 15%);
--color-btn-selected-bg: hsl(220deg 14% 94% / 100%);
--color-btn-primary-text: #fff;
--color-btn-primary-bg: #84a59d; /* --tertiary */
--color-btn-primary-border: rgb(43, 43, 43 / 15%); /* --dark */
--color-btn-primary-shadow: 0 1px 0 rgb(31 35 40 / 10%);
--color-btn-primary-inset-shadow: inset 0 1px 0 rgb(255 255 255 / 3%);
--color-btn-primary-hover-bg: #284b63; /* --secondary */
--color-btn-primary-hover-border: rgb(43, 43, 43 / 15%); /* --dark */
--color-btn-primary-selected-bg: #284b63; /* --secondary */
--color-btn-primary-selected-shadow: inset 0 1px 0 rgb(0 45 17 / 20%);
--color-btn-primary-disabled-text: rgb(255 255 255 / 80%);
--color-btn-primary-disabled-bg: #94d3a2;
--color-btn-primary-disabled-border: rgb(31 35 40 / 15%);
--color-action-list-item-default-hover-bg: rgb(208 215 222 / 32%);
--color-segmented-control-bg: #eaeef2;
--color-segmented-control-button-bg: #fff;
--color-segmented-control-button-selected-border: #8c959f;
--color-fg-default: #2b2b2b; /* --dark */
--color-fg-muted: #4e4e4e; /* --darkgray */
--color-fg-subtle: #4e4e4e; /* --darkgray */
--color-canvas-default: #fff;
--color-canvas-overlay: #fff;
--color-canvas-inset: #f6f8fa;
--color-canvas-subtle: #f6f8fa;
--color-border-default: #d0d7de;
--color-border-muted: hsl(210deg 18% 87% / 100%);
--color-neutral-muted: rgb(175 184 193 / 20%);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-accent-muted: rgb(84 174 255 / 40%);
--color-accent-subtle: #ddf4ff;
--color-success-fg: #1a7f37;
--color-attention-fg: #9a6700;
--color-attention-muted: rgb(212 167 44 / 40%);
--color-attention-subtle: #fff8c5;
--color-danger-fg: #d1242f;
--color-danger-muted: rgb(255 129 130 / 40%);
--color-danger-subtle: #ffebe9;
--color-primer-shadow-inset: inset 0 1px 0 rgb(208 215 222 / 20%);
--color-scale-gray-1: #eaeef2;
--color-scale-blue-1: #b6e3ff;
/*! Extensions from @primer/css/alerts/flash.scss */
--color-social-reaction-bg-hover: var(--color-scale-gray-1);
--color-social-reaction-bg-reacted-hover: var(--color-scale-blue-1);
}
main .pagination-loader-container {
background-image: url("https://github.com/images/modules/pulls/progressive-disclosure-line.svg");
}
main .gsc-loading-image {
background-image: url("https://github.githubassets.com/images/mona-loading-default.gif");
}

View File

@ -156,7 +156,7 @@ a {
column-gap: #{map-get($desktopGrid, columnGap)}; column-gap: #{map-get($desktopGrid, columnGap)};
row-gap: #{map-get($desktopGrid, rowGap)}; row-gap: #{map-get($desktopGrid, rowGap)};
grid-template-areas: #{map-get($desktopGrid, templateAreas)}; grid-template-areas: #{map-get($desktopGrid, templateAreas)};
@media all and ($desktop) { @media all and ($tablet) {
grid-template-columns: #{map-get($tabletGrid, templateColumns)}; grid-template-columns: #{map-get($tabletGrid, templateColumns)};
grid-template-rows: #{map-get($tabletGrid, templateRows)}; grid-template-rows: #{map-get($tabletGrid, templateRows)};
column-gap: #{map-get($tabletGrid, columnGap)}; column-gap: #{map-get($tabletGrid, columnGap)};
@ -171,7 +171,7 @@ a {
grid-template-areas: #{map-get($mobileGrid, templateAreas)}; grid-template-areas: #{map-get($mobileGrid, templateAreas)};
} }
@media all and ($desktop) { @media all and not ($desktop) {
padding: 0 1rem; padding: 0 1rem;
} }
@media all and ($mobile) { @media all and ($mobile) {
@ -212,7 +212,7 @@ a {
margin-left: inherit; margin-left: inherit;
margin-right: inherit; margin-right: inherit;
} }
@media all and ($desktop) { @media all and not ($desktop) {
position: initial; position: initial;
height: unset; height: unset;
width: 100%; width: 100%;
@ -254,10 +254,11 @@ a {
min-width: 100%; min-width: 100%;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@media all and ($desktop) { @media all and ($tablet) {
margin-right: 0; margin-right: 0;
} }
@media all and ($mobile) { @media all and ($mobile) {
margin-right: 0;
margin-left: 0; margin-left: 0;
} }
} }

View File

@ -12,7 +12,7 @@ $breakpoints: (
$mobile: "(max-width: #{map-get($breakpoints, mobile)})"; $mobile: "(max-width: #{map-get($breakpoints, mobile)})";
$tablet: "(min-width: #{map-get($breakpoints, mobile)}) and (max-width: #{map-get($breakpoints, desktop)})"; $tablet: "(min-width: #{map-get($breakpoints, mobile)}) and (max-width: #{map-get($breakpoints, desktop)})";
$desktop: "(max-width: #{map-get($breakpoints, desktop)})"; $desktop: "(min-width: #{map-get($breakpoints, desktop)})";
$pageWidth: #{map-get($breakpoints, mobile)}; $pageWidth: #{map-get($breakpoints, mobile)};
$sidePanelWidth: 320px; //380px; $sidePanelWidth: 320px; //380px;