very-small-parser
Version:
A very small Markdown, HTML, and CSS parser.
80 lines (79 loc) • 3 kB
JavaScript
import { toText as hastToText } from '../../html/toText';
const toTextChildren = (children, ctx) => {
if (!children)
return '';
let str = '';
const length = children.length;
for (let i = 0; i < length; i++)
str += toText(children[i], ctx);
return str;
};
export const toText = (node, ctx = { b: '_' }) => {
if (Array.isArray(node))
return toTextChildren(node);
const inline = node;
const type = inline.type;
switch (type) {
case 'text':
return inline.value;
case 'inlineCode':
return '`' + node.value + '`';
case 'strong': {
const markup = ctx.b + ctx.b;
return markup + toTextChildren(inline.children, { ...ctx, b: ctx.b === '_' ? '*' : '_' }) + markup;
}
case 'emphasis': {
const markup = ctx.b;
return markup + toTextChildren(inline.children, { ...ctx, b: ctx.b === '_' ? '*' : '_' }) + markup;
}
case 'delete':
return '~~' + toTextChildren(inline.children) + '~~';
case 'spoiler':
return '||' + toTextChildren(inline.children) + '||';
case 'inlineMath':
return '$' + inline.value + '$';
case 'footnoteReference':
return '[^' + inline.label + ']';
case 'linkReference':
case 'imageReference': {
const { identifier, referenceType } = inline;
const start = type === 'imageReference' ? '![' : '[';
switch (referenceType) {
case 'full':
return (start + (type === 'imageReference' ? inline.alt : toTextChildren(inline.children)) + '][' + identifier + ']');
case 'collapsed':
return start + identifier + '][]';
// case 'shortcut':
default:
return start + identifier + ']';
}
}
case 'link':
case 'image': {
const { title, url } = inline;
const start = type === 'image' ? ' + ')';
}
case 'inlineLink':
return inline.value;
case 'sup':
return '^' + toTextChildren(inline.children) + '^';
case 'sub':
return '~' + toTextChildren(inline.children) + '~';
case 'mark':
return '==' + toTextChildren(inline.children) + '==';
case 'handle':
return inline.prefix + inline.value;
case 'underline':
return '++' + toTextChildren(inline.children) + '++';
case 'break':
return ' \n';
case 'icon':
return ':' + inline.emoji + ':';
case 'element':
return hastToText(inline, ' ');
case 'whitespace':
return ' '.repeat(inline.length);
}
return toTextChildren(inline.children);
};