Merge pull request #24 from doocs/feature-code-snippet

Feature code snippet
This commit is contained in:
Yang Libin 2020-07-28 20:55:38 +08:00 committed by GitHub
commit 27b8fe99b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 200 additions and 115 deletions

View File

@ -13,7 +13,6 @@
<link rel="apple-touch-icon-precomposed" <link rel="apple-touch-icon-precomposed"
href="https://imgkr.cn-bj.ufileos.com/f3accc83-b854-4e99-afb5-8a6465e1d84f.png"> href="https://imgkr.cn-bj.ufileos.com/f3accc83-b854-4e99-afb5-8a6465e1d84f.png">
<script src="https://cdn.bootcdn.net/ajax/libs/prettify/r224/prettify.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/prettify/r224/prettify.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/prettify/r224/prettify.min.css" rel="stylesheet">
</head> </head>
<body> <body>

View File

@ -1,3 +1,4 @@
@import './code-theme.less';
* { * {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
@ -154,69 +155,6 @@ section {
cursor: pointer; cursor: pointer;
} }
/*wechat code block*/
.rich_media_content .code-snippet *,
.rich_media_content .code-snippet__fix * {
max-width: 1000% !important;
}
.code-snippet__fix {
word-wrap: break-word !important;
font-size: 14px;
margin: 10px 8px;
color: #333;
position: relative;
background-color: rgb(238, 238, 238);
border: 1px solid #f0f0f0;
border-radius: 2px;
display: flex;
line-height: 24px;
}
.code-snippet__fix .code-snippet__line-index {
counter-reset: line;
flex-shrink: 0;
height: 100%;
padding: 1em;
list-style-type: none;
}
.code-snippet__fix .code-snippet__line-index li {
list-style-type: none;
text-align: right;
}
.code-snippet__fix .code-snippet__line-index li::before {
min-width: 1.5em;
text-align: right;
left: -2.5em;
counter-increment: line;
content: counter(line);
display: inline;
color: rgba(0, 0, 0, 0.15);
}
.code-snippet__fix pre {
overflow-x: auto;
padding: 1em 1em 1em 1em;
white-space: normal;
flex: 1;
-webkit-overflow-scrolling: touch;
}
.code-snippet__fix code {
text-align: left;
font-size: 14px;
white-space: pre;
display: flex;
position: relative;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.code-snippet__fix ul li {
list-style: none;
}
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px; height: 6px;

View File

@ -0,0 +1,2 @@
@import './codeTheme/wechat-code-block.less';
@import './codeTheme/github-code-block.less';

View File

@ -0,0 +1,47 @@
/*github code block*/
.code-snippet__github {
display: flex;
font-size: 12px;
margin: 10px 8px;
position: relative;
height: auto;
background-color: rgba(27,31,35,.05);
.code-snippet__line-index {
display: none;
}
.code__pre {
display: grid;
position: relative;
counter-reset: line;
overflow-x: auto;
padding: 1em;
white-space: normal;
flex: 1;
line-height: 20px;
font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;
-webkit-overflow-scrolling: touch;
}
pre {
display: inline-block;
font-size: 12px;
}
code {
display: flex;
position: relative;
padding-right: 8px;
text-align: left;
white-space: pre;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
&::before {
display: none;
}
}
ul li {
list-style: none;
}
}

View File

@ -0,0 +1,62 @@
/*wechat code block*/
.rich_media_content .code-snippet *,
.rich_media_content .code-snippet__wechat * {
max-width: 1000% !important;
}
.code-snippet__wechat {
word-wrap: break-word !important;
font-size: 14px;
margin: 10px 8px;
color: #333;
position: relative;
background-color: rgba(27, 31, 35, .05);
border: 1px solid #f0f0f0;
border-radius: 2px;
display: flex;
line-height: 24px;
}
.code-snippet__wechat .code-snippet__line-index {
counter-reset: line;
flex-shrink: 0;
height: 100%;
padding: 1em;
list-style-type: none;
}
.code-snippet__wechat .code-snippet__line-index li {
list-style-type: none;
text-align: right;
}
.code-snippet__wechat .code-snippet__line-index li::before {
min-width: 1.5em;
text-align: right;
left: -2.5em;
counter-increment: line;
content: counter(line);
display: inline;
color: rgba(0, 0, 0, 0.15);
}
.code-snippet__wechat pre {
overflow-x: auto;
padding: 1em 1em 1em 1em;
white-space: normal;
flex: 1;
-webkit-overflow-scrolling: touch;
}
.code-snippet__wechat code {
text-align: left;
font-size: 14px;
white-space: pre;
display: flex;
position: relative;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.code-snippet__wechat ul li {
list-style: none;
}

2
src/assets/less/github-v2.min.css vendored Normal file
View File

@ -0,0 +1,2 @@
/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
.prettyprint{font-family:Menlo,Bitstream Vera Sans Mono,DejaVu Sans Mono,Monaco,Consolas,monospace;border:0!important}.pln{color:#333}ol.linenums{margin-top:0;margin-bottom:0;color:#ccc}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{padding-left:1em;background-color:#fff;list-style-type:decimal}@media screen{.str{color:#183691}.kwd{color:#a71d5d}.com{color:#969896}.typ{color:#0086b3}.lit{color:#0086b3}.pun{color:#333}.opn{color:#333}.clo{color:#333}.tag{color:navy}.atn{color:#795da3}.atv{color:#183691}.dec{color:#333}.var{color:teal}.fun{color:#900}}

View File

@ -37,17 +37,29 @@ export default {
colorOption: [{ colorOption: [{
label: '经典蓝', label: '经典蓝',
value: 'rgba(15, 76, 129, 1)', value: 'rgba(15, 76, 129, 1)',
hex: '最新流行' desc: '最新流行'
}, },
{ {
label: '翡翠绿', label: '翡翠绿',
value: 'rgba(0, 152, 116, 1)', value: 'rgba(0, 152, 116, 1)',
hex: '优雅清新' desc: '优雅清新'
}, },
{ {
label: '活力橘', label: '活力橘',
value: 'rgba(250, 81, 81, 1)', value: 'rgba(250, 81, 81, 1)',
hex: '热情活泼' desc: '热情活泼'
}
],
codeThemeOption: [
{
label: '微信',
value: 'wechat',
desc: '默认样式'
},
{
label: 'GitHub',
value: 'github',
desc: '精简风格'
} }
], ],
form: { form: {

View File

@ -1,4 +1,5 @@
import marked from 'marked' import marked from 'marked';
import store from '../../../store/index';
const WxRenderer = function (opts) { const WxRenderer = function (opts) {
this.opts = opts this.opts = opts
let ENV_STRETCH_IMAGE = true let ENV_STRETCH_IMAGE = true
@ -68,22 +69,22 @@ const WxRenderer = function (opts) {
this.buildAddition = () => { this.buildAddition = () => {
return ` return `
<style> <style>
.preview-wrapper pre::before { .preview-wrapper pre::before {
font-family: "SourceSansPro", "HelveticaNeue", Arial, sans-serif; font-family: "SourceSansPro", "HelveticaNeue", Arial, sans-serif;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
color: #ccc; color: #ccc;
text-align: center; text-align: center;
font-size: 0.8em; font-size: 0.8em;
padding: 5px 10px 0; padding: 5px 10px 0;
line-height: 15px; line-height: 15px;
height: 15px; height: 15px;
font-weight: 600; font-weight: 600;
} }
</style> </style>
` `
} }
this.setOptions = newOpts => { this.setOptions = newOpts => {
@ -135,16 +136,15 @@ const WxRenderer = function (opts) {
codeLines.push(`<code class="prettyprint"><span class="code-snippet_outer">${(line || '<br>')}</span></code>`) codeLines.push(`<code class="prettyprint"><span class="code-snippet_outer">${(line || '<br>')}</span></code>`)
numbers.push('<li></li>') numbers.push('<li></li>')
} }
let lang = infoString || '' const lang = infoString || '';
const codeTheme = 'github';
return ` return `
<section class="code-snippet__fix code-snippet__js"> <section class="code-snippet__${codeTheme}">
<ul class="code-snippet__line-index code-snippet__js">${numbers.join('')}</ul> <pre class="code__pre" data-lang="${lang}">
<pre class="code__pre code-snippet__js" data-lang="${lang}"> ${codeLines.join('')}
${codeLines.join('')} </pre>
</pre> </section>
</section> `;
`
} }
renderer.codespan = (text, infoString) => `<code ${getStyles('codespan')}>${text}</code>` renderer.codespan = (text, infoString) => `<code ${getStyles('codespan')}>${text}</code>`
renderer.listitem = text => `<span ${getStyles('listitem')}><span style="margin-right: 10px;"><%s/></span>${text}</span>` renderer.listitem = text => `<span ${getStyles('listitem')}><span style="margin-right: 10px;"><%s/></span>${text}</span>`

View File

@ -23,29 +23,29 @@
</el-tooltip> </el-tooltip>
<el-form size="mini" class="ctrl" :inline=true> <el-form size="mini" class="ctrl" :inline=true>
<el-form-item> <el-form-item>
<el-select v-model="selectFont" size="mini" placeholder="选择字体" clearable @change="fontChanged"> <el-select v-model="selectFont" size="mini" placeholder="选择字体" clearable @change="fontChanged">
<el-option v-for="font in config.builtinFonts" :style="{fontFamily: font.value}" :key="font.value" <el-option v-for="font in config.builtinFonts" :style="{fontFamily: font.value}" :key="font.value"
:label="font.label" :value="font.value"> :label="font.label" :value="font.value">
<span class="select-item-left">{{ font.label }}</span> <span class="select-item-left">{{ font.label }}</span>
<span class="select-item-right">Abc</span> <span class="select-item-right">Abc</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-select v-model="selectSize" size="mini" placeholder="选择段落字号" clearable @change="sizeChanged"> <el-select v-model="selectSize" size="mini" placeholder="选择段落字号" clearable @change="sizeChanged">
<el-option v-for="size in config.sizeOption" :key="size.value" :label="size.label" :value="size.value"> <el-option v-for="size in config.sizeOption" :key="size.value" :label="size.label" :value="size.value">
<span class="select-item-left">{{ size.label }}</span> <span class="select-item-left">{{ size.label }}</span>
<span class="select-item-right">{{ size.desc }}</span> <span class="select-item-right">{{ size.desc }}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-select v-model="selectColor" size="mini" placeholder="选择颜色" clearable @change="colorChanged"> <el-select v-model="selectColor" size="mini" placeholder="选择颜色" clearable @change="colorChanged">
<el-option v-for="color in config.colorOption" :key="color.value" :label="color.label" :value="color.value"> <el-option v-for="color in config.colorOption" :key="color.value" :label="color.label" :value="color.value">
<span class="select-item-left">{{ color.label }}</span> <span class="select-item-left">{{ color.label }}</span>
<span class="select-item-right">{{ color.hex }}</span> <span class="select-item-right">{{ color.desc }}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-tooltip content="自定义颜色" :effect="effect" placement="top"> <el-tooltip content="自定义颜色" :effect="effect" placement="top">
<el-color-picker v-model="selectColor" size="mini" show-alpha @change="colorChanged"></el-color-picker> <el-color-picker v-model="selectColor" size="mini" show-alpha @change="colorChanged"></el-color-picker>
@ -94,7 +94,8 @@ export default {
showResetConfirm: false, showResetConfirm: false,
selectFont: '', selectFont: '',
selectSize: '', selectSize: '',
selectColor: '' selectColor: '',
selectCodeTheme: 'github'
}; };
}, },
components: { components: {
@ -114,6 +115,7 @@ export default {
currentFont: state=> state.currentFont, currentFont: state=> state.currentFont,
currentSize: state=> state.currentSize, currentSize: state=> state.currentSize,
currentColor: state=> state.currentColor, currentColor: state=> state.currentColor,
codeTheme: state=> state.codeTheme,
nightMode: state=> state.nightMode nightMode: state=> state.nightMode
}) })
}, },
@ -144,6 +146,10 @@ export default {
this.setCurrentColor(color); this.setCurrentColor(color);
this.$emit('refresh') this.$emit('refresh')
}, },
codeThemeChanged(theme) {
this.setCurrentCodeTheme(theme);
this.$emit('refresh')
},
statusChanged(val) { statusChanged(val) {
this.setCiteStatus(val) this.setCiteStatus(val)
this.$emit('refresh') this.$emit('refresh')
@ -231,13 +237,23 @@ export default {
this.showResetConfirm = false; this.showResetConfirm = false;
this.editor.focus() this.editor.focus()
}, },
...mapMutations(['clearEditorToDefault','setCurrentColor', 'setCiteStatus', 'themeChanged', ...mapMutations([
'setCurrentFont', 'setCurrentSize', 'setCssEditorValue', 'setWxRendererOptions']) 'clearEditorToDefault',
'setCurrentColor',
'setCiteStatus',
'themeChanged',
'setCurrentFont',
'setCurrentSize',
'setCssEditorValue',
'setCurrentCodeTheme',
'setWxRendererOptions'
])
}, },
mounted() { mounted() {
this.selectFont = this.currentFont; this.selectFont = this.currentFont;
this.selectSize = this.currentSize; this.selectSize = this.currentSize;
this.selectColor = this.currentColor; this.selectColor = this.currentColor;
this.selectCodeTheme = this.codeTheme;
} }
} }
</script> </script>

View File

@ -24,6 +24,7 @@ const state = {
currentColor: '', currentColor: '',
citeStatus: 0, citeStatus: 0,
nightMode: false, nightMode: false,
codeTheme: 'github',
rightClickMenuVisible: false rightClickMenuVisible: false
}; };
const mutations = { const mutations = {
@ -52,6 +53,10 @@ const mutations = {
state.currentColor = data; state.currentColor = data;
localStorage.setItem('color', data) localStorage.setItem('color', data)
}, },
setCurrentCodeTheme(state, data) {
state.codeTheme = data;
localStorage.setItem('codeTheme', data)
},
setRightClickMenuVisible(state, data) { setRightClickMenuVisible(state, data) {
state.rightClickMenuVisible = data; state.rightClickMenuVisible = data;
}, },
@ -62,6 +67,7 @@ const mutations = {
state.currentFont = localStorage.getItem('fonts') || config.builtinFonts[0].value state.currentFont = localStorage.getItem('fonts') || config.builtinFonts[0].value
state.currentColor = localStorage.getItem('color') || config.colorOption[1].value state.currentColor = localStorage.getItem('color') || config.colorOption[1].value
state.currentSize = localStorage.getItem('size') || config.sizeOption[2].value state.currentSize = localStorage.getItem('size') || config.sizeOption[2].value
state.codeTheme = localStorage.getItem('codeTheme') || config.codeThemeOption[0].value
state.citeStatus = localStorage.getItem('citeStatus') === 'true' state.citeStatus = localStorage.getItem('citeStatus') === 'true'
state.wxRenderer = new WxRenderer({ state.wxRenderer = new WxRenderer({
theme: setColor(state.currentColor), theme: setColor(state.currentColor),

View File

@ -405,5 +405,6 @@ export default {
<style lang="less"> <style lang="less">
@import url('../assets/less/app.less'); @import url('../assets/less/app.less');
@import url('../assets/less/style-mirror.css'); @import url('../assets/less/style-mirror.css');
@import url('../assets/less/github-v2.min.css');
</style> </style>