@churchapps/apphelper-markdown
Version:
ChurchApps markdown/lexical editor components
65 lines (64 loc) • 2.86 kB
JavaScript
import { $createTextNode, $isTextNode } from "lexical";
import { $isCustomLinkNode, CustomLinkNode, $createCustomLinkNode } from "./CustomLinkNode";
import { EmojiNode, $createEmojiNode } from "../emoji/EmojiNode";
import iconNamesList from '../../IconNamesList';
const CUSTOM_LINK_NODE_MARKDOWN_REGEX_QUERY = /(?:\[([^[]+?)\])(?:\(([^(]+)\))(?:({([^}]*)})?)(?:((.*)\)?))$/;
const CUSTOM_LINK_NODE_MARKDOWN_REGEX = new RegExp(CUSTOM_LINK_NODE_MARKDOWN_REGEX_QUERY);
const replaceCustomLinkNode = (textNode, match) => {
let linkUrl = match[2], linkText = match[1];
if (match.input.length > match.input.trim().length) {
linkText = ' '.repeat(match.input.length - match.input.trim().length) + linkText;
}
const otherText = match[5];
const linkNode = $createCustomLinkNode(linkUrl, match[4] ? (match[4].includes("_self") ? "_self" : "_blank") : "_blank", match[4]
? match[4]
.split(" ")
.filter((word) => word[0] === ".")
.map((word) => word.replace(".", ""))
: []);
const linkTextNode = $createTextNode(linkText);
linkTextNode.setFormat(textNode.getFormat());
linkNode.append(linkTextNode);
textNode.replace(linkNode);
const emojiText = otherText.replace(CUSTOM_LINK_NODE_MARKDOWN_REGEX, '').trim();
if (match[5]) {
const otherTextNode = $createTextNode(match[5].replace(CUSTOM_LINK_NODE_MARKDOWN_REGEX, ''));
linkNode.getParent().append(otherTextNode);
}
if (CUSTOM_LINK_NODE_MARKDOWN_REGEX.test(match[5])) {
const blankNode = $createTextNode("");
linkNode.getParent().append(blankNode);
replaceCustomLinkNode(blankNode, match[5].match(CUSTOM_LINK_NODE_MARKDOWN_REGEX_QUERY));
}
if (emojiText) {
if (!iconNamesList.includes(emojiText.replaceAll(':', '')))
return;
linkNode.getParent().append($createEmojiNode(emojiText.replaceAll(':', '')));
}
};
export const CUSTOM_LINK_NODE_TRANSFORMER = {
dependencies: [EmojiNode, CustomLinkNode],
export: (node, _exportChildren, exportFormat) => {
if (!$isCustomLinkNode(node)) {
return null;
}
const linkContent = `[${node.getTextContent()}](${node.__url}){:target="${node.__target}" ${node
?.__classNames
?.join(' ')
.split(' ')
.map((className) => "." + className.replaceAll('.', ''))
.join(" ")}}`;
const firstChild = node.getFirstChild();
if (node.getChildrenSize() === 1 && $isTextNode(firstChild)) {
return exportFormat(firstChild, linkContent);
}
else {
return linkContent;
}
},
importRegExp: CUSTOM_LINK_NODE_MARKDOWN_REGEX,
regExp: CUSTOM_LINK_NODE_MARKDOWN_REGEX,
replace: replaceCustomLinkNode,
trigger: "[",
type: "text-match"
};