[noImplicitAny: true] src/text
This commit is contained in:
		
							parent
							
								
									871f886702
								
							
						
					
					
						commit
						8c40917cc2
					
				|  | @ -216,5 +216,8 @@ | |||
| 		"websocket": "1.0.26", | ||||
| 		"ws": "5.2.0", | ||||
| 		"xev": "2.0.1" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@types/jsdom": "11.0.5" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| import { lib as emojilib } from 'emojilib'; | ||||
| const { lib: emojilib } = require('emojilib'); | ||||
| import { JSDOM } from 'jsdom'; | ||||
| import config from '../config'; | ||||
| import { INote } from '../models/note'; | ||||
| import { TextElement } from './parse'; | ||||
| 
 | ||||
| const handlers: {[key: string]: (window: any, token: any, mentionedRemoteUsers: INote["mentionedRemoteUsers"]) => void} = { | ||||
| 	bold({ document }, { bold }) { | ||||
|  | @ -90,7 +91,7 @@ const handlers: {[key: string]: (window: any, token: any, mentionedRemoteUsers: | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export default (tokens, mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) => { | ||||
| export default (tokens: TextElement[], mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) => { | ||||
| 	const { window } = new JSDOM(''); | ||||
| 
 | ||||
| 	for (const token of tokens) { | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| function escape(text) { | ||||
| function escape(text: string) { | ||||
| 	return text | ||||
| 		.replace(/>/g, '>') | ||||
| 		.replace(/</g, '<'); | ||||
|  | @ -110,7 +110,14 @@ const symbols = [ | |||
| 	'?' | ||||
| ]; | ||||
| 
 | ||||
| const elements = [ | ||||
| type Token = { | ||||
| 	html: string | ||||
| 	next: number | ||||
| }; | ||||
| 
 | ||||
| type Element = (code: string, i: number, source: string) => (Token | null); | ||||
| 
 | ||||
| const elements: Element[] = [ | ||||
| 	// comment
 | ||||
| 	code => { | ||||
| 		if (code.substr(0, 2) != '//') return null; | ||||
|  | @ -305,7 +312,7 @@ export default (source: string, lang?: string) => { | |||
| 
 | ||||
| 	let i = 0; | ||||
| 
 | ||||
| 	function push(token) { | ||||
| 	function push(token: Token) { | ||||
| 		html += token.html; | ||||
| 		code = code.substr(token.next); | ||||
| 		i += token.next; | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Bold | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -10,5 +16,5 @@ module.exports = text => { | |||
| 		type: 'bold', | ||||
| 		content: bold, | ||||
| 		bold: bold.substr(2, bold.length - 4) | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementBold; | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,14 @@ | |||
| 
 | ||||
| import genHtml from '../core/syntax-highlighter'; | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -13,5 +20,5 @@ module.exports = text => { | |||
| 		content: code, | ||||
| 		code: code.substr(3, code.length - 6).trim(), | ||||
| 		html: genHtml(code.substr(3, code.length - 6).trim()) | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementCode; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Emoji | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -10,5 +16,5 @@ module.exports = text => { | |||
| 		type: 'emoji', | ||||
| 		content: emoji, | ||||
| 		emoji: emoji.substr(1, emoji.length - 2) | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementEmoji; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Hashtag | ||||
|  */ | ||||
| 
 | ||||
| module.exports = (text, i) => { | ||||
| 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]; | ||||
|  | @ -15,5 +21,5 @@ module.exports = (text, i) => { | |||
| 		content: isHead ? hashtag : hashtag.substr(1), | ||||
| 		hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2) | ||||
| 	}); | ||||
| 	return res; | ||||
| }; | ||||
| 	return res as TextElementHashtag[]; | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,14 @@ | |||
| 
 | ||||
| import genHtml from '../core/syntax-highlighter'; | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -13,5 +20,5 @@ module.exports = text => { | |||
| 		content: code, | ||||
| 		code: code.substr(1, code.length - 2).trim(), | ||||
| 		html: genHtml(code.substr(1, code.length - 2).trim()) | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementInlineCode; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,15 @@ | |||
|  * Link | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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] == '?'; | ||||
|  | @ -15,5 +23,5 @@ module.exports = text => { | |||
| 		title: title, | ||||
| 		url: url, | ||||
| 		silent: silent | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementLink; | ||||
| } | ||||
|  |  | |||
|  | @ -3,7 +3,14 @@ | |||
|  */ | ||||
| import parseAcct from '../../../acct/parse'; | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -13,5 +20,5 @@ module.exports = text => { | |||
| 		content: mention, | ||||
| 		username, | ||||
| 		host | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementMention; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Quoted text | ||||
|  */ | ||||
| 
 | ||||
| module.exports = 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]; | ||||
|  | @ -10,5 +16,5 @@ module.exports = text => { | |||
| 		type: 'quote', | ||||
| 		content: quote, | ||||
| 		quote: quote.substr(1, quote.length - 2).trim(), | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementQuote; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Search | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| export type TextElementSearch = { | ||||
| 	type: "search" | ||||
| 	content: string | ||||
| 	query: string | ||||
| }; | ||||
| 
 | ||||
| export default function(text: string) { | ||||
| 	const match = text.match(/^(.+?) 検索(\n|$)/); | ||||
| 	if (!match) return null; | ||||
| 	return { | ||||
|  | @ -10,4 +16,4 @@ module.exports = text => { | |||
| 		content: match[0], | ||||
| 		query: match[1] | ||||
| 	}; | ||||
| }; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * Title | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -10,5 +16,5 @@ module.exports = text => { | |||
| 		type: 'title', | ||||
| 		content: title, | ||||
| 		title: title.substr(1, title.length - 3) | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementTitle; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,13 @@ | |||
|  * URL | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text => { | ||||
| 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]; | ||||
|  | @ -10,5 +16,5 @@ module.exports = text => { | |||
| 		type: 'url', | ||||
| 		content: url, | ||||
| 		url: url | ||||
| 	}; | ||||
| }; | ||||
| 	} as TextElementUrl; | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,18 @@ | |||
|  * Misskey Text Analyzer | ||||
|  */ | ||||
| 
 | ||||
| import { TextElementBold } from "./elements/bold"; | ||||
| import { TextElementCode } from "./elements/code"; | ||||
| import { TextElementEmoji } from "./elements/emoji"; | ||||
| import { TextElementHashtag } from "./elements/hashtag"; | ||||
| import { TextElementInlineCode } from "./elements/inline-code"; | ||||
| import { TextElementLink } from "./elements/link"; | ||||
| import { TextElementMention } from "./elements/mention"; | ||||
| import { TextElementQuote } from "./elements/quote"; | ||||
| import { TextElementSearch } from "./elements/search"; | ||||
| import { TextElementTitle } from "./elements/title"; | ||||
| import { TextElementUrl } from "./elements/url"; | ||||
| 
 | ||||
| const elements = [ | ||||
| 	require('./elements/bold'), | ||||
| 	require('./elements/title'), | ||||
|  | @ -14,17 +26,31 @@ const elements = [ | |||
| 	require('./elements/quote'), | ||||
| 	require('./elements/emoji'), | ||||
| 	require('./elements/search') | ||||
| ]; | ||||
| ].map(element => element.default as TextElementProcessor); | ||||
| 
 | ||||
| export default (source: string): any[] => { | ||||
| export type TextElement = {type: "text", content: string} | ||||
| 	| TextElementBold | ||||
| 	| TextElementCode | ||||
| 	| TextElementEmoji | ||||
| 	| TextElementHashtag | ||||
| 	| TextElementInlineCode | ||||
| 	| TextElementLink | ||||
| 	| TextElementMention | ||||
| 	| TextElementQuote | ||||
| 	| TextElementSearch | ||||
| 	| TextElementTitle | ||||
| 	| TextElementUrl; | ||||
| export type TextElementProcessor = (text: string, i: number) => TextElement | TextElement[]; | ||||
| 
 | ||||
| export default (source: string): TextElement[] => { | ||||
| 
 | ||||
| 	if (source == '') { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	const tokens = []; | ||||
| 	const tokens: TextElement[] = []; | ||||
| 
 | ||||
| 	function push(token) { | ||||
| 	function push(token: TextElement) { | ||||
| 		if (token != null) { | ||||
| 			tokens.push(token); | ||||
| 			source = source.substr(token.content.length); | ||||
|  | @ -59,9 +85,8 @@ export default (source: string): any[] => { | |||
| 	} | ||||
| 
 | ||||
| 	// テキストを纏める
 | ||||
| 	tokens[0] = [tokens[0]]; | ||||
| 	return tokens.reduce((a, b) => { | ||||
| 		if (a[a.length - 1].type == 'text' && b.type == 'text') { | ||||
| 		if (a.length && a[a.length - 1].type == 'text' && b.type == 'text') { | ||||
| 			const tail = a.pop(); | ||||
| 			return a.concat({ | ||||
| 				type: 'text', | ||||
|  | @ -70,5 +95,5 @@ export default (source: string): any[] => { | |||
| 		} else { | ||||
| 			return a.concat(b); | ||||
| 		} | ||||
| 	}); | ||||
| 	}, [] as TextElement[]); | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										15
									
								
								yarn.lock
								
								
								
								
							
							
						
						
									
										15
									
								
								yarn.lock
								
								
								
								
							|  | @ -277,6 +277,15 @@ | |||
|   version "3.11.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.11.1.tgz#ac5bab26be5f9c6f74b6b23420f2cfa5a7a6ba40" | ||||
| 
 | ||||
| "@types/jsdom@11.0.5": | ||||
|   version "11.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-11.0.5.tgz#b12fffc73eb3731b218e9665a50f023b6b84b5cb" | ||||
|   dependencies: | ||||
|     "@types/events" "*" | ||||
|     "@types/node" "*" | ||||
|     "@types/tough-cookie" "*" | ||||
|     parse5 "^3.0.2" | ||||
| 
 | ||||
| "@types/keygrip@*": | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.1.tgz#ff540462d2fb4d0a88441ceaf27d287b01c3d878" | ||||
|  | @ -8221,6 +8230,12 @@ parse5@4.0.0: | |||
|   version "4.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" | ||||
| 
 | ||||
| parse5@^3.0.2: | ||||
|   version "3.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| parseurl@^1.3.0, parseurl@~1.3.2: | ||||
|   version "1.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue