mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-31 00:34:05 -06:00
Updated parser typing + Mermaid parser
This commit is contained in:
parent
ff398d6b1d
commit
f176486cf2
@ -24,10 +24,8 @@ export const CustomDefault: QuartzParserPlugin<Partial<Options>> = (userOpts) =>
|
|||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_ctx) {
|
||||||
const plug: Pluggable = (tree: Root, _file) => {
|
const plug: Pluggable = (tree: Root, _file) => {
|
||||||
if (opts.enabled) {
|
const replacements: [RegExp, string | ReplaceFunction][] = []
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
mdastFindReplace(tree, replacements)
|
||||||
mdastFindReplace(tree, replacements)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
@ -35,9 +33,9 @@ export const CustomDefault: QuartzParserPlugin<Partial<Options>> = (userOpts) =>
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
const js = {} as JSResource
|
||||||
return { js }
|
return js
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,10 @@ export const ObsidianArrow: QuartzParserPlugin<Partial<Options>> = (userOpts) =>
|
|||||||
return {
|
return {
|
||||||
name: "ObsidianArrow",
|
name: "ObsidianArrow",
|
||||||
textTransform(_ctx, src: string | Buffer) {
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
if (src instanceof Buffer) {
|
if (opts.enabled) {
|
||||||
src = src.toString()
|
if (src instanceof Buffer) {
|
||||||
|
src = src.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
@ -60,9 +62,9 @@ export const ObsidianArrow: QuartzParserPlugin<Partial<Options>> = (userOpts) =>
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
const js = {} as JSResource
|
||||||
return { js }
|
return js
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,15 +68,16 @@ export const ObsidianCallouts: QuartzParserPlugin<Partial<Options>> = (userOpts)
|
|||||||
return {
|
return {
|
||||||
name: "ObsidianCallouts",
|
name: "ObsidianCallouts",
|
||||||
textTransform(_ctx, src: string | Buffer) {
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
if (src instanceof Buffer) {
|
if (opts.enabled) {
|
||||||
src = src.toString()
|
if (src instanceof Buffer) {
|
||||||
|
src = src.toString()
|
||||||
|
}
|
||||||
|
src = src.replace(calloutLineRegex, (value) => {
|
||||||
|
// force newline after title of callout
|
||||||
|
return value + "\n> "
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
src = src.replace(calloutLineRegex, (value) => {
|
|
||||||
// force newline after title of callout
|
|
||||||
return value + "\n> "
|
|
||||||
})
|
|
||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_ctx) {
|
||||||
@ -190,14 +191,16 @@ export const ObsidianCallouts: QuartzParserPlugin<Partial<Options>> = (userOpts)
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
if (opts.enabled) {
|
||||||
js.push({
|
const js: JSResource = {
|
||||||
script: calloutScript,
|
script: calloutScript,
|
||||||
loadTime: "afterDOMReady",
|
loadTime: "afterDOMReady",
|
||||||
contentType: "inline",
|
contentType: "inline",
|
||||||
})
|
}
|
||||||
return { js }
|
return js
|
||||||
|
}
|
||||||
|
return {} as JSResource
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,13 @@ export const ObsidianComments: QuartzParserPlugin<Partial<Options>> = (userOpts)
|
|||||||
return {
|
return {
|
||||||
name: "ObsidianComments",
|
name: "ObsidianComments",
|
||||||
textTransform(_ctx, src: string | Buffer) {
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
// do comments at text level
|
if (opts.enabled) {
|
||||||
if (src instanceof Buffer) {
|
if (src instanceof Buffer) {
|
||||||
src = src.toString()
|
src = src.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
src = src.replace(commentRegex, "")
|
src = src.replace(commentRegex, "")
|
||||||
|
}
|
||||||
|
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
@ -41,9 +42,9 @@ export const ObsidianComments: QuartzParserPlugin<Partial<Options>> = (userOpts)
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
const js = {} as JSResource
|
||||||
return { js }
|
return js
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,10 @@ export const ObsidianHighlights: QuartzParserPlugin<Partial<Options>> = (userOpt
|
|||||||
return {
|
return {
|
||||||
name: "ObsidianHighlights",
|
name: "ObsidianHighlights",
|
||||||
textTransform(_ctx, src: string | Buffer) {
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
if (src instanceof Buffer) {
|
if (opts.enabled) {
|
||||||
src = src.toString()
|
if (src instanceof Buffer) {
|
||||||
|
src = src.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return src
|
return src
|
||||||
},
|
},
|
||||||
@ -47,9 +49,9 @@ export const ObsidianHighlights: QuartzParserPlugin<Partial<Options>> = (userOpt
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
const js = {} as JSResource
|
||||||
return { js }
|
return js
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,4 +2,5 @@ export { ObsidianArrow } from "./arrows"
|
|||||||
export { ObsidianCallouts } from "./callouts"
|
export { ObsidianCallouts } from "./callouts"
|
||||||
export { ObsidianComments } from "./comments"
|
export { ObsidianComments } from "./comments"
|
||||||
export { ObsidianHighlights } from "./highlights"
|
export { ObsidianHighlights } from "./highlights"
|
||||||
|
export { ObsidianMermaid } from "./mermaid"
|
||||||
export { ObsidianWikilinks } from "./wikilinks"
|
export { ObsidianWikilinks } from "./wikilinks"
|
||||||
|
|||||||
@ -0,0 +1,78 @@
|
|||||||
|
import { QuartzParserPlugin } from "../../types"
|
||||||
|
import { JSResource } from "../../../util/resources"
|
||||||
|
import { visit } from "unist-util-visit"
|
||||||
|
import { Root, Code } from "mdast"
|
||||||
|
import { Pluggable } from "unified"
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
enabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOptions: Options = {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ObsidianMermaid: QuartzParserPlugin<Partial<Options>> = (userOpts) => {
|
||||||
|
const opts: Options = { ...defaultOptions, ...userOpts }
|
||||||
|
return {
|
||||||
|
name: "ObsidianMermaid",
|
||||||
|
textTransform(_ctx, src: string | Buffer) {
|
||||||
|
if (opts.enabled) {
|
||||||
|
if (src instanceof Buffer) {
|
||||||
|
src = src.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
},
|
||||||
|
markdownPlugins(_ctx) {
|
||||||
|
const plug: Pluggable = (tree: Root, _file) => {
|
||||||
|
if (opts.enabled) {
|
||||||
|
visit(tree, "code", (node: Code) => {
|
||||||
|
if (node.lang === "mermaid") {
|
||||||
|
node.data = {
|
||||||
|
hProperties: {
|
||||||
|
className: ["mermaid"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plug
|
||||||
|
},
|
||||||
|
htmlPlugins(_ctx) {
|
||||||
|
const plug: Pluggable = () => {}
|
||||||
|
return plug
|
||||||
|
},
|
||||||
|
externalResources() {
|
||||||
|
if (opts.enabled) {
|
||||||
|
const js: JSResource = {
|
||||||
|
script: `
|
||||||
|
let mermaidImport = undefined
|
||||||
|
document.addEventListener('nav', async () => {
|
||||||
|
if (document.querySelector("code.mermaid")) {
|
||||||
|
mermaidImport ||= await import('https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs')
|
||||||
|
const mermaid = mermaidImport.default
|
||||||
|
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: false,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
theme: darkMode ? 'dark' : 'default'
|
||||||
|
})
|
||||||
|
|
||||||
|
await mermaid.run({
|
||||||
|
querySelector: '.mermaid'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
loadTime: "afterDOMReady",
|
||||||
|
moduleType: "module",
|
||||||
|
contentType: "inline",
|
||||||
|
}
|
||||||
|
return js
|
||||||
|
}
|
||||||
|
return {} as JSResource
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -80,83 +80,79 @@ export const ObsidianWikilinks: QuartzParserPlugin<Partial<Options>> = (userOpts
|
|||||||
},
|
},
|
||||||
markdownPlugins(_ctx) {
|
markdownPlugins(_ctx) {
|
||||||
const plug: Pluggable = (tree: Root, path) => {
|
const plug: Pluggable = (tree: Root, path) => {
|
||||||
if (opts.enabled) {
|
const replacements: [RegExp, string | ReplaceFunction][] = []
|
||||||
const replacements: [RegExp, string | ReplaceFunction][] = []
|
replacements.push([
|
||||||
replacements.push([
|
wikilinkRegex,
|
||||||
wikilinkRegex,
|
(value: string, ...capture: string[]) => {
|
||||||
(value: string, ...capture: string[]) => {
|
let [rawFp, rawHeader, rawAlias] = capture
|
||||||
let [rawFp, rawHeader, rawAlias] = capture
|
const fp = rawFp?.trim() ?? ""
|
||||||
const fp = rawFp?.trim() ?? ""
|
const anchor = rawHeader?.trim() ?? ""
|
||||||
const anchor = rawHeader?.trim() ?? ""
|
const alias = rawAlias?.slice(1).trim()
|
||||||
const alias = rawAlias?.slice(1).trim()
|
|
||||||
|
|
||||||
// embed cases
|
// embed cases
|
||||||
if (value.startsWith("!")) {
|
if (value.startsWith("!")) {
|
||||||
const ext: string = path.extname(fp).toLowerCase()
|
const ext: string = path.extname(fp).toLowerCase()
|
||||||
const url = slugifyFilePath(fp as FilePath)
|
const url = slugifyFilePath(fp as FilePath)
|
||||||
if ([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp"].includes(ext)) {
|
if ([".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp"].includes(ext)) {
|
||||||
const match = wikilinkImageEmbedRegex.exec(alias ?? "")
|
const match = wikilinkImageEmbedRegex.exec(alias ?? "")
|
||||||
const alt = match?.groups?.alt ?? ""
|
const alt = match?.groups?.alt ?? ""
|
||||||
const width = match?.groups?.width ?? "auto"
|
const width = match?.groups?.width ?? "auto"
|
||||||
const height = match?.groups?.height ?? "auto"
|
const height = match?.groups?.height ?? "auto"
|
||||||
return {
|
return {
|
||||||
type: "image",
|
type: "image",
|
||||||
url,
|
url,
|
||||||
data: {
|
data: {
|
||||||
hProperties: {
|
hProperties: {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
alt,
|
alt,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
|
||||||
} else if ([".mp4", ".webm", ".ogv", ".mov", ".mkv"].includes(ext)) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<video src="${url}" controls></video>`,
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
[".mp3", ".webm", ".wav", ".m4a", ".ogg", ".3gp", ".flac"].includes(ext)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<audio src="${url}" controls></audio>`,
|
|
||||||
}
|
|
||||||
} else if ([".pdf"].includes(ext)) {
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
value: `<iframe src="${url}" class="pdf"></iframe>`,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const block = anchor
|
|
||||||
return {
|
|
||||||
type: "html",
|
|
||||||
data: { hProperties: { transclude: true } },
|
|
||||||
value: `<blockquote class="transclude" data-url="${url}" data-block="${block}" data-embed-alias="${alias}"><a href="${
|
|
||||||
url + anchor
|
|
||||||
}" class="transclude-inner">Transclude of ${url}${block}</a></blockquote>`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, fall through to regular link
|
|
||||||
}
|
|
||||||
|
|
||||||
// internal link
|
|
||||||
const url = fp + anchor
|
|
||||||
return {
|
|
||||||
type: "link",
|
|
||||||
url,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
value: alias ?? fp,
|
|
||||||
},
|
},
|
||||||
],
|
}
|
||||||
|
} else if ([".mp4", ".webm", ".ogv", ".mov", ".mkv"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<video src="${url}" controls></video>`,
|
||||||
|
}
|
||||||
|
} else if ([".mp3", ".webm", ".wav", ".m4a", ".ogg", ".3gp", ".flac"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<audio src="${url}" controls></audio>`,
|
||||||
|
}
|
||||||
|
} else if ([".pdf"].includes(ext)) {
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
value: `<iframe src="${url}" class="pdf"></iframe>`,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const block = anchor
|
||||||
|
return {
|
||||||
|
type: "html",
|
||||||
|
data: { hProperties: { transclude: true } },
|
||||||
|
value: `<blockquote class="transclude" data-url="${url}" data-block="${block}" data-embed-alias="${alias}"><a href="${
|
||||||
|
url + anchor
|
||||||
|
}" class="transclude-inner">Transclude of ${url}${block}</a></blockquote>`,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
])
|
// otherwise, fall through to regular link
|
||||||
mdastFindReplace(tree, replacements)
|
}
|
||||||
}
|
|
||||||
|
// internal link
|
||||||
|
const url = fp + anchor
|
||||||
|
return {
|
||||||
|
type: "link",
|
||||||
|
url,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
value: alias ?? fp,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
mdastFindReplace(tree, replacements)
|
||||||
}
|
}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
@ -164,9 +160,9 @@ export const ObsidianWikilinks: QuartzParserPlugin<Partial<Options>> = (userOpts
|
|||||||
const plug: Pluggable = () => {}
|
const plug: Pluggable = () => {}
|
||||||
return plug
|
return plug
|
||||||
},
|
},
|
||||||
externalResources(_ctx) {
|
externalResources() {
|
||||||
const js = [] as JSResource[]
|
const js = {} as JSResource
|
||||||
return { js }
|
return js
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import {
|
|||||||
ObsidianCallouts,
|
ObsidianCallouts,
|
||||||
ObsidianComments,
|
ObsidianComments,
|
||||||
ObsidianHighlights,
|
ObsidianHighlights,
|
||||||
|
ObsidianMermaid,
|
||||||
ObsidianWikilinks,
|
ObsidianWikilinks,
|
||||||
} from "../parsers/obsidian"
|
} from "../parsers/obsidian"
|
||||||
|
|
||||||
@ -206,6 +207,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<ObsidianO
|
|||||||
plugins.push(ObsidianHighlights({ enabled: opts.highlight }).markdownPlugins(ctx))
|
plugins.push(ObsidianHighlights({ enabled: opts.highlight }).markdownPlugins(ctx))
|
||||||
plugins.push(ObsidianArrow({ enabled: opts.parseArrows }).markdownPlugins(ctx))
|
plugins.push(ObsidianArrow({ enabled: opts.parseArrows }).markdownPlugins(ctx))
|
||||||
plugins.push(ObsidianCallouts({ enabled: opts.callouts }).markdownPlugins(ctx))
|
plugins.push(ObsidianCallouts({ enabled: opts.callouts }).markdownPlugins(ctx))
|
||||||
|
plugins.push(ObsidianMermaid({ enabled: opts.mermaid }).markdownPlugins(ctx))
|
||||||
|
|
||||||
return plugins
|
return plugins
|
||||||
},
|
},
|
||||||
@ -219,6 +221,9 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<ObsidianO
|
|||||||
externalResources() {
|
externalResources() {
|
||||||
const js: JSResource[] = []
|
const js: JSResource[] = []
|
||||||
|
|
||||||
|
js.push(ObsidianCallouts({ enabled: opts.callouts }).externalResources() as JSResource)
|
||||||
|
js.push(ObsidianMermaid({ enabled: opts.mermaid }).externalResources() as JSResource)
|
||||||
|
|
||||||
return { js }
|
return { js }
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { PluggableList, Pluggable } from "unified"
|
import { PluggableList, Pluggable } from "unified"
|
||||||
import { StaticResources } from "../util/resources"
|
import { JSResource, StaticResources } from "../util/resources"
|
||||||
import { ProcessedContent } from "./vfile"
|
import { ProcessedContent } from "./vfile"
|
||||||
import { QuartzComponent } from "../components/types"
|
import { QuartzComponent } from "../components/types"
|
||||||
import { FilePath } from "../util/path"
|
import { FilePath } from "../util/path"
|
||||||
@ -55,5 +55,5 @@ export type QuartzParserPluginInstance = {
|
|||||||
textTransform: (ctx: BuildCtx, src: string | Buffer) => string | Buffer
|
textTransform: (ctx: BuildCtx, src: string | Buffer) => string | Buffer
|
||||||
markdownPlugins: (ctx: BuildCtx) => Pluggable
|
markdownPlugins: (ctx: BuildCtx) => Pluggable
|
||||||
htmlPlugins: (ctx: BuildCtx) => Pluggable
|
htmlPlugins: (ctx: BuildCtx) => Pluggable
|
||||||
externalResources: (ctx: BuildCtx) => Partial<StaticResources>
|
externalResources: () => JSResource | string
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user