mirror of
https://iceshrimp.dev/iceshrimp/iceshrimp
synced 2024-12-01 08:18:05 +09:00
Support math rendering on MFM (#3260)
This commit is contained in:
parent
a4670f9396
commit
97d4c04276
@ -46,6 +46,7 @@
|
||||
"@types/is-root": "1.0.0",
|
||||
"@types/is-url": "1.2.28",
|
||||
"@types/js-yaml": "3.11.2",
|
||||
"@types/katex": "0.5.0",
|
||||
"@types/koa": "2.0.46",
|
||||
"@types/koa-bodyparser": "5.0.1",
|
||||
"@types/koa-compress": "2.0.8",
|
||||
@ -140,6 +141,7 @@
|
||||
"jsdom": "13.0.0",
|
||||
"json5": "2.1.0",
|
||||
"json5-loader": "1.0.1",
|
||||
"katex": "0.10.0",
|
||||
"koa": "2.6.1",
|
||||
"koa-bodyparser": "4.2.1",
|
||||
"koa-compress": "3.0.0",
|
||||
|
26
src/client/app/common/views/components/formula.vue
Normal file
26
src/client/app/common/views/components/formula.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<span v-html="compiledFormula"></span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as katex from 'katex';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
formula: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compiledFormula(): any {
|
||||
return katex.renderToString(this.formula);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import "../../../../../../node_modules/katex/dist/katex.min.css";
|
||||
</style>
|
@ -1,5 +1,6 @@
|
||||
import Vue, { VNode } from 'vue';
|
||||
import { length } from 'stringz';
|
||||
import MkFormula from './formula.vue';
|
||||
import parse from '../../../../../mfm/parse';
|
||||
import getAcct from '../../../../../misc/acct/render';
|
||||
import MkUrl from './url.vue';
|
||||
@ -199,6 +200,14 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
})];
|
||||
}
|
||||
|
||||
case 'math': {
|
||||
return [createElement(MkFormula, {
|
||||
props: {
|
||||
formula: token.formula
|
||||
}
|
||||
})];
|
||||
}
|
||||
|
||||
case 'search': {
|
||||
return [createElement(MkGoogle, {
|
||||
props: {
|
||||
|
@ -53,6 +53,12 @@ const handlers: { [key: string]: (window: any, token: any, mentionedRemoteUsers:
|
||||
document.body.appendChild(element);
|
||||
},
|
||||
|
||||
math({ document }, { formula }) {
|
||||
const element = document.createElement('code');
|
||||
element.textContent = formula;
|
||||
document.body.appendChild(element);
|
||||
},
|
||||
|
||||
link({ document }, { url, title }) {
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
|
20
src/mfm/parse/elements/math.ts
Normal file
20
src/mfm/parse/elements/math.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Math
|
||||
*/
|
||||
|
||||
export type TextElementMath = {
|
||||
type: 'math';
|
||||
content: string;
|
||||
formula: string;
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^\$(.+?)\$/);
|
||||
if (!match) return null;
|
||||
const math = match[0];
|
||||
return {
|
||||
type: 'math',
|
||||
content: math,
|
||||
formula: match[1]
|
||||
} as TextElementMath;
|
||||
}
|
@ -8,6 +8,7 @@ import { TextElementCode } from './elements/code';
|
||||
import { TextElementEmoji } from './elements/emoji';
|
||||
import { TextElementHashtag } from './elements/hashtag';
|
||||
import { TextElementInlineCode } from './elements/inline-code';
|
||||
import { TextElementMath } from './elements/math';
|
||||
import { TextElementLink } from './elements/link';
|
||||
import { TextElementMention } from './elements/mention';
|
||||
import { TextElementQuote } from './elements/quote';
|
||||
@ -29,6 +30,7 @@ const elements = [
|
||||
require('./elements/hashtag'),
|
||||
require('./elements/code'),
|
||||
require('./elements/inline-code'),
|
||||
require('./elements/math'),
|
||||
require('./elements/quote'),
|
||||
require('./elements/emoji'),
|
||||
require('./elements/search'),
|
||||
@ -42,6 +44,7 @@ export type TextElement = { type: 'text', content: string }
|
||||
| TextElementEmoji
|
||||
| TextElementHashtag
|
||||
| TextElementInlineCode
|
||||
| TextElementMath
|
||||
| TextElementLink
|
||||
| TextElementMention
|
||||
| TextElementQuote
|
||||
|
@ -210,6 +210,15 @@ describe('Text', () => {
|
||||
assert.equal(tokens[0].content, '`var x = "Strawberry Pasta";`');
|
||||
});
|
||||
|
||||
it('math', () => {
|
||||
const fomula = 'x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.';
|
||||
const text = `$${fomula}$`;
|
||||
const tokens = analyze(text);
|
||||
assert.deepEqual([
|
||||
{ type: 'math', content: text, formula: fomula }
|
||||
], tokens);
|
||||
});
|
||||
|
||||
it('search', () => {
|
||||
const tokens1 = analyze('a b c 検索');
|
||||
assert.deepEqual([
|
||||
|
Loading…
Reference in New Issue
Block a user