-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathindex.js
114 lines (96 loc) · 2.66 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
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
106
107
108
109
110
111
112
113
114
'use strict';
var marked = require('./gen/marked-mod');
// Alias marked's default renderer as HtmlRenderer.
var HtmlRenderer = marked.Renderer;
// Monkey-patch the HTML renderer with the `newSequence` function, which
// is required by our modified version of marked.
HtmlRenderer.prototype.newSequence = function() {
return '';
};
// The AstBuilder is a renderer that produces an abstract syntax tree
// representing the structure of the Markdown source.
function AstBuilder() {
}
AstBuilder.prototype.newSequence = function() {
return [];
};
var handlerArgs = {
code: ['code', 'lang', 'escaped', 'fenced'],
blockquote: ['quote'],
html: ['html'],
heading: ['text', 'level', 'raw'],
hr: [],
list: ['body', 'ordered'],
listitem: ['text'],
paragraph: ['text'],
table: ['header', 'body'],
tablerow: ['content'],
tablecell: ['content', 'flags'],
strong: ['text'],
em: ['text'],
codespan: ['text'],
br: [],
del: ['text'],
link: ['href', 'title', 'text'],
image: ['href', 'title', 'text']
};
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
function map(arr, fn) {
var result = [];
for (var i = 0; i < arr.length; ++i) {
result.push(fn(arr[i], i));
}
return result;
}
// Returns a handler function which just returns an object which captures the
// values of all the arguments to the handler function.
function makeHandler(type, args) {
return function() {
var result = { type: type };
for (var i = 0; i < args.length; ++i) {
result[args[i]] = arguments[i];
}
return result;
};
}
for (var k in handlerArgs) {
AstBuilder.prototype[k] = makeHandler(k, handlerArgs[k]);
}
function parse(text) {
return marked(text, {
renderer: new AstBuilder()
});
}
function render(node, renderer) {
if (!isObject(node))
return node;
// Render all of the children.
var results = isArray(node) ? [] : {};
for (var key in node) {
if (node.hasOwnProperty(key))
results[key] = render(node[key], renderer);
}
if (isArray(node))
return results.join('');
// Splat the results object onto the appropriate handler in the renderer.
var handlerFn = renderer[node.type];
if (!handlerFn) throw new Error("Missing handler for '" + node.type + "'");
var args = map(handlerArgs[node.type], function(argName) {
return results[argName];
});
return handlerFn.apply(renderer, args);
}
module.exports = {
_marked: marked,
parse: parse,
render: function(tree, renderer) {
return render(tree, renderer || new HtmlRenderer());
},
AstBuilder: AstBuilder
};