This commit is contained in:
		
							parent
							
								
									d24bb24c6e
								
							
						
					
					
						commit
						68dd705500
					
				
					 5 changed files with 77 additions and 15 deletions
				
			
		
							
								
								
									
										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 => t == '' ? [createElement('br')] : [createElement('span', t), createElement('br')]);
 | 
				
			||||||
								.map(t => [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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue