-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
136 lines (114 loc) · 3.01 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'use strict';
var typeOf = require('kind-of');
var extend = require('extend-shallow');
/**
* Parse sections in `input` with the given `options`.
*
* ```js
* var sections = require('{%= name %}');
* var result = sections(input, options);
* // { content: 'Content before sections', sections: [] }
* ```
* @param {String|Buffer|Object} `input` If input is an object, it's `content` property must be a string or buffer.
* @param {Object} options
* @return {Object} Returns an object with a `content` string and an array of `sections` objects.
* @api public
*/
module.exports = function(input, options) {
if (typeof options === 'function') {
options = { parse: options };
}
var file = toObject(input);
var defaults = {section_delimiter: '---', parse: identity};
var opts = extend({}, defaults, options);
var delim = opts.section_delimiter;
var lines = file.content.split(/\r?\n/);
var sections = null;
var section = createSection();
var content = [];
var stack = [];
function initSections(val) {
file.content = val;
sections = [];
content = [];
}
function closeSection(val) {
if (stack.length) {
section.key = getKey(stack[0], delim);
section.content = val;
opts.parse(section, sections);
sections.push(section);
section = createSection();
content = [];
stack = [];
}
}
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var len = stack.length;
var ln = line.trim();
if (isDelimiter(ln, delim)) {
if (ln.length === 3 && i !== 0) {
if (len === 0 || len === 2) {
content.push(line);
continue;
}
stack.push(ln);
section.data = content.join('\n');
content = [];
continue;
}
if (sections === null) {
initSections(content.join('\n'));
}
if (len === 2) {
closeSection(content.join('\n'));
}
stack.push(ln);
continue;
}
content.push(line);
}
if (sections === null) {
initSections(content.join('\n'));
} else {
closeSection(content.join('\n'));
}
file.sections = sections;
return file;
};
function isDelimiter(line, delim) {
if (line.slice(0, delim.length) !== delim) {
return false;
}
if (line.charAt(delim.length + 1) === delim.slice(-1)) {
return false;
}
return true;
}
function toObject(input) {
if (typeOf(input) !== 'object') {
input = { content: input };
}
if (typeof input.content !== 'string' && !isBuffer(input.content)) {
throw new TypeError('expected a buffer or string');
}
input.content = input.content.toString();
input.sections = [];
return input;
}
function getKey(val, delim) {
return val ? val.slice(delim.length).trim() : '';
}
function createSection() {
return { key: '', data: '', content: '' };
}
function identity(val) {
return val;
}
function isBuffer(val) {
if (val && val.constructor && typeof val.constructor.isBuffer === 'function') {
return val.constructor.isBuffer(val);
}
return false;
}