-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathplugin.coffee
105 lines (91 loc) · 3.47 KB
/
plugin.coffee
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
async = require 'async'
Showdown = require 'showdown'
fs = require 'fs'
path = require 'path'
url = require 'url'
hljs = require 'highlight.js'
cheerio = require 'cheerio'
showdownRender = (page, callback) ->
# convert the page
extensions = page.metadata.showdownExtensions or ['github', 'table', 'math', 'smartypants', 'footnotes']
converter = new Showdown.converter(extensions: extensions)
page._htmlraw = converter.makeHtml(page.markdown)
# apply highlight.js,
# don't run if text is empty
if page._htmlraw.length
$ = cheerio.load page._htmlraw
blocks = $("pre code")
count = blocks.length
if count > 0
blocks.each () ->
item = $(this)
lang = item.attr("class")
code = item.html()
if lang isnt "" and lang isnt undefined
item.html(hljs.highlight(lang, code).value)
else
item.html(hljs.highlightAuto(code).value)
count -= 1
# only callback once all blocks have been highlighted
if (!count)
# workaround for shutup.css hiding code comments generated by highlight.js
$("span.comment", blocks).removeClass("comment").addClass("cs")
page._htmlraw = $.html()
callback null, page
else
callback null, page
else
callback null, page
module.exports = (env, callback) ->
class ShowdownPage extends env.plugins.MarkdownPage
getHtml: (base=env.config.baseUrl) ->
# TODO: cleaner way to achieve this?
# http://stackoverflow.com/a/4890350
name = @getFilename()
name = name[name.lastIndexOf('/')+1..]
loc = @getLocation(base)
fullName = if name is 'index.html' then loc else loc + name
# handle links to anchors within the page
@_html = @_htmlraw.replace(/(<(a|img)[^>]+(href|src)=")(#[^"]+)/g, '$1' + fullName + '$4')
# handle relative links
@_html = @_html.replace(/(<(a|img)[^>]+(href|src)=")(?!http|\/)([^"]+)/g, '$1' + loc + '$4')
# handles non-relative links within the site (e.g. /about)
if base
@_html = @_html.replace(/(<(a|img)[^>]+(href|src)=")\/([^"]+)/g, '$1' + base + '$4')
return @_html
getIntro: (base=env.config.baseUrl) ->
@_html = @getHtml(base)
idx = ~@_html.indexOf('<span class="more') or ~@_html.indexOf('<h2') or ~@_html.indexOf('<hr')
# TODO: simplify!
if idx
@_intro = @_html.toString().substr 0, ~idx
hr_index = @_html.indexOf('<hr')
footnotes_index = @_html.indexOf('<div class="footnotes">')
# ignore hr if part of Showdown's footnote section
if hr_index && ~footnotes_index && !(hr_index < footnotes_index)
@_intro = @_html
else
@_intro = @_html
return @_intro
@property 'hasMore', ->
@_html ?= @getHtml()
@_intro ?= @getIntro()
@_hasMore ?= (@_html.length > @_intro.length)
return @_hasMore
ShowdownPage.fromFile = (filepath, callback) ->
async.waterfall [
(callback) ->
fs.readFile filepath.full, callback
(buffer, callback) ->
ShowdownPage.extractMetadata buffer.toString(), callback
(result, callback) =>
{markdown, metadata} = result
page = new this filepath, metadata, markdown
callback null, page
(page, callback) =>
showdownRender page, callback
(page, callback) =>
callback null, page
], callback
env.registerContentPlugin 'pages', '**/*.*(markdown|mkd|md)', ShowdownPage
callback()