diff --git a/docs/plugins/ObsidianFlavoredMarkdown.md b/docs/plugins/ObsidianFlavoredMarkdown.md index 414f743b8..f02425f74 100644 --- a/docs/plugins/ObsidianFlavoredMarkdown.md +++ b/docs/plugins/ObsidianFlavoredMarkdown.md @@ -23,6 +23,7 @@ This plugin accepts the following configuration options: - `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax. - `enableVideoEmbed`: If `true` (default), enables the embedding of video files. - `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`. +- `inlineFootnotes`: If `true` (default), enables parsing of inline footnotes. > [!warning] > Don't remove this plugin if you're using [[Obsidian compatibility|Obsidian]] to author the content! diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index b0b0a42ef..dc337e9fe 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -38,6 +38,7 @@ export interface Options { enableYouTubeEmbed: boolean enableVideoEmbed: boolean enableCheckbox: boolean + inlineFootnotes: boolean } const defaultOptions: Options = { @@ -53,6 +54,7 @@ const defaultOptions: Options = { enableYouTubeEmbed: true, enableVideoEmbed: true, enableCheckbox: false, + inlineFootnotes: true, } const calloutMapping = { @@ -143,6 +145,8 @@ const wikilinkImageEmbedRegex = new RegExp( /^(?(?!^\d*x?\d*$).*?)?(\|?\s*?(?\d+)(x(?\d+))?)?$/, ) +const inlineFootnoteRegex = /\^\[((?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*)\]/g + export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> = (userOpts) => { const opts = { ...defaultOptions, ...userOpts } @@ -213,6 +217,35 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> }) } + if (opts.inlineFootnotes) { + // Replaces ^[inline] footnotes with regular footnotes [^1]: + const footnotes: Record = {} + + // Replace inline footnotes with references and collect definitions + const result = (src as string).replace( + inlineFootnoteRegex, + (_match: string, content: string) => { + const id = `inline-${Object.keys(footnotes).length + 1}` + footnotes[id] = content.trim() + return `[^${id}]` + }, + ) + + // Append footnote definitions if any are found + if (Object.keys(footnotes).length > 0) { + return ( + result + + "\n\n" + + Object.entries(footnotes) + .map(([id, content]) => `[^${id}]: ${content}`) + .join("\n") + + "\n" + ) + } + + return result + } + return src }, markdownPlugins(_ctx) {