UNPKG

2.22 kBJavaScriptView Raw
1
2/**
3 * Module dependencies.
4 */
5
6var md = require('marked');
7
8/**
9 * Parse the given `str` of markdown.
10 *
11 * @param {String} str
12 * @param {Object} options
13 * @return {Object}
14 * @api public
15 */
16
17module.exports = function(str, options){
18 options = options || {};
19
20 options = {
21 normalizer: options.normalizer || 'spaced'
22 };
23
24 var normalize = normalizers[options.normalizer];
25 var toks = md.lexer(str);
26 var conf = {};
27 var keys = [];
28 var depth = 0;
29 var inlist = false;
30
31 toks.forEach(function(tok){
32 switch (tok.type) {
33 case 'heading':
34 while (depth-- >= tok.depth) keys.pop();
35 keys.push(normalize(tok.text));
36 depth = tok.depth;
37 break;
38 case 'list_item_start':
39 inlist = true;
40 break;
41 case 'list_item_end':
42 inlist = false;
43 break;
44 case 'text':
45 put(conf, keys, tok.text, normalize);
46 break;
47 case 'code':
48 put(conf, keys, tok.text, normalize, true);
49 break;
50 }
51 });
52
53 return conf;
54};
55
56/**
57 * Add `str` to `obj` with the given `keys`
58 * which represents the traversal path.
59 *
60 * @param {Object} obj
61 * @param {Array} keys
62 * @param {String} str
63 * @param {Function} normalize
64 * @api private
65 */
66
67function put(obj, keys, str, normalize, code) {
68 var target = obj;
69 var last;
70
71 for (var i = 0; i < keys.length; i++) {
72 var key = keys[i];
73 last = target;
74 target[key] = target[key] || {};
75 target = target[key];
76 }
77
78 // code
79 if (code) {
80 if (!Array.isArray(last[key])) last[key] = [];
81 last[key].push(str);
82 return;
83 }
84
85 var i = str.indexOf(':');
86
87 // list
88 if (-1 == i) {
89 if (!Array.isArray(last[key])) last[key] = [];
90 last[key].push(str.trim());
91 return;
92 }
93
94 // map
95 var key = normalize(str.slice(0, i));
96 var val = str.slice(i + 1).trim();
97 target[key] = val;
98}
99
100/**
101 * Normalize `str`.
102 */
103
104function normalize(str) {
105 return str.replace(/\s+/g, ' ').toLowerCase().trim();
106}
107
108var normalizers = {
109 spaced: function(str) {
110 return str.replace(/\s+/g, ' ').toLowerCase().trim();
111 },
112 camelcase: function(str) {
113 return str.toLowerCase().replace(/\s+([^\s])/g, function(_, char) { return char.toUpperCase(); }).trim();
114 }
115};