-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathyamlhead.js
More file actions
102 lines (95 loc) · 2.34 KB
/
yamlhead.js
File metadata and controls
102 lines (95 loc) · 2.34 KB
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
//
// # YAMLHead
//
//
// ## Dependencies
//
// For subclassing.
var inherit = require('util').inherits;
// Subclasses Stream.
var Stream = require('stream').Stream;
// For parsing YAML.
var yaml = require('js-yaml');
// For reading files.
var fs = require('fs');
//
// ## Constructor
//
// Subclass Stream and make readable.
//
var YAMLHead = function (path, options, callback) {
Stream.call(this);
this.readable = true;
this.writable = true;
this.callback = typeof options === 'function' ? options : callback;
this.options = typeof options === 'object' ? options : null;
this.path = path;
this.header = false;
this.data = '';
this._sep = /(\s*?\-+\s*\n)/g;
this._ended = false;
this._err = false;
fs.createReadStream(this.path, this.options).pipe(this);
};
inherit(YAMLHead, Stream);
//
// ## Write
//
// Stream API implementation. When reading from the target file this function
// gets called.
//
YAMLHead.prototype.write = function(data) {
this.data += data;
// Check for YAML header separator.
if (!this.header) {
// Handle Jekyll-style triple dashes at the beginning of the file
this.data = this.data.replace(/^---\s*[\r\n]+/, '');
var pos = this.data.search(this._sep);
if (pos !== -1) {
try {
var matches = this.data.match(this._sep);
var header = this.data.substr(0, pos);
this.data = this.data.substr(pos + matches[0].length);
this.header = yaml.safeLoad(header);
this.emit('header', this.header);
this.emit('data', this.data);
}
catch (err) {
this._err = err;
if (this.callback) {
this.callback(err);
}
else {
this.emit('error', err);
}
this.end();
this.emit('end');
}
}
}
else {
this.emit('data', data);
}
};
//
// ## End
//
// Stream API implementation. When reading from the target file is done
// `.pipe()` will call this function. Kinda.
//
YAMLHead.prototype.end = function() {
if (this._ended) return;
this._ended = true;
this.emit('end');
if (this.callback && !this._err) {
this.callback(null, this.header, this.data);
}
};
//
// ## Public API
//
// The function you will actually call when requiring YAMLHead.
//
module.exports = function (path, options, callback) {
return new YAMLHead(path, options, callback);
};