From e9f8897fe28249642d47dd1ecf3e6a76b552ddf5 Mon Sep 17 00:00:00 2001 From: Aya Morisawa Date: Thu, 20 Dec 2018 19:41:04 +0900 Subject: Refactor MFM Co-authored-by: syuilo syuilotan@yahoo.co.jp --- src/mfm/parse.ts | 56 ++++++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 30 deletions(-) (limited to 'src/mfm/parse.ts') 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)); }; -- cgit v1.2.3-freya