forked from github/quartz
feat: unified org-garden
This commit is contained in:
107
flake.nix
107
flake.nix
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
description = "Quartz org-roam dev shell and build app";
|
description = "Quartz org-roam — org notes to website";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
@@ -11,95 +11,31 @@
|
|||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
fs = pkgs.lib.fileset;
|
|
||||||
|
|
||||||
orgGardenApp = org-garden.packages.${system}.default;
|
# Re-export org-garden's packages
|
||||||
|
orgGardenPkgs = org-garden.packages.${system};
|
||||||
|
|
||||||
# Pre-fetched npm dependency tree (node_modules).
|
# Convenience aliases
|
||||||
# src is filtered to only package.json + package-lock.json so that
|
orgGardenApp = orgGardenPkgs.default;
|
||||||
# edits to Quartz source files do not invalidate this derivation.
|
|
||||||
quartzDeps = pkgs.buildNpmPackage {
|
|
||||||
pname = "quartz-deps";
|
|
||||||
version = "4.5.2";
|
|
||||||
src = fs.toSource {
|
|
||||||
root = ./.;
|
|
||||||
fileset = fs.unions [
|
|
||||||
./package.json
|
|
||||||
./package-lock.json
|
|
||||||
];
|
|
||||||
};
|
|
||||||
npmDepsHash = "sha256-7u+VlIx44B3/ivM9vLMIOn+e4TL4eS6B682vhS+Ikb4=";
|
|
||||||
dontBuild = true;
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r node_modules $out/node_modules
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# The build application wrapper script (one-shot build)
|
|
||||||
buildApp = pkgs.writeShellApplication {
|
|
||||||
name = "build";
|
|
||||||
runtimeInputs = [ pkgs.nodejs_22 ];
|
|
||||||
text = ''
|
|
||||||
NOTES_DIR="''${1:?Usage: build <path-to-notes-dir>}"
|
|
||||||
NOTES_DIR=$(realpath "$NOTES_DIR")
|
|
||||||
ORIG_CWD=$(pwd)
|
|
||||||
|
|
||||||
# Set up a writable working copy of the repo in a temp dir
|
|
||||||
WORK=$(mktemp -d)
|
|
||||||
trap 'rm -rf "$WORK"' EXIT
|
|
||||||
cp -r ${self}/. "$WORK/repo"
|
|
||||||
chmod -R u+w "$WORK/repo"
|
|
||||||
|
|
||||||
# Drop in pre-built node_modules
|
|
||||||
ln -s ${quartzDeps}/node_modules "$WORK/repo/node_modules"
|
|
||||||
|
|
||||||
# Pass paths via environment for org-garden
|
|
||||||
export QUARTZ_PATH="$WORK/repo"
|
|
||||||
export NODE_PATH="${pkgs.nodejs_22}/bin/node"
|
|
||||||
|
|
||||||
# Run org-garden build (org → md → static site)
|
|
||||||
${orgGardenApp}/bin/org-garden build "$NOTES_DIR" \
|
|
||||||
--output "$WORK/repo" \
|
|
||||||
--content-dir "$WORK/repo/content"
|
|
||||||
|
|
||||||
# Copy public output to caller's cwd
|
|
||||||
cp -r "$WORK/repo/public" "$ORIG_CWD/public"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Development server with watch + live reload
|
|
||||||
notesApp = pkgs.writeShellApplication {
|
|
||||||
name = "notes";
|
|
||||||
runtimeInputs = [ pkgs.nodejs_22 orgGardenApp ];
|
|
||||||
text = ''
|
|
||||||
NOTES_DIR="''${1:?Usage: notes <notes-dir>}"
|
|
||||||
NOTES_DIR=$(realpath "$NOTES_DIR")
|
|
||||||
|
|
||||||
# Set up writable working copy
|
|
||||||
WORK=$(mktemp -d)
|
|
||||||
trap 'rm -rf "$WORK"' EXIT
|
|
||||||
cp -r ${self}/. "$WORK/repo"
|
|
||||||
chmod -R u+w "$WORK/repo"
|
|
||||||
ln -s ${quartzDeps}/node_modules "$WORK/repo/node_modules"
|
|
||||||
|
|
||||||
# Pass paths via environment
|
|
||||||
export QUARTZ_PATH="$WORK/repo"
|
|
||||||
export NODE_PATH="${pkgs.nodejs_22}/bin/node"
|
|
||||||
|
|
||||||
# org-garden reads these internally
|
|
||||||
org-garden serve "$NOTES_DIR" \
|
|
||||||
--output "$WORK/repo" \
|
|
||||||
--content-dir "$WORK/repo/content"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
# All packages come from org-garden
|
||||||
|
packages = orgGardenPkgs // {
|
||||||
|
default = orgGardenApp;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Apps
|
||||||
|
apps = {
|
||||||
|
default = { type = "app"; program = "${orgGardenApp}/bin/org-garden"; };
|
||||||
|
org-garden = { type = "app"; program = "${orgGardenApp}/bin/org-garden"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
# Dev shell for working on the repo
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
pkgs.nodejs_22
|
pkgs.nodejs_22
|
||||||
pkgs.elixir
|
pkgs.elixir
|
||||||
pkgs.mcp-nixos
|
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
@@ -107,14 +43,5 @@
|
|||||||
elixir --version 2>/dev/null | head -1 || true
|
elixir --version 2>/dev/null | head -1 || true
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.default = buildApp;
|
|
||||||
packages.build = buildApp;
|
|
||||||
packages.notes = notesApp;
|
|
||||||
packages.org-garden = orgGardenApp;
|
|
||||||
|
|
||||||
apps.default = { type = "app"; program = "${buildApp}/bin/build"; };
|
|
||||||
apps.build = { type = "app"; program = "${buildApp}/bin/build"; };
|
|
||||||
apps.notes = { type = "app"; program = "${notesApp}/bin/notes"; };
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,18 @@
|
|||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
fs = pkgs.lib.fileset;
|
fs = pkgs.lib.fileset;
|
||||||
|
|
||||||
# Emacs with ox-hugo — needed at runtime by the escript
|
# =========================================================================
|
||||||
# (export_org_files calls `emacs --batch` with ox-hugo).
|
# Emacs with ox-hugo
|
||||||
|
# =========================================================================
|
||||||
|
# Needed at runtime by the escript (export calls `emacs --batch` with ox-hugo)
|
||||||
emacsWithOxHugo = (pkgs.emacsPackagesFor pkgs.emacs-nox).emacsWithPackages
|
emacsWithOxHugo = (pkgs.emacsPackagesFor pkgs.emacs-nox).emacsWithPackages
|
||||||
(epkgs: [ epkgs.ox-hugo ]);
|
(epkgs: [ epkgs.ox-hugo ]);
|
||||||
|
|
||||||
# Pre-fetched Hex/Mix dependencies.
|
# =========================================================================
|
||||||
# src is filtered to mix.exs + mix.lock so source edits don't
|
# Elixir Pipeline
|
||||||
# invalidate this derivation.
|
# =========================================================================
|
||||||
|
|
||||||
|
# Pre-fetched Hex/Mix dependencies
|
||||||
mixDeps = pkgs.beamPackages.fetchMixDeps {
|
mixDeps = pkgs.beamPackages.fetchMixDeps {
|
||||||
pname = "org-garden-mix-deps";
|
pname = "org-garden-mix-deps";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
@@ -33,32 +37,103 @@
|
|||||||
sha256 = "sha256-si7JAomY1HZ33m6ihUJP5i6PO39CE1clYvuMtn0CbPU=";
|
sha256 = "sha256-si7JAomY1HZ33m6ihUJP5i6PO39CE1clYvuMtn0CbPU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Compiled org-garden escript (without runtime wrappers).
|
# Compiled org-garden escript
|
||||||
# Note: escript name is org_garden (from app: :org_garden in mix.exs)
|
|
||||||
orgGardenEscript = pkgs.beamPackages.mixRelease {
|
orgGardenEscript = pkgs.beamPackages.mixRelease {
|
||||||
pname = "org-garden";
|
pname = "org-garden";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
src = ./.;
|
src = fs.toSource {
|
||||||
|
root = ./.;
|
||||||
|
fileset = fs.unions [
|
||||||
|
./mix.exs
|
||||||
|
./mix.lock
|
||||||
|
./lib
|
||||||
|
];
|
||||||
|
};
|
||||||
escriptBinName = "org_garden";
|
escriptBinName = "org_garden";
|
||||||
mixFodDeps = mixDeps;
|
mixFodDeps = mixDeps;
|
||||||
|
|
||||||
stripDebug = true;
|
stripDebug = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Wrapped org-garden that puts emacs (with ox-hugo) on PATH so
|
# =========================================================================
|
||||||
# the escript's System.cmd("emacs", ...) calls succeed.
|
# Quartz (fetched from upstream, patched)
|
||||||
|
# =========================================================================
|
||||||
|
|
||||||
|
# Pin to specific upstream commit
|
||||||
|
quartzVersion = "4.5.2";
|
||||||
|
quartzRev = "ec00a40aefca73596ab76e3ebe3a8e1129b43688";
|
||||||
|
|
||||||
|
# Fetch upstream Quartz source
|
||||||
|
quartzSrc = pkgs.fetchFromGitHub {
|
||||||
|
owner = "jackyzha0";
|
||||||
|
repo = "quartz";
|
||||||
|
rev = quartzRev;
|
||||||
|
hash = "sha256-HdtQB5+SRWiypOvAJuJa3Nodl4JHehp2Mz6Rj5gOG0w=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Apply our patches to Quartz
|
||||||
|
quartzPatched = pkgs.runCommand "quartz-patched-${quartzVersion}" {
|
||||||
|
src = quartzSrc;
|
||||||
|
} ''
|
||||||
|
cp -r $src $out
|
||||||
|
chmod -R u+w $out
|
||||||
|
cd $out
|
||||||
|
patch -p1 < ${./patches/01-glob-gitignore.patch}
|
||||||
|
patch -p1 < ${./patches/02-build-gitignore.patch}
|
||||||
|
patch -p1 < ${./patches/03-static-hugo.patch}
|
||||||
|
patch -p1 < ${./patches/04-oxhugofm-figure.patch}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Pre-fetch Quartz npm dependencies
|
||||||
|
quartzDeps = pkgs.buildNpmPackage {
|
||||||
|
pname = "org-garden-quartz-deps";
|
||||||
|
version = quartzVersion;
|
||||||
|
src = quartzPatched;
|
||||||
|
npmDepsHash = "sha256-7u+VlIx44B3/ivM9vLMIOn+e4TL4eS6B682vhS+Ikb4=";
|
||||||
|
dontBuild = true;
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r node_modules $out/node_modules
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Combined Application
|
||||||
|
# =========================================================================
|
||||||
|
|
||||||
|
# Wrapped org-garden with Quartz bundled
|
||||||
orgGardenApp = pkgs.writeShellApplication {
|
orgGardenApp = pkgs.writeShellApplication {
|
||||||
name = "org-garden";
|
name = "org-garden";
|
||||||
runtimeInputs = [ emacsWithOxHugo pkgs.inotify-tools pkgs.nodejs_22 ];
|
runtimeInputs = [ emacsWithOxHugo pkgs.inotify-tools pkgs.nodejs_22 ];
|
||||||
text = ''
|
text = ''
|
||||||
|
# Set up Quartz working directory
|
||||||
|
QUARTZ_WORK=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$QUARTZ_WORK"' EXIT
|
||||||
|
|
||||||
|
# Copy patched Quartz source
|
||||||
|
cp -r ${quartzPatched}/. "$QUARTZ_WORK/"
|
||||||
|
chmod -R u+w "$QUARTZ_WORK"
|
||||||
|
|
||||||
|
# Copy default config files
|
||||||
|
cp ${./quartz-config/quartz.config.ts} "$QUARTZ_WORK/"
|
||||||
|
cp ${./quartz-config/quartz.layout.ts} "$QUARTZ_WORK/"
|
||||||
|
cp ${./quartz-config/globals.d.ts} "$QUARTZ_WORK/"
|
||||||
|
cp ${./quartz-config/index.d.ts} "$QUARTZ_WORK/"
|
||||||
|
|
||||||
|
# Link pre-built node_modules
|
||||||
|
ln -s ${quartzDeps}/node_modules "$QUARTZ_WORK/node_modules"
|
||||||
|
|
||||||
|
export QUARTZ_PATH="$QUARTZ_WORK"
|
||||||
|
export NODE_PATH="${pkgs.nodejs_22}/bin/node"
|
||||||
|
|
||||||
exec ${orgGardenEscript}/bin/org_garden "$@"
|
exec ${orgGardenEscript}/bin/org_garden "$@"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages.default = orgGardenApp;
|
packages.default = orgGardenApp;
|
||||||
packages.escript = orgGardenEscript;
|
packages.escript = orgGardenEscript;
|
||||||
|
packages.quartz-patched = quartzPatched;
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
|||||||
19
org-garden/patches/01-glob-gitignore.patch
Normal file
19
org-garden/patches/01-glob-gitignore.patch
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
diff --git a/quartz/util/glob.ts b/quartz/util/glob.ts
|
||||||
|
index 7a71160..91fbaa7 100644
|
||||||
|
--- a/quartz/util/glob.ts
|
||||||
|
+++ b/quartz/util/glob.ts
|
||||||
|
@@ -10,12 +10,13 @@ export async function glob(
|
||||||
|
pattern: string,
|
||||||
|
cwd: string,
|
||||||
|
ignorePatterns: string[],
|
||||||
|
+ respectGitignore: boolean = true,
|
||||||
|
): Promise<FilePath[]> {
|
||||||
|
const fps = (
|
||||||
|
await globby(pattern, {
|
||||||
|
cwd,
|
||||||
|
ignore: ignorePatterns,
|
||||||
|
- gitignore: true,
|
||||||
|
+ gitignore: respectGitignore,
|
||||||
|
})
|
||||||
|
).map(toPosixPath)
|
||||||
|
return fps as FilePath[]
|
||||||
13
org-garden/patches/02-build-gitignore.patch
Normal file
13
org-garden/patches/02-build-gitignore.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/quartz/build.ts b/quartz/build.ts
|
||||||
|
index b98f4a8..3166a06 100644
|
||||||
|
--- a/quartz/build.ts
|
||||||
|
+++ b/quartz/build.ts
|
||||||
|
@@ -71,7 +71,7 @@ async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) {
|
||||||
|
console.log(`Cleaned output directory \`${output}\` in ${perf.timeSince("clean")}`)
|
||||||
|
|
||||||
|
perf.addEvent("glob")
|
||||||
|
- const allFiles = await glob("**/*.*", argv.directory, cfg.configuration.ignorePatterns)
|
||||||
|
+ const allFiles = await glob("**/*.*", argv.directory, cfg.configuration.ignorePatterns, false)
|
||||||
|
const markdownPaths = allFiles.filter((fp) => fp.endsWith(".md")).sort()
|
||||||
|
console.log(
|
||||||
|
`Found ${markdownPaths.length} input files from \`${argv.directory}\` in ${perf.timeSince("glob")}`,
|
||||||
34
org-garden/patches/03-static-hugo.patch
Normal file
34
org-garden/patches/03-static-hugo.patch
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
diff --git a/quartz/plugins/emitters/static.ts b/quartz/plugins/emitters/static.ts
|
||||||
|
index 0b45290..8b34049 100644
|
||||||
|
--- a/quartz/plugins/emitters/static.ts
|
||||||
|
+++ b/quartz/plugins/emitters/static.ts
|
||||||
|
@@ -7,6 +7,7 @@ import { dirname } from "path"
|
||||||
|
export const Static: QuartzEmitterPlugin = () => ({
|
||||||
|
name: "Static",
|
||||||
|
async *emit({ argv, cfg }) {
|
||||||
|
+ // Copy Quartz's own internal static assets (quartz/static/) → output/static/
|
||||||
|
const staticPath = joinSegments(QUARTZ, "static")
|
||||||
|
const fps = await glob("**", staticPath, cfg.configuration.ignorePatterns)
|
||||||
|
const outputStaticPath = joinSegments(argv.output, "static")
|
||||||
|
@@ -18,6 +19,21 @@ export const Static: QuartzEmitterPlugin = () => ({
|
||||||
|
await fs.promises.copyFile(src, dest)
|
||||||
|
yield dest
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Copy user-facing static assets (static/) → output/ preserving paths.
|
||||||
|
+ // This mirrors Hugo's convention: static/ox-hugo/foo.png is served at /ox-hugo/foo.png,
|
||||||
|
+ // which matches the src="/ox-hugo/..." paths that ox-hugo writes into exported markdown.
|
||||||
|
+ const userStaticPath = "static"
|
||||||
|
+ if (fs.existsSync(userStaticPath)) {
|
||||||
|
+ const userFps = await glob("**", userStaticPath, cfg.configuration.ignorePatterns, false)
|
||||||
|
+ for (const fp of userFps) {
|
||||||
|
+ const src = joinSegments(userStaticPath, fp) as FilePath
|
||||||
|
+ const dest = joinSegments(argv.output, fp) as FilePath
|
||||||
|
+ await fs.promises.mkdir(dirname(dest), { recursive: true })
|
||||||
|
+ await fs.promises.copyFile(src, dest)
|
||||||
|
+ yield dest
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
},
|
||||||
|
async *partialEmit() {},
|
||||||
|
})
|
||||||
44
org-garden/patches/04-oxhugofm-figure.patch
Normal file
44
org-garden/patches/04-oxhugofm-figure.patch
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
diff --git a/quartz/plugins/transformers/oxhugofm.ts b/quartz/plugins/transformers/oxhugofm.ts
|
||||||
|
index 303566e..4fb5e2c 100644
|
||||||
|
--- a/quartz/plugins/transformers/oxhugofm.ts
|
||||||
|
+++ b/quartz/plugins/transformers/oxhugofm.ts
|
||||||
|
@@ -27,7 +27,10 @@ const defaultOptions: Options = {
|
||||||
|
const relrefRegex = new RegExp(/\[([^\]]+)\]\(\{\{< relref "([^"]+)" >\}\}\)/, "g")
|
||||||
|
const predefinedHeadingIdRegex = new RegExp(/(.*) {#(?:.*)}/, "g")
|
||||||
|
const hugoShortcodeRegex = new RegExp(/{{(.*)}}/, "g")
|
||||||
|
-const figureTagRegex = new RegExp(/< ?figure src="(.*)" ?>/, "g")
|
||||||
|
+// Matches the full Hugo {{< figure src="..." ... >}} shortcode and captures src.
|
||||||
|
+// Must run before the generic shortcode stripper to avoid partial-match issues
|
||||||
|
+// with captions that contain HTML (e.g. <span class="figure-number">).
|
||||||
|
+const figureShortcodeRegex = new RegExp(/{{<\s*figure\b[^}]*\bsrc="([^"]*)"[^}]*>}}/, "g")
|
||||||
|
// \\\\\( -> matches \\(
|
||||||
|
// (.+?) -> Lazy match for capturing the equation
|
||||||
|
// \\\\\) -> matches \\)
|
||||||
|
@@ -70,19 +73,19 @@ export const OxHugoFlavouredMarkdown: QuartzTransformerPlugin<Partial<Options>>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (opts.removeHugoShortcode) {
|
||||||
|
+ if (opts.replaceFigureWithMdImg) {
|
||||||
|
src = src.toString()
|
||||||
|
- src = src.replaceAll(hugoShortcodeRegex, (_value, ...capture) => {
|
||||||
|
- const [scContent] = capture
|
||||||
|
- return scContent
|
||||||
|
+ src = src.replaceAll(figureShortcodeRegex, (_value, ...capture) => {
|
||||||
|
+ const [imgSrc] = capture
|
||||||
|
+ return ``
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (opts.replaceFigureWithMdImg) {
|
||||||
|
+ if (opts.removeHugoShortcode) {
|
||||||
|
src = src.toString()
|
||||||
|
- src = src.replaceAll(figureTagRegex, (_value, ...capture) => {
|
||||||
|
- const [src] = capture
|
||||||
|
- return ``
|
||||||
|
+ src = src.replaceAll(hugoShortcodeRegex, (_value, ...capture) => {
|
||||||
|
+ const [scContent] = capture
|
||||||
|
+ return scContent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
17
org-garden/quartz-config/globals.d.ts
vendored
Normal file
17
org-garden/quartz-config/globals.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export declare global {
|
||||||
|
interface Document {
|
||||||
|
addEventListener<K extends keyof CustomEventMap>(
|
||||||
|
type: K,
|
||||||
|
listener: (this: Document, ev: CustomEventMap[K]) => void,
|
||||||
|
): void
|
||||||
|
removeEventListener<K extends keyof CustomEventMap>(
|
||||||
|
type: K,
|
||||||
|
listener: (this: Document, ev: CustomEventMap[K]) => void,
|
||||||
|
): void
|
||||||
|
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K] | UIEvent): void
|
||||||
|
}
|
||||||
|
interface Window {
|
||||||
|
spaNavigate(url: URL, isBack: boolean = false)
|
||||||
|
addCleanup(fn: (...args: any[]) => void)
|
||||||
|
}
|
||||||
|
}
|
||||||
15
org-garden/quartz-config/index.d.ts
vendored
Normal file
15
org-garden/quartz-config/index.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
declare module "*.scss" {
|
||||||
|
const content: string
|
||||||
|
export = content
|
||||||
|
}
|
||||||
|
|
||||||
|
// dom custom event
|
||||||
|
interface CustomEventMap {
|
||||||
|
prenav: CustomEvent<{}>
|
||||||
|
nav: CustomEvent<{ url: FullSlug }>
|
||||||
|
themechange: CustomEvent<{ theme: "light" | "dark" }>
|
||||||
|
readermodechange: CustomEvent<{ mode: "on" | "off" }>
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContentIndex = Record<FullSlug, ContentDetails>
|
||||||
|
declare const fetchData: Promise<ContentIndex>
|
||||||
101
org-garden/quartz-config/quartz.config.ts
Normal file
101
org-garden/quartz-config/quartz.config.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { QuartzConfig } from "./quartz/cfg"
|
||||||
|
import * as Plugin from "./quartz/plugins"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quartz 4 Configuration
|
||||||
|
*
|
||||||
|
* See https://quartz.jzhao.xyz/configuration for more information.
|
||||||
|
*/
|
||||||
|
const config: QuartzConfig = {
|
||||||
|
configuration: {
|
||||||
|
pageTitle: "Quartz 4",
|
||||||
|
pageTitleSuffix: "",
|
||||||
|
enableSPA: true,
|
||||||
|
enablePopovers: true,
|
||||||
|
analytics: {
|
||||||
|
provider: "plausible",
|
||||||
|
},
|
||||||
|
locale: "en-US",
|
||||||
|
baseUrl: "quartz.jzhao.xyz",
|
||||||
|
ignorePatterns: ["private", "templates", ".obsidian"],
|
||||||
|
defaultDateType: "modified",
|
||||||
|
theme: {
|
||||||
|
fontOrigin: "googleFonts",
|
||||||
|
cdnCaching: true,
|
||||||
|
typography: {
|
||||||
|
header: "Schibsted Grotesk",
|
||||||
|
body: "Source Sans Pro",
|
||||||
|
code: "IBM Plex Mono",
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
lightMode: {
|
||||||
|
light: "#faf8f8",
|
||||||
|
lightgray: "#e5e5e5",
|
||||||
|
gray: "#b8b8b8",
|
||||||
|
darkgray: "#4e4e4e",
|
||||||
|
dark: "#2b2b2b",
|
||||||
|
secondary: "#284b63",
|
||||||
|
tertiary: "#84a59d",
|
||||||
|
highlight: "rgba(143, 159, 169, 0.15)",
|
||||||
|
textHighlight: "#fff23688",
|
||||||
|
},
|
||||||
|
darkMode: {
|
||||||
|
light: "#161618",
|
||||||
|
lightgray: "#393639",
|
||||||
|
gray: "#646464",
|
||||||
|
darkgray: "#d4d4d4",
|
||||||
|
dark: "#ebebec",
|
||||||
|
secondary: "#7b97aa",
|
||||||
|
tertiary: "#84a59d",
|
||||||
|
highlight: "rgba(143, 159, 169, 0.15)",
|
||||||
|
textHighlight: "#b3aa0288",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
transformers: [
|
||||||
|
Plugin.FrontMatter({ delimiters: "+++", language: "toml" }),
|
||||||
|
Plugin.CreatedModifiedDate({
|
||||||
|
priority: ["frontmatter", "git", "filesystem"],
|
||||||
|
}),
|
||||||
|
Plugin.SyntaxHighlighting({
|
||||||
|
theme: {
|
||||||
|
light: "github-light",
|
||||||
|
dark: "github-dark",
|
||||||
|
},
|
||||||
|
keepBackground: false,
|
||||||
|
}),
|
||||||
|
// OxHugoFlavouredMarkdown must come before GitHubFlavoredMarkdown.
|
||||||
|
// Note: not compatible with ObsidianFlavoredMarkdown — use one or the other.
|
||||||
|
// If ox-hugo exports TOML frontmatter, change FrontMatter to:
|
||||||
|
// Plugin.FrontMatter({ delims: "+++", language: "toml" })
|
||||||
|
Plugin.OxHugoFlavouredMarkdown(),
|
||||||
|
Plugin.GitHubFlavoredMarkdown(),
|
||||||
|
Plugin.TableOfContents(),
|
||||||
|
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
|
||||||
|
Plugin.Description(),
|
||||||
|
Plugin.Latex({ renderEngine: "katex" }),
|
||||||
|
],
|
||||||
|
filters: [Plugin.RemoveDrafts()],
|
||||||
|
emitters: [
|
||||||
|
Plugin.AliasRedirects(),
|
||||||
|
Plugin.ComponentResources(),
|
||||||
|
Plugin.ContentPage(),
|
||||||
|
Plugin.FolderPage(),
|
||||||
|
Plugin.TagPage(),
|
||||||
|
Plugin.ContentIndex({
|
||||||
|
enableSiteMap: true,
|
||||||
|
enableRSS: true,
|
||||||
|
}),
|
||||||
|
Plugin.Assets(),
|
||||||
|
Plugin.Static(),
|
||||||
|
Plugin.Favicon(),
|
||||||
|
Plugin.NotFoundPage(),
|
||||||
|
// Comment out CustomOgImages to speed up build time
|
||||||
|
Plugin.CustomOgImages(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
68
org-garden/quartz-config/quartz.layout.ts
Normal file
68
org-garden/quartz-config/quartz.layout.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { PageLayout, SharedLayout } from "./quartz/cfg"
|
||||||
|
import * as Component from "./quartz/components"
|
||||||
|
|
||||||
|
// components shared across all pages
|
||||||
|
export const sharedPageComponents: SharedLayout = {
|
||||||
|
head: Component.Head(),
|
||||||
|
header: [],
|
||||||
|
afterBody: [],
|
||||||
|
footer: Component.Footer({
|
||||||
|
links: {
|
||||||
|
GitHub: "https://github.com/jackyzha0/quartz",
|
||||||
|
"Discord Community": "https://discord.gg/cRFFHYye7t",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// components for pages that display a single page (e.g. a single note)
|
||||||
|
export const defaultContentPageLayout: PageLayout = {
|
||||||
|
beforeBody: [
|
||||||
|
Component.ConditionalRender({
|
||||||
|
component: Component.Breadcrumbs(),
|
||||||
|
condition: (page) => page.fileData.slug !== "index",
|
||||||
|
}),
|
||||||
|
Component.ArticleTitle(),
|
||||||
|
Component.ContentMeta(),
|
||||||
|
Component.TagList(),
|
||||||
|
],
|
||||||
|
left: [
|
||||||
|
Component.PageTitle(),
|
||||||
|
Component.MobileOnly(Component.Spacer()),
|
||||||
|
Component.Flex({
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
Component: Component.Search(),
|
||||||
|
grow: true,
|
||||||
|
},
|
||||||
|
{ Component: Component.Darkmode() },
|
||||||
|
{ Component: Component.ReaderMode() },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
Component.Explorer(),
|
||||||
|
],
|
||||||
|
right: [
|
||||||
|
Component.Graph(),
|
||||||
|
Component.DesktopOnly(Component.TableOfContents()),
|
||||||
|
Component.Backlinks(),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// components for pages that display lists of pages (e.g. tags or folders)
|
||||||
|
export const defaultListPageLayout: PageLayout = {
|
||||||
|
beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta()],
|
||||||
|
left: [
|
||||||
|
Component.PageTitle(),
|
||||||
|
Component.MobileOnly(Component.Spacer()),
|
||||||
|
Component.Flex({
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
Component: Component.Search(),
|
||||||
|
grow: true,
|
||||||
|
},
|
||||||
|
{ Component: Component.Darkmode() },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
Component.Explorer(),
|
||||||
|
],
|
||||||
|
right: [],
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user