comment-parser 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jshintrc +11 -0
- package/CHANGELOG.md +9 -0
- package/README.md +89 -30
- package/index.js +239 -108
- package/package.json +8 -6
- package/tests/custom-parsers.spec.js +139 -0
- package/tests/parse.spec.js +315 -54
- package/tests/option-raw.spec.js +0 -154
- package/tests/parse-location.spec.js +0 -169
package/.jshintrc
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# v0.2.3
|
|
2
|
+
|
|
3
|
+
- `bugfix` Accept `/** one line */` comments
|
|
4
|
+
- `refactor` Get rid of `lodash` to avoid unnecessary extra size when bundled
|
|
5
|
+
|
|
6
|
+
# v0.2.2
|
|
7
|
+
|
|
8
|
+
- `feature` allow spaces in default values `@my-tag {my.type} [name=John Doe]`
|
|
9
|
+
|
|
1
10
|
# v0.2.1
|
|
2
11
|
|
|
3
12
|
- `refactor` make line pasing mechanism more tolerable
|
package/README.md
CHANGED
|
@@ -25,45 +25,104 @@ this would be parsed into following
|
|
|
25
25
|
|
|
26
26
|
```javascript
|
|
27
27
|
[{
|
|
28
|
-
tags: [{
|
|
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
|
-
|
|
28
|
+
"tags": [{
|
|
29
|
+
"tag": "some-tag",
|
|
30
|
+
"type": "Type",
|
|
31
|
+
"name": "name",
|
|
32
|
+
"optional": false,
|
|
33
|
+
"description": "Singleline or multiline description text",
|
|
34
|
+
"line": 3,
|
|
35
|
+
"source": "@some-tag {Type} name Singleline or multiline description text"
|
|
36
|
+
}, {
|
|
37
|
+
"tag": "some-tag",
|
|
38
|
+
"type": "Type",
|
|
39
|
+
"name": "name.subname",
|
|
40
|
+
"optional": false,
|
|
41
|
+
"description": "Singleline or multiline description text",
|
|
42
|
+
"line": 4,
|
|
43
|
+
"source": "@some-tag {Type} name.subname Singleline or multiline description text"
|
|
44
|
+
}, {
|
|
45
|
+
"tag": "some-tag",
|
|
46
|
+
"type": "Type",
|
|
47
|
+
"name": "name.subname.subsubname",
|
|
48
|
+
"optional": false,
|
|
49
|
+
"description": "Singleline or\nmultiline description text",
|
|
50
|
+
"line": 5,
|
|
51
|
+
"source": "@some-tag {Type} name.subname.subsubname Singleline or\nmultiline description text"
|
|
52
|
+
}, {
|
|
53
|
+
"tag": "another-tag",
|
|
54
|
+
"name": "",
|
|
55
|
+
"optional": false,
|
|
56
|
+
"type": "",
|
|
57
|
+
"description": "",
|
|
58
|
+
"line": 7,
|
|
59
|
+
"source": "@another-tag"
|
|
60
|
+
}],
|
|
61
|
+
"line": 0,
|
|
62
|
+
"description": "Singleline or multiline description text. Line breaks are preserved.",
|
|
63
|
+
"source": "Singleline or multiline description text. Line breaks are preserved.\n\n@some-tag {Type} name Singleline or multiline description text\n@some-tag {Type} name.subname Singleline or multiline description text\n@some-tag {Type} name.subname.subsubname Singleline or\nmultiline description text\n@another-tag"
|
|
56
64
|
}]
|
|
57
65
|
```
|
|
58
66
|
|
|
59
67
|
By default dotted names like `name.subname.subsubname` will be expanded into nested sections, this can be prevented by passing `opts.dotted_names = false`.
|
|
60
68
|
|
|
61
|
-
You can also make raw line available in parsed results by passing `opts.raw_value = true`.
|
|
62
|
-
|
|
63
69
|
Invalid comment blocks are skipped. Comments starting with `/*` and `/***` are considered not valid.
|
|
64
70
|
|
|
65
71
|
Also you can parse entire file with `parse.file('path/to/file', callback)` or acquire an instance of [Transform](http://nodejs.org/api/stream.html#stream_class_stream_transform) stream with `parse.stream()`.
|
|
66
72
|
|
|
73
|
+
Custom parsers
|
|
74
|
+
==============
|
|
75
|
+
|
|
76
|
+
In case you need to parse tags in different way you can pass `opts.parsers = [parser1, ..., parserN]`, where each parser is `function name(str:String, data:Object):{source:String, data:Object}`.
|
|
77
|
+
|
|
78
|
+
Each parser function takes string left after previous parsers applied and data produced by them. And returns `null` or `{source: '', data:{}}` where `source` is consumed substring and `data` is a payload with tag node fields.
|
|
79
|
+
|
|
80
|
+
Tag node data is build by merging result bits from all parsers. Here is some example that is not doing actual parsing but is demonstrating the flow:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
/**
|
|
84
|
+
* Source to be parsed below
|
|
85
|
+
* @tag {type} name Description
|
|
86
|
+
*/
|
|
87
|
+
parse(source, {parsers: [
|
|
88
|
+
// takes entire string
|
|
89
|
+
function parse_tag(str, data) {
|
|
90
|
+
return {source: ' @tag', data: {tag: 'tag'}};
|
|
91
|
+
},
|
|
92
|
+
// parser throwing exception
|
|
93
|
+
function check_tag(str, data) {
|
|
94
|
+
if (allowed_tags.indexOf(data.tag) === -1) {
|
|
95
|
+
throw new Error('Unrecognized tag "' + data.tag + '"');
|
|
96
|
+
}
|
|
97
|
+
// takes the rest of the string after ' @tag''
|
|
98
|
+
function parse_name1(str, data) {
|
|
99
|
+
return {source: ' name', data: {name: 'name'}};
|
|
100
|
+
},
|
|
101
|
+
// alternative name parser
|
|
102
|
+
function parse_name2(str, data) {
|
|
103
|
+
return {source: ' name', data: {name: 'name'}};
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This would produce following:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
[{
|
|
111
|
+
"tags": [{
|
|
112
|
+
"tag": "tag",
|
|
113
|
+
"type": "type",
|
|
114
|
+
"name": "name",
|
|
115
|
+
"optional": false,
|
|
116
|
+
"description": "Description",
|
|
117
|
+
"line": 2,
|
|
118
|
+
"source": "@tag {type} name Description"
|
|
119
|
+
}],
|
|
120
|
+
"line": 0,
|
|
121
|
+
"description": "Source to be parsed below",
|
|
122
|
+
"source": "Source to be parsed below\n@tag {type} name Description"
|
|
123
|
+
}]
|
|
124
|
+
```
|
|
125
|
+
|
|
67
126
|
Happy coding :)
|
|
68
127
|
|
|
69
128
|
|
package/index.js
CHANGED
|
@@ -1,135 +1,243 @@
|
|
|
1
1
|
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
2
4
|
var fs = require('fs');
|
|
3
5
|
var stream = require('stream');
|
|
4
6
|
var util = require('util');
|
|
5
7
|
|
|
6
|
-
var _ = require('lodash');
|
|
7
|
-
|
|
8
8
|
var RE_COMMENT_START = /^\s*\/\*\*\s*$/m;
|
|
9
9
|
var RE_COMMENT_LINE = /^\s*\*(?:\s|$)/m;
|
|
10
10
|
var RE_COMMENT_END = /^\s*\*\/\s*$/m;
|
|
11
|
+
var RE_COMMENT_1LINE = /^\s*\/\*\*\s*(.*)\s*\*\/\s*$/;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
* analogue of str.match(/@(\S+)(?:\s+\{([^\}]+)\})?(?:\s+(\S+))?(?:\s+([^$]+))?/);
|
|
14
|
-
* @param {string} str raw jsdoc string
|
|
15
|
-
* @returns {object} parsed tag node
|
|
16
|
-
*/
|
|
17
|
-
function parse_tag_line(str) {
|
|
18
|
-
if (typeof str !== 'string') { return false; }
|
|
19
|
-
|
|
20
|
-
if (str[0] !== '@') { return false; }
|
|
21
|
-
|
|
22
|
-
var pos = 1;
|
|
23
|
-
var l = str.length;
|
|
24
|
-
var error = null;
|
|
25
|
-
var res = {
|
|
26
|
-
tag : _tag(),
|
|
27
|
-
type : _type() || '',
|
|
28
|
-
name : _name() || '',
|
|
29
|
-
description : _rest() || ''
|
|
30
|
-
};
|
|
13
|
+
/* ------- util functions ------- */
|
|
31
14
|
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
function merge(/* ...objects */) {
|
|
16
|
+
var k, obj, res = {}, objs = Array.prototype.slice.call(arguments);
|
|
17
|
+
while (objs.length) {
|
|
18
|
+
obj = objs.shift();
|
|
19
|
+
for (k in obj) { if (obj.hasOwnProperty(k)) {
|
|
20
|
+
res[k] = obj[k];
|
|
21
|
+
}}
|
|
34
22
|
}
|
|
35
|
-
|
|
36
23
|
return res;
|
|
24
|
+
}
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
function find(list, filter) {
|
|
27
|
+
var k, i = list.length, matchs = true;
|
|
28
|
+
while (i--) {
|
|
29
|
+
for (k in filter) { if (filter.hasOwnProperty(k)) {
|
|
30
|
+
matchs = (filter[k] === list[i][k]) && matchs;
|
|
31
|
+
}}
|
|
32
|
+
if (matchs) { return list[i]; }
|
|
40
33
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function skipws(str) {
|
|
38
|
+
var i = 0;
|
|
39
|
+
do {
|
|
40
|
+
if (str[i] !== ' ') { return i; }
|
|
41
|
+
} while (++i < str.length);
|
|
42
|
+
return i;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ------- default parsers ------- */
|
|
46
|
+
|
|
47
|
+
var PARSERS = {};
|
|
48
|
+
|
|
49
|
+
PARSERS.parse_tag = function parse_tag(str) {
|
|
50
|
+
var result = str.match(/^\s*@(\S+)/);
|
|
51
|
+
|
|
52
|
+
if (!result) { throw new Error('Invalid `@tag`, missing @ symbol'); }
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
source : result[0],
|
|
56
|
+
data : {tag: result[1]}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
PARSERS.parse_type = function parse_type(str, data) {
|
|
61
|
+
if (data.errors && data.errors.length) { return null; }
|
|
62
|
+
|
|
63
|
+
var pos = skipws(str);
|
|
64
|
+
var res = '';
|
|
65
|
+
var curlies = 0;
|
|
66
|
+
|
|
67
|
+
if (str[pos] !== '{') { return null; }
|
|
68
|
+
|
|
69
|
+
while (pos < str.length) {
|
|
70
|
+
curlies += (str[pos] === '{' ? 1 : (str[pos] === '}' ? -1 : 0));
|
|
71
|
+
res += str[pos];
|
|
72
|
+
pos ++;
|
|
73
|
+
if (curlies === 0) { break; }
|
|
47
74
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
return res.substr(1, res.length - 2);
|
|
75
|
+
|
|
76
|
+
if (curlies !== 0) { throw new Error('Invalid `{type}`, unpaired curlies'); }
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
source : str.slice(0, pos),
|
|
80
|
+
data : {type: res.slice(1, -1)}
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
PARSERS.parse_name = function parse_name(str, data) {
|
|
85
|
+
if (data.errors && data.errors.length) { return null; }
|
|
86
|
+
|
|
87
|
+
var pos = skipws(str);
|
|
88
|
+
var name = '';
|
|
89
|
+
var brackets = 0;
|
|
90
|
+
|
|
91
|
+
while (pos < str.length) {
|
|
92
|
+
brackets += (str[pos] === '[' ? 1 : (str[pos] === ']' ? -1 : 0));
|
|
93
|
+
name += str[pos];
|
|
94
|
+
pos ++;
|
|
95
|
+
if (brackets === 0 && /\s/.test(str[pos])) { break; }
|
|
70
96
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
97
|
+
|
|
98
|
+
if (brackets !== 0) { throw new Error('Invalid `name`, unpaired brackets'); }
|
|
99
|
+
|
|
100
|
+
var res = {name: name, optional: false};
|
|
101
|
+
|
|
102
|
+
if (name[0] === '[' && name[name.length - 1] === ']') {
|
|
103
|
+
res.optional = true;
|
|
104
|
+
name = name.slice(1, -1);
|
|
105
|
+
|
|
106
|
+
if (name.indexOf('=') !== -1) {
|
|
107
|
+
var parts = name.split('=');
|
|
108
|
+
name = parts[0];
|
|
109
|
+
res.default = parts[1].replace(/^(["'])(.+)(\1)$/, '$2');
|
|
110
|
+
}
|
|
75
111
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
112
|
+
|
|
113
|
+
res.name = name;
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
source : str.slice(0, pos),
|
|
117
|
+
data : res
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
PARSERS.parse_description = function parse_description(str, data) {
|
|
122
|
+
if (data.errors && data.errors.length) { return null; }
|
|
123
|
+
|
|
124
|
+
var result = str.match(/^\s+([^$]+)?/);
|
|
125
|
+
|
|
126
|
+
if (result) {
|
|
127
|
+
return {
|
|
128
|
+
source : result[0],
|
|
129
|
+
data : {description: result[1] === undefined ? '' : result[1]}
|
|
130
|
+
};
|
|
79
131
|
}
|
|
80
|
-
}
|
|
81
132
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.reduce(function(sections, line) {
|
|
85
|
-
if (line.value.match(/^@(\w+)/)) { sections.push([]); }
|
|
86
|
-
var section = sections[sections.length - 1];
|
|
87
|
-
section.line = section.line || line.line;
|
|
88
|
-
section.push(line.value);
|
|
89
|
-
return sections;
|
|
90
|
-
}, [[]])
|
|
91
|
-
.map(function(section) {
|
|
92
|
-
return {value: section.join('\n').trim(), line: section.line};
|
|
93
|
-
});
|
|
133
|
+
return null;
|
|
134
|
+
};
|
|
94
135
|
|
|
95
|
-
|
|
136
|
+
/* ------- parsing ------- */
|
|
96
137
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Parses "@tag {type} name description"
|
|
140
|
+
* @param {string} str Raw doc string
|
|
141
|
+
* @param {Array[function]} parsers Array of parsers to be applied to the source
|
|
142
|
+
* @returns {object} parsed tag node
|
|
143
|
+
*/
|
|
144
|
+
function parse_tag(str, parsers) {
|
|
145
|
+
if (typeof str !== 'string' || str[0] !== '@') { return null; }
|
|
146
|
+
|
|
147
|
+
var data = parsers.reduce(function(state, parser) {
|
|
148
|
+
var result;
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
result = parser(state.source, merge({}, state.data));
|
|
152
|
+
// console.log('----------------');
|
|
153
|
+
// console.log(parser.name, ':', result);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
// console.warn('Parser "%s" failed: %s', parser.name, err.message);
|
|
156
|
+
state.data.errors = (state.data.errors || [])
|
|
157
|
+
.concat(parser.name + ': ' + err.message);
|
|
158
|
+
}
|
|
100
159
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
160
|
+
if (result) {
|
|
161
|
+
state.source = state.source.slice(result.source.length);
|
|
162
|
+
state.data = merge(state.data, result.data);
|
|
104
163
|
}
|
|
105
164
|
|
|
106
|
-
|
|
107
|
-
|
|
165
|
+
return state;
|
|
166
|
+
}, {
|
|
167
|
+
source : str,
|
|
168
|
+
data : {}
|
|
169
|
+
}).data;
|
|
170
|
+
|
|
171
|
+
data.optional = !!data.optional;
|
|
172
|
+
data.type = data.type === undefined ? '' : data.type;
|
|
173
|
+
data.name = data.name === undefined ? '' : data.name;
|
|
174
|
+
data.description = data.description === undefined ? '' : data.description;
|
|
175
|
+
|
|
176
|
+
return data;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Parses comment block (array of String lines)
|
|
181
|
+
*/
|
|
182
|
+
function parse_block(source, opts) {
|
|
183
|
+
|
|
184
|
+
var source_str = source
|
|
185
|
+
.map(function(line) { return line.source; })
|
|
186
|
+
.join('\n')
|
|
187
|
+
.trim();
|
|
108
188
|
|
|
109
|
-
|
|
110
|
-
// probably if should be hidden with option or moved out to some jsdoc standard
|
|
111
|
-
if (tag_node.name.match(/^\[(\S+)\]$/)) {
|
|
112
|
-
tag_node.optional = true;
|
|
113
|
-
tag_node.name = RegExp.$1;
|
|
189
|
+
var start = source[0].number;
|
|
114
190
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
191
|
+
// merge source lines into tags
|
|
192
|
+
// we assume tag starts with "@"
|
|
193
|
+
source = source
|
|
194
|
+
.reduce(function(tags, line) {
|
|
195
|
+
line.source = line.source.trim();
|
|
196
|
+
|
|
197
|
+
if (line.source.match(/^@(\w+)/)) {
|
|
198
|
+
tags.push({source: [line.source], line: line.number});
|
|
199
|
+
} else {
|
|
200
|
+
var tag = tags[tags.length - 1];
|
|
201
|
+
tag.source.push(line.source);
|
|
120
202
|
}
|
|
121
|
-
}
|
|
122
203
|
|
|
123
|
-
|
|
204
|
+
return tags;
|
|
205
|
+
}, [{source: []}])
|
|
206
|
+
.map(function(tag) {
|
|
207
|
+
tag.source = tag.source.join('\n').trim();
|
|
208
|
+
return tag;
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Block description
|
|
212
|
+
var description = source.shift();
|
|
213
|
+
|
|
214
|
+
// skip if no descriptions and no tags
|
|
215
|
+
if (description.source === '' && source.length === 0) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
var tags = source.reduce(function(tags, tag) {
|
|
220
|
+
var tag_node = parse_tag(tag.source, opts.parsers || [
|
|
221
|
+
PARSERS.parse_tag,
|
|
222
|
+
PARSERS.parse_type,
|
|
223
|
+
PARSERS.parse_name,
|
|
224
|
+
PARSERS.parse_description
|
|
225
|
+
]);
|
|
226
|
+
|
|
227
|
+
if (!tag_node) { return tags; }
|
|
228
|
+
|
|
229
|
+
tag_node.line = tag.line;
|
|
230
|
+
tag_node.source = tag.source;
|
|
231
|
+
|
|
124
232
|
if (opts.dotted_names && tag_node.name.indexOf('.') !== -1) {
|
|
125
233
|
var parent_name;
|
|
126
234
|
var parent_tag;
|
|
127
235
|
var parent_tags = tags;
|
|
128
|
-
parts = tag_node.name.split('.');
|
|
236
|
+
var parts = tag_node.name.split('.');
|
|
129
237
|
|
|
130
238
|
while (parts.length > 1) {
|
|
131
239
|
parent_name = parts.shift();
|
|
132
|
-
parent_tag =
|
|
240
|
+
parent_tag = find(parent_tags, {
|
|
133
241
|
tag : tag_node.tag,
|
|
134
242
|
name : parent_name
|
|
135
243
|
});
|
|
@@ -156,28 +264,50 @@ function parse_chunk(source, opts) {
|
|
|
156
264
|
|
|
157
265
|
return tags.concat(tag_node);
|
|
158
266
|
}, []);
|
|
159
|
-
|
|
267
|
+
|
|
268
|
+
// console.log('-----------');
|
|
269
|
+
// console.log(description, tags);
|
|
270
|
+
|
|
160
271
|
return {
|
|
161
272
|
tags : tags,
|
|
162
|
-
line :
|
|
163
|
-
description : description.
|
|
273
|
+
line : start,
|
|
274
|
+
description : description.source,
|
|
275
|
+
source : source_str
|
|
164
276
|
};
|
|
165
277
|
}
|
|
166
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Produces `extract` function with internal state initialized
|
|
281
|
+
*/
|
|
167
282
|
function mkextract(opts) {
|
|
168
283
|
|
|
169
284
|
var chunk = null;
|
|
170
|
-
var
|
|
285
|
+
var number = 0;
|
|
171
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Cumulatively reading lines until they make one comment block
|
|
289
|
+
* Returns block object or null.
|
|
290
|
+
*/
|
|
172
291
|
return function extract(line) {
|
|
173
|
-
|
|
292
|
+
|
|
293
|
+
// if oneliner
|
|
294
|
+
// then parse it immediately
|
|
295
|
+
if (line.match(RE_COMMENT_1LINE)) {
|
|
296
|
+
// console.log('line (1)', line);
|
|
297
|
+
// console.log(' clean:', line.replace(RE_COMMENT_1LINE, '$1'));
|
|
298
|
+
return parse_block([{
|
|
299
|
+
source: line.replace(RE_COMMENT_1LINE, '$1'),
|
|
300
|
+
number: number}], opts);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
number += 1;
|
|
174
304
|
|
|
175
305
|
// if start of comment
|
|
176
306
|
// then init the chunk
|
|
177
307
|
if (line.match(RE_COMMENT_START)) {
|
|
178
308
|
// console.log('line (1)', line);
|
|
179
309
|
// console.log(' clean:', line.replace(RE_COMMENT_START, ''));
|
|
180
|
-
chunk = [{
|
|
310
|
+
chunk = [{source: line.replace(RE_COMMENT_START, ''), number: number - 1}];
|
|
181
311
|
return null;
|
|
182
312
|
}
|
|
183
313
|
|
|
@@ -186,7 +316,7 @@ function mkextract(opts) {
|
|
|
186
316
|
if (chunk && line.match(RE_COMMENT_LINE)) {
|
|
187
317
|
// console.log('line (2)', line);
|
|
188
318
|
// console.log(' clean:', line.replace(RE_COMMENT_LINE, ''));
|
|
189
|
-
chunk.push({
|
|
319
|
+
chunk.push({source: line.replace(RE_COMMENT_LINE, ''), number: number - 1});
|
|
190
320
|
return null;
|
|
191
321
|
}
|
|
192
322
|
|
|
@@ -195,18 +325,17 @@ function mkextract(opts) {
|
|
|
195
325
|
if (chunk && line.match(RE_COMMENT_END)) {
|
|
196
326
|
// console.log('line (3)', line);
|
|
197
327
|
// console.log(' clean:', line.replace(RE_COMMENT_END, ''));
|
|
198
|
-
chunk.push({
|
|
199
|
-
return
|
|
328
|
+
chunk.push({source: line.replace(RE_COMMENT_END, ''), number: number - 1});
|
|
329
|
+
return parse_block(chunk, opts);
|
|
200
330
|
}
|
|
201
331
|
|
|
202
332
|
// if non-comment line
|
|
203
333
|
// then reset the chunk
|
|
204
334
|
chunk = null;
|
|
205
|
-
line_number = 0;
|
|
206
335
|
};
|
|
207
336
|
}
|
|
208
337
|
|
|
209
|
-
/* ------- Transform
|
|
338
|
+
/* ------- Transform stream ------- */
|
|
210
339
|
|
|
211
340
|
function Parser(opts) {
|
|
212
341
|
opts = opts || {};
|
|
@@ -251,6 +380,8 @@ module.exports = function parse(source, opts) {
|
|
|
251
380
|
return blocks;
|
|
252
381
|
};
|
|
253
382
|
|
|
383
|
+
module.exports.PARSERS = PARSERS;
|
|
384
|
+
|
|
254
385
|
module.exports.file = function file(file_path, done) {
|
|
255
386
|
|
|
256
387
|
var collected = [];
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comment-parser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Generic JSDoc-like comment parser. ",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
7
7
|
"test": "tests"
|
|
8
8
|
},
|
|
9
|
-
"dependencies": {
|
|
10
|
-
"lodash": "~2.4.1"
|
|
11
|
-
},
|
|
9
|
+
"dependencies": {},
|
|
12
10
|
"devDependencies": {
|
|
11
|
+
"chai": "~1.9.0",
|
|
12
|
+
"jshint": "^2.5.10",
|
|
13
|
+
"jshint-stylish": "^1.0.0",
|
|
13
14
|
"mocha": "~1.17.1",
|
|
14
|
-
"
|
|
15
|
+
"nodemon": "^1.2.1"
|
|
15
16
|
},
|
|
16
17
|
"scripts": {
|
|
17
|
-
"test": "mocha tests/*"
|
|
18
|
+
"test": "jshint --reporter node_modules/jshint-stylish/stylish.js index.js && mocha tests/*",
|
|
19
|
+
"watch": "nodemon -q -w index.js -w tests/ -x npm test"
|
|
18
20
|
},
|
|
19
21
|
"repository": {
|
|
20
22
|
"type": "git",
|