summaryrefslogtreecommitdiff
path: root/src/mfm/parse.ts
blob: 58e126be3ebcc39655b61f1a85651ff30cf784d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import parser, { Node, plainParser } from './parser';
import * as A from '../prelude/array';
import * as S from '../prelude/string';

export default (source: string, plainText = false): Node[] => {
	if (source == null || source == '') {
		return null;
	}

	let nodes: Node[] = plainText ? plainParser.root.tryParse(source) : parser.root.tryParse(source);

	const combineText = (es: Node[]): Node =>
		({ name: 'text', props: { text: S.concat(es.map(e => e.props.text)) } });

	const concatText = (nodes: Node[]): Node[] =>
		A.concat(A.groupOn(x => x.name, nodes).map(es =>
			es[0].name === 'text' ? [combineText(es)] : es
		));

	const concatTextRecursive = (es: Node[]): void => {
		for (const x of es.filter(x => x.children)) {
			x.children = concatText(x.children);
			concatTextRecursive(x.children);
		}
	};

	nodes = concatText(nodes);
	concatTextRecursive(nodes);

	const removeEmptyTextNodes = (nodes: Node[]) => {
		for (const n of nodes.filter(n => n.children)) {
			n.children = removeEmptyTextNodes(n.children);
		}
		return nodes.filter(n => !(n.name == 'text' && n.props.text == ''));
	};

	nodes = removeEmptyTextNodes(nodes);

	return nodes;
};