spacedocs 0.0.2

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.
data/dox/lib/dox.js ADDED
@@ -0,0 +1,286 @@
1
+ /*!
2
+ * Module dependencies.
3
+ */
4
+
5
+ var markdown = require('github-flavored-markdown').parse
6
+ , escape = require('./utils').escape;
7
+
8
+ /**
9
+ * Library version.
10
+ */
11
+
12
+ exports.version = '0.3.1';
13
+
14
+ /**
15
+ * Parse comments in the given string of `js`.
16
+ *
17
+ * @param {String} js
18
+ * @param {Object} options
19
+ * @return {Array}
20
+ * @see exports.parseComment
21
+ * @api public
22
+ */
23
+
24
+ exports.parseComments = function(js, options){
25
+ js = js.trim()
26
+
27
+ options = options || {};
28
+
29
+ var comments = []
30
+ , raw = options.raw
31
+ , comment
32
+ , buf = ''
33
+ , ignore
34
+ , within
35
+ , code
36
+ , indent;
37
+
38
+ for (var i = 0, len = js.length; i < len; ++i) {
39
+ // start comment
40
+ if (!within && '/' == js[i] && '*' == js[i+1]) {
41
+ // code following previous comment
42
+ if (buf.trim().length) {
43
+ comment = comments[comments.length - 1];
44
+ if(comment) {
45
+ comment.code = code = buf.trim();
46
+ comment.ctx = exports.parseCodeContext(code);
47
+ }
48
+ buf = '';
49
+ }
50
+ i += 2;
51
+ within = true;
52
+ ignore = '!' == js[i];
53
+ // end comment
54
+ } else if (within && '*' == js[i] && '/' == js[i+1]) {
55
+ i += 2;
56
+ lines = buf.split('\n');
57
+
58
+ indentLevel = lines[lines.length - 1].length;
59
+ indentRegex = new RegExp('^[ \\t]{' + indentLevel + '}', 'gm');
60
+ buf = buf.replace(indentRegex, '');
61
+
62
+ buf = buf.replace(/^[ \t]*\* ?/gm, '');
63
+ var comment = exports.parseComment(buf, options);
64
+ comment.ignore = ignore;
65
+ comments.push(comment);
66
+ within = ignore = false;
67
+ buf = '';
68
+ // buffer comment or code
69
+ } else {
70
+ buf += js[i];
71
+ }
72
+ }
73
+
74
+ // trailing code
75
+ if (buf.trim().length) {
76
+ comment = comments[comments.length - 1];
77
+ code = buf.trim();
78
+ comment.code = code;
79
+ comment.ctx = exports.parseCodeContext(code);
80
+ }
81
+
82
+ return comments;
83
+ };
84
+
85
+ /**
86
+ * Parse the given comment `str`.
87
+ *
88
+ * The comment object returned contains the following
89
+ *
90
+ * - `tags` array of tag objects
91
+ * - `description` the first line of the comment
92
+ * - `body` lines following the description
93
+ * - `content` both the description and the body
94
+ * - `isPrivate` true when "@api private" is used
95
+ *
96
+ * @param {String} str
97
+ * @param {Object} options
98
+ * @return {Object}
99
+ * @see exports.parseTag
100
+ * @api public
101
+ */
102
+
103
+ exports.parseComment = function(str, options) {
104
+ str = str.trim();
105
+ options = options || {};
106
+
107
+ var comment = { tags: [] }
108
+ , raw = options.raw
109
+ , description = {};
110
+
111
+ // parse comment body
112
+ description.full = str.split('\n@')[0].replace(/^([A-Z][\w ]+):$/gm, '## $1');
113
+ description.summary = description.full.split('\n\n')[0];
114
+ description.body = description.full.split('\n\n').slice(1).join('\n\n');
115
+ comment.description = description;
116
+
117
+ // parse tags
118
+ if (~str.indexOf('\n@')) {
119
+ var tags = '@' + str.split('\n@').slice(1).join('\n@');
120
+ comment.tags = tags.split('\n').map(exports.parseTag);
121
+ comment.isPrivate = comment.tags.some(function(tag){
122
+ return 'api' == tag.type && 'private' == tag.visibility;
123
+ })
124
+ }
125
+
126
+ // markdown
127
+ if (!raw) {
128
+ description.full = markdown(description.full);
129
+ description.summary = markdown(description.summary);
130
+ description.body = markdown(description.body);
131
+ }
132
+
133
+ return comment;
134
+ }
135
+
136
+ /**
137
+ * Parse tag string "@param {Array} name description" etc.
138
+ *
139
+ * @param {String}
140
+ * @return {Object}
141
+ * @api public
142
+ */
143
+
144
+ exports.parseTag = function(str) {
145
+ var tag = {}
146
+ , parts = str.split(/ +/)
147
+ , type = tag.type = parts.shift().replace('@', '');
148
+
149
+ switch (type) {
150
+ case 'param':
151
+ tag.types = exports.parseTagTypes(parts.shift());
152
+ tag.name = parts.shift() || '';
153
+ tag.description = parts.join(' ');
154
+ break;
155
+ case 'return':
156
+ tag.types = exports.parseTagTypes(parts.shift());
157
+ tag.description = parts.join(' ');
158
+ break;
159
+ case 'see':
160
+ if (~str.indexOf('http')) {
161
+ tag.title = parts.length > 1
162
+ ? parts.shift()
163
+ : '';
164
+ tag.url = parts.join(' ');
165
+ } else {
166
+ tag.local = parts.join(' ');
167
+ }
168
+ case 'api':
169
+ tag.visibility = parts.shift();
170
+ break;
171
+ case 'type':
172
+ tag.types = exports.parseTagTypes(parts.shift());
173
+ break;
174
+ case 'memberOf':
175
+ tag.parent = parts.shift();
176
+ break;
177
+ case 'augments':
178
+ tag.otherClass = parts.shift();
179
+ break;
180
+ case 'borrows':
181
+ tag.otherMemberName = parts.join(' ').split(' as ')[0];
182
+ tag.thisMemberName = parts.join(' ').split(' as ')[1];
183
+ break;
184
+ default:
185
+ tag.string = parts.join(' ');
186
+ break;
187
+ }
188
+
189
+ return tag;
190
+ }
191
+
192
+ /**
193
+ * Parse tag type string "{Array|Object}" etc.
194
+ *
195
+ * @param {String} str
196
+ * @return {Array}
197
+ * @api public
198
+ */
199
+
200
+ exports.parseTagTypes = function(str) {
201
+ return str
202
+ .replace(/[{}]/g, '')
203
+ .split(/ *[|,\/] */);
204
+ };
205
+
206
+ /**
207
+ * Parse the context from the given `str` of js.
208
+ *
209
+ * This method attempts to discover the context
210
+ * for the comment based on it's code. Currently
211
+ * supports:
212
+ *
213
+ * - function statements
214
+ * - function expressions
215
+ * - prototype methods
216
+ * - prototype properties
217
+ * - methods
218
+ * - properties
219
+ * - declarations
220
+ *
221
+ * @param {String} str
222
+ * @return {Object}
223
+ * @api public
224
+ */
225
+
226
+ exports.parseCodeContext = function(str){
227
+ var str = str.split('\n')[0];
228
+
229
+ // function statement
230
+ if (/^function (\w+) *\(/.exec(str)) {
231
+ return {
232
+ type: 'function'
233
+ , name: RegExp.$1
234
+ , string: RegExp.$1 + '()'
235
+ };
236
+ // function expression
237
+ } else if (/^var *(\w+) *= *function/.exec(str)) {
238
+ return {
239
+ type: 'function'
240
+ , name: RegExp.$1
241
+ , string: RegExp.$1 + '()'
242
+ };
243
+ // prototype method
244
+ } else if (/^(\w+)\.prototype\.(\w+) *= *function/.exec(str)) {
245
+ return {
246
+ type: 'method'
247
+ , constructor: RegExp.$1
248
+ , name: RegExp.$2
249
+ , string: RegExp.$1 + '.prototype.' + RegExp.$2 + '()'
250
+ };
251
+ // prototype property
252
+ } else if (/^(\w+)\.prototype\.(\w+) *= *([^\n;]+)/.exec(str)) {
253
+ return {
254
+ type: 'property'
255
+ , constructor: RegExp.$1
256
+ , name: RegExp.$2
257
+ , value: RegExp.$3
258
+ , string: RegExp.$1 + '.prototype' + RegExp.$2
259
+ };
260
+ // method
261
+ } else if (/^(\w+)\.(\w+) *= *function/.exec(str)) {
262
+ return {
263
+ type: 'method'
264
+ , receiver: RegExp.$1
265
+ , name: RegExp.$2
266
+ , string: RegExp.$1 + '.' + RegExp.$2 + '()'
267
+ };
268
+ // property
269
+ } else if (/^(\w+)\.(\w+) *= *([^\n;]+)/.exec(str)) {
270
+ return {
271
+ type: 'property'
272
+ , receiver: RegExp.$1
273
+ , name: RegExp.$2
274
+ , value: RegExp.$3
275
+ , string: RegExp.$1 + '.' + RegExp.$2
276
+ };
277
+ // declaration
278
+ } else if (/^var +(\w+) *= *([^\n;]+)/.exec(str)) {
279
+ return {
280
+ type: 'declaration'
281
+ , name: RegExp.$1
282
+ , value: RegExp.$2
283
+ , string: RegExp.$1
284
+ };
285
+ }
286
+ };
data/dox/lib/utils.js ADDED
@@ -0,0 +1,15 @@
1
+
2
+ /**
3
+ * Escape the given `html`.
4
+ *
5
+ * @param {String} html
6
+ * @return {String}
7
+ * @api private
8
+ */
9
+
10
+ exports.escape = function(html){
11
+ return String(html)
12
+ .replace(/&(?!\w+;)/g, '&amp;')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;');
15
+ };
data/dox/package.json ADDED
@@ -0,0 +1,16 @@
1
+ { "name": "dox"
2
+ , "description": "Markdown / JSdoc documentation generator"
3
+ , "version": "0.3.1"
4
+ , "author": "TJ Holowaychuk <tj@vision-media.ca>"
5
+ , "repository": { "type": "git", "url": "git://github.com/visionmedia/dox.git" }
6
+ , "keywords": ["documentation", "docs", "markdown", "jsdoc"]
7
+ , "bin": { "dox": "./bin/dox" }
8
+ , "dependencies": {
9
+ "github-flavored-markdown": ">= 0.0.1"
10
+ , "commander": "0.5.2"
11
+ }
12
+ , "devDependencies": {
13
+ "mocha": "*"
14
+ , "should": "*"
15
+ }
16
+ }
@@ -0,0 +1,287 @@
1
+
2
+ /**
3
+ * Module dependencies.
4
+ */
5
+
6
+ var dox = require('../')
7
+ , should = require('should')
8
+ , fs = require('fs');
9
+
10
+ function fixture(name, fn) {
11
+ fs.readFile(__dirname + '/fixtures/' + name, 'utf8', fn);
12
+ }
13
+
14
+ module.exports = {
15
+ 'test .version': function(){
16
+ dox.version.should.match(/^\d+\.\d+\.\d+$/);
17
+ },
18
+
19
+ 'test .parseComments() blocks': function(done){
20
+ fixture('a.js', function(err, str){
21
+ var comments = dox.parseComments(str)
22
+ , file = comments.shift()
23
+ , version = comments.shift();
24
+ file.should.have.property('ignore', true);
25
+ file.description.full.should.equal('<p>A<br />Copyright (c) 2010 Author Name <Author Email><br />MIT Licensed</p>');
26
+ file.description.summary.should.equal('<p>A<br />Copyright (c) 2010 Author Name <Author Email><br />MIT Licensed</p>');
27
+ file.description.body.should.equal('');
28
+ file.tags.should.be.empty;
29
+
30
+ version.should.have.property('ignore', false);
31
+ version.description.full.should.equal('<p>Library version.</p>');
32
+ version.description.summary.should.equal('<p>Library version.</p>');
33
+ version.description.body.should.equal('');
34
+ version.tags.should.be.empty;
35
+ done();
36
+ });
37
+ },
38
+
39
+ 'test .parseComments() tags': function(done){
40
+ fixture('b.js', function(err, str){
41
+ var comments = dox.parseComments(str);
42
+
43
+ var version = comments.shift();
44
+ version.description.summary.should.equal('<p>Library version.</p>');
45
+ version.description.full.should.equal('<p>Library version.</p>');
46
+ version.tags.should.have.length(2);
47
+ version.tags[0].type.should.equal('type');
48
+ version.tags[0].types.should.eql(['String']);
49
+ version.tags[1].type.should.equal('api');
50
+ version.tags[1].visibility.should.equal('public');
51
+ version.ctx.type.should.equal('property');
52
+ version.ctx.receiver.should.equal('exports');
53
+ version.ctx.name.should.equal('version');
54
+ version.ctx.value.should.equal("'0.0.1'");
55
+
56
+ var parse = comments.shift();
57
+ parse.description.summary.should.equal('<p>Parse the given <code>str</code>.</p>');
58
+ parse.description.body.should.equal('<h2>Examples</h2>\n\n<pre><code>parse(str)\n// =&amp;gt; "wahoo"\n</code></pre>');
59
+ parse.description.full.should.equal('<p>Parse the given <code>str</code>.</p>\n\n<h2>Examples</h2>\n\n<pre><code>parse(str)\n// =&amp;gt; "wahoo"\n</code></pre>');
60
+ parse.tags[0].type.should.equal('param');
61
+ parse.tags[0].name.should.equal('str');
62
+ parse.tags[0].description.should.equal('to parse');
63
+ parse.tags[0].types.should.eql(['String', 'Buffer']);
64
+ parse.tags[1].type.should.equal('return');
65
+ parse.tags[1].types.should.eql(['String']);
66
+ parse.tags[2].visibility.should.equal('public');
67
+ done();
68
+ });
69
+ },
70
+
71
+ 'test .parseComments() complex': function(done){
72
+ fixture('c.js', function(err, str){
73
+ var comments = dox.parseComments(str);
74
+
75
+ var file = comments.shift();
76
+
77
+ file.tags.should.be.empty;
78
+ // the following doesn't work as gh-md now obfuscates emails different on every pass
79
+ //file.description.full.should.equal('<p>Dox<br />Copyright (c) 2010 TJ Holowaychuk <a href=\'mailto:tj@vision-media.ca\'>tj@vision-media.ca</a><br />MIT Licensed</p>');
80
+ file.description.full.should.be.a('string');
81
+ file.ignore.should.be.true;
82
+
83
+ var mods = comments.shift();
84
+ mods.tags.should.be.empty;
85
+ mods.description.full.should.equal('<p>Module dependencies.</p>');
86
+ mods.description.summary.should.equal('<p>Module dependencies.</p>');
87
+ mods.description.body.should.equal('');
88
+ mods.ignore.should.be.false;
89
+ mods.code.should.equal('var markdown = require(\'github-flavored-markdown\').parse;');
90
+ mods.ctx.type.should.equal('declaration');
91
+ mods.ctx.name.should.equal('markdown');
92
+ mods.ctx.value.should.equal('require(\'github-flavored-markdown\').parse');
93
+
94
+ var version = comments.shift();
95
+ version.tags.should.be.empty;
96
+ version.description.full.should.equal('<p>Library version.</p>');
97
+
98
+ var parseComments = comments.shift();
99
+ parseComments.tags.should.have.length(4);
100
+ parseComments.ctx.type.should.equal('method');
101
+ parseComments.ctx.receiver.should.equal('exports');
102
+ parseComments.ctx.name.should.equal('parseComments');
103
+ parseComments.description.full.should.equal('<p>Parse comments in the given string of <code>js</code>.</p>');
104
+ parseComments.description.summary.should.equal('<p>Parse comments in the given string of <code>js</code>.</p>');
105
+ parseComments.description.body.should.equal('');
106
+
107
+ var parseComment = comments.shift();
108
+ parseComment.tags.should.have.length(4);
109
+ parseComment.description.summary.should.equal('<p>Parse the given comment <code>str</code>.</p>');
110
+ parseComment.description.full.should.equal('<p>Parse the given comment <code>str</code>.</p>\n\n<h2>The comment object returned contains the following</h2>\n\n<ul>\n<li><code>tags</code> array of tag objects</li>\n<li><code>description</code> the first line of the comment</li>\n<li><code>body</code> lines following the description</li>\n<li><code>content</code> both the description and the body</li>\n<li><code>isPrivate</code> true when "@api private" is used</li>\n</ul>');
111
+ parseComment.description.body.should.equal('<h2>The comment object returned contains the following</h2>\n\n<ul>\n<li><code>tags</code> array of tag objects</li>\n<li><code>description</code> the first line of the comment</li>\n<li><code>body</code> lines following the description</li>\n<li><code>content</code> both the description and the body</li>\n<li><code>isPrivate</code> true when "@api private" is used</li>\n</ul>');
112
+
113
+ var escape = comments.pop();
114
+ escape.tags.should.have.length(3);
115
+ escape.description.full.should.equal('<p>Escape the given <code>html</code>.</p>');
116
+ escape.ctx.type.should.equal('function');
117
+ escape.ctx.name.should.equal('escape');
118
+ done();
119
+ });
120
+ },
121
+
122
+ 'test .parseComments() tags': function (done){
123
+ fixture('d.js', function(err, str){
124
+ var comments = dox.parseComments(str);
125
+ var first = comments.shift();
126
+ first.tags.should.have.length(4);
127
+ first.description.full.should.equal('<p>Parse tag type string "{Array|Object}" etc.</p>');
128
+ first.description.summary.should.equal('<p>Parse tag type string "{Array|Object}" etc.</p>');
129
+ first.description.body.should.equal('');
130
+ first.ctx.type.should.equal('method');
131
+ first.ctx.receiver.should.equal('exports');
132
+ first.ctx.name.should.equal('parseTagTypes');
133
+ first.code.should.equal('exports.parseTagTypes = function(str) {\n return str\n .replace(/[{}]/g, \'\')\n .split(/ *[|,\\/] */);\n};');
134
+ done();
135
+ });
136
+ },
137
+
138
+ 'test .parseComments() code': function(done){
139
+ fixture('b.js', function(err, str){
140
+ var comments = dox.parseComments(str)
141
+ , version = comments.shift()
142
+ , parse = comments.shift();
143
+
144
+ version.code.should.equal("exports.version = '0.0.1';");
145
+ parse.code.should.equal('exports.parse = function(str) {\n return "wahoo";\n}');
146
+ done();
147
+ });
148
+ },
149
+
150
+ 'test .parseComments() titles': function(done){
151
+ fixture('titles.js', function(err, str){
152
+ var comments = dox.parseComments(str);
153
+ comments[0].description.body.should.include('<h2>Some examples</h2>');
154
+ comments[0].description.body.should.not.include('<h2>for example</h2>');
155
+ comments[0].description.body.should.include('<p>Some longer thing<br />for example:</p>');
156
+ done();
157
+ });
158
+ },
159
+
160
+ 'test .parseCodeContext() function statement': function(){
161
+ var ctx = dox.parseCodeContext('function foo(){\n\n}');
162
+ ctx.type.should.equal('function');
163
+ ctx.name.should.equal('foo');
164
+ },
165
+
166
+ 'test .parseCodeContext() function expression': function(){
167
+ var ctx = dox.parseCodeContext('var foo = function(){\n\n}');
168
+ ctx.type.should.equal('function');
169
+ ctx.name.should.equal('foo');
170
+ },
171
+
172
+ 'test .parseCodeContext() prototype method': function(){
173
+ var ctx = dox.parseCodeContext('User.prototype.save = function(){}');
174
+ ctx.type.should.equal('method');
175
+ ctx.constructor.should.equal('User');
176
+ ctx.name.should.equal('save');
177
+ },
178
+
179
+ 'test .parseCodeContext() prototype property': function(){
180
+ var ctx = dox.parseCodeContext('Database.prototype.enabled = true;\nasdf');
181
+ ctx.type.should.equal('property');
182
+ ctx.constructor.should.equal('Database');
183
+ ctx.name.should.equal('enabled');
184
+ ctx.value.should.equal('true');
185
+ },
186
+
187
+ 'test .parseCodeContext() method': function(){
188
+ var ctx = dox.parseCodeContext('user.save = function(){}');
189
+ ctx.type.should.equal('method');
190
+ ctx.receiver.should.equal('user');
191
+ ctx.name.should.equal('save');
192
+ },
193
+
194
+ 'test .parseCodeContext() property': function(){
195
+ var ctx = dox.parseCodeContext('user.name = "tj";\nasdf');
196
+ ctx.type.should.equal('property');
197
+ ctx.receiver.should.equal('user');
198
+ ctx.name.should.equal('name');
199
+ ctx.value.should.equal('"tj"');
200
+ },
201
+
202
+ 'test .parseCodeContext() declaration': function(){
203
+ var ctx = dox.parseCodeContext('var name = "tj";\nasdf');
204
+ ctx.type.should.equal('declaration');
205
+ ctx.name.should.equal('name');
206
+ ctx.value.should.equal('"tj"');
207
+ },
208
+
209
+ 'test .parseTag() @constructor': function(){
210
+ var tag = dox.parseTag('@constructor');
211
+ tag.type.should.equal('constructor');
212
+ },
213
+
214
+ 'test .parseTag() @see': function(){
215
+ var tag = dox.parseTag('@see http://google.com');
216
+ tag.type.should.equal('see');
217
+ tag.title.should.equal('');
218
+ tag.url.should.equal('http://google.com');
219
+
220
+ var tag = dox.parseTag('@see Google http://google.com');
221
+ tag.type.should.equal('see');
222
+ tag.title.should.equal('Google');
223
+ tag.url.should.equal('http://google.com');
224
+
225
+ var tag = dox.parseTag('@see exports.parseComment');
226
+ tag.type.should.equal('see');
227
+ tag.local.should.equal('exports.parseComment');
228
+ },
229
+
230
+ 'test .parseTag() @api': function(){
231
+ var tag = dox.parseTag('@api private');
232
+ tag.type.should.equal('api');
233
+ tag.visibility.should.equal('private');
234
+ },
235
+
236
+ 'test .parseTag() @type': function(){
237
+ var tag = dox.parseTag('@type {String}');
238
+ tag.type.should.equal('type');
239
+ tag.types.should.eql(['String']);
240
+ },
241
+
242
+ 'test .parseTag() @param': function(){
243
+ var tag = dox.parseTag('@param {String|Buffer}');
244
+ tag.type.should.equal('param');
245
+ tag.types.should.eql(['String', 'Buffer']);
246
+ tag.name.should.equal('');
247
+ tag.description.should.equal('');
248
+ },
249
+
250
+ 'test .parseTag() @return': function(){
251
+ var tag = dox.parseTag('@return {String} a normal string');
252
+ tag.type.should.equal('return');
253
+ tag.types.should.eql(['String']);
254
+ tag.description.should.equal('a normal string');
255
+ },
256
+
257
+ 'test .parseTag() @augments': function(){
258
+ var tag = dox.parseTag('@augments otherClass');
259
+ tag.type.should.equal('augments');
260
+ tag.otherClass.should.equal('otherClass')
261
+ },
262
+
263
+ 'test .parseTag() @author': function(){
264
+ var tag = dox.parseTag('@author Bob Bobson');
265
+ tag.type.should.equal('author');
266
+ tag.string.should.equal('Bob Bobson');
267
+ },
268
+
269
+ 'test .parseTag() @borrows': function(){
270
+ var tag = dox.parseTag('@borrows foo as bar');
271
+ tag.type.should.equal('borrows');
272
+ tag.otherMemberName.should.equal('foo');
273
+ tag.thisMemberName.should.equal('bar');
274
+ },
275
+
276
+ 'test .parseTag() @memberOf': function(){
277
+ var tag = dox.parseTag('@memberOf Foo.bar')
278
+ tag.type.should.equal('memberOf')
279
+ tag.parent.should.equal('Foo.bar')
280
+ },
281
+
282
+ 'test .parseTag() default': function(){
283
+ var tag = dox.parseTag('@hello universe is better than world');
284
+ tag.type.should.equal('hello');
285
+ tag.string.should.equal('universe is better than world');
286
+ }
287
+ };
@@ -0,0 +1,12 @@
1
+
2
+ /*!
3
+ * A
4
+ * Copyright (c) 2010 Author Name <Author Email>
5
+ * MIT Licensed
6
+ */
7
+
8
+ /**
9
+ * Library version.
10
+ */
11
+
12
+ exports.version = '0.0.1';
@@ -0,0 +1,26 @@
1
+
2
+ /**
3
+ * Library version.
4
+ *
5
+ * @type {String}
6
+ * @api public
7
+ */
8
+
9
+ exports.version = '0.0.1';
10
+
11
+ /**
12
+ * Parse the given `str`.
13
+ *
14
+ * Examples:
15
+ *
16
+ * parse(str)
17
+ * // => "wahoo"
18
+ *
19
+ * @param {String|Buffer} str to parse
20
+ * @return {String}
21
+ * @api public
22
+ */
23
+
24
+ exports.parse = function(str) {
25
+ return "wahoo";
26
+ }