@mkljczk/lexical-remark
Version:
This package contains Markdown helpers and functionality for Lexical using remark-parse.
74 lines (73 loc) • 2.7 kB
JavaScript
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;
};