MFMをテキストに戻す (#6131)
* Disable Nyaize in quote * mfmを文字列に戻す、nyaizeにmfmを使用 * Revert "Disable Nyaize in quote" This reverts commit 1b238905a5535267d32d7e1aec8afd8bb07b0619. * refactor * use return type as string
This commit is contained in:
parent
20ac7e62e9
commit
a471e4b783
3 changed files with 117 additions and 36 deletions
112
src/mfm/toString.ts
Normal file
112
src/mfm/toString.ts
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
import { MfmForest, MfmTree } from './prelude';
|
||||||
|
import { nyaize } from '../misc/nyaize';
|
||||||
|
|
||||||
|
export type RestoreOptions = {
|
||||||
|
doNyaize?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function toString(tokens: MfmForest | null, opts?: RestoreOptions): string {
|
||||||
|
|
||||||
|
if (tokens === null) return '';
|
||||||
|
|
||||||
|
function appendChildren(children: MfmForest, opts?: RestoreOptions): string {
|
||||||
|
return children.map(t => handlers[t.node.type](t, opts)).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlers: { [key: string]: (token: MfmTree, opts?: RestoreOptions) => string } = {
|
||||||
|
bold(token, opts) {
|
||||||
|
return `**${appendChildren(token.children, opts)}**`;
|
||||||
|
},
|
||||||
|
|
||||||
|
big(token, opts) {
|
||||||
|
return `***${appendChildren(token.children, opts)}***`;
|
||||||
|
},
|
||||||
|
|
||||||
|
small(token, opts) {
|
||||||
|
return `<small>${appendChildren(token.children, opts)}</small>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
strike(token, opts) {
|
||||||
|
return `~~${appendChildren(token.children, opts)}~~`;
|
||||||
|
},
|
||||||
|
|
||||||
|
italic(token, opts) {
|
||||||
|
return `<i>${appendChildren(token.children, opts)}</i>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
motion(token, opts) {
|
||||||
|
return `<motion>${appendChildren(token.children, opts)}</motion>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
spin(token, opts) {
|
||||||
|
return `<spin>${appendChildren(token.children, opts)}</spin>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
jump(token, opts) {
|
||||||
|
return `<jump>${appendChildren(token.children, opts)}</jump>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
flip(token, opts) {
|
||||||
|
return `<flip>${appendChildren(token.children, opts)}</flip>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
blockCode(token) {
|
||||||
|
return `\`\`\`${token.node.props.lang || ''}\n${token.node.props.code}\n\`\`\`\n`;
|
||||||
|
},
|
||||||
|
|
||||||
|
center(token, opts) {
|
||||||
|
return `<center>${appendChildren(token.children, opts)}</center>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
emoji(token) {
|
||||||
|
return (token.node.props.emoji ? token.node.props.emoji : `:${token.node.props.name}:`);
|
||||||
|
},
|
||||||
|
|
||||||
|
hashtag(token) {
|
||||||
|
return `#${token.node.props.hashtag}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
inlineCode(token) {
|
||||||
|
return `\`${token.node.props.code}\``;
|
||||||
|
},
|
||||||
|
|
||||||
|
mathInline(token) {
|
||||||
|
return `\\(${token.node.props.formula}\\)`;
|
||||||
|
},
|
||||||
|
|
||||||
|
mathBlock(token) {
|
||||||
|
return `\\[${token.node.props.formula}\\]`;
|
||||||
|
},
|
||||||
|
|
||||||
|
link(token, opts) {
|
||||||
|
return `[${appendChildren(token.children, opts)}](${token.node.props.url})`;
|
||||||
|
},
|
||||||
|
|
||||||
|
mention(token) {
|
||||||
|
return token.node.props.canonical;
|
||||||
|
},
|
||||||
|
|
||||||
|
quote(token) {
|
||||||
|
return `${appendChildren(token.children, {doNyaize: false}).replace(/^/gm,'>').trim()}\n`;
|
||||||
|
},
|
||||||
|
|
||||||
|
title(token, opts) {
|
||||||
|
return `[${appendChildren(token.children, opts)}]\n`;
|
||||||
|
},
|
||||||
|
|
||||||
|
text(token, opts) {
|
||||||
|
return (opts && opts.doNyaize) ? nyaize(token.node.props.text) : token.node.props.text;
|
||||||
|
},
|
||||||
|
|
||||||
|
url(token) {
|
||||||
|
return `<${token.node.props.url}>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
search(token, opts) {
|
||||||
|
const query = token.node.props.query;
|
||||||
|
return `${(opts && opts.doNyaize ? nyaize(query) : query)} [search]\n`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return appendChildren(tokens, { doNyaize: (opts && opts.doNyaize) || false }).trim();
|
||||||
|
}
|
|
@ -1,8 +1,5 @@
|
||||||
import rndstr from 'rndstr';
|
|
||||||
|
|
||||||
export function nyaize(text: string): string {
|
export function nyaize(text: string): string {
|
||||||
const [toNyaize, exclusionMap] = exclude(text);
|
return text
|
||||||
const nyaized = toNyaize
|
|
||||||
// ja-JP
|
// ja-JP
|
||||||
.replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ')
|
.replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ')
|
||||||
// en-US
|
// en-US
|
||||||
|
@ -13,34 +10,4 @@ export function nyaize(text: string): string {
|
||||||
))
|
))
|
||||||
.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, '다냥')
|
.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, '다냥')
|
||||||
.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, '냥');
|
.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, '냥');
|
||||||
return replaceExceptions(nyaized, exclusionMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
function exclude(text: string): [string, Record<string, string>] {
|
|
||||||
const map: Record<string, string> = {};
|
|
||||||
function substitute(match: string): string {
|
|
||||||
let randomstr: string;
|
|
||||||
do {
|
|
||||||
randomstr = rndstr({ length: 16, chars: '🀀-🀫' });
|
|
||||||
} while(Object.prototype.hasOwnProperty.call(map, randomstr));
|
|
||||||
map[randomstr] = match;
|
|
||||||
return randomstr;
|
|
||||||
}
|
|
||||||
const replaced = text
|
|
||||||
.replace(/```(.+?)?\n([\s\S]+?)```(\n|$)/gm, match => substitute(match)) // code block
|
|
||||||
.replace(/`([^`\n]+?)`/g, match => substitute(match)) // inline code
|
|
||||||
.replace(/(https?:\/\/.*?)(?= |$)/gm, match => substitute(match)) // URL
|
|
||||||
.replace(/:([a-z0-9_+-]+):/gim, match => substitute(match)) // emoji
|
|
||||||
.replace(/#([^\s.,!?'"#:\/\[\]【】]+)/gm, match => substitute(match)) // hashtag
|
|
||||||
.replace(/@\w([\w-]*\w)?(?:@[\w.\-]+\w)?/gm, match => substitute(match)); // mention
|
|
||||||
return [replaced, map];
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceExceptions(text: string, map: Record<string, string>): string {
|
|
||||||
for (const rule in map) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(map, rule)) {
|
|
||||||
text = text.replace(rule, map[rule]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { EntityRepository, Repository, In } from 'typeorm';
|
import { EntityRepository, Repository, In } from 'typeorm';
|
||||||
import { Note } from '../entities/note';
|
import { Note } from '../entities/note';
|
||||||
import { User } from '../entities/user';
|
import { User } from '../entities/user';
|
||||||
import { nyaize } from '../../misc/nyaize';
|
|
||||||
import { Emojis, Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls } from '..';
|
import { Emojis, Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls } from '..';
|
||||||
import { ensure } from '../../prelude/ensure';
|
import { ensure } from '../../prelude/ensure';
|
||||||
import { SchemaType } from '../../misc/schema';
|
import { SchemaType } from '../../misc/schema';
|
||||||
import { awaitAll } from '../../prelude/await-all';
|
import { awaitAll } from '../../prelude/await-all';
|
||||||
import { convertLegacyReaction, convertLegacyReactions } from '../../misc/reaction-lib';
|
import { convertLegacyReaction, convertLegacyReactions } from '../../misc/reaction-lib';
|
||||||
|
import { toString } from '../../mfm/toString';
|
||||||
|
import { parse } from '../../mfm/parse';
|
||||||
|
|
||||||
export type PackedNote = SchemaType<typeof packedNoteSchema>;
|
export type PackedNote = SchemaType<typeof packedNoteSchema>;
|
||||||
|
|
||||||
|
@ -217,7 +218,8 @@ export class NoteRepository extends Repository<Note> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (packed.user.isCat && packed.text) {
|
if (packed.user.isCat && packed.text) {
|
||||||
packed.text = nyaize(packed.text);
|
const tokens = packed.text ? parse(packed.text) : [];
|
||||||
|
packed.text = toString(tokens, { doNyaize: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.skipHide) {
|
if (!opts.skipHide) {
|
||||||
|
|
Loading…
Reference in a new issue