Comparing version 0.4.1 to 0.5.0
12
index.js
/*! | ||
* docdown v0.4.1 | ||
* docdown v0.5.0 | ||
* Copyright 2011-2016 John-David Dalton <http://allyoucanleet.com/> | ||
@@ -16,4 +16,10 @@ * Available under MIT license <https://mths.be/mit> | ||
* | ||
* @name docdown | ||
* @param options The options to use to generate documentation. | ||
* @param {Object} options The options object. | ||
* @param {string} options.path The input file path. | ||
* @param {string} options.url The source URL. | ||
* @param {string} [options.hash='default'] The hash style for links ('default' or 'github'). | ||
* @param {string} [options.lang='js'] The language indicator for code blocks. | ||
* @param {boolean} [options.sort=true] Specify wether entries are sorted. | ||
* @param {string} [options.title='<%= basename(options.path) %> API documentation'] The documentation title. | ||
* @param {string} [options.toc='properties'] The table of contents organization style ('categories' or 'properties'). | ||
* @returns {string} The generated Markdown code. | ||
@@ -20,0 +26,0 @@ */ |
165
lib/alias.js
@@ -12,3 +12,3 @@ 'use strict'; | ||
* @param {string} name The alias name. | ||
* @param {Object} owner The alias this._owner. | ||
* @param {Object} owner The alias owner. | ||
*/ | ||
@@ -25,3 +25,3 @@ function Alias(name, owner) { | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array|string} The entry's `alias` objects. | ||
* @returns {Array|string} Returns the entry's `alias` objects. | ||
*/ | ||
@@ -36,3 +36,3 @@ function getAliases(index) { | ||
* @memberOf Alias | ||
* @returns {string} The function call. | ||
* @returns {string} Returns the function call. | ||
*/ | ||
@@ -47,3 +47,3 @@ function getCall() { | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's `category` data. | ||
* @returns {string} Returns the owner entry's `category` data. | ||
*/ | ||
@@ -58,3 +58,3 @@ function getCategory() { | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's description. | ||
* @returns {string} Returns the owner entry's description. | ||
*/ | ||
@@ -69,3 +69,3 @@ function getDesc() { | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's `example` data. | ||
* @returns {string} Returns the owner entry's `example` data. | ||
*/ | ||
@@ -77,154 +77,164 @@ function getExample() { | ||
/** | ||
* Checks if the entry is an alias. | ||
* Extracts the entry's hash value for permalinking. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true`. | ||
* @param {string} [style] The hash style. | ||
* @returns {string} Returns the entry's hash value (without a hash itself). | ||
*/ | ||
function isAlias() { | ||
return true; | ||
function getHash(style) { | ||
return this._owner.getHash(style); | ||
} | ||
/** | ||
* Checks if the owner entry is a constructor. | ||
* Resolves the owner entry's line number. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if a constructor, else `false`. | ||
* @returns {number} Returns the owner entry's line number. | ||
*/ | ||
function isCtor() { | ||
return this._owner.isCtor(); | ||
function getLineNumber() { | ||
return this._owner.getLineNumber(); | ||
} | ||
/** | ||
* Checks if the entry is a function reference. | ||
* Extracts the owner entry's `member` data. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if the entry is a function reference, else `false`. | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array|string} Returns the owner entry's `member` data. | ||
*/ | ||
function isFunction() { | ||
return this._owner.isFunction(); | ||
function getMembers(index) { | ||
return this._owner.getMembers(index); | ||
} | ||
/** | ||
* Checks if the owner entry is a license. | ||
* Extracts the owner entry's `name` data. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if a license, else `false`. | ||
* @returns {string} Returns the owner entry's `name` data. | ||
*/ | ||
function isLicense() { | ||
return this._owner.isLicense(); | ||
function getName() { | ||
return this._name; | ||
} | ||
/** | ||
* Checks if the owner entry *is* assigned to a prototype. | ||
* Gets the owner entry object. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if assigned to a prototype, else `false`. | ||
* @returns {Object} Returns the owner entry. | ||
*/ | ||
function isPlugin() { | ||
return this._owner.isPlugin(); | ||
function getOwner() { | ||
return this._owner; | ||
} | ||
/** | ||
* Checks if the owner entry is private. | ||
* Extracts the owner entry's `param` data. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if private, else `false`. | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array} Returns the owner entry's `param` data. | ||
*/ | ||
function isPrivate() { | ||
return this._owner.isPrivate(); | ||
function getParams(index) { | ||
return this._owner.getParams(index); | ||
} | ||
/** | ||
* Checks if the owner entry is *not* assigned to a prototype. | ||
* Extracts the owner entry's `returns` data. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if not assigned to a prototype, else `false`. | ||
* @returns {string} Returns the owner entry's `returns` data. | ||
*/ | ||
function isStatic() { | ||
return this._owner.isStatic(); | ||
function getReturns() { | ||
return this._owner.getReturns(); | ||
} | ||
/** | ||
* Extracts the entry's hash value for permalinking. | ||
* Extracts the owner entry's `since` data. | ||
* | ||
* @memberOf Alias | ||
* @param {string} [style] The hash style. | ||
* @returns {string} The entry's hash value (without a hash itself). | ||
* @returns {string} Returns the owner entry's `since` data. | ||
*/ | ||
function getHash(style) { | ||
return this._owner.getHash(style); | ||
function getSince() { | ||
return this._owner.getSince(); | ||
} | ||
/** | ||
* Resolves the owner entry's line number. | ||
* Extracts the owner entry's `type` data. | ||
* | ||
* @memberOf Alias | ||
* @returns {number} The owner entry's line number. | ||
* @returns {string} Returns the owner entry's `type` data. | ||
*/ | ||
function getLineNumber() { | ||
return this._owner.getLineNumber(); | ||
function getType() { | ||
return this._owner.getType(); | ||
} | ||
/** | ||
* Extracts the owner entry's `member` data. | ||
* Checks if the entry is an alias. | ||
* | ||
* @memberOf Alias | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array|string} The owner entry's `member` data. | ||
* @returns {boolean} Returns `true`. | ||
*/ | ||
function getMembers(index) { | ||
return this._owner.getMembers(index); | ||
function isAlias() { | ||
return true; | ||
} | ||
/** | ||
* Extracts the owner entry's `name` data. | ||
* Checks if the owner entry is a constructor. | ||
* | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's `name` data. | ||
* @returns {boolean} Returns `true` if a constructor, else `false`. | ||
*/ | ||
function getName() { | ||
return this._name; | ||
function isCtor() { | ||
return this._owner.isCtor(); | ||
} | ||
/** | ||
* Gets the owner entry object. | ||
* Checks if the entry is a function reference. | ||
* | ||
* @memberOf Alias | ||
* @returns {Object} The owner entry. | ||
* @returns {boolean} Returns `true` if the entry is a function reference, else `false`. | ||
*/ | ||
function getOwner() { | ||
return this._owner; | ||
function isFunction() { | ||
return this._owner.isFunction(); | ||
} | ||
/** | ||
* Extracts the owner entry's `param` data. | ||
* Checks if the owner entry is a license. | ||
* | ||
* @memberOf Alias | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array} The owner entry's `param` data. | ||
* @returns {boolean} Returns `true` if a license, else `false`. | ||
*/ | ||
function getParams(index) { | ||
return this._owner.getParams(index); | ||
function isLicense() { | ||
return this._owner.isLicense(); | ||
} | ||
/** | ||
* Extracts the owner entry's `returns` data. | ||
* Checks if the owner entry *is* assigned to a prototype. | ||
* | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's `returns` data. | ||
* @returns {boolean} Returns `true` if assigned to a prototype, else `false`. | ||
*/ | ||
function getReturns() { | ||
return this._owner.getReturns(); | ||
function isPlugin() { | ||
return this._owner.isPlugin(); | ||
} | ||
/** | ||
* Extracts the owner entry's `type` data. | ||
* Checks if the owner entry is private. | ||
* | ||
* @memberOf Alias | ||
* @returns {string} The owner entry's `type` data. | ||
* @returns {boolean} Returns `true` if private, else `false`. | ||
*/ | ||
function getType() { | ||
return this._owner.getType(); | ||
function isPrivate() { | ||
return this._owner.isPrivate(); | ||
} | ||
/** | ||
* Checks if the owner entry is *not* assigned to a prototype. | ||
* | ||
* @memberOf Alias | ||
* @returns {boolean} Returns `true` if not assigned to a prototype, else `false`. | ||
*/ | ||
function isStatic() { | ||
return this._owner.isStatic(); | ||
} | ||
/*----------------------------------------------------------------------------*/ | ||
@@ -238,2 +248,11 @@ | ||
'getExample': getExample, | ||
'getHash': getHash, | ||
'getLineNumber': getLineNumber, | ||
'getMembers': getMembers, | ||
'getName': getName, | ||
'getOwner': getOwner, | ||
'getParams': getParams, | ||
'getReturns': getReturns, | ||
'getSince': getSince, | ||
'getType': getType, | ||
'isAlias': isAlias, | ||
@@ -246,12 +265,4 @@ 'isCtor': isCtor, | ||
'isStatic': isStatic, | ||
'getLineNumber': getLineNumber, | ||
'getMembers': getMembers, | ||
'getName': getName, | ||
'getOwner': getOwner, | ||
'getParams': getParams, | ||
'getReturns': getReturns, | ||
'getType': getType, | ||
'getHash': getHash | ||
}); | ||
module.exports = Alias; |
542
lib/entry.js
'use strict'; | ||
var _ = require('lodash'), | ||
fp = require('lodash/fp'), | ||
os = require('os'), | ||
@@ -10,24 +11,96 @@ Alias = require('./alias.js'), | ||
function cleanValue(string) { | ||
string = string == null ? '' : (string + ''); | ||
return _.trim(string.replace(/(?:^|\n)[\t ]*\*[\t ]*/g, ' ')); | ||
/** | ||
* Gets the param type of `tag`. | ||
* | ||
* @private | ||
* @param {Object} tag The param tag to inspect. | ||
* @returns {string} Returns the param type. | ||
*/ | ||
function getParamType(tag) { | ||
var expression = tag.expression, | ||
result = '', | ||
type = tag.type; | ||
if (type == 'AllLiteral') { | ||
result = '*'; | ||
} | ||
if (type == 'NameExpression') { | ||
result = _.toString(tag.name); | ||
} | ||
if (type == 'RestType') { | ||
result = '...' + result; | ||
} | ||
if (type == 'TypeApplication') { | ||
expression = undefined; | ||
result = _(tag) | ||
.chain() | ||
.get('applications') | ||
.map(_.flow(getParamType, fp.add(fp, '[]'))) | ||
.sort(util.compareNatural) | ||
.join('|') | ||
.value(); | ||
} | ||
if (type == 'UnionType') { | ||
result = _(tag) | ||
.chain() | ||
.get('elements') | ||
.map(getParamType) | ||
.sort(util.compareNatural) | ||
.join('|') | ||
.value(); | ||
} | ||
if (expression) { | ||
result += getParamType(expression); | ||
} | ||
return type == 'UnionType' | ||
? ('(' + result + ')') | ||
: result; | ||
} | ||
function getMultilineValue(string, tagName) { | ||
var prelude = tagName == 'description' ? '^ */\\*\\*(?: *\\n *\\* *)?' : ('^ *\\*[\\t ]*@' + _.escapeRegExp(tagName) + '\\b'), | ||
postlude = '(?=\\*\\s+\\@[a-z]|\\*/)', | ||
result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); | ||
return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); | ||
/** | ||
* Gets an `entry` tag by `tagName`. | ||
* | ||
* @private | ||
* @param {Object} entry The entry to inspect. | ||
* @param {string} tagName The name of the tag. | ||
* @returns {null|Object} Returns the tag. | ||
*/ | ||
function getTag(entry, tagName) { | ||
var parsed = entry.parsed; | ||
return _.find(parsed.tags, ['title', tagName]) || null; | ||
} | ||
function getValue(string, tagName) { | ||
tagName = tagName == 'member' ? (tagName + '(?:Of)?') : _.escapeRegExp(tagName); | ||
var result = _.result(RegExp('^ *\\*[\\t ]*@' + tagName + '\\s+(.+)', 'm').exec(string), 1, ''); | ||
return cleanValue(result); | ||
/** | ||
* Gets an `entry` tag value by `tagName`. | ||
* | ||
* @private | ||
* @param {Object} entry The entry to inspect. | ||
* @param {string} tagName The name of the tag. | ||
* @returns {string} Returns the tag value. | ||
*/ | ||
function getValue(entry, tagName) { | ||
var parsed = entry.parsed, | ||
result = parsed.description, | ||
tag = getTag(entry, tagName); | ||
if (tagName == 'type') { | ||
result = _.get(tag, 'type.name'); | ||
} else if (tagName != 'description') { | ||
result = _.get(tag, 'name') || _.get(tag, 'description'); | ||
} | ||
return tagName == 'example' | ||
? _.toString(result) | ||
: util.format(result); | ||
} | ||
function hasTag(string, tagName) { | ||
tagName = tagName == '*' ? '\\w+' : _.escapeRegExp(tagName); | ||
return RegExp('^ *\\*[\\t ]*@' + tagName + '\\b', 'm').test(string); | ||
/** | ||
* Checks if `entry` has a tag of `tagName`. | ||
* | ||
* @private | ||
* @param {Object} entry The entry to inspect. | ||
* @param {string} tagName The name of the tag. | ||
* @returns {boolean} Returns `true` if the tag is found, else `false`. | ||
*/ | ||
function hasTag(entry, tagName) { | ||
return getTag(entry, tagName) !== null; | ||
} | ||
@@ -46,2 +119,8 @@ | ||
function Entry(entry, source, lang) { | ||
this.parsed = util.parse( | ||
entry | ||
.replace(/@param-/g, '@paramhidden') | ||
.replace(/(\*)\/\s*.+$/, '*') | ||
); | ||
this.entry = entry; | ||
@@ -54,2 +133,8 @@ this.lang = lang == null ? 'js' : lang; | ||
this.getExample = _.memoize(this.getExample); | ||
this.getHash = _.memoize(this.getHash); | ||
this.getLineNumber = _.memoize(this.getLineNumber); | ||
this.getName = _.memoize(this.getName); | ||
this.getReturns = _.memoize(this.getReturns); | ||
this.getSince = _.memoize(this.getSince); | ||
this.getType = _.memoize(this.getType); | ||
this.isAlias = _.memoize(this.isAlias); | ||
@@ -62,6 +147,2 @@ this.isCtor = _.memoize(this.isCtor); | ||
this.isStatic = _.memoize(this.isStatic); | ||
this.getLineNumber = _.memoize(this.getLineNumber); | ||
this.getName = _.memoize(this.getName); | ||
this.getReturns = _.memoize(this.getReturns); | ||
this.getType = _.memoize(this.getType); | ||
this._aliases = this._members = this._params = undefined; | ||
@@ -76,7 +157,6 @@ } | ||
* @param {string} source The source code. | ||
* @returns {Array} The array of entries. | ||
* @returns {Array} Returns the array of entries. | ||
*/ | ||
function getEntries(source) { | ||
source = source == null ? '' : (source + ''); | ||
return source.match(/\/\*\*(?![-!])[\s\S]*?\*\/\s*.+/g) || []; | ||
return _.toString(source).match(/\/\*\*(?![-!])[\s\S]*?\*\/\s*.+/g) || []; | ||
} | ||
@@ -89,21 +169,16 @@ | ||
* @param {number} index The index of the array value to return. | ||
* @returns {Array|string} The entry's `alias` objects. | ||
* @returns {Array|string} Returns the entry's `alias` objects. | ||
*/ | ||
function getAliases(index) { | ||
if (this._aliases === undefined) { | ||
var result = _.result(/\*[\t ]*@alias\s+(.+)/.exec(this.entry), 1); | ||
if (result) { | ||
result = result.replace(/(?:^|\n)[\t ]*\*[\t ]*/, ' ').trim(); | ||
result = result.split(/,\s*/); | ||
result.sort(util.compareNatural); | ||
result = _.map(result, _.bind(function(value) { | ||
return new Alias(value, this); | ||
}, this)); | ||
} | ||
this._aliases = result; | ||
var owner = this; | ||
this._aliases = _(getValue(this, 'alias')) | ||
.split(/,\s*/) | ||
.compact() | ||
.sort(util.compareNatural) | ||
.map(function(value) { return new Alias(value, owner); }) | ||
.value(); | ||
} | ||
return index != null | ||
? this._aliases[index] | ||
: this._aliases; | ||
var result = this._aliases; | ||
return index === undefined ? result : result[index]; | ||
} | ||
@@ -115,3 +190,3 @@ | ||
* @memberOf Entry | ||
* @returns {string} The function call. | ||
* @returns {string} Returns the function call. | ||
*/ | ||
@@ -125,13 +200,10 @@ function getCall() { | ||
} | ||
// Get the function name. | ||
// Avoid `this.getName()` because it calls `this.getCall()`. | ||
var name = _.result(/\*[\t ]*@name\s+(.+)/.exec(this.entry), 1, result || ''); | ||
var name = getValue(this, 'name') || _.toString(result); | ||
if (!this.isFunction()) { | ||
return name; | ||
} | ||
var params = this.getParams(), | ||
paramNames = []; | ||
var params = this.getParams(); | ||
result = _.castArray(result); | ||
// Compile the function call syntax. | ||
result = [result]; | ||
_.each(params, function(param) { | ||
@@ -149,3 +221,2 @@ var paramValue = param[1], | ||
} | ||
paramNames.push(_.trim(paramValue, '[]')); | ||
}); | ||
@@ -161,9 +232,7 @@ | ||
* @memberOf Entry | ||
* @returns {string} The entry's `category` data. | ||
* @returns {string} Returns the entry's `category` data. | ||
*/ | ||
function getCategory() { | ||
var result = _.result(/\*[\t ]*@category\s+(.+)/.exec(this.entry), 1, ''); | ||
return result | ||
? cleanValue(result) | ||
: (this.getType() == 'Function' ? 'Methods' : 'Properties'); | ||
var result = getValue(this, 'category'); | ||
return result || (this.getType() == 'Function' ? 'Methods' : 'Properties'); | ||
} | ||
@@ -175,22 +244,11 @@ | ||
* @memberOf Entry | ||
* @returns {string} The entry's description. | ||
* @returns {string} Returns the entry's description. | ||
*/ | ||
function getDesc() { | ||
var result = getMultilineValue(this.entry, 'description'); | ||
if (!result) { | ||
return result; | ||
} | ||
result = _.trim(result | ||
.replace(/:\n(?=[\t ]*\S)/g, ':<br>\n') | ||
.replace(/(?:^|\n)[\t ]*\*\n[\t ]*\*[\t ]*/g, '\n\n') | ||
.replace(/(?:^|\n)[\t ]*\*[\t ]/g, ' ') | ||
.replace(/\n( *)[-*](?=[\t ]+\S)/g, '\n<br>\n$1*') | ||
.replace(/^[\t ]*\n/gm, '<br>\n<br>\n') | ||
); | ||
var type = this.getType(), | ||
result = getValue(this, 'description'); | ||
var type = this.getType(); | ||
if (type != 'unknown') { | ||
result = (type == 'Function' ? '' : '(' + type.replace(/\|/g, ', ') + '): ') + result; | ||
} | ||
return result; | ||
return (!result || type == 'Function' || type == 'unknown') | ||
? result | ||
: ('(' + _.trim(type.replace(/\|/g, ', '), '()') + '): ' + result); | ||
} | ||
@@ -202,21 +260,166 @@ | ||
* @memberOf Entry | ||
* @returns {string} The entry's `example` data. | ||
* @returns {string} Returns the entry's `example` data. | ||
*/ | ||
function getExample() { | ||
var result = getMultilineValue(this.entry, 'example'); | ||
if (result) { | ||
result = '```' + this.lang + '\n' + result + '\n```'; | ||
var result = getValue(this, 'example'); | ||
return result && ('```' + this.lang + '\n' + result + '\n```'); | ||
} | ||
/** | ||
* Extracts the entry's hash value for permalinking. | ||
* | ||
* @memberOf Entry | ||
* @param {string} [style] The hash style. | ||
* @returns {string} Returns the entry's hash value (without a hash itself). | ||
*/ | ||
function getHash(style) { | ||
var result = _.toString(this.getMembers(0)); | ||
switch (style) { | ||
case 'github': | ||
if (result) { | ||
result += this.isPlugin() ? 'prototype' : ''; | ||
} | ||
result += this.getCall(); | ||
return result | ||
.replace(/[\\.=|'"(){}\[\]\t ]/g, '') | ||
.replace(/[#,]+/g, '-') | ||
.toLowerCase(); | ||
case 'default': | ||
default: | ||
if (result) { | ||
result += '-' + (this.isPlugin() ? 'prototype-' : ''); | ||
} | ||
result += this.isAlias() ? this.getOwner().getName() : this.getName(); | ||
return result | ||
.replace(/\./g, '-') | ||
.replace(/^_-/, ''); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Resolves the entry's line number. | ||
* | ||
* @memberOf Entry | ||
* @returns {number} Returns the entry's line number. | ||
*/ | ||
function getLineNumber() { | ||
var lines = this.source | ||
.slice(0, this.source.indexOf(this.entry) + this.entry.length) | ||
.match(/\n/g) | ||
.slice(1); | ||
// Offset by 2 because the first line number is before a line break and the | ||
// last line doesn't include a line break. | ||
return lines.length + 2; | ||
} | ||
/** | ||
* Extracts the entry's `member` data. | ||
* | ||
* @memberOf Entry | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array|string} Returns the entry's `member` data. | ||
*/ | ||
function getMembers(index) { | ||
if (this._members === undefined) { | ||
this._members = _(getValue(this, 'member') || getValue(this, 'memberOf')) | ||
.split(/,\s*/) | ||
.compact() | ||
.sort(util.compareNatural) | ||
.value(); | ||
} | ||
var result = this._members; | ||
return index === undefined ? result : result[index]; | ||
} | ||
/** | ||
* Extracts the entry's `name` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {string} Returns the entry's `name` data. | ||
*/ | ||
function getName() { | ||
return hasTag(this, 'name') | ||
? getValue(this, 'name') | ||
: _.toString(_.first(this.getCall().split('('))); | ||
} | ||
/** | ||
* Extracts the entry's `param` data. | ||
* | ||
* @memberOf Entry | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array} Returns the entry's `param` data. | ||
*/ | ||
function getParams(index) { | ||
if (this._params === undefined) { | ||
this._params = _.map(_.filter(this.parsed.tags, ['title', 'param']), function(tag) { | ||
var defaultValue = tag['default'], | ||
desc = util.format(tag.description), | ||
name = _.toString(tag.name), | ||
type = getParamType(tag.type); | ||
if (defaultValue != null) { | ||
name += '=' + defaultValue; | ||
} | ||
if (_.get(tag, 'type.type') == 'OptionalType') { | ||
name = '[' + name + ']'; | ||
} | ||
return [type, name, desc]; | ||
}); | ||
} | ||
var result = this._params; | ||
return index === undefined ? result : result[index]; | ||
} | ||
/** | ||
* Extracts the entry's `returns` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {array} Returns the entry's `returns` data. | ||
*/ | ||
function getReturns() { | ||
var tag = getTag(this, 'returns'), | ||
desc = _.toString(_.get(tag, 'description')), | ||
type = _.toString(_.get(tag, 'type.name')) || '*'; | ||
return tag ? [type, desc] : []; | ||
} | ||
/** | ||
* Extracts the entry's `since` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {string} Returns the entry's `since` data. | ||
*/ | ||
function getSince() { | ||
return getValue(this, 'since'); | ||
} | ||
/** | ||
* Extracts the entry's `type` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {string} Returns the entry's `type` data. | ||
*/ | ||
function getType() { | ||
var result = getValue(this, 'type'); | ||
if (!result) { | ||
return this.isFunction() ? 'Function' : 'unknown'; | ||
} | ||
return /^(?:array|function|object|regexp)$/.test(result) | ||
? _.capitalize(result) | ||
: result; | ||
} | ||
/** | ||
* Checks if the entry is an alias. | ||
* | ||
* @memberOf Entry | ||
* @type {Function} | ||
* @returns {boolean} Returns `false`. | ||
*/ | ||
function isAlias() { | ||
return false; | ||
} | ||
var isAlias = _.constant(false); | ||
@@ -230,3 +433,3 @@ /** | ||
function isCtor() { | ||
return hasTag(this.entry, 'constructor'); | ||
return hasTag(this, 'constructor'); | ||
} | ||
@@ -245,3 +448,3 @@ | ||
_.size(this.getReturns()) || | ||
/\*[\t ]*@function\b/.test(this.entry) || | ||
hasTag(this, 'function') || | ||
/\*\/\s*function/.test(this.entry) | ||
@@ -258,3 +461,3 @@ ); | ||
function isLicense() { | ||
return hasTag(this.entry, 'license'); | ||
return hasTag(this, 'license'); | ||
} | ||
@@ -270,5 +473,5 @@ | ||
return ( | ||
(!this.isCtor()) && | ||
(!this.isPrivate()) && | ||
(!this.isStatic()) | ||
!this.isCtor() && | ||
!this.isPrivate() && | ||
!this.isStatic() | ||
); | ||
@@ -286,4 +489,4 @@ } | ||
this.isLicense() || | ||
hasTag(this.entry, 'private') || | ||
!hasTag(this.entry, '*') | ||
hasTag(this, 'private') || | ||
_.isEmpty(this.parsed.tags) | ||
); | ||
@@ -300,7 +503,7 @@ } | ||
var isPublic = !this.isPrivate(), | ||
result = isPublic && hasTag(this.entry, 'static'); | ||
result = isPublic && hasTag(this, 'static'); | ||
// Get the result in cases where it isn't explicitly stated. | ||
if (isPublic && !result) { | ||
var parent = _.last((this.getMembers(0) || '').split(/[#.]/)); | ||
var parent = _.last(_.toString(this.getMembers(0)).split(/[#.]/)); | ||
if (!parent) { | ||
@@ -321,152 +524,2 @@ return true; | ||
/** | ||
* Resolves the entry's line number. | ||
* | ||
* @memberOf Entry | ||
* @returns {number} The entry's line number. | ||
*/ | ||
function getLineNumber() { | ||
var entry = this.entry, | ||
lines = this.source.slice(0, this.source.indexOf(entry) + entry.length).match(/\n/g).slice(1); | ||
// Offset by 2 because the first line number is before a line break and the | ||
// last line doesn't include a line break. | ||
return lines.length + 2; | ||
} | ||
/** | ||
* Extracts the entry's `member` data. | ||
* | ||
* @memberOf Entry | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array|string} The entry's `member` data. | ||
*/ | ||
function getMembers(index) { | ||
if (this._members === undefined) { | ||
var result = getValue(this.entry, 'member'); | ||
if (result) { | ||
result = result.split(/,\s*/); | ||
result.sort(util.compareNatural); | ||
} | ||
this._members = result || []; | ||
} | ||
return index != null | ||
? this._members[index] | ||
: this._members; | ||
} | ||
/** | ||
* Extracts the entry's `name` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {string} The entry's `name` data. | ||
*/ | ||
function getName() { | ||
var result = hasTag(this.entry, 'name') | ||
? getValue(this.entry, 'name') | ||
: _.first(this.getCall().split('(')); | ||
return (result || '').replace(/\'/g, ''); | ||
} | ||
/** | ||
* Extracts the entry's `param` data. | ||
* | ||
* @memberOf Entry | ||
* @param {number} [index] The index of the array value to return. | ||
* @returns {Array} The entry's `param` data. | ||
*/ | ||
function getParams(index) { | ||
if (this._params === undefined) { | ||
var match, | ||
re = /@param\s+\{\(?([^}]+?)\)?\}\s+(\[.+\]|[\w]+(?:\[.+\])?)\s+([\s\S]*?)(?=\@|\*\/)/gim, | ||
result = []; | ||
while (match = re.exec(this.entry)) { | ||
match = match.slice(1); | ||
match = match.map(function(aParamPart,index) { | ||
return aParamPart.trim() | ||
}); | ||
match[2] = match[2].replace(/(?:^|\n)[\t ]*\*[\t ]*/g, ' '); | ||
result.push(match); | ||
} | ||
var tuples = _.compact(match); | ||
_.each(tuples, function(tuple){ | ||
result.push(tuple.trim()); | ||
}); | ||
this._params = result; | ||
} | ||
return index !== undefined | ||
? this._params[index] | ||
: this._params; | ||
} | ||
/** | ||
* Extracts the entry's `returns` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {array} The entry's `returns` data. | ||
*/ | ||
function getReturns() { | ||
var result = getMultilineValue(this.entry, 'returns'), | ||
returnType = _.result(/(?:\{)([\w|\*]*)(?:\})/gi.exec(result), 1); | ||
return returnType | ||
? [returnType, result.replace(/(\{[\w|\*]*\})/gi,'')] | ||
: []; | ||
} | ||
/** | ||
* Extracts the entry's `type` data. | ||
* | ||
* @memberOf Entry | ||
* @returns {string} The entry's `type` data. | ||
*/ | ||
function getType() { | ||
var result = getValue(this.entry, 'type'); | ||
if (result) { | ||
if (/^(?:array|function|object|regexp)$/.test(result)) { | ||
result = _.capitalize(result); | ||
} | ||
} else { | ||
result = this.isFunction() ? 'Function' : 'unknown'; | ||
} | ||
return result; | ||
} | ||
/** | ||
* Extracts the entry's hash value for permalinking. | ||
* | ||
* @memberOf Entry | ||
* @param {string} [style] The hash style. | ||
* @returns {string} The entry's hash value (without a hash itself). | ||
*/ | ||
function getHash(style) { | ||
var result = this.getMembers(0) || ''; | ||
switch (style) { | ||
case 'github': | ||
if (result) { | ||
result += this.isPlugin() ? 'prototype' : ''; | ||
} | ||
result += this.getCall(); | ||
return result | ||
.replace(/\(\[|\[\]/g, '') | ||
.replace(/[\t =|\'"{}.()\]]/g, '') | ||
.replace(/[\[#,]+/g, '-') | ||
.toLowerCase(); | ||
case 'default': | ||
default: | ||
if (result) { | ||
result += '-' + (this.isPlugin() ? 'prototype-' : ''); | ||
} | ||
result += this.isAlias() ? this.getOwner().getName() : this.getName(); | ||
return result | ||
.replace(/\./g, '-') | ||
.replace(/^_-/, ''); | ||
} | ||
} | ||
/*----------------------------------------------------------------------------*/ | ||
@@ -482,2 +535,10 @@ | ||
'getExample': getExample, | ||
'getHash': getHash, | ||
'getLineNumber': getLineNumber, | ||
'getMembers': getMembers, | ||
'getName': getName, | ||
'getParams': getParams, | ||
'getReturns': getReturns, | ||
'getSince': getSince, | ||
'getType': getType, | ||
'isAlias': isAlias, | ||
@@ -489,12 +550,5 @@ 'isCtor': isCtor, | ||
'isPrivate': isPrivate, | ||
'isStatic': isStatic, | ||
'getLineNumber': getLineNumber, | ||
'getMembers': getMembers, | ||
'getName': getName, | ||
'getParams': getParams, | ||
'getReturns': getReturns, | ||
'getType': getType, | ||
'getHash': getHash | ||
'isStatic': isStatic | ||
}); | ||
module.exports = Entry; |
@@ -29,3 +29,3 @@ 'use strict'; | ||
* @param {string} string The string to escape. | ||
* @returns {string} The escaped string. | ||
* @returns {string} Returns the escaped string. | ||
*/ | ||
@@ -54,43 +54,2 @@ function escape(string) { | ||
/** | ||
* Make an anchor link. | ||
* | ||
* @private | ||
* @param {string} name The attribute name (id, href). | ||
* @param {string} value The attribute value. | ||
* @param {string} text The anchor text. | ||
* | ||
*/ | ||
function makeHashHTML(name, value, text) { | ||
text = text == null ? '' : (text + ''); | ||
return '<a ' + name+'="' + value + '">' + text + '</a>'; | ||
} | ||
/** | ||
* Performs common string formatting operations. | ||
* | ||
* @private | ||
* @param {string} string The string to format. | ||
* @returns {string} The formatted string. | ||
*/ | ||
function format(string) { | ||
var snippets = []; | ||
// Replace all code snippets with a token. | ||
string = string.replace(reCode, function(match) { | ||
snippets.push(match); | ||
return token; | ||
}); | ||
return _.trim(string | ||
// Italicize parentheses. | ||
.replace(/(^|\s)(\([^)]+\))/g, '$1*$2*') | ||
// Mark numbers as inline code. | ||
.replace(/[\t ](-?\d+(?:.\d+)?)(?!\.[^\n])/g, ' `$1`') | ||
// Replace all tokens with code snippets. | ||
.replace(reToken, function(match) { | ||
return snippets.shift(); | ||
})); | ||
} | ||
/** | ||
* Get the seperator (`.` or `.prototype.`) | ||
@@ -100,3 +59,3 @@ * | ||
* @param {Entry} Entry object to get selector for. | ||
* | ||
* @returns {string} Returns the member seperator. | ||
*/ | ||
@@ -113,8 +72,20 @@ function getSeparator(entry) { | ||
* @param {Object} object The template object. | ||
* @returns {string} The modified string. | ||
* @returns {string} Returns the modified string. | ||
*/ | ||
function interpolate(string, object) { | ||
return format(_.template(string)(object)); | ||
return util.format(_.template(string)(object)); | ||
} | ||
/** | ||
* Make an anchor link. | ||
* | ||
* @private | ||
* @param {string} href The anchor href. | ||
* @param {string} text The anchor text. | ||
* @returns {string} Returns the anchor HTML. | ||
*/ | ||
function makeAnchor(href, text) { | ||
return '<a href="' + href + '">' + _.toString(text) + '</a>'; | ||
} | ||
/*----------------------------------------------------------------------------*/ | ||
@@ -127,2 +98,3 @@ | ||
* @param {object} The options object. | ||
* @returns {string} Returns the documentation markdown. | ||
*/ | ||
@@ -210,2 +182,10 @@ function generateDoc(source, options) { | ||
// Add optional since version. | ||
var since = entry.getSince(); | ||
if (!_.isEmpty(since)) { | ||
entryMarkdown.push( | ||
'#### Since', | ||
since | ||
); | ||
} | ||
// Add optional aliases. | ||
@@ -233,2 +213,6 @@ var aliases = entry.getAliases(); | ||
_.each(params, function(param, index) { | ||
var paramType = param[0]; | ||
if (_.startsWith(paramType, '(')) { | ||
paramType = _.trim(paramType, '()'); | ||
} | ||
entryMarkdown.push( | ||
@@ -239,3 +223,3 @@ interpolate('${num}. `${name}` (${type}): ${desc}', { | ||
'num': index + 1, | ||
'type': escape(param[0]) | ||
'type': escape(paramType) | ||
}) | ||
@@ -249,2 +233,6 @@ ); | ||
if (!_.isEmpty(returns)) { | ||
var returnType = returns[0]; | ||
if (_.startsWith(returnType, '(')) { | ||
returnType = _.trim(returnType, '()'); | ||
} | ||
entryMarkdown.push( | ||
@@ -254,3 +242,3 @@ '#### Returns', | ||
'desc': escape(returns[1]), | ||
'type': escape(returns[0]) | ||
'type': escape(returnType) | ||
}), | ||
@@ -326,4 +314,3 @@ '' | ||
'* ' + | ||
makeHashHTML( | ||
'href', | ||
makeAnchor( | ||
'#' + entry.getHash(hashStyle), | ||
@@ -330,0 +317,0 @@ '`' + title + '`' |
'use strict'; | ||
var split = String.prototype.split; | ||
var _ = require('lodash'), | ||
doctrine = require('doctrine'); | ||
var reCode = /`.*?`/g, | ||
reToken = /@@token@@/g, | ||
split = String.prototype.split, | ||
token = '@@token@@'; | ||
/*----------------------------------------------------------------------------*/ | ||
/** | ||
* The `Array#sort` comparator to produce a | ||
* [natural sort order](https://en.wikipedia.org/wiki/Natural_sort_order). | ||
* | ||
* @memberOf util | ||
* @param {*} value The value to compare. | ||
* @param {*} other The other value to compare. | ||
* @returns {number} Returns the sort order indicator for `value`. | ||
*/ | ||
function compareNatural(value, other) { | ||
@@ -26,2 +43,55 @@ var index = -1, | ||
exports.compareNatural = compareNatural; | ||
/** | ||
* Performs common string formatting operations. | ||
* | ||
* @memberOf util | ||
* @param {string} string The string to format. | ||
* @returns {string} Returns the formatted string. | ||
*/ | ||
function format(string) { | ||
string = _.toString(string); | ||
// Replace all code snippets with a token. | ||
var snippets = []; | ||
string = string.replace(reCode, function(match) { | ||
snippets.push(match); | ||
return token; | ||
}); | ||
return string | ||
// Add line breaks. | ||
.replace(/:\n(?=[\t ]*\S)/g, ':<br>\n') | ||
.replace(/\n( *)[-*](?=[\t ]+\S)/g, '\n<br>\n$1*') | ||
.replace(/^[\t ]*\n/gm, '<br>\n<br>\n') | ||
// Normalize whitespace. | ||
.replace(/\n +/g, ' ') | ||
// Italicize parentheses. | ||
.replace(/(^|\s)(\(.+\))/g, '$1*$2*') | ||
// Mark numbers as inline code. | ||
.replace(/[\t ](-?\d+(?:.\d+)?)(?!\.[^\n])/g, ' `$1`') | ||
// Replace all tokens with code snippets. | ||
.replace(reToken, function(match) { | ||
return snippets.shift(); | ||
}) | ||
.trim(); | ||
} | ||
/** | ||
* Parses the JSDoc `comment` into an object. | ||
* | ||
* @memberOf util | ||
* @param {string} comment The comment to parse. | ||
* @returns {Object} Returns the parsed object. | ||
*/ | ||
var parse = _.partial(doctrine.parse, _, { | ||
'lineNumbers': true, | ||
'recoverable': true, | ||
'sloppy': true, | ||
'unwrap': true | ||
}); | ||
module.exports = { | ||
'compareNatural': compareNatural, | ||
'format': format, | ||
'parse': parse | ||
}; |
{ | ||
"name": "docdown", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "A simple JSDoc to Markdown documentation generator.", | ||
@@ -17,3 +17,4 @@ "license": "MIT", | ||
"dependencies": { | ||
"lodash": "^4.1.0" | ||
"doctrine": "^1.2.0", | ||
"lodash": "^4.6.1" | ||
}, | ||
@@ -20,0 +21,0 @@ "scripts": { |
@@ -1,2 +0,2 @@ | ||
# docdown v0.4.1 | ||
# docdown v0.5.0 | ||
@@ -3,0 +3,0 @@ A simple JSDoc to Markdown documentation generator. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37566
1149
2
+ Addeddoctrine@^1.2.0
+ Addeddoctrine@1.5.0(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedisarray@1.0.0(transitive)
Updatedlodash@^4.6.1