From 79d2374d8ec1de10740d36309c26d00e5ab44c68 Mon Sep 17 00:00:00 2001 From: Aya Morisawa <AyaMorisawa4869@gmail.com> Date: Fri, 25 Jan 2019 23:08:06 +0900 Subject: [PATCH] Add multiline math syntax Co-authored-by: syuilo <syuilotan@yahoo.co.jp> --- .../common/views/components/formula-core.vue | 7 +++++- .../app/common/views/components/formula.vue | 6 ++++- src/client/app/common/views/components/mfm.ts | 16 +++++++++++-- src/mfm/html.ts | 8 ++++++- src/mfm/parser.ts | 23 ++++++++++++------- test/mfm.ts | 19 +++++++++++---- 6 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/client/app/common/views/components/formula-core.vue b/src/client/app/common/views/components/formula-core.vue index 254e0df308..69697d6df0 100644 --- a/src/client/app/common/views/components/formula-core.vue +++ b/src/client/app/common/views/components/formula-core.vue @@ -1,5 +1,6 @@ <template> -<span v-html="compiledFormula"></span> +<div v-if="block" v-html="compiledFormula"></div> +<span v-else v-html="compiledFormula"></span> </template> <script lang="ts"> @@ -11,6 +12,10 @@ export default Vue.extend({ formula: { type: String, required: true + }, + block: { + type: Boolean, + required: true } }, computed: { diff --git a/src/client/app/common/views/components/formula.vue b/src/client/app/common/views/components/formula.vue index 02ed96daac..73572b72c6 100644 --- a/src/client/app/common/views/components/formula.vue +++ b/src/client/app/common/views/components/formula.vue @@ -1,5 +1,5 @@ <template> -<x-formula :formula="formula"/> +<x-formula :formula="formula" :block="block" /> </template> <script lang="ts"> @@ -14,6 +14,10 @@ export default Vue.extend({ formula: { type: String, required: true + }, + block: { + type: Boolean, + required: true } } }); diff --git a/src/client/app/common/views/components/mfm.ts b/src/client/app/common/views/components/mfm.ts index ad3d8204cc..7a875dc2b0 100644 --- a/src/client/app/common/views/components/mfm.ts +++ b/src/client/app/common/views/components/mfm.ts @@ -228,12 +228,24 @@ export default Vue.component('misskey-flavored-markdown', { })]; } - case 'math': { + case 'mathInline': { //const MkFormula = () => import('./formula.vue').then(m => m.default); return [createElement(MkFormula, { key: Math.random(), props: { - formula: token.node.props.formula + formula: token.node.props.formula, + block: false + } + })]; + } + + case 'mathBlock': { + //const MkFormula = () => import('./formula.vue').then(m => m.default); + return [createElement(MkFormula, { + key: Math.random(), + props: { + formula: token.node.props.formula, + block: true } })]; } diff --git a/src/mfm/html.ts b/src/mfm/html.ts index 6af2833858..b86d33a39a 100644 --- a/src/mfm/html.ts +++ b/src/mfm/html.ts @@ -87,7 +87,13 @@ export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteU return el; }, - math(token) { + mathInline(token) { + const el = doc.createElement('code'); + el.textContent = token.node.props.formula; + return el; + }, + + mathBlock(token) { const el = doc.createElement('code'); el.textContent = token.node.props.formula; return el; diff --git a/src/mfm/parser.ts b/src/mfm/parser.ts index b86e1d5559..01b69c9690 100644 --- a/src/mfm/parser.ts +++ b/src/mfm/parser.ts @@ -103,7 +103,8 @@ const mfm = P.createLanguage({ r.blockCode, r.inlineCode, r.quote, - r.math, + r.mathInline, + r.mathBlock, r.search, r.title, r.center, @@ -121,7 +122,7 @@ const mfm = P.createLanguage({ r.mention, r.hashtag, r.emoji, - r.math, + r.mathInline, r.text ).atLeast(1).tryParse(x), {})), //#endregion @@ -135,7 +136,7 @@ const mfm = P.createLanguage({ r.mention, r.hashtag, r.emoji, - r.math, + r.mathInline, r.text ).atLeast(1).tryParse(x), {})), //#endregion @@ -180,7 +181,7 @@ const mfm = P.createLanguage({ r.mention, r.hashtag, r.emoji, - r.math, + r.mathInline, r.url, r.link, r.text @@ -274,10 +275,16 @@ const mfm = P.createLanguage({ }), //#endregion - //#region Math - math: r => + //#region Math (inline) + mathInline: r => P.regexp(/\\\((.+?)\\\)/, 1) - .map(x => createLeaf('math', { formula: x })), + .map(x => createLeaf('mathInline', { formula: x })), + //#endregion + + //#region Math (block) + mathBlock: r => + P.regexp(/\\\[([\s\S]+?)\\\]/, 1) + .map(x => createLeaf('mathBlock', { formula: x.trim() })), //#endregion //#region Mention @@ -311,7 +318,7 @@ const mfm = P.createLanguage({ r.emoji, r.url, r.link, - r.math, + r.mathInline, r.text ).atLeast(1).tryParse(x), {})), //#endregion diff --git a/test/mfm.ts b/test/mfm.ts index a4b4a13973..f850e649a3 100644 --- a/test/mfm.ts +++ b/test/mfm.ts @@ -836,15 +836,26 @@ describe('MFM', () => { }); }); - it('math', () => { + it('mathInline', () => { const fomula = 'x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}'; - const text = `\\(${fomula}\\)`; - const tokens = analyze(text); + const content = `\\(${fomula}\\)`; + const tokens = analyze(content); assert.deepStrictEqual(tokens, [ - leaf('math', { formula: fomula }) + leaf('mathInline', { formula: fomula }) ]); }); + describe('mathBlock', () => { + it('simple', () => { + const fomula = 'x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}'; + const content = `\\[\n${fomula}\n\\]`; + const tokens = analyze(content); + assert.deepStrictEqual(tokens, [ + leaf('mathBlock', { formula: fomula }) + ]); + }); + }); + it('search', () => { const tokens1 = analyze('a b c 検索'); assert.deepStrictEqual(tokens1, [