Extract MFM normalize function
This commit is contained in:
parent
5bbf4187e6
commit
6eb9ba31bf
2 changed files with 34 additions and 28 deletions
31
src/mfm/normalize.ts
Normal file
31
src/mfm/normalize.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import * as A from '../prelude/array';
|
||||||
|
import * as S from '../prelude/string';
|
||||||
|
import { MfmForest, MfmTree } from './parser';
|
||||||
|
import { createTree, createLeaf } from '../prelude/tree';
|
||||||
|
|
||||||
|
function isEmptyTextTree(t: MfmTree): boolean {
|
||||||
|
return t.node.type == 'text' && t.node.props.text === '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function concatTextTrees(ts: MfmForest): MfmTree {
|
||||||
|
return createLeaf({ type: 'text', props: { text: S.concat(ts.map(x => x.node.props.text)) } });
|
||||||
|
}
|
||||||
|
|
||||||
|
function concatIfTextTrees(ts: MfmForest): MfmForest {
|
||||||
|
return ts[0].node.type === 'text' ? [concatTextTrees(ts)] : ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function concatConsecutiveTextTrees(ts: MfmForest): MfmForest {
|
||||||
|
const us = A.concat(A.groupOn(t => t.node.type, ts).map(concatIfTextTrees));
|
||||||
|
return us.map(t => createTree(t.node, concatConsecutiveTextTrees(t.children)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEmptyTextNodes(ts: MfmForest): MfmForest {
|
||||||
|
return ts
|
||||||
|
.filter(t => !isEmptyTextTree(t))
|
||||||
|
.map(t => createTree(t.node, removeEmptyTextNodes(t.children)));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalize(ts: MfmForest): MfmForest {
|
||||||
|
return removeEmptyTextNodes(concatConsecutiveTextTrees(ts));
|
||||||
|
}
|
|
@ -1,30 +1,5 @@
|
||||||
import parser, { plainParser, MfmForest, MfmTree } from './parser';
|
import parser, { plainParser, MfmForest } from './parser';
|
||||||
import * as A from '../prelude/array';
|
import { normalize } from './normalize';
|
||||||
import * as S from '../prelude/string';
|
|
||||||
import { createTree, createLeaf } from '../prelude/tree';
|
|
||||||
|
|
||||||
function concatTextTrees(ts: MfmForest): MfmTree {
|
|
||||||
return createLeaf({ type: 'text', props: { text: S.concat(ts.map(x => x.node.props.text)) } });
|
|
||||||
}
|
|
||||||
|
|
||||||
function concatIfTextTrees(ts: MfmForest): MfmForest {
|
|
||||||
return ts[0].node.type === 'text' ? [concatTextTrees(ts)] : ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
function concatConsecutiveTextTrees(ts: MfmForest): MfmForest {
|
|
||||||
const us = A.concat(A.groupOn(t => t.node.type, ts).map(concatIfTextTrees));
|
|
||||||
return us.map(t => createTree(t.node, concatConsecutiveTextTrees(t.children)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEmptyTextTree(t: MfmTree): boolean {
|
|
||||||
return t.node.type == 'text' && t.node.props.text === '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeEmptyTextNodes(ts: MfmForest): MfmForest {
|
|
||||||
return ts
|
|
||||||
.filter(t => !isEmptyTextTree(t))
|
|
||||||
.map(t => createTree(t.node, removeEmptyTextNodes(t.children)));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (source: string, plainText = false): MfmForest => {
|
export default (source: string, plainText = false): MfmForest => {
|
||||||
if (source == null || source == '') {
|
if (source == null || source == '') {
|
||||||
|
@ -32,5 +7,5 @@ export default (source: string, plainText = false): MfmForest => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const raw = plainText ? plainParser.root.tryParse(source) : parser.root.tryParse(source) as MfmForest;
|
const raw = plainText ? plainParser.root.tryParse(source) : parser.root.tryParse(source) as MfmForest;
|
||||||
return removeEmptyTextNodes(concatConsecutiveTextTrees(raw));
|
return normalize(raw);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue