From 1f4ae2f63a609d51942daa23772439379496064e Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 2 Apr 2021 10:36:11 +0900 Subject: Use mfm-js for MFM parsing (#7415) * wip * Update mfm.ts * wip * update mfmjs * refactor * nanka * Update mfm.ts * Update to-html.ts * Update to-html.ts * wip * fix test * fix test --- src/misc/extract-custom-emojis-from-mfm.ts | 18 ++++++++++++++++ src/misc/extract-emojis.ts | 9 -------- src/misc/extract-hashtags.ts | 19 ++++++++++++----- src/misc/extract-mentions.ts | 17 +++++++++++---- src/misc/extract-url-from-mfm.ts | 34 ++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 src/misc/extract-custom-emojis-from-mfm.ts delete mode 100644 src/misc/extract-emojis.ts create mode 100644 src/misc/extract-url-from-mfm.ts (limited to 'src/misc') diff --git a/src/misc/extract-custom-emojis-from-mfm.ts b/src/misc/extract-custom-emojis-from-mfm.ts new file mode 100644 index 0000000000..f1477a79f0 --- /dev/null +++ b/src/misc/extract-custom-emojis-from-mfm.ts @@ -0,0 +1,18 @@ +import * as mfm from 'mfm-js'; +import { unique } from '@/prelude/array'; + +export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] { + const emojiNodes = [] as mfm.MfmEmojiCode[]; + + function scan(nodes: mfm.MfmNode[]) { + for (const node of nodes) { + if (node.type === 'emojiCode') emojiNodes.push(node); + else if (node.children) scan(node.children); + } + } + + scan(nodes); + + const emojis = emojiNodes.filter(x => x.props.name.length <= 100).map(x => x.props.name!); + return unique(emojis); +} diff --git a/src/misc/extract-emojis.ts b/src/misc/extract-emojis.ts deleted file mode 100644 index 2c57e9a8aa..0000000000 --- a/src/misc/extract-emojis.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { EmojiNode, MfmForest } from '../mfm/prelude'; -import { preorderF } from '../prelude/tree'; -import { unique } from '../prelude/array'; - -export default function(mfmForest: MfmForest): string[] { - const emojiNodes = preorderF(mfmForest).filter(x => x.type === 'emoji') as EmojiNode[]; - const emojis = emojiNodes.filter(x => x.props.name && x.props.name.length <= 100).map(x => x.props.name); - return unique(emojis); -} diff --git a/src/misc/extract-hashtags.ts b/src/misc/extract-hashtags.ts index 36b2296a76..9961755ccd 100644 --- a/src/misc/extract-hashtags.ts +++ b/src/misc/extract-hashtags.ts @@ -1,9 +1,18 @@ -import { HashtagNode, MfmForest } from '../mfm/prelude'; -import { preorderF } from '../prelude/tree'; -import { unique } from '../prelude/array'; +import * as mfm from 'mfm-js'; +import { unique } from '@/prelude/array'; + +export default function(nodes: mfm.MfmNode[]): string[] { + const hashtagNodes = [] as mfm.MfmHashtag[]; + + function scan(nodes: mfm.MfmNode[]) { + for (const node of nodes) { + if (node.type === 'hashtag') hashtagNodes.push(node); + else if (node.children) scan(node.children); + } + } + + scan(nodes); -export default function(mfmForest: MfmForest): string[] { - const hashtagNodes = preorderF(mfmForest).filter(x => x.type === 'hashtag') as HashtagNode[]; const hashtags = hashtagNodes.map(x => x.props.hashtag); return unique(hashtags); } diff --git a/src/misc/extract-mentions.ts b/src/misc/extract-mentions.ts index 72330d31e1..a9d4b378f3 100644 --- a/src/misc/extract-mentions.ts +++ b/src/misc/extract-mentions.ts @@ -1,10 +1,19 @@ // test is located in test/extract-mentions -import { MentionNode, MfmForest } from '../mfm/prelude'; -import { preorderF } from '../prelude/tree'; +import * as mfm from 'mfm-js'; -export default function(mfmForest: MfmForest): MentionNode['props'][] { +export default function(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] { // TODO: 重複を削除 - const mentionNodes = preorderF(mfmForest).filter(x => x.type === 'mention') as MentionNode[]; + const mentionNodes = [] as mfm.MfmMention[]; + + function scan(nodes: mfm.MfmNode[]) { + for (const node of nodes) { + if (node.type === 'mention') mentionNodes.push(node); + else if (node.children) scan(node.children); + } + } + + scan(nodes); + return mentionNodes.map(x => x.props); } diff --git a/src/misc/extract-url-from-mfm.ts b/src/misc/extract-url-from-mfm.ts new file mode 100644 index 0000000000..aa7f5f2540 --- /dev/null +++ b/src/misc/extract-url-from-mfm.ts @@ -0,0 +1,34 @@ +import * as mfm from 'mfm-js'; +import { unique } from '@/prelude/array'; + +// unique without hash +// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ] +const removeHash = (x: string) => x.replace(/#[^#]*$/, ''); + +export function extractUrlFromMfm(nodes: mfm.MfmNode[], respectSilentFlag = true): string[] { + const urlNodes = [] as (mfm.MfmUrl | mfm.MfmLink)[]; + + function scan(nodes: mfm.MfmNode[]) { + for (const node of nodes) { + if (node.type === 'url') { + urlNodes.push(node); + } else if (node.type === 'link') { + if (!respectSilentFlag || !node.props.silent) { + urlNodes.push(node); + } + } else if (node.children) { + scan(node.children); + } + } + } + + scan(nodes); + + const urls = unique(urlNodes.map(x => x.props.url)); + + return urls.reduce((array, url) => { + const removed = removeHash(url); + if (!array.map(x => removeHash(x)).includes(removed)) array.push(url); + return array; + }, [] as string[]); +} -- cgit v1.2.3-freya