@mkljczk/lexical-remark
Version:
This package contains Markdown helpers and functionality for Lexical using remark-parse.
88 lines (87 loc) • 2.94 kB
JavaScript
import { $isElementNode } from 'lexical';
import { zwitch } from 'zwitch';
import { blockquote } from './handlers/blockquote.js';
import { hardBreak } from './handlers/break.js';
import { code } from './handlers/code.js';
import { emphasis } from './handlers/emphasis.js';
import { heading } from './handlers/heading.js';
import { html } from './handlers/html.js';
import { image } from './handlers/image.js';
import { inlineCode } from './handlers/inlineCode.js';
import { link } from './handlers/link.js';
import { list } from './handlers/list.js';
import { listItem } from './handlers/listitem.js';
import { paragraph } from './handlers/paragraph.js';
import { root } from './handlers/root.js';
import { strong } from './handlers/strong.js';
import { text } from './handlers/text.js';
import { thematicBreak } from './handlers/thematicBreak.js';
export class Parser {
stack = [];
formatting = [];
handlers;
constructor(handlers) {
this.handlers = handlers ?? {};
}
parse(tree) {
return zwitch('type', {
handlers: {
blockquote,
break: hardBreak,
code,
emphasis,
hardBreak,
heading,
html,
image,
inlineCode,
link,
list,
listItem,
paragraph,
root,
strong,
text,
thematicBreak,
...this.handlers,
},
invalid: (node) => console.log('invalid node type', node),
unknown: (_node, _parser) => console.log('unknown node type'),
})(tree, this);
}
pop(node) {
const returnNode = this.stack.pop();
if (!returnNode) {
throw new Error('Cannot pop from empty stack');
}
if (typeof node === 'function') {
if (!node(returnNode)) {
console.log({ node, returnNode });
throw new Error('Popped node does not match expected typeguard');
}
}
else if (typeof node === 'string') {
if (returnNode.getType?.() !== node) {
console.log({ node, returnNode });
throw new Error('Popped node does not match expected type');
}
}
else if (node && node !== returnNode) {
console.log({ node, returnNode });
throw new Error('Popped node does not match expected node');
}
return returnNode;
}
push(node) {
this.stack.push(node);
}
append(node) {
if (this.stack.length === 0) {
console.log({ node });
throw new Error('Cannot append node to empty stack');
}
const parent = this.stack[this.stack.length - 1];
if ($isElementNode(parent))
parent.append(node);
}
}