diff --git a/src/parser.pegjs b/src/parser.pegjs index 555ec65..290d997 100644 --- a/src/parser.pegjs +++ b/src/parser.pegjs @@ -66,7 +66,7 @@ fullParser = nodes:(&. n:(block / inline) { return n; })* { return mergeText(nodes); } plainParser - = nodes:(&. n:(emojiCode / unicodeEmoji / text) { return n; })* { return mergeText(nodes); } + = nodes:(&. n:(emojiCode / unicodeEmoji / plainText) { return n; })* { return mergeText(nodes); } inlineParser = nodes:(&. n:inline { return n; })* { return mergeText(nodes); } @@ -165,7 +165,7 @@ inline / url / link / fn - / text + / inlineText // inline: emoji code @@ -289,7 +289,7 @@ mentionHostPart // inline: hashtag hashtag - = "#" content:hashtagContent + = "#" !("\uFE0F"? "\u20E3") content:hashtagContent { return HASHTAG(content); } @@ -382,7 +382,13 @@ fnArg // inline: text -text +inlineText + = !(LF / _) . &hashtag . { return text(); } // hashtag ignore + / . /* text node */ + +// inline: text (for plainParser) + +plainText = . /* text node */ // diff --git a/test/parser.ts b/test/parser.ts index fc29f1a..f277ec8 100644 --- a/test/parser.ts +++ b/test/parser.ts @@ -4,7 +4,29 @@ import { TEXT, CENTER, FN, UNI_EMOJI, MENTION, EMOJI_CODE, HASHTAG, N_URL, BOLD, SMALL, ITALIC, STRIKE, QUOTE, MATH_BLOCK, SEARCH, CODE_BLOCK, LINK } from '../built/index'; -describe('parser', () => { +describe('PlainParser', () => { + describe('text', () => { + it('basic', () => { + const input = 'abc'; + const output = [TEXT('abc')]; + assert.deepStrictEqual(mfm.parsePlain(input), output); + }); + + it('ignore hashtag', () => { + const input = 'abc#abc'; + const output = [TEXT('abc#abc')]; + assert.deepStrictEqual(mfm.parsePlain(input), output); + }); + + it('keycap number sign', () => { + const input = 'abc#️⃣abc'; + const output = [TEXT('abc'), UNI_EMOJI('#️⃣'), TEXT('abc')]; + assert.deepStrictEqual(mfm.parsePlain(input), output); + }); + }); +}); + +describe('FullParser', () => { describe('text', () => { it('普通のテキストを入力すると1つのテキストノードが返される', () => { const input = 'abc'; @@ -222,6 +244,12 @@ describe('parser', () => { const output = [TEXT('今起きた'), UNI_EMOJI('😇')]; assert.deepStrictEqual(mfm.parse(input), output); }); + + it('keycap number sign', () => { + const input = 'abc#️⃣123'; + const output = [TEXT('abc'), UNI_EMOJI('#️⃣'), TEXT('123')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); }); describe('big', () => { @@ -397,9 +425,28 @@ describe('parser', () => { // mention describe('hashtag', () => { - it('and unicode emoji', () => { - const input = '#️⃣abc123#abc'; - const output = [UNI_EMOJI('#️⃣'), TEXT('abc123'), HASHTAG('abc')]; + it('basic', () => { + const input = 'before #abc after'; + const output = [TEXT('before '), HASHTAG('abc'), TEXT(' after')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + + it('with keycap number sign', () => { + const input = '#️⃣abc123 #abc'; + const output = [UNI_EMOJI('#️⃣'), TEXT('abc123 '), HASHTAG('abc')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + + it('with keycap number sign 2', () => { + const input = `abc +#️⃣abc`; + const output = [TEXT('abc\n'), UNI_EMOJI('#️⃣'), TEXT('abc')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + + it('ignore a hashtag if the before char is neither a space nor an LF', () => { + const input = 'abc#abc'; + const output = [TEXT('abc#abc')]; assert.deepStrictEqual(mfm.parse(input), output); }); });