Files
outline/shared/editor/rules/embeds.ts

93 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import MarkdownIt from "markdown-it";
import Token from "markdown-it/lib/token";
import { EmbedDescriptor } from "../embeds";
function isParagraph(token: Token) {
return token?.type === "paragraph_open";
}
function isLinkOpen(token: Token) {
return token.type === "link_open";
}
function isLinkClose(token: Token) {
return token.type === "link_close";
}
export default function linksToEmbeds(embeds: EmbedDescriptor[]) {
function isEmbed(token: Token, link: Token) {
const href = link.attrs ? link.attrs[0][1] : "";
const simpleLink = href === token.content;
if (!simpleLink) {
return false;
}
if (!embeds) {
return false;
}
for (const embed of embeds) {
const matches = embed.matcher(href);
if (matches) {
return {
...embed,
matches,
};
}
}
return false;
}
return function markdownEmbeds(md: MarkdownIt) {
md.core.ruler.after("inline", "embeds", (state) => {
const tokens = state.tokens;
let insideLink;
for (let i = 0; i < tokens.length - 1; i++) {
// once we find a paragraph, look through it's children for links
if (isParagraph(tokens[i - 1])) {
const tokenChildren = tokens[i].children || [];
for (let j = 0; j < tokenChildren.length - 1; j++) {
const current = tokenChildren[j];
if (!current) {
continue;
}
if (isLinkOpen(current)) {
insideLink = current;
continue;
}
if (isLinkClose(current)) {
insideLink = null;
continue;
}
// of hey, we found a link lets check to see if it should be
// converted to an embed
if (insideLink) {
const result = isEmbed(current, insideLink);
if (result) {
const { content } = current;
// convert to embed token
const token = new Token("embed", "iframe", 0);
token.attrSet("href", content);
// delete the inline link this makes the assumption that the
// embed is the only thing in the para.
tokens.splice(i - 1, 3, token);
break;
}
}
}
}
}
return false;
});
};
}