This commit is contained in:
syuilo 2018-02-27 12:32:01 +09:00
parent f2e62377bd
commit 72d20418c9
5 changed files with 77 additions and 15 deletions

View 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(),
};
};

View file

@ -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;

View file

@ -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);
} }
}); });

View file

@ -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

View file

@ -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