diff --git a/src/mfm/parse/index.ts b/src/mfm/parse/index.ts index 105378343b..f2beec14ff 100644 --- a/src/mfm/parse/index.ts +++ b/src/mfm/parse/index.ts @@ -15,6 +15,9 @@ import { TextElementSearch } from './elements/search'; import { TextElementTitle } from './elements/title'; import { TextElementUrl } from './elements/url'; import { TextElementMotion } from './elements/motion'; +import { groupOn } from '../../prelude/array'; +import * as A from '../../prelude/array'; +import * as S from '../../prelude/string'; const elements = [ require('./elements/big'), @@ -89,16 +92,10 @@ export default (source: string): TextElement[] => { i++; } - // テキストを纏める - return tokens.reduce((a, b) => { - if (a.length && a[a.length - 1].type == 'text' && b.type == 'text') { - const tail = a.pop(); - return a.concat({ - type: 'text', - content: tail.content + b.content - }); - } else { - return a.concat(b); - } - }, [] as TextElement[]); + const combineText = (es: TextElement[]): TextElement => + ({ type: 'text', content: S.concat(es.map(e => e.content)) }); + + return A.concat(groupOn(x => x.type, tokens).map(es => + es[0].type === 'text' ? [combineText(es)] : es + )); }; diff --git a/src/prelude/array.ts b/src/prelude/array.ts index 42f05dc0c9..8536e486d6 100644 --- a/src/prelude/array.ts +++ b/src/prelude/array.ts @@ -29,3 +29,19 @@ export function unique(xs: T[]): T[] { export function sum(xs: number[]): number { return xs.reduce((a, b) => a + b, 0); } + +export function groupBy(f: (x: T, y: T) => boolean, xs: T[]): T[][] { + const groups = [] as T[][]; + for (const x of xs) { + if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) { + groups[groups.length - 1].push(x); + } else { + groups.push([x]); + } + } + return groups; +} + +export function groupOn(f: (x: T) => S, xs: T[]): T[][] { + return groupBy((a, b) => f(a) === f(b), xs); +} diff --git a/src/prelude/string.ts b/src/prelude/string.ts index cae776bc3d..6149235e47 100644 --- a/src/prelude/string.ts +++ b/src/prelude/string.ts @@ -1,3 +1,7 @@ +export function concat(xs: string[]): string { + return xs.reduce((a, b) => a + b, ""); +} + export function capitalize(s: string): string { return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1)); }