Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stacklets/memory/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ COPY quartz/components/FamilyHead.tsx ./quartz/components/FamilyHead.tsx
COPY quartz/components/FamilyCrumbs.tsx ./quartz/components/FamilyCrumbs.tsx
COPY quartz/components/scripts/familyNav.inline.ts ./quartz/components/scripts/familyNav.inline.ts
COPY quartz/plugins/familyLists.tsx ./quartz/plugins/emitters/familyLists.tsx
COPY quartz/plugins/vaultLinks.ts ./quartz/plugins/transformers/vaultLinks.ts
# The shipped ontology, for the topic areas a vault installed earlier
# does not name yet (see readOntology in familyModel.ts).
COPY seeds/ontology.toml ./ontology.seed.toml
Expand Down
34 changes: 34 additions & 0 deletions stacklets/memory/quartz/plugins/vaultLinks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { QuartzTransformerPlugin } from "../types"
import { Root, Link } from "mdast"
import { visit } from "unist-util-visit"
import path from "path"

// NEW TRANSFORMER (not an upstream override).
//
// The vault writes links between its own files relative to the file,
// `[Springfield Power](../../../correspondents/springfield-power.md)`,
// because that is the form Forgejo and Obsidian resolve. CrawlLinks runs
// with markdownLinkResolution "absolute" (see quartz.config.ts) and reads
// every link as a path from the vault root, `..` included, so such a link
// lands one or more levels too high and 404s. This resolves each relative
// link against its file's directory first and hands CrawlLinks the
// root path it expects. A link that would climb out of the vault is left
// as it is.

const RELATIVE = /^\.\.?\//

export const VaultLinks: QuartzTransformerPlugin = () => ({
name: "VaultLinks",
markdownPlugins() {
return [
() => (tree: Root, file) => {
const dir = path.posix.dirname(file.data.relativePath ?? "")
visit(tree, "link", (node: Link) => {
if (!RELATIVE.test(node.url)) return
const resolved = path.posix.normalize(path.posix.join(dir, node.url))
if (!resolved.startsWith("..")) node.url = "/" + resolved
})
},
]
},
})
3 changes: 3 additions & 0 deletions stacklets/memory/quartz/quartz.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
import { FamilyLists } from "./quartz/plugins/emitters/familyLists"
import { VaultLinks } from "./quartz/plugins/transformers/vaultLinks"

// Runtime env. `WIKI_HOST` is "memory.<domain>" in domain mode and
// the empty-domain rendering "memory." in port mode — we treat the
Expand Down Expand Up @@ -136,6 +137,8 @@ const config: QuartzConfig = {
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
Plugin.GitHubFlavoredMarkdown(),
Plugin.TableOfContents(),
// Relative vault links to root paths, before CrawlLinks reads them.
VaultLinks(),
Plugin.CrawlLinks({ markdownLinkResolution: "absolute" }),
Plugin.Description(),
// MathJax, not KaTeX, and the reason is privacy rather than
Expand Down
Loading