Attach SVG and PNG (×2) download buttons to every rendered SVG (TikZ, Mermaid, …) once post-render finishes. Exports always use the original colors with a white background baked in, regardless of theme.
65 lines
1.5 KiB
TypeScript
65 lines
1.5 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 { attachSvgDownloads } from "@/utils/svgDownload"
|
|
|
|
interface MarkdownPostRenderOptions {
|
|
onReady?: () => void
|
|
tikz?: 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.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 }
|
|
)
|
|
}
|