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
})
}