import { managedComponentHTML } from "./components/index" import { defaultOptions } from "./defaults" import type { PluginOptions } from "./types" import type MarkdownIt from "markdown-it" /** * A markdown-it plugin, which allows authors to embed content from various providers. * * @example * ```Markdown * @[A classic rick-roll](https://www.youtube.com/watch?v=dQw4w9WgXcQ "Watch this video!") * ``` * Output: * ```HTML * ``` */ export default function markdownItEmbedPlugin(md: MarkdownIt, userOptions: PluginOptions = {}) { const options = { ...defaultOptions, ...userOptions } // Token rendering rule for iframe md.renderer.rules.embed = (tokens, idx) => { const token = tokens[idx] // Dynamically get the src and title attributes from markdown-it token const src = token.attrs?.find(attr => attr[0] === "src")?.[1] ?? "" const title = token.attrs?.find(attr => attr[0] === "title")?.[1] const url = new URL(src); let html = ""; return managedComponentHTML(options, url, title); // if (options.useManagedComponents && supportsManagedComponent(url.hostname)) { // html = managedComponentHTML(options, url, title); // } else { // fallback to iframe // html = embeddedIframeHTML(options, url, title); // } // return html; } // Inline rule for matching custom syntax md.inline.ruler.before("link", "embed", (state) => { const src = state.src const reg = /@\[([^\]]+)?]\((https:\/\/[^\s"]+)(?: "([^"]+)")?\)/ const match = reg.exec(src.slice(state.pos)) if (!match) return false // Adjust state position to skip matched syntax state.pos += match[0].length // Create tokens const tokenOpen = state.push("figure_open", "figure", 1) tokenOpen.block = true tokenOpen.attrs = [["class", options.classNames!.join(" ")]] const tokenEmbed = state.push("embed", "", 0) tokenEmbed.block = true tokenEmbed.attrs = [ ["src", match[2]], ["title", match[1]] ] if (match[3]) { const tokenFigcaptionOpen = state.push("figcaption_open", "figcaption", 1) tokenFigcaptionOpen.block = true const tokenText = state.push("text", "", 0) tokenText.content = match[3] const tokenFigcaptionClose = state.push("figcaption_close", "figcaption", -1) tokenFigcaptionClose.block = true } const tokenClose = state.push("figure_close", "figure", -1) tokenClose.block = true return true }) }