Files
remanso/src/hooks/useMarkdownPostRender.hook.ts
Julien Calixte 1b6c7542d7
All checks were successful
CI / verify (push) Successful in 2m9s
feat(notes): render macroplan code blocks as a delivery plan grid
Follows the tikz pattern: the fence emits a base64 placeholder, then
the post-render hook lazily imports the parser and grid (separate
chunks) and mounts the grid only when a placeholder exists. Mono font
forced on the block because the flag-stacking math assumes Fira Code.
2026-07-08 00:01:21 +02:00

71 lines
1.7 KiB
TypeScript

import { nextTick, type Ref, toValue, watch } from "vue"
import { useImages } from "@/hooks/useImages.hook"
import {
runMermaid,
runTikz,
useShikiji
} from "@/hooks/useMarkdown.hook"
import { runMacroplan } from "@/modules/macroplan/runMacroplan"
import { attachSvgDownloads } from "@/utils/svgDownload"
interface MarkdownPostRenderOptions {
onReady?: () => void
tikz?: boolean
macroplan?: boolean
mermaid?: () => boolean
shikiji?: () => boolean
images?: () => string | null | undefined
triggers?: Ref<unknown>[]
}
export const useMarkdownPostRender = (
contentRef: Ref<unknown>,
scopeSelector: () => string,
options: MarkdownPostRenderOptions = {}
) => {
const sources = [contentRef, ...(options.triggers ?? [])]
watch(
sources,
async () => {
if (!toValue(contentRef)) return
await nextTick()
options.onReady?.()
const scope = scopeSelector()
const wantsTikz = !!options.tikz
const wantsMermaid = !!options.mermaid?.()
const renderJobs: Promise<unknown>[] = []
if (wantsTikz) {
renderJobs.push(runTikz(`${scope} .tikz`))
}
if (wantsMermaid) {
renderJobs.push(runMermaid(`${scope} .mermaid`))
}
if (options.macroplan) {
renderJobs.push(runMacroplan(`${scope} .macroplan-block`))
}
if (options.shikiji?.()) {
void useShikiji()
}
const imagesSha = options.images?.()
if (imagesSha) {
useImages(imagesSha)
}
if (wantsTikz || wantsMermaid) {
await Promise.allSettled(renderJobs)
await nextTick()
attachSvgDownloads(document.querySelector(scope))
}
},
{ immediate: true }
)
}