summaryrefslogtreecommitdiff
path: root/src/mfm/parse.ts
diff options
context:
space:
mode:
authorAya Morisawa <AyaMorisawa4869@gmail.com>2018-12-20 19:41:04 +0900
committerAya Morisawa <AyaMorisawa4869@gmail.com>2018-12-20 19:42:10 +0900
commite9f8897fe28249642d47dd1ecf3e6a76b552ddf5 (patch)
treec64445f671f782ae2a08e149400b1297f99e5eae /src/mfm/parse.ts
parentFix overlap of birthday label on datepicker (#3697) (diff)
downloadmisskey-e9f8897fe28249642d47dd1ecf3e6a76b552ddf5.tar.gz
misskey-e9f8897fe28249642d47dd1ecf3e6a76b552ddf5.tar.bz2
misskey-e9f8897fe28249642d47dd1ecf3e6a76b552ddf5.zip
Refactor MFM
Co-authored-by: syuilo syuilotan@yahoo.co.jp
Diffstat (limited to 'src/mfm/parse.ts')
-rw-r--r--src/mfm/parse.ts56
1 files changed, 26 insertions, 30 deletions
diff --git a/src/mfm/parse.ts b/src/mfm/parse.ts
index 58e126be3e..21e4ca651f 100644
--- a/src/mfm/parse.ts
+++ b/src/mfm/parse.ts
@@ -1,40 +1,36 @@
-import parser, { Node, plainParser } from './parser';
+import parser, { plainParser, MfmForest, MfmTree } from './parser';
import * as A from '../prelude/array';
import * as S from '../prelude/string';
+import { createTree, createLeaf } from '../prelude/tree';
-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);
+function concatTextTrees(ts: MfmForest): MfmTree {
+ return createLeaf({ type: 'text', props: { text: S.concat(ts.map(x => x.node.props.text)) } });
+}
- const combineText = (es: Node[]): Node =>
- ({ name: 'text', props: { text: S.concat(es.map(e => e.props.text)) } });
+function concatIfTextTrees(ts: MfmForest): MfmForest {
+ return ts[0].node.type === 'text' ? [concatTextTrees(ts)] : ts;
+}
- const concatText = (nodes: Node[]): Node[] =>
- A.concat(A.groupOn(x => x.name, nodes).map(es =>
- es[0].name === 'text' ? [combineText(es)] : es
- ));
+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)));
+}
- const concatTextRecursive = (es: Node[]): void => {
- for (const x of es.filter(x => x.children)) {
- x.children = concatText(x.children);
- concatTextRecursive(x.children);
- }
- };
+function isEmptyTextTree(t: MfmTree): boolean {
+ return t.node.type == 'text' && t.node.props.text === '';
+}
- nodes = concatText(nodes);
- concatTextRecursive(nodes);
+function removeEmptyTextNodes(ts: MfmForest): MfmForest {
+ return ts
+ .filter(t => !isEmptyTextTree(t))
+ .map(t => createTree(t.node, removeEmptyTextNodes(t.children)));
+}
- 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);
+export default (source: string, plainText = false): MfmForest => {
+ if (source == null || source == '') {
+ return null;
+ }
- return nodes;
+ const raw = plainText ? plainParser.root.tryParse(source) : parser.root.tryParse(source) as MfmForest;
+ return removeEmptyTextNodes(concatConsecutiveTextTrees(raw));
};