Add jsdoc plugin that maps @todo tags to @stability and @observable tags.
This is a temporary measure until Plovr handles custom tags or is replaced in the build system. Add support for indicating API stability with inline documentation In preparation for documenting the stability of API features, this commit adds support for indicating API stability via a new jsdoc tag @stability. There is a small plugin for jsdoc that adds a new tag, @stabiility, with some ability to enforce specific level names. The templates and css have been updated to include the stability level in the generated documentation. (+1 squashed commit) Squashed commits: [d6bc03d] Add jsdoc plugin for documenting observable properties of a class.
This commit is contained in:
@@ -13,11 +13,17 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
"plugins/markdown",
|
"plugins/markdown",
|
||||||
"apidoc/plugins/inheritdoc",
|
"apidoc/plugins/inheritdoc",
|
||||||
"apidoc/plugins/exports"
|
"apidoc/plugins/exports",
|
||||||
|
"apidoc/plugins/todo",
|
||||||
|
"apidoc/plugins/observable",
|
||||||
|
"apidoc/plugins/stability"
|
||||||
],
|
],
|
||||||
"markdown": {
|
"markdown": {
|
||||||
"parser": "gfm"
|
"parser": "gfm"
|
||||||
},
|
},
|
||||||
|
"stability": {
|
||||||
|
"levels": ["deprecated","experimental","unstable","stable","frozen","locked"]
|
||||||
|
},
|
||||||
"templates": {
|
"templates": {
|
||||||
"cleverLinks": false,
|
"cleverLinks": false,
|
||||||
"monospaceLinks": false,
|
"monospaceLinks": false,
|
||||||
|
|||||||
26
apidoc/plugins/observable.js
Normal file
26
apidoc/plugins/observable.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
var util = require('util');
|
||||||
|
exports.defineTags = function(dictionary) {
|
||||||
|
dictionary.defineTag('observable', {
|
||||||
|
mustHaveValue: true,
|
||||||
|
canHaveType: true,
|
||||||
|
canHaveName: true,
|
||||||
|
onTagged: function(doclet, tag) {
|
||||||
|
if (!doclet.observables) {
|
||||||
|
doclet.observables = [];
|
||||||
|
}
|
||||||
|
var description = tag.value.description;
|
||||||
|
var readonly = description.split(' ').shift() === 'readonly';
|
||||||
|
if (readonly) {
|
||||||
|
description = description.split(' ').slice(1).join(' ');
|
||||||
|
}
|
||||||
|
doclet.observables.push({
|
||||||
|
name: tag.value.name,
|
||||||
|
type: {
|
||||||
|
names: tag.value.type.names
|
||||||
|
},
|
||||||
|
description: description,
|
||||||
|
readonly: readonly
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
20
apidoc/plugins/stability.js
Normal file
20
apidoc/plugins/stability.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
var conf = env.conf.stability;
|
||||||
|
var defaultLevels = ["deprecated","experimental","unstable","stable","frozen","locked"];
|
||||||
|
var levels = conf.levels || defaultLevels;
|
||||||
|
var util = require('util');
|
||||||
|
exports.defineTags = function(dictionary) {
|
||||||
|
dictionary.defineTag('stability', {
|
||||||
|
mustHaveValue: true,
|
||||||
|
canHaveType: false,
|
||||||
|
canHaveName: true,
|
||||||
|
onTagged: function(doclet, tag) {
|
||||||
|
var level = tag.text;
|
||||||
|
if (levels.indexOf(level) >=0) {
|
||||||
|
doclet.stability = level;
|
||||||
|
} else {
|
||||||
|
var errorText = util.format('Invalid stability level (%s) in %s line %s', tag.text, doclet.meta.filename, doclet.meta.lineno);
|
||||||
|
require('jsdoc/util/error').handle( new Error(errorText) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
28
apidoc/plugins/todo.js
Normal file
28
apidoc/plugins/todo.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
var util = require('util');
|
||||||
|
exports.defineTags = function(dictionary) {
|
||||||
|
dictionary.defineTag('todo', {
|
||||||
|
mustHaveValue: true,
|
||||||
|
canHaveType: true,
|
||||||
|
canHaveName: true,
|
||||||
|
onTagged: function(doclet, tag) {
|
||||||
|
var parts = tag.text.split(' ');
|
||||||
|
if (parts[0] === 'stability') {
|
||||||
|
doclet.stability = parts.slice(1).join(' ');
|
||||||
|
} else if (parts[0] === 'observable') {
|
||||||
|
if (!doclet.observables) {
|
||||||
|
doclet.observables = [];
|
||||||
|
}
|
||||||
|
var readonly = parts.length > 3 && parts[3] === 'readonly';
|
||||||
|
var description = (readonly ? parts.slice(4) : parts.slice(3)).join(' ');
|
||||||
|
doclet.observables.push({
|
||||||
|
name: parts[2],
|
||||||
|
type: {
|
||||||
|
names: tag.value.type.names
|
||||||
|
},
|
||||||
|
description: description,
|
||||||
|
readonly: readonly
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -92,6 +92,15 @@
|
|||||||
<?js }); ?></dl>
|
<?js }); ?></dl>
|
||||||
<?js } ?>
|
<?js } ?>
|
||||||
|
|
||||||
|
<?js
|
||||||
|
var observables = doc.observables;
|
||||||
|
if (observables && observables.length && observables.forEach) {
|
||||||
|
?>
|
||||||
|
<h3 class="subsection-title">Observable Properties</h3>
|
||||||
|
<dl><?js= self.partial('observables.tmpl', observables) ?></dl>
|
||||||
|
|
||||||
|
<?js } ?>
|
||||||
|
|
||||||
<?js
|
<?js
|
||||||
var members = self.find({kind: 'member', memberof: title === 'Globals'? {isUndefined: true} : doc.longname});
|
var members = self.find({kind: 'member', memberof: title === 'Globals'? {isUndefined: true} : doc.longname});
|
||||||
if (members && members.length && members.forEach) {
|
if (members && members.length && members.forEach) {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<dt class="<?js= data.access ?>">
|
<dt class="<?js= data.access ?>">
|
||||||
<h4 class="name" id="<?js= id ?>"><?js= data.attribs + name + data.signature ?></h4>
|
<h4 class="name" id="<?js= id ?>"><?js= data.attribs + name + data.signature ?></h4>
|
||||||
|
|
||||||
|
<?js= this.partial('stability.tmpl', data) ?>
|
||||||
|
|
||||||
<?js if (data.summary) { ?>
|
<?js if (data.summary) { ?>
|
||||||
<p class="summary"><?js= summary ?></p>
|
<p class="summary"><?js= summary ?></p>
|
||||||
<?js } ?>
|
<?js } ?>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ var self = this;
|
|||||||
<dt>
|
<dt>
|
||||||
<h4 class="name" id="<?js= id ?>"><?js= data.attribs + (kind == 'class'? 'new ':'') + name + data.signature ?></h4>
|
<h4 class="name" id="<?js= id ?>"><?js= data.attribs + (kind == 'class'? 'new ':'') + name + data.signature ?></h4>
|
||||||
|
|
||||||
|
<?js= this.partial('stability.tmpl', data) ?>
|
||||||
|
|
||||||
<?js if (data.summary) { ?>
|
<?js if (data.summary) { ?>
|
||||||
<p class="summary"><?js= summary ?></p>
|
<p class="summary"><?js= summary ?></p>
|
||||||
<?js } ?>
|
<?js } ?>
|
||||||
|
|||||||
40
apidoc/template/tmpl/observables.tmpl
Normal file
40
apidoc/template/tmpl/observables.tmpl
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?js
|
||||||
|
var props = obj;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<table class="props">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Get</th>
|
||||||
|
<th>Set</th>
|
||||||
|
<th>Event</th>
|
||||||
|
<th class="last">Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<?js
|
||||||
|
var self = this;
|
||||||
|
props.forEach(function(prop) {
|
||||||
|
if (!prop) { return; }
|
||||||
|
var getter = 'yes';
|
||||||
|
var setter = prop.readonly ? 'no' : 'yes';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="name"><code><?js= prop.name ?></code></td>
|
||||||
|
<td class="type">
|
||||||
|
<?js if (prop.type && prop.type.names) {?>
|
||||||
|
<?js= self.partial('type.tmpl', prop.type.names) ?>
|
||||||
|
<?js } ?>
|
||||||
|
</td>
|
||||||
|
<td class="getter"><?js= getter ?></td>
|
||||||
|
<td class="setter"><?js= setter ?></td>
|
||||||
|
<td class="event"><code>change:<?js= prop.name ?></code></td>
|
||||||
|
<td class="description last"><?js= prop.description ?></td>
|
||||||
|
</tr>
|
||||||
|
<?js }); ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
9
apidoc/template/tmpl/stability.tmpl
Normal file
9
apidoc/template/tmpl/stability.tmpl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?js
|
||||||
|
var data = obj;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (data.stability) { ?>
|
||||||
|
<div class="stability stability-<?js= stability ?>">Stability: <?js= data.stability ?></div>
|
||||||
|
<?js } else { ?>
|
||||||
|
<div class="stability">Stability: not documented</div>
|
||||||
|
<?js } ?>
|
||||||
@@ -27,3 +27,40 @@ body, h1, h2, h3, h4, p, li, td, th {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stability {
|
||||||
|
padding: 8px 35px 8px 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||||
|
color: #333;
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stability-deprecated {
|
||||||
|
color: #b94a48;
|
||||||
|
background-color: #f2dede;
|
||||||
|
border-color: #eed3d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stability-experimental {
|
||||||
|
color: #c09853;
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
border-color: #fbeed5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stability-unstable {
|
||||||
|
color: #3a87ad;
|
||||||
|
background-color: #d9edf7;
|
||||||
|
border-color: #bce8f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stability-stable,
|
||||||
|
.stability-locked,
|
||||||
|
.stability-locked, {
|
||||||
|
color: #468847;
|
||||||
|
background-color: #dff0d8;
|
||||||
|
border-color: #d6e9c6;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user