Skip to content

Commit cb32702

Browse files
committed
Perform syntax highlighting
1 parent 653e688 commit cb32702

File tree

6 files changed

+119
-2
lines changed

6 files changed

+119
-2
lines changed

lib/fix_html.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict'
2+
3+
const cheerio = require('cheerio')
4+
const hljs = require('highlight.js')
5+
6+
/**
7+
* Performs syntax highlighting and stuff.
8+
*/
9+
10+
module.exports = function fixHtml (html) {
11+
const $ = cheerio.load(html)
12+
syntaxHighlight($)
13+
return $.html()
14+
}
15+
16+
/**
17+
* Performs syntax highlighting via highlight.js. Given parameter `$` is a
18+
* cheerio object that it will modify in place.
19+
*/
20+
21+
function syntaxHighlight ($) {
22+
$('pre > code[class]').each(function () {
23+
const $this = $(this)
24+
const langs = $this.attr('class').split(' ').filter((c) => /^lang-/.test(c))
25+
const lang = langs && langs[0].substr(5) // 'lang-js' => 'js'
26+
27+
// Mappings of marked-to-github classes.
28+
const dict = {
29+
'hljs-string': 'pl-s',
30+
'hljs-comment': 'pl-c',
31+
'hljs-keyword': 'pl-k',
32+
'hljs-attribute': 'pl-e',
33+
'hljs-built_in': 'pl-c1',
34+
'hljs-title': 'pl-ent',
35+
'hljs-value': 'pl-s',
36+
'hljs-literal': 'pl-c1'
37+
}
38+
39+
let html = $this.text()
40+
html = hljs.highlight(lang, html).value
41+
$this.html(html)
42+
43+
$this.find('[class^="hljs-"]').each(function () {
44+
let $$this = $(this)
45+
var synonym = dict[$$this.attr('class')]
46+
if (synonym) $$this.attr('class', synonym)
47+
})
48+
})
49+
}

lib/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
'use strict'
2+
13
const ware = require('ware')
24
const each = require('lodash/collection/each')
35
const marked = require('marked')
46

57
const tocify = require('./tocify')
68
const indexify = require('./indexify')
9+
const fixHtml = require('./fix_html')
710

811
module.exports = function (options) {
912
var app = ware()
@@ -75,9 +78,11 @@ function renderMarkdown (files, ms, done) {
7578
// render each page
7679
each(pages, (page, fname) => {
7780
const file = files[page.source]
81+
const html = marked(file.contents.toString(), { gfm: true, tables: true })
82+
7883
file._processed = true
7984
file.markdown = file.contents
80-
file.html = marked(file.markdown.toString(), { gfm: true, tables: true })
85+
file.html = fixHtml(html)
8186
file.title = page.title
8287
file.source = page.source
8388
file.slug = page.slug

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"url": "https://github.com/docpress/docpress-core/issues"
88
},
99
"dependencies": {
10+
"cheerio": "0.19.0",
1011
"lodash": "3.10.1",
1112
"marked": "0.3.5",
1213
"metalsmith": "2.1.0",

test/index/pre_test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const compile = require('../../index')()
2+
3+
describe('index/pre:', function () {
4+
beforeEach(function (done) {
5+
var ms = {
6+
metadata () { return { docs: 'docs' } }
7+
}
8+
9+
this.files = {
10+
'docs/README.md': {
11+
contents: '* [Readme](/README.md)\n'
12+
},
13+
'README.md': {
14+
contents: '```js\nwindow.alert()\n```'
15+
}
16+
}
17+
18+
compile(this.files, ms, (err) => {
19+
if (err) throw err
20+
done()
21+
})
22+
})
23+
24+
it('renders index.html with syntax highlighting', function () {
25+
const idx = this.files['index.html']
26+
expect(idx.contents).toEqual(
27+
'<pre><code class="lang-js">' +
28+
'<span class="pl-c1">window</span>.alert()\n' +
29+
'</code></pre>\n')
30+
})
31+
})

test/index/pre_with_quotes_test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const compile = require('../../index')()
2+
3+
describe('index/pre with quotes:', function () {
4+
beforeEach(function (done) {
5+
var ms = {
6+
metadata () { return { docs: 'docs' } }
7+
}
8+
9+
this.files = {
10+
'docs/README.md': {
11+
contents: '* [Readme](/README.md)\n'
12+
},
13+
'README.md': {
14+
contents: '```js\nalert(\'hi\')\n```'
15+
}
16+
}
17+
18+
compile(this.files, ms, (err) => {
19+
if (err) throw err
20+
done()
21+
})
22+
})
23+
24+
it('renders index.html with syntax highlighting', function () {
25+
const idx = this.files['index.html']
26+
expect(idx.contents).toEqual(
27+
'<pre><code class="lang-js">' +
28+
'alert(<span class="pl-s">&apos;hi&apos;</span>)\n' +
29+
'</code></pre>\n')
30+
})
31+
})

test/todo_test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('to do', function () {
2323

2424
describe('transforming html', function () {
2525
it('transforming links in document')
26-
it('highlight it already')
26+
it('syntax highlighting', done)
2727
})
2828
})
2929

0 commit comments

Comments
 (0)