/
code.js
69 lines (54 loc) · 1.88 KB
/
code.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
const Prism = require('prismjs')
const detab = require('detab')
const u = require('unist-builder')
const escapeHtml = require('escape-html')
const { parseThematicBlock } = require('./utils')
require('prismjs/components/index')()
const prismHighlighter = (rawCode, language, { lineHighlights, fileName }, { h, node }) => {
let lang = language === 'vue' ? 'html' : language
// eslint-disable-next-line no-prototype-builtins
const hasPrismHightlight = Prism.languages.hasOwnProperty(lang)
let code = hasPrismHightlight
? Prism.highlight(rawCode, Prism.languages[lang], lang)
: rawCode
if (!lang || !hasPrismHightlight) {
lang = 'text'
code = escapeHtml(code)
}
const props = {
className: [`language-${lang}`, 'line-numbers']
}
if (lineHighlights) {
props.dataLine = lineHighlights
}
const childs = []
/**
* If filename, then set span as a first child
*/
if (fileName) {
childs.push(h(node, 'span', { className: ['filename'] }, [u('text', fileName)]))
}
/**
* Set pre as a child
*/
childs.push(h(node, 'pre', props, [
h(node, 'code', [u('raw', code)])
]))
return h(node.position, 'div', { className: ['nuxt-content-highlight'] }, childs)
}
const toAst = (h, node) => (highlighted) => {
if (typeof highlighted === 'string') {
return h(node, 'div', { className: ['nuxt-content-highlight'] }, [u('raw', highlighted)])
}
return highlighted
}
module.exports = highlighter => (h, node) => {
const lang = node.lang + ' ' + (node.meta || '')
const { language, lineHighlights, fileName } = parseThematicBlock(lang)
const code = node.value ? detab(node.value + '\n') : ''
if (!highlighter) {
return prismHighlighter(code, language, { lineHighlights, fileName }, { h, node })
}
const highlightedCode = highlighter(code, language, { lineHighlights, fileName }, { h, node, u })
return toAst(h, node)(highlightedCode)
}