highlight.js 语法高亮
简介
在nodejs
项目中使用第三方库highlight.js实现代码块的高亮显示,highlight.js
提供了大量的编程语言和高亮显示样式。
按照我博客文章的代码块高亮显示为例,我首先使用了markdown-it
把Markdown
文章解析为html
,然后利用highlight.js
做到代码块的高亮显示。
思路
配置语法高亮
// 引入 highlight.js (包含所有语言)
const hljs = require('highlight.js')
// 定义 markdown-it 的语法高亮函数 highlight
const highlight = (str, lang) => {
let code = md.utils.escapeHtml(str)
if (lang && hljs.getLanguage(lang)) {
code = hljs.highlight(lang, str, true).value
}
return `<pre class="hljs"><code>${code}</code></pre>`
}
// 引入 markdown-it
// 在创建实例时传入刚才定义的 highlight函数 来配置语法高亮
const md = require('markdown-it')({ highlight })
highlight 函数
对于markdown-it
的语法高亮函数,markdown-it
解析到Markdown
文件的代码块,比如:
```javascript
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(port, () => {
console.log(`http://localhost:${port}`)
})
```
上面就是一个Markdown
的代码块语法,markdown-it
会把其中的代码传入highlight
函数的第一个参数,而代码块开头标志后的javascript
则会传入到highlight
函数的第二个参数。
所以上面代码中的highlight
函数接受这两个参数(str, lang)
,首先md.utils.escapeHtml(str)
是用来转义,具体解释请查看文末的补充内容,然后再使用第三方库highlight.js
的hljs.highlight(lang, str, true).value
(查看API详解)把代码解析成span
标签带类名的形式,比如:
<span class="hljs-keyword">const</span> express =
<span class="hljs-built_in">require</span>
这样就只需要在html
中引入样式就可以了。
css 样式
highlight.js
中提供了很多的样式,你可以在nodejs
的node_modules
中拿出来使用。
/node_modules/highlight.js/styles
中的css
文件复制出来用就好了。
这么多css
找一个自己喜欢的,也可以自己定义,查看官方所有样式效果Demo。
完整案例
express
const express = require('express')
const app = express()
const port = 3000
// 引入 highlight.js 并配置到 markdown-it
const hljs = require('highlight.js')
const highlight = (str, lang) => {
let code = md.utils.escapeHtml(str)
if (lang && hljs.getLanguage(lang)) {
code = hljs.highlight(lang, str, true).value
}
return `<pre class="hljs"><code>${code}</code></pre>`
}
const md = require('markdown-it')({ highlight })
const fs = require('fs')
const path = require('path')
// 配置模板引擎 art-template
app.engine('html', require('express-art-template'))
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
// 静态资源
app.use('/public', express.static(path.join(__dirname, 'public')))
app.get('/', (req, res) => {
// 读取 example.md Markdown文件
const fileString = fs.readFileSync('example.md').toString()
const htmlResult = md.render(fileString)
// 模板渲染 index.html
res.render('index', { content: htmlResult })
})
app.listen(port, () => {
console.log(`http://localhost:${port}`)
})
模板引擎
/views/index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="/public/css/github.css">
</head>
<body>
<div>{{@content}}</div>
</body>
</html>
Markdown
/example.md
文件:
```javascript
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(port, () => {
console.log(`http://localhost:${port}`)
})
```
效果
补充
MarkdownIt.utils
官方文档中也没用过多的展开解释utils
,让我们查看它的源码:
var HTML_ESCAPE_TEST_RE = /[&<>"]/;
var HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;
var HTML_REPLACEMENTS = {
'&': '&',
'<': '<',
'>': '>',
'"': '"'
};
function replaceUnsafeChar(ch) {
return HTML_REPLACEMENTS[ch];
}
function escapeHtml(str) {
if (HTML_ESCAPE_TEST_RE.test(str)) {
return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);
}
return str;
}
代码写的很直观,MarkdownIt.utils.escapeHtml()
的用处就是转义HTML,把传来解析的Markdown
内容中的<
、>
等进行转义,防止与HTML的标签语法冲突。
那为什么上面的highlight
函数中需要用呢?
highlight
函数中首先判断了参数lang
是否存在,就是Markdown
文件中代码块开头标志后有没有跟代码语言并且这个语言在highlight.js
库能否解析。如果
false
就不会通过highlight.js
库去解析语法高亮,而只返回了代码块的转义;如果
true
就会通过hightlight.js
库进行解析,返回的结果在highlight.js
中自己就进行了转义,所以不需要我们再去使用escapeHtml()
。
版权声明:
Anand's Blog文章皆为站长Anand Zhang原创内容,转载请注明出处。
包括商业转载在内,注明下方要求的文章出处信息即可,无需联系站长授权。
请尊重他人劳动成果,用爱发电十分不易,谢谢!
请注明出处:
本文出自:Anand's Blog