comment-parser 0.5.0 → 0.5.4
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/.travis.yml +8 -4
- package/CHANGELOG.md +14 -0
- package/README.md +14 -6
- package/index.d.ts +29 -0
- package/index.js +1 -1
- package/package.json +14 -7
- package/parsers.js +26 -17
- package/tests/parse.js +4 -4
- package/tests/parse.spec.js +175 -1
package/.travis.yml
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# v0.5.4
|
|
2
|
+
- allow quoted literal names, e.g. `@tag "My Var" description`
|
|
3
|
+
|
|
4
|
+
# v0.5.3
|
|
5
|
+
- corrected TypeScript definitions
|
|
6
|
+
|
|
7
|
+
# v0.5.2
|
|
8
|
+
- added TypeScript definitions
|
|
9
|
+
- removed `readable-stream` dependency
|
|
10
|
+
|
|
11
|
+
# v0.5.1
|
|
12
|
+
- Support for tab as separator between tag components.
|
|
13
|
+
- Docs: Indicate when `optional` is `true`; `default` property
|
|
14
|
+
|
|
1
15
|
# v0.5.0
|
|
2
16
|
- line wrapping control with `opts.join`
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ It is not trying to detect relations between tags or somehow recognize their mea
|
|
|
17
17
|
* @some-tag {Type} name.subname Singleline or multiline description text
|
|
18
18
|
* @some-tag {Type} name.subname.subsubname Singleline or
|
|
19
19
|
* multiline description text
|
|
20
|
+
* @some-tag {Type} [optionalName=someDefault]
|
|
20
21
|
* @another-tag
|
|
21
22
|
*/
|
|
22
23
|
```
|
|
@@ -49,13 +50,22 @@ this would be parsed into following
|
|
|
49
50
|
"description": "Singleline or\nmultiline description text",
|
|
50
51
|
"line": 5,
|
|
51
52
|
"source": "@some-tag {Type} name.subname.subsubname Singleline or\nmultiline description text"
|
|
53
|
+
}, {
|
|
54
|
+
"tag": "some-tag",
|
|
55
|
+
"type": "Type",
|
|
56
|
+
"name": "optionalName",
|
|
57
|
+
"optional": true,
|
|
58
|
+
"description": "",
|
|
59
|
+
"line": 7,
|
|
60
|
+
"default": "someDefault",
|
|
61
|
+
"source": "@some-tag {Type} [optionalName=someDefault]"
|
|
52
62
|
}, {
|
|
53
63
|
"tag": "another-tag",
|
|
54
64
|
"name": "",
|
|
55
65
|
"optional": false,
|
|
56
66
|
"type": "",
|
|
57
67
|
"description": "",
|
|
58
|
-
"line":
|
|
68
|
+
"line": 8,
|
|
59
69
|
"source": "@another-tag"
|
|
60
70
|
}],
|
|
61
71
|
"line": 0,
|
|
@@ -156,8 +166,6 @@ This would produce following:
|
|
|
156
166
|
|
|
157
167
|
## Contributors
|
|
158
168
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- [Sergii Iavorskyi](https://github.com/yavorskiy)
|
|
163
|
-
- [tengattack](https://github.com/tengattack)
|
|
169
|
+
```
|
|
170
|
+
> npm info --registry https://registry.npmjs.org comment-parser contributors
|
|
171
|
+
```
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Type definitions for comment-parser
|
|
2
|
+
// Project: comment-parser
|
|
3
|
+
// Definitions by: Javier "Ciberman" Mora <https://github.com/jhm-ciberman/>
|
|
4
|
+
|
|
5
|
+
declare namespace CommentParser {
|
|
6
|
+
export interface Comment {
|
|
7
|
+
tags: Tag[];
|
|
8
|
+
line: number;
|
|
9
|
+
description: string;
|
|
10
|
+
source: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Tag {
|
|
13
|
+
tag: string;
|
|
14
|
+
name: string;
|
|
15
|
+
optional: boolean;
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
line: number;
|
|
19
|
+
source: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Options {
|
|
22
|
+
parsers?: [(str: string, data: any) => { source: string, data: any }];
|
|
23
|
+
dotted_names?: boolean;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare function parse(str: string, opts?: CommentParser.Options): [CommentParser.Comment];
|
|
28
|
+
|
|
29
|
+
export = parse;
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comment-parser",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Generic JSDoc-like comment parser. ",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
6
7
|
"directories": {
|
|
7
8
|
"test": "tests"
|
|
8
9
|
},
|
|
9
|
-
"dependencies": {
|
|
10
|
-
"readable-stream": "^2.0.4"
|
|
11
|
-
},
|
|
10
|
+
"dependencies": {},
|
|
12
11
|
"devDependencies": {
|
|
13
|
-
"chai": "
|
|
12
|
+
"chai": "^4.2.0",
|
|
14
13
|
"eslint": "^4.7.1",
|
|
15
14
|
"eslint-config-standard": "^10.2.1",
|
|
16
15
|
"eslint-plugin-import": "^2.7.0",
|
|
17
16
|
"eslint-plugin-node": "^5.1.1",
|
|
18
17
|
"eslint-plugin-promise": "^3.5.0",
|
|
19
18
|
"eslint-plugin-standard": "^3.0.1",
|
|
20
|
-
"mocha": "^
|
|
21
|
-
"nodemon": "^1.
|
|
19
|
+
"mocha": "^5.2.0",
|
|
20
|
+
"nodemon": "^1.18.9"
|
|
22
21
|
},
|
|
23
22
|
"scripts": {
|
|
24
23
|
"pretest": "eslint .",
|
|
@@ -35,6 +34,14 @@
|
|
|
35
34
|
"parser"
|
|
36
35
|
],
|
|
37
36
|
"author": "Sergii Iavorskyi <yavorskiy.s@gmail.com> (https://github.com/yavorskiy)",
|
|
37
|
+
"contributors": [
|
|
38
|
+
"Alexej Yaroshevich (https://github.com/zxqfox)",
|
|
39
|
+
"Dieter Oberkofler (https://github.com/doberkofler)",
|
|
40
|
+
"Evgeny Reznichenko (https://github.com/zxcabs)",
|
|
41
|
+
"Javier \"Ciberma\" Mora (https://github.com/jhm-ciberman)",
|
|
42
|
+
"Jordan Harband (https://github.com/ljharb)",
|
|
43
|
+
"tengattack (https://github.com/tengattack)"
|
|
44
|
+
],
|
|
38
45
|
"license": "MIT",
|
|
39
46
|
"bugs": {
|
|
40
47
|
"url": "https://github.com/yavorskiy/comment-parser/issues"
|
package/parsers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
function skipws (str) {
|
|
2
2
|
var i = 0
|
|
3
3
|
do {
|
|
4
|
-
if (str[i] !== ' ') { return i }
|
|
4
|
+
if (str[i] !== ' ' && str[i] !== '\t') { return i }
|
|
5
5
|
} while (++i < str.length)
|
|
6
6
|
return i
|
|
7
7
|
}
|
|
@@ -51,26 +51,35 @@ PARSERS.parse_name = function parse_name (str, data) {
|
|
|
51
51
|
var pos = skipws(str)
|
|
52
52
|
var name = ''
|
|
53
53
|
var brackets = 0
|
|
54
|
+
var res = {optional: false}
|
|
55
|
+
|
|
56
|
+
// if it starts with quoted group assume it is a literal
|
|
57
|
+
var quotedGroups = str.slice(pos).split('"')
|
|
58
|
+
if (quotedGroups.length > 1 && quotedGroups[0] === '' && quotedGroups.length % 2 === 1) {
|
|
59
|
+
name = quotedGroups[1]
|
|
60
|
+
pos += name.length + 2
|
|
61
|
+
// assume name is non-space string or anything wrapped into brackets
|
|
62
|
+
} else {
|
|
63
|
+
while (pos < str.length) {
|
|
64
|
+
brackets += (str[pos] === '[' ? 1 : (str[pos] === ']' ? -1 : 0))
|
|
65
|
+
name += str[pos]
|
|
66
|
+
pos++
|
|
67
|
+
if (brackets === 0 && /\s/.test(str[pos])) { break }
|
|
68
|
+
}
|
|
54
69
|
|
|
55
|
-
|
|
56
|
-
brackets += (str[pos] === '[' ? 1 : (str[pos] === ']' ? -1 : 0))
|
|
57
|
-
name += str[pos]
|
|
58
|
-
pos++
|
|
59
|
-
if (brackets === 0 && /\s/.test(str[pos])) { break }
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (brackets !== 0) { throw new Error('Invalid `name`, unpaired brackets') }
|
|
70
|
+
if (brackets !== 0) { throw new Error('Invalid `name`, unpaired brackets') }
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
res = {name: name, optional: false}
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
if (name[0] === '[' && name[name.length - 1] === ']') {
|
|
75
|
+
res.optional = true
|
|
76
|
+
name = name.slice(1, -1)
|
|
69
77
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
if (name.indexOf('=') !== -1) {
|
|
79
|
+
var parts = name.split('=')
|
|
80
|
+
name = parts[0]
|
|
81
|
+
res.default = parts[1].replace(/^(["'])(.+)(\1)$/, '$2')
|
|
82
|
+
}
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
|
package/tests/parse.js
CHANGED
|
@@ -11,8 +11,8 @@ var parse = require('../index')
|
|
|
11
11
|
|
|
12
12
|
module.exports = function (func, opts) {
|
|
13
13
|
var str = func.toString()
|
|
14
|
-
|
|
15
|
-
str.indexOf('{') + 1,
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
str = str
|
|
15
|
+
.slice(str.indexOf('{') + 1, str.lastIndexOf('}'))
|
|
16
|
+
.replace(/\r\n/g, '\n')
|
|
17
|
+
return parse(str, opts)
|
|
18
18
|
}
|
package/tests/parse.spec.js
CHANGED
|
@@ -366,6 +366,30 @@ describe('Comment string parsing', function () {
|
|
|
366
366
|
})
|
|
367
367
|
})
|
|
368
368
|
|
|
369
|
+
/* eslint-disable no-tabs */
|
|
370
|
+
it('should parse tag with type, name and description `@tag {my.type} name description separated by tab`', function () {
|
|
371
|
+
expect(parse(function () {
|
|
372
|
+
/**
|
|
373
|
+
* @my-tag {my.type} name description
|
|
374
|
+
*/
|
|
375
|
+
})[0])
|
|
376
|
+
.to.eql({
|
|
377
|
+
line: 1,
|
|
378
|
+
source: '@my-tag\t{my.type}\tname\tdescription',
|
|
379
|
+
description: '',
|
|
380
|
+
tags: [{
|
|
381
|
+
tag: 'my-tag',
|
|
382
|
+
line: 2,
|
|
383
|
+
type: 'my.type',
|
|
384
|
+
name: 'name',
|
|
385
|
+
source: '@my-tag\t{my.type}\tname\tdescription',
|
|
386
|
+
description: 'description',
|
|
387
|
+
optional: false
|
|
388
|
+
}]
|
|
389
|
+
})
|
|
390
|
+
})
|
|
391
|
+
/* eslint-enable no-tabs */
|
|
392
|
+
|
|
369
393
|
it('should parse tag with multiline description', function () {
|
|
370
394
|
expect(parse(function () {
|
|
371
395
|
/**
|
|
@@ -588,7 +612,7 @@ describe('Comment string parsing', function () {
|
|
|
588
612
|
* @my-tag name.sub-name
|
|
589
613
|
* @my-tag name.sub-name.sub-sub-name
|
|
590
614
|
*/
|
|
591
|
-
}, {dotted_names: true})[0])
|
|
615
|
+
}, { dotted_names: true })[0])
|
|
592
616
|
.to.eql({
|
|
593
617
|
line: 1,
|
|
594
618
|
description: 'Description',
|
|
@@ -864,4 +888,154 @@ describe('Comment string parsing', function () {
|
|
|
864
888
|
}]
|
|
865
889
|
})
|
|
866
890
|
})
|
|
891
|
+
|
|
892
|
+
it('should parse same line closing section (issue #22)', function () {
|
|
893
|
+
expect(parse(function () {
|
|
894
|
+
/**
|
|
895
|
+
* Start here
|
|
896
|
+
* Here is more stuff */
|
|
897
|
+
var a
|
|
898
|
+
})[0])
|
|
899
|
+
.to.eql({
|
|
900
|
+
description: 'Start here\nHere is more stuff',
|
|
901
|
+
line: 1,
|
|
902
|
+
source: 'Start here\nHere is more stuff',
|
|
903
|
+
tags: []
|
|
904
|
+
})
|
|
905
|
+
})
|
|
906
|
+
|
|
907
|
+
it('should tolerate inconsistent formatting (issue #29)', function () {
|
|
908
|
+
expect(parse(function () {
|
|
909
|
+
/**
|
|
910
|
+
* @param {Object} options 配置
|
|
911
|
+
* @return {Any} obj 组件返回的对象
|
|
912
|
+
* @example
|
|
913
|
+
* var widget = XX.showWidget('searchlist', {
|
|
914
|
+
* onComplete: function() {
|
|
915
|
+
* todoSomething();
|
|
916
|
+
* }
|
|
917
|
+
* });
|
|
918
|
+
*/
|
|
919
|
+
}, {
|
|
920
|
+
join: 1,
|
|
921
|
+
trim: false
|
|
922
|
+
})[0]).to.eql({
|
|
923
|
+
description: '',
|
|
924
|
+
line: 1,
|
|
925
|
+
source: "\n@param {Object} options 配置\n@return {Any} obj 组件返回的对象\n@example\nvar widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
|
|
926
|
+
tags: [{
|
|
927
|
+
description: '配置',
|
|
928
|
+
line: 2,
|
|
929
|
+
name: 'options',
|
|
930
|
+
optional: false,
|
|
931
|
+
source: '@param {Object} options 配置',
|
|
932
|
+
tag: 'param',
|
|
933
|
+
type: 'Object'
|
|
934
|
+
}, {
|
|
935
|
+
description: '组件返回的对象',
|
|
936
|
+
line: 3,
|
|
937
|
+
name: 'obj',
|
|
938
|
+
optional: false,
|
|
939
|
+
source: '@return {Any} obj 组件返回的对象',
|
|
940
|
+
tag: 'return',
|
|
941
|
+
type: 'Any'
|
|
942
|
+
}, {
|
|
943
|
+
description: "widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
|
|
944
|
+
line: 4,
|
|
945
|
+
name: '\nvar',
|
|
946
|
+
optional: false,
|
|
947
|
+
source: "@example\nvar widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
|
|
948
|
+
tag: 'example',
|
|
949
|
+
type: ''
|
|
950
|
+
}]
|
|
951
|
+
})
|
|
952
|
+
})
|
|
953
|
+
|
|
954
|
+
it('should keep optional names spaces (issue #41)`', function () {
|
|
955
|
+
expect(parse(function () {
|
|
956
|
+
/**
|
|
957
|
+
* @section [Brand Colors] Here you can find all the brand colors
|
|
958
|
+
*/
|
|
959
|
+
})[0])
|
|
960
|
+
.to.eql({
|
|
961
|
+
line: 1,
|
|
962
|
+
source: '@section [Brand Colors] Here you can find all the brand colors',
|
|
963
|
+
description: '',
|
|
964
|
+
tags: [{
|
|
965
|
+
tag: 'section',
|
|
966
|
+
line: 2,
|
|
967
|
+
type: '',
|
|
968
|
+
name: 'Brand Colors',
|
|
969
|
+
source: '@section [Brand Colors] Here you can find all the brand colors',
|
|
970
|
+
optional: true,
|
|
971
|
+
description: 'Here you can find all the brand colors'
|
|
972
|
+
}]
|
|
973
|
+
})
|
|
974
|
+
})
|
|
975
|
+
|
|
976
|
+
it('should keep quotes in description (issue #41)`', function () {
|
|
977
|
+
expect(parse(function () {
|
|
978
|
+
/**
|
|
979
|
+
* @section "Brand Colors" Here you can find all the brand colors
|
|
980
|
+
*/
|
|
981
|
+
})[0])
|
|
982
|
+
.to.eql({
|
|
983
|
+
line: 1,
|
|
984
|
+
source: '@section "Brand Colors" Here you can find all the brand colors',
|
|
985
|
+
description: '',
|
|
986
|
+
tags: [{
|
|
987
|
+
tag: 'section',
|
|
988
|
+
line: 2,
|
|
989
|
+
type: '',
|
|
990
|
+
name: 'Brand Colors',
|
|
991
|
+
source: '@section "Brand Colors" Here you can find all the brand colors',
|
|
992
|
+
optional: false,
|
|
993
|
+
description: 'Here you can find all the brand colors'
|
|
994
|
+
}]
|
|
995
|
+
})
|
|
996
|
+
})
|
|
997
|
+
|
|
998
|
+
it('should use only quoted name (issue #41)`', function () {
|
|
999
|
+
expect(parse(function () {
|
|
1000
|
+
/**
|
|
1001
|
+
* @section "Brand Colors" Here you can find "all" the brand colors
|
|
1002
|
+
*/
|
|
1003
|
+
})[0])
|
|
1004
|
+
.to.eql({
|
|
1005
|
+
line: 1,
|
|
1006
|
+
source: '@section "Brand Colors" Here you can find "all" the brand colors',
|
|
1007
|
+
description: '',
|
|
1008
|
+
tags: [{
|
|
1009
|
+
tag: 'section',
|
|
1010
|
+
line: 2,
|
|
1011
|
+
type: '',
|
|
1012
|
+
name: 'Brand Colors',
|
|
1013
|
+
source: '@section "Brand Colors" Here you can find "all" the brand colors',
|
|
1014
|
+
optional: false,
|
|
1015
|
+
description: 'Here you can find "all" the brand colors'
|
|
1016
|
+
}]
|
|
1017
|
+
})
|
|
1018
|
+
})
|
|
1019
|
+
|
|
1020
|
+
it('should ignore inconsitent quoted groups (issue #41)`', function () {
|
|
1021
|
+
expect(parse(function () {
|
|
1022
|
+
/**
|
|
1023
|
+
* @section "Brand Colors Here you can find all the brand colors
|
|
1024
|
+
*/
|
|
1025
|
+
})[0])
|
|
1026
|
+
.to.eql({
|
|
1027
|
+
line: 1,
|
|
1028
|
+
source: '@section "Brand Colors Here you can find all the brand colors',
|
|
1029
|
+
description: '',
|
|
1030
|
+
tags: [{
|
|
1031
|
+
tag: 'section',
|
|
1032
|
+
line: 2,
|
|
1033
|
+
type: '',
|
|
1034
|
+
name: '"Brand',
|
|
1035
|
+
source: '@section "Brand Colors Here you can find all the brand colors',
|
|
1036
|
+
optional: false,
|
|
1037
|
+
description: 'Colors Here you can find all the brand colors'
|
|
1038
|
+
}]
|
|
1039
|
+
})
|
|
1040
|
+
})
|
|
867
1041
|
})
|