在網路技術文章內寫了程式碼卻沒上色,會讓人感覺瞬間降了一個層次
談到程式碼/語法上色,絕對是highlight.js這個library為首選
安裝
npm install highlight.js --save
客製化highlight.js plugin
檔案放在~/plugins/highlight.js,名稱可自訂
import hljs from 'highlight.js/lib/core.js'
import xml from 'highlight.js/lib/languages/xml'
import scss from 'highlight.js/lib/languages/scss'
import javascript from 'highlight.js/lib/languages/javascript'
import bash from 'highlight.js/lib/languages/bash'
import 'highlight.js/styles/tomorrow-night-bright.css'
import Vue from 'vue'
// register languages
hljs.registerLanguage('xml', xml)
hljs.registerLanguage('scss', scss)
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('bash', bash)
Vue.directive('highlight', function (el) {
let elements = el.querySelectorAll('pre.ql-syntax')
elements.forEach((element) => {
hljs.highlightElement(element)
})
})
第六行import你想要的上色主題樣式,預覽可看這裡
querySelectorAll內的'pre.ql-syntax' 乃客製化重點
取決於你的customized editor吐出來的html轉譯結果
我使用的vue-quill-editor吐出來是<pre>帶ql-syntax class
若使用其他editor套件,舉例來說,若吐出來是<pre><code>...</code></pre>
那就需要修改成'pre > code' 之類的相對應的選擇語法
舊版本使用hljs.highlightBlock()在v12.0會被遺棄,故這裡更新為hljs.highlightElement()
修改nuxt.config.js
plugins: [
{ src: '~plugins/highlight.js', ssr: true },
],
於component、page中使用
擷取一小段code作範例,使用上很簡單,要渲染的地方加上v-highlight即可
<section class="overflow-x-hidden">
<div id="content" v-highlight v-html="content"></div>
</section>
BONUS: 修改被highlight.js渲染的區塊的CSS
預設渲染區塊的樣式沒有border-radious
外加其他一些CSS小細節想改,此時須用到CSS deep selector!
這裡直接貼上Hamsterism使用的修改樣式,單就highlight.js的話,乃/deep/ .hljs
<style lang="scss" scoped>
#content {
/deep/ blockquote {
border-left: 4px solid $hamsterism-btn-color-primary;
margin-bottom: 5px;
margin-top: 5px;
padding: 0.5rem 1rem;
color: $hamsterism-text-color-dark;
background-color: $hamsterism-btn-color-secondary-light;
}
/deep/ code {
font-size: 85%;
padding: 2px 4px;
background-color: $hamsterism-btn-color-secondary-light;
border-radius: 3px;
}
/deep/ img {
max-width: 100%;
display: block;
margin: auto;
}
/deep/ .hljs {
border-radius: 5px;
padding: 1rem;
margin: 0.5rem 0;
background-color: $hamsterism-bg-color-primary;
}
}
</style>
在編輯頁面的部份,我沒法將highlight.js嵌入vue-quill-editor,故改以在editor外,另新增「預覽畫面」<div>的方式,在送出前來檢視文章編輯情況。
後記
Nuxt官網使用的上色library為Prism
其實由本文中的程式碼上色不難看出,highlight.js的自動判定語言有其缺陷存在
雖然我已限定只有bash、scss、xml、javascript四種語言
但判定上常常會抓錯(按F12看上色區塊被添加的css class可知)
由於我的部落格使用的是透過editor產出的raw html code
目前暫時無法做到指定區塊為特定語言渲染
(也許透過自定義highlight.js語言判定可實現吧?)
只能讓highlight.js統一抓'pre.ql-syntax' 內的結果
若看官們有什麼更好的workaround,歡迎來信交流!