From 6e343d50f10f2f381aed94853c41d59b33c1ee03 Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 4 Dec 2018 01:28:21 +0900 Subject: [PATCH] [MFM] Implement strike syntax Resolve #3485 --- src/client/app/common/views/components/mfm.ts | 4 ++++ src/mfm/html.ts | 6 ++++++ src/mfm/parser.ts | 19 +++++++++++++++++++ test/mfm.ts | 11 +++++++++++ 4 files changed, 40 insertions(+) diff --git a/src/client/app/common/views/components/mfm.ts b/src/client/app/common/views/components/mfm.ts index d1ce4873f..dbc874c53 100644 --- a/src/client/app/common/views/components/mfm.ts +++ b/src/client/app/common/views/components/mfm.ts @@ -96,6 +96,10 @@ export default Vue.component('misskey-flavored-markdown', { return [createElement('b', genEl(token.children))]; } + case 'strike': { + return [createElement('del', genEl(token.children))]; + } + case 'big': { bigCount++; const isLong = getTextCount(token.children) > 10 || getChildrenCount(token.children) > 5; diff --git a/src/mfm/html.ts b/src/mfm/html.ts index 8b63d8f82..083150ab7 100644 --- a/src/mfm/html.ts +++ b/src/mfm/html.ts @@ -31,6 +31,12 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser return el; }, + strike(token) { + const el = doc.createElement('del'); + dive(token.children).forEach(child => el.appendChild(child)); + return el; + }, + motion(token) { const el = doc.createElement('i'); dive(token.children).forEach(child => el.appendChild(child)); diff --git a/src/mfm/parser.ts b/src/mfm/parser.ts index 3f9d68df3..4bd45516a 100644 --- a/src/mfm/parser.ts +++ b/src/mfm/parser.ts @@ -68,6 +68,7 @@ const mfm = P.createLanguage({ root: r => P.alt( r.big, r.bold, + r.strike, r.motion, r.url, r.link, @@ -129,6 +130,7 @@ const mfm = P.createLanguage({ .map(x => makeNodeWithChildren('center', P.alt( r.big, r.bold, + r.strike, r.motion, r.mention, r.hashtag, @@ -189,6 +191,7 @@ const mfm = P.createLanguage({ return makeNodeWithChildren('link', P.alt( r.big, r.bold, + r.strike, r.motion, r.emoji, r.text @@ -228,6 +231,7 @@ const mfm = P.createLanguage({ P.alt(P.regexp(/\(\(\(([\s\S]+?)\)\)\)/, 1), P.regexp(/(.+?)<\/motion>/, 1)) .map(x => makeNodeWithChildren('motion', P.alt( r.bold, + r.strike, r.mention, r.hashtag, r.emoji, @@ -261,6 +265,20 @@ const mfm = P.createLanguage({ })), //#endregion + //#region Strike + strike: r => + P.regexp(/~~(.+?)~~/, 1) + .map(x => makeNodeWithChildren('strike', P.alt( + r.bold, + r.mention, + r.hashtag, + r.url, + r.link, + r.emoji, + r.text + ).atLeast(1).tryParse(x))), + //#endregion + //#region Title title: r => newline.then(P((input, i) => { @@ -271,6 +289,7 @@ const mfm = P.createLanguage({ const contents = P.alt( r.big, r.bold, + r.strike, r.motion, r.url, r.link, diff --git a/test/mfm.ts b/test/mfm.ts index eeb92aa2a..111f70bef 100644 --- a/test/mfm.ts +++ b/test/mfm.ts @@ -702,6 +702,17 @@ describe('Text', () => { ], tokens); }); }); + + describe('strike', () => { + it('simple', () => { + const tokens = analyze('~~foo~~'); + assert.deepEqual([ + nodeWithChildren('strike', [ + text('foo') + ]), + ], tokens); + }); + }); }); describe('toHtml', () => {