-
Notifications
You must be signed in to change notification settings - Fork 30
/
index.js
79 lines (62 loc) · 2.03 KB
/
index.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
70
71
72
73
74
75
76
77
78
79
const hljs = require('highlight.js')
function maybe (f) {
try {
return f()
} catch (e) {
return false
}
}
// Allow registration of other languages.
const registerLangs = (register) => register &&
Object.entries(register).map(([lang, pack]) => { hljs.registerLanguage(lang, pack) })
// Highlight with given language.
const highlight = (code, lang) =>
maybe(() => hljs.highlight(lang || 'plaintext', code, true).value) || ''
// Highlight with given language or automatically.
const highlightAuto = (code, lang) =>
lang
? highlight(code, lang)
: maybe(() => hljs.highlightAuto(code).value) || ''
// Wrap a render function to add `hljs` class to code blocks.
const wrap = render =>
function (...args) {
return render.apply(this, args)
.replace('<code class="', '<code class="hljs ')
.replace('<code>', '<code class="hljs">')
}
function inlineCodeRenderer (tokens, idx, options) {
const code = tokens[idx]
const next = tokens[idx + 1]
let lang
if (next && next.type === 'text') {
// Match kramdown- or pandoc-style language specifier.
// e.g. `code`{:.ruby} or `code`{.haskell}
const match = /^{:?\.([^}]+)}/.exec(next.content)
if (match) {
lang = match[1]
// Remove the language specification from text following the code.
next.content = next.content.slice(match[0].length)
}
}
const highlighted = options.highlight(code.content, lang)
const cls = lang ? ` class="${options.langPrefix + lang}"` : ''
return `<code${cls}>${highlighted}</code>`
}
const highlightjs = (md, opts) => {
opts = Object.assign({}, highlightjs.defaults, opts)
registerLangs(opts.register)
md.options.highlight = opts.auto ? highlightAuto : highlight
md.renderer.rules.fence = wrap(md.renderer.rules.fence)
if (opts.code) {
md.renderer.rules.code_block = wrap(md.renderer.rules.code_block)
}
if (opts.inline) {
md.renderer.rules.code_inline = inlineCodeRenderer
}
}
highlightjs.defaults = {
auto: true,
code: true,
inline: false
}
module.exports = highlightjs