This commit is contained in:
		
							
								
								
									
										14
									
								
								src/api/common/text/elements/quote.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/api/common/text/elements/quote.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | /** | ||||||
|  |  * Quoted text | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module.exports = text => { | ||||||
|  | 	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(), | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
| @@ -10,6 +10,7 @@ const elements = [ | |||||||
| 	require('./elements/hashtag'), | 	require('./elements/hashtag'), | ||||||
| 	require('./elements/code'), | 	require('./elements/code'), | ||||||
| 	require('./elements/inline-code'), | 	require('./elements/inline-code'), | ||||||
|  | 	require('./elements/quote'), | ||||||
| 	require('./elements/emoji') | 	require('./elements/emoji') | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| @@ -33,12 +34,12 @@ export default (source: string) => { | |||||||
| 	// パース | 	// パース | ||||||
| 	while (source != '') { | 	while (source != '') { | ||||||
| 		const parsed = elements.some(el => { | 		const parsed = elements.some(el => { | ||||||
| 			let tokens = el(source, i); | 			let _tokens = el(source, i); | ||||||
| 			if (tokens) { | 			if (_tokens) { | ||||||
| 				if (!Array.isArray(tokens)) { | 				if (!Array.isArray(_tokens)) { | ||||||
| 					tokens = [tokens]; | 					_tokens = [_tokens]; | ||||||
| 				} | 				} | ||||||
| 				tokens.forEach(push); | 				_tokens.forEach(push); | ||||||
| 				return true; | 				return true; | ||||||
| 			} else { | 			} else { | ||||||
| 				return false; | 				return false; | ||||||
|   | |||||||
| @@ -3,6 +3,10 @@ import * as emojilib from 'emojilib'; | |||||||
| import { url } from '../../../config'; | import { url } from '../../../config'; | ||||||
| import MkUrl from './url.vue'; | import MkUrl from './url.vue'; | ||||||
|  |  | ||||||
|  | const flatten = list => list.reduce( | ||||||
|  | 	(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), [] | ||||||
|  | ); | ||||||
|  |  | ||||||
| export default Vue.component('mk-post-html', { | export default Vue.component('mk-post-html', { | ||||||
| 	props: { | 	props: { | ||||||
| 		ast: { | 		ast: { | ||||||
| @@ -19,20 +23,16 @@ export default Vue.component('mk-post-html', { | |||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	render(createElement) { | 	render(createElement) { | ||||||
| 		const els = [].concat.apply([], (this as any).ast.map(token => { | 		const els = flatten((this as any).ast.map(token => { | ||||||
| 			switch (token.type) { | 			switch (token.type) { | ||||||
| 				case 'text': | 				case 'text': | ||||||
| 					const text = token.content.replace(/(\r\n|\n|\r)/g, '\n'); | 					const text = token.content.replace(/(\r\n|\n|\r)/g, '\n'); | ||||||
|  |  | ||||||
| 					if ((this as any).shouldBreak) { | 					if ((this as any).shouldBreak) { | ||||||
| 						if (text.indexOf('\n') != -1) { |  | ||||||
| 						const x = text.split('\n') | 						const x = text.split('\n') | ||||||
| 								.map(t => [createElement('span', t), createElement('br')]); | 							.map(t => t == '' ? [createElement('br')] : [createElement('span', t), createElement('br')]); | ||||||
| 						x[x.length - 1].pop(); | 						x[x.length - 1].pop(); | ||||||
| 						return x; | 						return x; | ||||||
| 						} else { |  | ||||||
| 							return createElement('span', text); |  | ||||||
| 						} |  | ||||||
| 					} else { | 					} else { | ||||||
| 						return createElement('span', text.replace(/\n/g, ' ')); | 						return createElement('span', text.replace(/\n/g, ' ')); | ||||||
| 					} | 					} | ||||||
| @@ -91,12 +91,46 @@ export default Vue.component('mk-post-html', { | |||||||
| 				case 'inline-code': | 				case 'inline-code': | ||||||
| 					return createElement('code', token.html); | 					return createElement('code', token.html); | ||||||
|  |  | ||||||
|  | 				case 'quote': | ||||||
|  | 					const text2 = token.quote.replace(/(\r\n|\n|\r)/g, '\n'); | ||||||
|  |  | ||||||
|  | 					if ((this as any).shouldBreak) { | ||||||
|  | 						const x = text2.split('\n') | ||||||
|  | 							.map(t => [createElement('span', t), createElement('br')]); | ||||||
|  | 						x[x.length - 1].pop(); | ||||||
|  | 						return createElement('div', { | ||||||
|  | 							attrs: { | ||||||
|  | 								class: 'quote' | ||||||
|  | 							} | ||||||
|  | 						}, x); | ||||||
|  | 					} else { | ||||||
|  | 						return createElement('span', { | ||||||
|  | 							attrs: { | ||||||
|  | 								class: 'quote' | ||||||
|  | 							} | ||||||
|  | 						}, text2.replace(/\n/g, ' ')); | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 				case 'emoji': | 				case 'emoji': | ||||||
| 					const emoji = emojilib.lib[token.emoji]; | 					const emoji = emojilib.lib[token.emoji]; | ||||||
| 					return createElement('span', emoji ? emoji.char : token.content); | 					return createElement('span', emoji ? emoji.char : token.content); | ||||||
|  |  | ||||||
|  | 				default: | ||||||
|  | 					console.log('unknown ast type:', token.type); | ||||||
| 			} | 			} | ||||||
| 		})); | 		})); | ||||||
|  |  | ||||||
| 		return createElement('span', els); | 		const _els = []; | ||||||
|  | 		els.forEach((el, i) => { | ||||||
|  | 			if (el.tag == 'br') { | ||||||
|  | 				if (els[i - 1].tag != 'div') { | ||||||
|  | 					_els.push(el); | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				_els.push(el); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		return createElement('span', _els); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -416,6 +416,12 @@ export default Vue.extend({ | |||||||
| 					font-size 1.1em | 					font-size 1.1em | ||||||
| 					color #717171 | 					color #717171 | ||||||
|  |  | ||||||
|  | 					>>> .quote | ||||||
|  | 						margin 8px | ||||||
|  | 						padding 6px 12px | ||||||
|  | 						color #aaa | ||||||
|  | 						border-left solid 3px #eee | ||||||
|  |  | ||||||
| 					.mk-url-preview | 					.mk-url-preview | ||||||
| 						margin-top 8px | 						margin-top 8px | ||||||
|  |  | ||||||
| @@ -512,6 +518,7 @@ export default Vue.extend({ | |||||||
|  |  | ||||||
| <style lang="stylus" module> | <style lang="stylus" module> | ||||||
| .text | .text | ||||||
|  |  | ||||||
| 	code | 	code | ||||||
| 		padding 4px 8px | 		padding 4px 8px | ||||||
| 		margin 0 0.5em | 		margin 0 0.5em | ||||||
|   | |||||||
| @@ -349,6 +349,12 @@ export default Vue.extend({ | |||||||
| 					font-size 1.1em | 					font-size 1.1em | ||||||
| 					color #717171 | 					color #717171 | ||||||
|  |  | ||||||
|  | 					>>> .quote | ||||||
|  | 						margin 8px | ||||||
|  | 						padding 6px 12px | ||||||
|  | 						color #aaa | ||||||
|  | 						border-left solid 3px #eee | ||||||
|  |  | ||||||
| 					.mk-url-preview | 					.mk-url-preview | ||||||
| 						margin-top 8px | 						margin-top 8px | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo