リモートユーザーのHTMLで表現されたプロフィールをMFMに変換するように
This commit is contained in:
20
src/mfm/parse/elements/bold.ts
Normal file
20
src/mfm/parse/elements/bold.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Bold
|
||||
*/
|
||||
|
||||
export type TextElementBold = {
|
||||
type: 'bold'
|
||||
content: string
|
||||
bold: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^\*\*(.+?)\*\*/);
|
||||
if (!match) return null;
|
||||
const bold = match[0];
|
||||
return {
|
||||
type: 'bold',
|
||||
content: bold,
|
||||
bold: bold.substr(2, bold.length - 4)
|
||||
} as TextElementBold;
|
||||
}
|
24
src/mfm/parse/elements/code.ts
Normal file
24
src/mfm/parse/elements/code.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Code (block)
|
||||
*/
|
||||
|
||||
import genHtml from '../core/syntax-highlighter';
|
||||
|
||||
export type TextElementCode = {
|
||||
type: 'code'
|
||||
content: string
|
||||
code: string
|
||||
html: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^```([\s\S]+?)```/);
|
||||
if (!match) return null;
|
||||
const code = match[0];
|
||||
return {
|
||||
type: 'code',
|
||||
content: code,
|
||||
code: code.substr(3, code.length - 6).trim(),
|
||||
html: genHtml(code.substr(3, code.length - 6).trim())
|
||||
} as TextElementCode;
|
||||
}
|
20
src/mfm/parse/elements/emoji.ts
Normal file
20
src/mfm/parse/elements/emoji.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Emoji
|
||||
*/
|
||||
|
||||
export type TextElementEmoji = {
|
||||
type: 'emoji'
|
||||
content: string
|
||||
emoji: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^:[a-zA-Z0-9+-_]+:/);
|
||||
if (!match) return null;
|
||||
const emoji = match[0];
|
||||
return {
|
||||
type: 'emoji',
|
||||
content: emoji,
|
||||
emoji: emoji.substr(1, emoji.length - 2)
|
||||
} as TextElementEmoji;
|
||||
}
|
25
src/mfm/parse/elements/hashtag.ts
Normal file
25
src/mfm/parse/elements/hashtag.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Hashtag
|
||||
*/
|
||||
|
||||
export type TextElementHashtag = {
|
||||
type: 'hashtag'
|
||||
content: string
|
||||
hashtag: string
|
||||
};
|
||||
|
||||
export default function(text: string, i: number) {
|
||||
if (!(/^\s#[^\s]+/.test(text) || (i == 0 && /^#[^\s]+/.test(text)))) return null;
|
||||
const isHead = text[0] == '#';
|
||||
const hashtag = text.match(/^\s?#[^\s]+/)[0];
|
||||
const res: any[] = !isHead ? [{
|
||||
type: 'text',
|
||||
content: text[0]
|
||||
}] : [];
|
||||
res.push({
|
||||
type: 'hashtag',
|
||||
content: isHead ? hashtag : hashtag.substr(1),
|
||||
hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2)
|
||||
});
|
||||
return res as TextElementHashtag[];
|
||||
}
|
24
src/mfm/parse/elements/inline-code.ts
Normal file
24
src/mfm/parse/elements/inline-code.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Code (inline)
|
||||
*/
|
||||
|
||||
import genHtml from '../core/syntax-highlighter';
|
||||
|
||||
export type TextElementInlineCode = {
|
||||
type: 'inline-code'
|
||||
content: string
|
||||
code: string
|
||||
html: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^`(.+?)`/);
|
||||
if (!match) return null;
|
||||
const code = match[0];
|
||||
return {
|
||||
type: 'inline-code',
|
||||
content: code,
|
||||
code: code.substr(1, code.length - 2).trim(),
|
||||
html: genHtml(code.substr(1, code.length - 2).trim())
|
||||
} as TextElementInlineCode;
|
||||
}
|
27
src/mfm/parse/elements/link.ts
Normal file
27
src/mfm/parse/elements/link.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Link
|
||||
*/
|
||||
|
||||
export type TextElementLink = {
|
||||
type: 'link'
|
||||
content: string
|
||||
title: string
|
||||
url: string
|
||||
silent: boolean
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^\??\[([^\[\]]+?)\]\((https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+?)\)/);
|
||||
if (!match) return null;
|
||||
const silent = text[0] == '?';
|
||||
const link = match[0];
|
||||
const title = match[1];
|
||||
const url = match[2];
|
||||
return {
|
||||
type: 'link',
|
||||
content: link,
|
||||
title: title,
|
||||
url: url,
|
||||
silent: silent
|
||||
} as TextElementLink;
|
||||
}
|
24
src/mfm/parse/elements/mention.ts
Normal file
24
src/mfm/parse/elements/mention.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Mention
|
||||
*/
|
||||
import parseAcct from '../../../acct/parse';
|
||||
|
||||
export type TextElementMention = {
|
||||
type: 'mention'
|
||||
content: string
|
||||
username: string
|
||||
host: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^@[a-z0-9_]+(?:@[a-z0-9\.\-]+[a-z0-9])?/i);
|
||||
if (!match) return null;
|
||||
const mention = match[0];
|
||||
const { username, host } = parseAcct(mention.substr(1));
|
||||
return {
|
||||
type: 'mention',
|
||||
content: mention,
|
||||
username,
|
||||
host
|
||||
} as TextElementMention;
|
||||
}
|
20
src/mfm/parse/elements/quote.ts
Normal file
20
src/mfm/parse/elements/quote.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Quoted text
|
||||
*/
|
||||
|
||||
export type TextElementQuote = {
|
||||
type: 'quote'
|
||||
content: string
|
||||
quote: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^"([\s\S]+?)\n"/);
|
||||
if (!match) return null;
|
||||
const quote = match[0];
|
||||
return {
|
||||
type: 'quote',
|
||||
content: quote,
|
||||
quote: quote.substr(1, quote.length - 2).trim(),
|
||||
} as TextElementQuote;
|
||||
}
|
19
src/mfm/parse/elements/search.ts
Normal file
19
src/mfm/parse/elements/search.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Search
|
||||
*/
|
||||
|
||||
export type TextElementSearch = {
|
||||
type: 'search'
|
||||
content: string
|
||||
query: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^(.+?) 検索(\n|$)/);
|
||||
if (!match) return null;
|
||||
return {
|
||||
type: 'search',
|
||||
content: match[0],
|
||||
query: match[1]
|
||||
};
|
||||
}
|
20
src/mfm/parse/elements/title.ts
Normal file
20
src/mfm/parse/elements/title.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Title
|
||||
*/
|
||||
|
||||
export type TextElementTitle = {
|
||||
type: 'title'
|
||||
content: string
|
||||
title: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^【(.+?)】\n/);
|
||||
if (!match) return null;
|
||||
const title = match[0];
|
||||
return {
|
||||
type: 'title',
|
||||
content: title,
|
||||
title: title.substr(1, title.length - 3)
|
||||
} as TextElementTitle;
|
||||
}
|
20
src/mfm/parse/elements/url.ts
Normal file
20
src/mfm/parse/elements/url.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
|
||||
export type TextElementUrl = {
|
||||
type: 'url'
|
||||
content: string
|
||||
url: string
|
||||
};
|
||||
|
||||
export default function(text: string) {
|
||||
const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/);
|
||||
if (!match) return null;
|
||||
const url = match[0];
|
||||
return {
|
||||
type: 'url',
|
||||
content: url,
|
||||
url: url
|
||||
} as TextElementUrl;
|
||||
}
|
Reference in New Issue
Block a user