From b3f42e62af698a67c2250533c437569559f1fdf9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 29 Dec 2016 07:49:51 +0900 Subject: Initial commit :four_leaf_clover: --- src/common/text/elements/bold.js | 17 ++++++++++ src/common/text/elements/hashtag.js | 23 +++++++++++++ src/common/text/elements/mention.js | 17 ++++++++++ src/common/text/elements/url.js | 16 +++++++++ src/common/text/index.js | 67 +++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 src/common/text/elements/bold.js create mode 100644 src/common/text/elements/hashtag.js create mode 100644 src/common/text/elements/mention.js create mode 100644 src/common/text/elements/url.js create mode 100644 src/common/text/index.js (limited to 'src/common') diff --git a/src/common/text/elements/bold.js b/src/common/text/elements/bold.js new file mode 100644 index 0000000000..41a01399dd --- /dev/null +++ b/src/common/text/elements/bold.js @@ -0,0 +1,17 @@ +/** + * Bold + */ + +const regexp = /\*\*(.+?)\*\*/; + +module.exports = { + test: x => new RegExp('^' + regexp.source).test(x), + parse: text => { + const bold = text.match(new RegExp('^' + regexp.source))[0]; + return { + type: 'bold', + content: bold, + bold: bold.substr(2, bold.length - 4) + }; + } +}; diff --git a/src/common/text/elements/hashtag.js b/src/common/text/elements/hashtag.js new file mode 100644 index 0000000000..f04b782007 --- /dev/null +++ b/src/common/text/elements/hashtag.js @@ -0,0 +1,23 @@ +/** + * Hashtag + */ + +module.exports = { + test: (x, i) => + /^\s#[^\s]+/.test(x) || (i == 0 && /^#[^\s]+/.test(x)) + , + parse: text => { + const isHead = text[0] == '#'; + const hashtag = text.match(/^\s?#[^\s]+/)[0]; + const res = !isHead ? [{ + type: 'text', + content: text[0] + }] : []; + res.push({ + type: 'hashtag', + content: isHead ? hashtag : hashtag.substr(1), + hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2) + }); + return res; + } +}; diff --git a/src/common/text/elements/mention.js b/src/common/text/elements/mention.js new file mode 100644 index 0000000000..b58786fd1e --- /dev/null +++ b/src/common/text/elements/mention.js @@ -0,0 +1,17 @@ +/** + * Mention + */ + +const regexp = /@[a-zA-Z0-9\-]+/; + +module.exports = { + test: x => new RegExp('^' + regexp.source).test(x), + parse: text => { + const mention = text.match(new RegExp('^' + regexp.source))[0]; + return { + type: 'mention', + content: mention, + username: mention.substr(1) + }; + } +}; diff --git a/src/common/text/elements/url.js b/src/common/text/elements/url.js new file mode 100644 index 0000000000..d02aef0800 --- /dev/null +++ b/src/common/text/elements/url.js @@ -0,0 +1,16 @@ +/** + * URL + */ + +const regexp = /https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/; + +module.exports = { + test: x => new RegExp('^' + regexp.source).test(x), + parse: text => { + const link = text.match(new RegExp('^' + regexp.source))[0]; + return { + type: 'link', + content: link + }; + } +}; diff --git a/src/common/text/index.js b/src/common/text/index.js new file mode 100644 index 0000000000..973e7c5236 --- /dev/null +++ b/src/common/text/index.js @@ -0,0 +1,67 @@ +/** + * Misskey Text Analyzer + */ + +const elements = [ + require('./elements/bold'), + require('./elements/url'), + require('./elements/mention'), + require('./elements/hashtag') +]; + +function analyze(source) { + + if (source == '') { + return null; + } + + const tokens = []; + + function push(token) { + if (token != null) { + tokens.push(token); + source = source.substr(token.content.length); + } + } + + let i = 0; + + // パース + while (source != '') { + const parsed = elements.some(el => { + if (el.test(source, i)) { + let tokens = el.parse(source); + if (!Array.isArray(tokens)) { + tokens = [tokens]; + } + tokens.forEach(push); + return true; + } + }); + + if (!parsed) { + push({ + type: 'text', + content: source[0] + }); + } + + i++; + } + + // テキストを纏める + tokens[0] = [tokens[0]]; + return tokens.reduce((a, b) => { + if (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); + } + }); +} + +module.exports = analyze; -- cgit v1.2.3-freya