| | |
| | | // ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) |
| | | // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) |
| | | // (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias) |
| | | const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g") |
| | | const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)?(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g") |
| | | const highlightRegex = new RegExp(/==(.+)==/, "g") |
| | | const commentRegex = new RegExp(/%%(.+)%%/, "g") |
| | | // from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts |
| | | const calloutRegex = new RegExp(/^\[\!(\w+)\]([+-]?)/) |
| | | // (?:^| ) -> non-capturing group, tag should start be separated by a space or be the start of the line |
| | | // #(\w+) -> tag itself is # followed by a string of alpha-numeric characters |
| | | const tagRegex = new RegExp(/(?:^| )#(\w+)/, "g") |
| | | const tagRegex = new RegExp(/(?:^| )#([\w-_\/]+)/, "g") |
| | | |
| | | export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options> | undefined> = ( |
| | | userOpts, |
| | |
| | | if (opts.wikilinks) { |
| | | src = src.toString() |
| | | return src.replaceAll(wikilinkRegex, (value, ...capture) => { |
| | | const [fp, rawHeader, rawAlias] = capture |
| | | const [rawFp, rawHeader, rawAlias] = capture |
| | | const fp = rawFp ?? "" |
| | | const anchor = rawHeader?.trim().slice(1) |
| | | const displayAnchor = anchor ? `#${slugAnchor(anchor)}` : "" |
| | | const displayAlias = rawAlias ?? "" |
| | | const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? "" |
| | | const embedDisplay = value.startsWith("!") ? "!" : "" |
| | | return `${embedDisplay}[[${fp}${displayAnchor}${displayAlias}]]` |
| | | }) |
| | |
| | | plugins.push(() => { |
| | | return (tree: Root, _file) => { |
| | | findAndReplace(tree, wikilinkRegex, (value: string, ...capture: string[]) => { |
| | | let [fp, rawHeader, rawAlias] = capture |
| | | fp = fp.trim() |
| | | let [rawFp, rawHeader, rawAlias] = capture |
| | | const fp = rawFp?.trim() ?? "" |
| | | const anchor = rawHeader?.trim() ?? "" |
| | | const alias = rawAlias?.slice(1).trim() |
| | | |
| | |
| | | } |
| | | |
| | | // internal link |
| | | // const url = transformInternalLink(fp + anchor) |
| | | const url = fp + anchor |
| | | return { |
| | | type: "link", |
| | |
| | | js.push({ |
| | | script: ` |
| | | import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs'; |
| | | const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' |
| | | mermaid.initialize({ |
| | | startOnLoad: false, |
| | | securityLevel: 'loose', |
| | | theme: darkMode ? 'dark' : 'default' |
| | | }); |
| | | document.addEventListener('nav', async () => { |
| | | const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' |
| | | mermaid.initialize({ |
| | | securityLevel: 'loose', |
| | | theme: darkMode ? 'dark' : 'default' |
| | | }); |
| | | await mermaid.run({ |
| | | querySelector: '.mermaid' |
| | | }) |
| | | }); |
| | | `, |
| | | loadTime: "afterDOMReady", |