Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const convertedNodes = [];
let remainingNodes = nodes;
while (remainingNodes.length > 0) {
const nextNode = remainingNodes[0];
if (nextNode.object === 'inline' || (nextNode.marks && nextNode.marks.length > 0)) {
const [markType, markNodes, remainder] = extractFirstMark(remainingNodes);
/**
* A node with a code mark will be a text node, and will not be adjacent
* to a sibling code node as the Slate schema requires them to be
* merged. Markdown also requires at least a space between inline code
* nodes.
*/
if (markType === 'code') {
const node = markNodes[0];
convertedNodes.push(u(markMap[markType], node.data, node.text));
} else if (!markType && markNodes.length === 1 && markNodes[0].object === 'inline') {
const node = markNodes[0];
convertedNodes.push(convertInlineNode(node, convertInlineAndTextChildren(node.nodes)));
} else {
const {
leadingWhitespace,
trailingWhitespace,
centerNodes,
} = normalizeFlankingWhitespace(markNodes);
const children = convertInlineAndTextChildren(centerNodes);
const markNode = u(markMap[markType], children);
// Filter out empty marks, otherwise their output literally by
// remark-stringify, eg. an empty bold node becomes "****"
if (mdastToString(markNode) === '') {
remainingNodes = remainder;
it('should preserve validly nested siblings of invalidly nested blocks', () => {
const input = u('root', [
u('paragraph', [
u('blockquote', [
u('strong', [
u('text', 'Deep validly nested text a.'),
u('heading', { depth: 1 }, [u('text', 'Heading text.')]),
u('text', 'Deep validly nested text b.'),
]),
]),
u('text', 'Validly nested text.'),
]),
]);
const output = u('root', [
u('blockquote', [
u('strong', [u('text', 'Deep validly nested text a.')]),
u('heading', { depth: 1 }, [u('text', 'Heading text.')]),
u('strong', [u('text', 'Deep validly nested text b.')]),
]),
u('paragraph', [u('text', 'Validly nested text.')]),
]);
it("must parse more complex math equations in math block", () => {
const processor = remark().use(math);
const targetText =
"$$p(\\theta_i \\thinspace | \\, \\{\\theta_{j \\neq i}\\}, D)$$";
const ast = processor.parse(targetText);
expect(ast).toEqual(
u("root", [
u("paragraph", [
u(
"math",
{
data: {
hChildren: [
u(
"text",
"p(\\theta_i \\thinspace | \\, \\{\\theta_{j \\neq i}\\}, D)"
)
],
hName: "div",
hProperties: {
className: "math"
}
}
it("must render super factorial to a math inline", () => {
const processor = remark().use(math);
const targetText = ["$$", "\\alpha\\$", "$$"].join("\n");
const ast = processor.parse(targetText);
expect(ast).toMatchObject(u("root", [u("math", "\\alpha\\$")]));
});
it('should unnest deeply nested blocks', () => {
const input = u('root', [
u('paragraph', [
u('paragraph', [
u('paragraph', [
u('paragraph', [u('text', 'Paragraph text.')]),
u('heading', { depth: 1 }, [u('text', 'Heading text.')]),
u('code', 'someCode()'),
u('blockquote', [
u('paragraph', [u('strong', [u('heading', [u('text', 'Quote text.')])])]),
]),
u('list', [u('listItem', [u('text', 'A list item.')])]),
u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]),
u('thematicBreak'),
]),
]),
]),
]);
const output = u('root', [
u('paragraph', [u('text', 'Paragraph text.')]),
u('heading', { depth: 1 }, [u('text', 'Heading text.')]),
u('code', 'someCode()'),
u('blockquote', [u('heading', [u('text', 'Quote text.')])]),
u('list', [u('listItem', [u('text', 'A list item.')])]),
u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]),
u('thematicBreak'),
]);
* Slate schemas don't usually infer basic type info from data, so each
* level of heading is a separately named type. The MDAST schema just
* has a single "heading" type with the depth stored in a "depth"
* property on the node. Here we derive the depth from the Slate node
* type - e.g., for "heading-two", we need a depth value of "2".
*/
case 'heading-one':
case 'heading-two':
case 'heading-three':
case 'heading-four':
case 'heading-five':
case 'heading-six': {
const depthMap = { one: 1, two: 2, three: 3, four: 4, five: 5, six: 6 };
const depthText = node.type.split('-')[1];
const depth = depthMap[depthText];
const mdastNode = u(typeMap[node.type], { depth }, children);
if (mdastToString(mdastNode)) {
return mdastNode;
}
return;
}
/**
* Code Blocks
*
* Code block nodes may have a single text child, or instead be void and
* store their value in `data.code`. They also may have a code language
* stored in the "lang" data property. Here we transfer both the node value
* and the "lang" data property to the new MDAST node, and spread any
* remaining data as `data`.
*/
case 'code-block': {
function renderHTML(node) {
if (!node) {
return '';
}
if (Array.isArray(node)) {
node = u('root', node);
}
return remark()
.use(remarkHtml)
.stringify(node);
}
function renderSeeLink(comment) {
return (
comment.sees.length > 0 &&
u(
'list',
{ ordered: false },
comment.sees.map(see =>
u('listItem', [
u('strong', [u('text', 'See Also ')].concat(see.children)),
]),
),
)
);
}
function renderParams(comment) {
return (
comment.params.length > 0 &&
u('html', renderParamsHTML(comment.params, { title: 'ARGUMENTS' }))
);
}
function renderHeading(comment, depth) {
return (
!!comment.name && [
u('heading', { depth }, [
u(
'text',
comment.kind === 'function' ? `${comment.name}()` : comment.name,
),
]),
]
);
}