From 6eb9ba31bf6c0cab134116accef84f78f6ed8c1d Mon Sep 17 00:00:00 2001
From: Aya Morisawa <AyaMorisawa4869@gmail.com>
Date: Wed, 30 Jan 2019 13:47:58 +0900
Subject: [PATCH] Extract MFM normalize function

---
 src/mfm/normalize.ts | 31 +++++++++++++++++++++++++++++++
 src/mfm/parse.ts     | 31 +++----------------------------
 2 files changed, 34 insertions(+), 28 deletions(-)
 create mode 100644 src/mfm/normalize.ts

diff --git a/src/mfm/normalize.ts b/src/mfm/normalize.ts
new file mode 100644
index 0000000000..9d5f0dab53
--- /dev/null
+++ b/src/mfm/normalize.ts
@@ -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));
+}
diff --git a/src/mfm/parse.ts b/src/mfm/parse.ts
index 21e4ca651f..2d796f5003 100644
--- a/src/mfm/parse.ts
+++ b/src/mfm/parse.ts
@@ -1,30 +1,5 @@
-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';
-
-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)));
-}
+import parser, { plainParser, MfmForest } from './parser';
+import { normalize } from './normalize';
 
 export default (source: string, plainText = false): MfmForest => {
 	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;
-	return removeEmptyTextNodes(concatConsecutiveTextTrees(raw));
+	return normalize(raw);
 };