Comparing version 0.6.1 to 0.7.0
@@ -0,1 +1,17 @@ | ||
0.7.0 / 2015-03-24 | ||
================== | ||
* Add context parsing for some ES6 syntax: | ||
- classes | ||
- class constructors | ||
- class methods | ||
- assignments via `let` or `const` | ||
* Add support for @description tag | ||
* Add context match for returned closure | ||
* Add: Tags without descriptions now have an `html` property containing a markdown parse of the tag's contents | ||
* Fix: more agnostic to code style when parsing contexts (eg, no longer ignores functions without spaces between function name and parenthesis) | ||
* Fix: No longer incorrectly tries to parse strings inside comments, causing large chunks of a file to be ignored. | ||
* Fix: No longer parses double slash in a string literal as being a comment start. | ||
* Deps: commander@2.7.1 | ||
0.6.1 / 2014-11-27 | ||
@@ -2,0 +18,0 @@ ================== |
133
lib/dox.js
@@ -5,4 +5,3 @@ /*! | ||
var markdown = require('marked') | ||
, escape = require('./utils').escape; | ||
var markdown = require('marked'); | ||
@@ -57,3 +56,2 @@ var renderer = new markdown.Renderer(); | ||
var comments = [] | ||
, raw = options.raw | ||
, skipSingleStar = options.skipSingleStar | ||
@@ -73,2 +71,3 @@ , comment | ||
for (var i = 0, len = js.length; i < len; ++i) { | ||
@@ -79,3 +78,3 @@ // start comment | ||
lineNumStarting = lineNum; | ||
// code following previous comment | ||
// code following the last comment | ||
if (buf.trim().length) { | ||
@@ -89,4 +88,8 @@ comment = comments[comments.length - 1]; | ||
if (comment.isConstructor && comment.ctx){ | ||
comment.ctx.type = "constructor"; | ||
} | ||
// starting a new namespace | ||
if (comment.ctx && comment.ctx.type === 'prototype'){ | ||
if (comment.ctx && (comment.ctx.type === 'prototype' || comment.ctx.type === 'class')){ | ||
parentContext = comment.ctx; | ||
@@ -123,3 +126,3 @@ } | ||
buf = ''; | ||
} else if (!withinSingle && !withinMultiline && '/' == js[i] && '/' == js[i+1]) { | ||
} else if (!withinSingle && !withinMultiline && !withinString && '/' == js[i] && '/' == js[i+1]) { | ||
withinSingle = true; | ||
@@ -130,3 +133,3 @@ buf += js[i]; | ||
buf += js[i]; | ||
} else if (!withinSingle && !withinMultiline && '\'' == js[i] || '"' == js[i]) { | ||
} else if (!withinSingle && !withinMultiline && ('\'' == js[i] || '"' == js[i])) { | ||
withinString = !withinString; | ||
@@ -138,6 +141,2 @@ buf += js[i]; | ||
if (comment && comment.isConstructor && comment.ctx){ | ||
comment.ctx.type = "constructor"; | ||
} | ||
if('\n' == js[i]) { | ||
@@ -164,4 +163,3 @@ lineNum++; | ||
comment.codeStart += buf.match(/^(\s*)/)[0].split('\n').length - 1; | ||
code = exports.trimIndentation(buf).trim(); | ||
comment.code = code; | ||
comment.code = code = exports.trimIndentation(buf).trim(); | ||
comment.ctx = exports.parseCodeContext(code, parentContext); | ||
@@ -238,5 +236,19 @@ } | ||
}); | ||
comment.isClass = comment.tags.some(function(tag){ | ||
return 'class' == tag.type; | ||
}); | ||
comment.isEvent = comment.tags.some(function(tag){ | ||
return 'event' == tag.type; | ||
}); | ||
if (!description.full || !description.full.trim()) { | ||
comment.tags.some(function(tag){ | ||
if ('description' == tag.type) { | ||
description.full = tag.full; | ||
description.summary = tag.summary; | ||
description.body = tag.body; | ||
return true; | ||
} | ||
}); | ||
} | ||
} | ||
@@ -251,2 +263,3 @@ | ||
if (tag.description) tag.description = markdown(tag.description); | ||
else tag.html = markdown(tag.string); | ||
}); | ||
@@ -256,3 +269,3 @@ } | ||
return comment; | ||
} | ||
}; | ||
@@ -308,4 +321,7 @@ //TODO: Find a smarter way to do this | ||
, parts = exports.extractTagParts(lines[0]) | ||
, type = tag.type = parts.shift().replace('@', ''); | ||
, type = tag.type = parts.shift().replace('@', '') | ||
, matchType = new RegExp('^@?' + type + ' *'); | ||
tag.string = str.replace(matchType, ''); | ||
if (lines.length > 1) { | ||
@@ -370,2 +386,7 @@ parts.push(lines.slice(1).join('\n')); | ||
break; | ||
case 'description': | ||
tag.full = parts.join(' ').trim(); | ||
tag.summary = tag.full.split('\n\n')[0]; | ||
tag.body = tag.full.split('\n\n').slice(1).join('\n\n'); | ||
break; | ||
default: | ||
@@ -377,3 +398,3 @@ tag.string = parts.join(' '); | ||
return tag; | ||
} | ||
}; | ||
@@ -458,2 +479,5 @@ /** | ||
* | ||
* - classes | ||
* - class constructors | ||
* - class methods | ||
* - function statements | ||
@@ -474,9 +498,50 @@ * - function expressions | ||
exports.parseCodeContext = function(str, parentContext) { | ||
var str = str.split('\n')[0]; | ||
parentContext = parentContext || {}; | ||
// function statement | ||
if (/^function ([\w$]+) *\(/.exec(str)) { | ||
// class, possibly exported by name or as a default | ||
if (/^\s*(export(\s+default)?\s+)?class\s+([\w$]+)(\s+extends\s+([\w$]+))?\s*{/.exec(str)) { | ||
return { | ||
type: 'class' | ||
, constructor: RegExp.$3 | ||
, cons: RegExp.$3 | ||
, name: RegExp.$3 | ||
, extends: RegExp.$5 | ||
, string: 'new ' + RegExp.$3 + '()' | ||
}; | ||
// class constructor | ||
} else if (/^\s*constructor\s*\(/.exec(str)) { | ||
return { | ||
type: 'constructor' | ||
, constructor: parentContext.name | ||
, cons: parentContext.name | ||
, name: 'constructor' | ||
, string: (parentContext && parentContext.name && parentContext.name + '.prototype.' || '') + 'constructor()' | ||
}; | ||
// class method | ||
} else if (/^\s*([\w$]+)\s*\(/.exec(str)) { | ||
return { | ||
type: 'method' | ||
, constructor: parentContext.name | ||
, cons: parentContext.name | ||
, name: RegExp.$1 | ||
, string: (parentContext && parentContext.name && parentContext.name + '.prototype.' || '') + RegExp.$1 + '()' | ||
}; | ||
// named function statement, possibly exported by name or as a default | ||
} else if (/^\s*(export(\s+default)?\s+)?function\s+([\w$]+)\s*\(/.exec(str)) { | ||
return { | ||
type: 'function' | ||
, name: RegExp.$3 | ||
, string: RegExp.$3 + '()' | ||
}; | ||
// anonymous function expression exported as a default | ||
} else if (/^\s*export\s+default\s+function\s*\(/.exec(str)) { | ||
return { | ||
type: 'function' | ||
, name: RegExp.$1 // undefined | ||
, string: RegExp.$1 + '()' | ||
}; | ||
// function expression | ||
} else if (/^return\s+function(?:\s+([\w$]+))?\s*\(/.exec(str)) { | ||
return { | ||
type: 'function' | ||
, name: RegExp.$1 | ||
@@ -486,3 +551,3 @@ , string: RegExp.$1 + '()' | ||
// function expression | ||
} else if (/^var *([\w$]+)[ \t]*=[ \t]*function/.exec(str)) { | ||
} else if (/^\s*(?:const|let|var)\s+([\w$]+)\s*=\s*function/.exec(str)) { | ||
return { | ||
@@ -494,3 +559,3 @@ type: 'function' | ||
// prototype method | ||
} else if (/^([\w$.]+)\.prototype\.([\w$]+)[ \t]*=[ \t]*function/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*\.\s*prototype\s*\.\s*([\w$]+)\s*=\s*function/.exec(str)) { | ||
return { | ||
@@ -504,3 +569,3 @@ type: 'method' | ||
// prototype property | ||
} else if (/^([\w$.]+)\.prototype\.([\w$]+)[ \t]*=[ \t]*([^\n;]+)/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*\.\s*prototype\s*\.\s*([\w$]+)\s*=\s*([^\n;]+)/.exec(str)) { | ||
return { | ||
@@ -511,7 +576,7 @@ type: 'property' | ||
, name: RegExp.$2 | ||
, value: RegExp.$3 | ||
, value: RegExp.$3.trim() | ||
, string: RegExp.$1 + '.prototype.' + RegExp.$2 | ||
}; | ||
// prototype property without assignment | ||
} else if (/^([\w$]+)\.prototype\.([\w$]+);/.exec(str)) { | ||
} else if (/^\s*([\w$]+)\s*\.\s*prototype\s*\.\s*([\w$]+)\s*/.exec(str)) { | ||
return { | ||
@@ -525,3 +590,3 @@ type: 'property' | ||
// inline prototype | ||
} else if (/^([\w$.]+)\.prototype[ \t]*=[ \t]*{/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*\.\s*prototype\s*=\s*{/.exec(str)) { | ||
return { | ||
@@ -535,3 +600,3 @@ type: 'prototype' | ||
// inline method | ||
} else if (/^[ \t]*([\w$.]+)[ \t]*:[ \t]*function/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*:\s*function/.exec(str)) { | ||
return { | ||
@@ -545,3 +610,3 @@ type: 'method' | ||
// inline property | ||
} else if (/^[ \t]*([\w$.]+)[ \t]*:[ \t]*([^\n;]+)/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*:\s*([^\n;]+)/.exec(str)) { | ||
return { | ||
@@ -552,7 +617,7 @@ type: 'property' | ||
, name: RegExp.$1 | ||
, value: RegExp.$2 | ||
, value: RegExp.$2.trim() | ||
, string: (parentContext && parentContext.name && parentContext.name + '.' || '') + RegExp.$1 | ||
}; | ||
// inline getter/setter | ||
} else if (/^[ \t]*(get|set)[ \t]*([\w$.]+)[ \t]*\(/.exec(str)) { | ||
} else if (/^\s*(get|set)\s*([\w$.]+)\s*\(/.exec(str)) { | ||
return { | ||
@@ -566,3 +631,3 @@ type: 'property' | ||
// method | ||
} else if (/^([\w$.]+)\.([\w$]+)[ \t]*=[ \t]*function/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*\.\s*([\w$]+)\s*=\s*function/.exec(str)) { | ||
return { | ||
@@ -575,3 +640,3 @@ type: 'method' | ||
// property | ||
} else if (/^([\w$.]+)\.([\w$]+)[ \t]*=[ \t]*([^\n;]+)/.exec(str)) { | ||
} else if (/^\s*([\w$.]+)\s*\.\s*([\w$]+)\s*=\s*([^\n;]+)/.exec(str)) { | ||
return { | ||
@@ -581,11 +646,11 @@ type: 'property' | ||
, name: RegExp.$2 | ||
, value: RegExp.$3 | ||
, value: RegExp.$3.trim() | ||
, string: RegExp.$1 + '.' + RegExp.$2 | ||
}; | ||
// declaration | ||
} else if (/^var +([\w$]+)[ \t]*=[ \t]*([^\n;]+)/.exec(str)) { | ||
} else if (/^\s*(?:const|let|var)\s+([\w$]+)\s*=\s*([^\n;]+)/.exec(str)) { | ||
return { | ||
type: 'declaration' | ||
, name: RegExp.$1 | ||
, value: RegExp.$2 | ||
, value: RegExp.$2.trim() | ||
, string: RegExp.$1 | ||
@@ -592,0 +657,0 @@ }; |
{ | ||
"name": "dox", | ||
"description": "Markdown / JSdoc documentation generator", | ||
"version": "0.6.1", | ||
"version": "0.7.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
"contributors": [ | ||
"Jarvis Badgley <chiper@chipersoft.com>", | ||
"Arseny Zarechnev <me@evindor.com>", | ||
"Thomas Parisot <hi@oncletom.io>", | ||
"Jarvis Badgley <chiper@chipersoft.com>", | ||
"Stephen Mathieson <me@stephenmathieson.com>", | ||
@@ -31,9 +31,9 @@ "Vladimir Tsvang <vtsvang@gmail.com>", | ||
"dependencies": { | ||
"commander": "0.6.1", | ||
"jsdoctypeparser": "^1.1.1", | ||
"commander": "~2.7.1", | ||
"jsdoctypeparser": "^1.1.4", | ||
"marked": ">=0.3.1" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^1.20.1", | ||
"should": "^4.0.4" | ||
"mocha": "~2.2.1", | ||
"should": "~5.2.0" | ||
}, | ||
@@ -40,0 +40,0 @@ "scripts": { |
@@ -54,6 +54,8 @@ # Dox | ||
"type": "example", | ||
"string": "<pre><code>utils.escape('<script></script>')\n// => '&lt;script&gt;&lt;/script&gt;'\n</code></pre>" | ||
"string": " utils.escape('<script></script>')\n // => '<script></script>'", | ||
"html": "<pre><code>utils.escape('<script></script>')\n// => '&lt;script&gt;&lt;/script&gt;'\n</code></pre>" | ||
}, | ||
{ | ||
"type": "param", | ||
"string": "{String} html string to be escaped", | ||
"types": [ | ||
@@ -67,2 +69,3 @@ "String" | ||
"type": "return", | ||
"string": "{String} escaped html", | ||
"types": [ | ||
@@ -75,2 +78,3 @@ "String" | ||
"type": "api", | ||
"string": "public", | ||
"visibility": "public" | ||
@@ -167,3 +171,3 @@ } | ||
}; | ||
```` | ||
``` | ||
yields: | ||
@@ -238,2 +242,3 @@ | ||
[ { type: 'param', | ||
string: '{String} str', | ||
types: [ 'String' ], | ||
@@ -243,2 +248,3 @@ name: 'str', | ||
{ type: 'param', | ||
string: '{{stream: Writable}} options', | ||
types: [ { stream: ['Writable'] } ], | ||
@@ -248,2 +254,3 @@ name: 'options', | ||
{ type: 'return', | ||
string: '{Object} exports for chaining', | ||
types: [ 'Object' ], | ||
@@ -293,2 +300,3 @@ description: 'exports for chaining' }, | ||
"type": "param", | ||
"string": "{string | {name: string, age: number | date}} name Name or person object", | ||
"name": "name", | ||
@@ -316,2 +324,3 @@ "description": "Name or person object", | ||
"type": "param", | ||
"string": "{{separator: string} =} options An options object", | ||
"name": "options", | ||
@@ -334,2 +343,3 @@ "description": "An options object", | ||
"type": "return", | ||
"string": "{string} The constructed information string", | ||
"types": [ | ||
@@ -336,0 +346,0 @@ "string" |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
41817
14
657
459
1
+ Addedcommander@2.7.1(transitive)
+ Addedgraceful-readlink@1.0.1(transitive)
- Removedcommander@0.6.1(transitive)
Updatedcommander@~2.7.1
Updatedjsdoctypeparser@^1.1.4