UNPKG

@mkljczk/lexical-remark

Version:

This package contains Markdown helpers and functionality for Lexical using remark-parse.

74 lines (73 loc) 2.7 kB
import { $isLineBreakNode, $isTextNode } from 'lexical'; const textTypes = ['text', 'inlineCode']; const wrapperTypes = ['emphasis', 'strong']; function isTextType(node) { if (typeof node !== 'object' || !node) { return false; } if ('type' in node && typeof node.type === 'string') { return textTypes.includes(node.type); } return false; } function isWrapperType(node) { if (typeof node !== 'object' || !node) { return false; } if ('type' in node && typeof node.type === 'string') { return wrapperTypes.includes(node.type); } return false; } export const paragraph = (node, { rootHandler }) => { const childNodes = node.getChildren(); const children = []; for (let i = 0; i < childNodes.length; i++) { const child = childNodes[i]; const newChild = rootHandler(child, { rootHandler }); if ($isTextNode(child) && children.length > 0) { const lastChild = children[children.length - 1]; if (isTextType(lastChild) && isTextType(newChild) && lastChild.type === newChild.type) { lastChild.value += newChild.value; continue; } else if (isWrapperType(lastChild) && isWrapperType(newChild) && lastChild.type === newChild.type) { let lastChildTextNode = lastChild.children[0]; let newChildTextNode = newChild.children[0]; while (isWrapperType(lastChildTextNode) && isWrapperType(newChildTextNode) && lastChildTextNode.type === newChildTextNode.type) { lastChildTextNode = lastChildTextNode.children[0]; newChildTextNode = newChildTextNode.children[0]; } lastChild.children[0].value += newChild.children[0].value; continue; } } else if ($isLineBreakNode(child)) { children.push({ type: 'break', }); continue; } if (newChild) { children.push(newChild); } } const remarkNode = { children: children .filter((child) => !!child) .reduce((acc, child) => { const latest = acc[acc.length - 1]; const latestButOne = acc[acc.length - 2]; if (latestButOne?.type === 'text' && latest?.type === 'break' && child.type === 'text') { latestButOne.value += `\n${child.value}`; acc.pop(); return acc; } return [...acc, child]; }, []), type: 'paragraph', }; return remarkNode; };