mirror of
https://github.com/photonstorm/phaser
synced 2024-09-21 06:51:55 +00:00
PIXI-in-Docs - Initial
- Initial support for generating PIXI-combined documentation - Includes yuidoc-to-jsdoc for generating pixi-jsdoc.js - Creates doc (using pixidoc + builddoc) tasks - Adds sourceproxy JSDoc plugin to map in corrected file/line meta - Added yuidocjs as a dev-dependency
This commit is contained in:
parent
96915e1612
commit
ce02d3402f
6 changed files with 431 additions and 2 deletions
2
docs/build/conf.json
vendored
2
docs/build/conf.json
vendored
|
@ -4,6 +4,7 @@
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"include": [
|
"include": [
|
||||||
|
"../pixi-jsdoc.js",
|
||||||
"../../src/Phaser.js",
|
"../../src/Phaser.js",
|
||||||
"../../src/animation/",
|
"../../src/animation/",
|
||||||
"../../src/core/",
|
"../../src/core/",
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
},
|
},
|
||||||
"plugins" : [
|
"plugins" : [
|
||||||
"local-plugins/proptomember",
|
"local-plugins/proptomember",
|
||||||
|
"local-plugins/sourceproxy",
|
||||||
"plugins/markdown"
|
"plugins/markdown"
|
||||||
],
|
],
|
||||||
"templates": {
|
"templates": {
|
||||||
|
|
38
docs/build/local-plugins/sourceproxy.js
vendored
Normal file
38
docs/build/local-plugins/sourceproxy.js
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* For use with custom `@sourcepath`, `@sourceline`, `@nosource` properties
|
||||||
|
* (which are used in YUIDoc-to-JSDoc to supply source documentation)
|
||||||
|
*/
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
exports.defineTags = function(dictionary) {
|
||||||
|
|
||||||
|
dictionary.defineTag('nosource', {
|
||||||
|
onTagged: function (doclet, tag) {
|
||||||
|
doclet.meta.nosource = true;
|
||||||
|
//doclet.meta.path = '';
|
||||||
|
//doclet.meta.filename = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dictionary.defineTag('sourcefile', {
|
||||||
|
onTagged: function (doclet, tag) {
|
||||||
|
var filename = tag.value;
|
||||||
|
doclet.meta.path = path.dirname(filename);
|
||||||
|
doclet.meta.filename = path.basename(filename);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dictionary.defineTag('sourceline', {
|
||||||
|
onTagged: function (doclet, tag) {
|
||||||
|
var lineno = tag.value;
|
||||||
|
doclet.meta.lineno = lineno;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.handlers = {};
|
||||||
|
exports.handlers.newDoclet = function (e) {
|
||||||
|
|
||||||
|
};
|
|
@ -40,6 +40,7 @@
|
||||||
"grunt-contrib-uglify": "^0.4.0",
|
"grunt-contrib-uglify": "^0.4.0",
|
||||||
"grunt-notify": "^0.3.0",
|
"grunt-notify": "^0.3.0",
|
||||||
"grunt-text-replace": "^0.3.11",
|
"grunt-text-replace": "^0.3.11",
|
||||||
"load-grunt-config": "~0.7.2"
|
"load-grunt-config": "~0.7.2",
|
||||||
|
"yuidocjs": "^0.3.50"
|
||||||
}
|
}
|
||||||
}
|
}
|
30
tasks/builddoc.js
Normal file
30
tasks/builddoc.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* A quick stub-task for running generating the JSDocs.
|
||||||
|
* This should probably be migrated to use grunt-jsdoc@beta (for jsdoc 3.x) or similar.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
|
grunt.registerTask('builddoc', 'Builds the project documentation', function () {
|
||||||
|
|
||||||
|
var done = this.async();
|
||||||
|
|
||||||
|
grunt.util.spawn({
|
||||||
|
cmd: 'jsdoc',
|
||||||
|
args: ['-c', 'conf.json', '../../README.md'],
|
||||||
|
opts: {
|
||||||
|
cwd: 'docs/build'
|
||||||
|
}
|
||||||
|
}, function (error, result, code) {
|
||||||
|
if (error) {
|
||||||
|
grunt.fail.warn("" + result);
|
||||||
|
done(false);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
58
tasks/pixidoc.js
Normal file
58
tasks/pixidoc.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* Generates the appropriate JSDoc from some (PIXI) YUIDoc.
|
||||||
|
* This could be turned into a more general pacakge.
|
||||||
|
*
|
||||||
|
* Requires: yuidocjs
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function generateYuiDoc (sourcePaths, grunt) {
|
||||||
|
|
||||||
|
var Y = require('yuidocjs');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
parseOnly: true,
|
||||||
|
quiet: true,
|
||||||
|
paths: sourcePaths
|
||||||
|
};
|
||||||
|
|
||||||
|
return (new Y.YUIDoc(options)).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
|
grunt.registerTask('pixidoc', 'Generates JSDoc from the PIXI YUIdocs', function () {
|
||||||
|
|
||||||
|
var sources = ['C:/code/ph/phaser/src/pixi'];
|
||||||
|
var output = 'docs/pixi-jsdoc.js';
|
||||||
|
|
||||||
|
var yui2jsdoc = require('./yuidoc-to-jsdoc/converter');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
// Right now yuidocsjs requires an absolute path so it emits an
|
||||||
|
// absolute path in the jsdoc (or the JSDoc will error on missing files)
|
||||||
|
sources = sources.map(function (source) {
|
||||||
|
return path.resolve(source);
|
||||||
|
});
|
||||||
|
|
||||||
|
var data = generateYuiDoc(sources);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
grunt.fail.warn("PIXI YUIDoc not generated - nothing to do")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fake in namespace (current limitation)
|
||||||
|
var header =
|
||||||
|
"/**\n" +
|
||||||
|
"* @namespace PIXI\n" +
|
||||||
|
"*/";
|
||||||
|
|
||||||
|
var res = yui2jsdoc.convert(data);
|
||||||
|
var flat = res.join("\n");
|
||||||
|
fs.writeFileSync(output, header + "\n" + flat);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
300
tasks/yuidoc-to-jsdoc/converter.js
vendored
Normal file
300
tasks/yuidoc-to-jsdoc/converter.js
vendored
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
/**
|
||||||
|
* Converts the JSON data out of YUIDoc into JSDoc documentation.
|
||||||
|
*
|
||||||
|
* Use a JSDoc plugin to handle custom @sourcefile/@sourceline and reattach meta-data.
|
||||||
|
*
|
||||||
|
* This works on the current PIXI source code (and, unfortunately, exposes a few issues it has).
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Does not work with 'props'
|
||||||
|
function paramdesc_to_str(desc, typedescs) {
|
||||||
|
var name = desc.name;
|
||||||
|
var typename = desc.type;
|
||||||
|
var description = desc.description;
|
||||||
|
|
||||||
|
if (desc.optional) {
|
||||||
|
if (desc.optdefault) {
|
||||||
|
name = "[" + name + "=" + desc.optdefault + "]";
|
||||||
|
} else {
|
||||||
|
name = "[" + name + "]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{" + resolve_typename(typename, typedescs) + "} " + name + " - " + description;
|
||||||
|
}
|
||||||
|
|
||||||
|
function returndesc_to_string(desc, typedescs) {
|
||||||
|
var typename = desc.type;
|
||||||
|
var description = desc.description;
|
||||||
|
if (typename) {
|
||||||
|
return "{" + resolve_typename(typename, typedescs) + "} " + description;
|
||||||
|
} else {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert flat 'typeitems' found in YUIDoc to a dictionary:
|
||||||
|
* className: {
|
||||||
|
* items: [..] - only properties and methods
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
function group_typeitems(typeitems) {
|
||||||
|
|
||||||
|
var types = {};
|
||||||
|
|
||||||
|
typeitems.forEach(function (itemdesc, i) {
|
||||||
|
var class_name = itemdesc['class'];
|
||||||
|
var itemtype = itemdesc.itemtype;
|
||||||
|
|
||||||
|
if (itemtype === 'method' || itemtype === 'property')
|
||||||
|
{
|
||||||
|
var type = types[class_name];
|
||||||
|
if (!type) {
|
||||||
|
type = types[class_name] = {
|
||||||
|
items: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type.items.push(itemdesc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return types;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this for anything but trivial types; it takes apart complex types
|
||||||
|
function resolve_typename(typename, typedescs) {
|
||||||
|
|
||||||
|
if (!typename) { typename = "Any"; }
|
||||||
|
|
||||||
|
if (typename.indexOf('|') > -1) {
|
||||||
|
var typenames = typename.split(/[|]/g);
|
||||||
|
} else {
|
||||||
|
typenames = [typename];
|
||||||
|
}
|
||||||
|
|
||||||
|
typenames = typenames.map(function (part) {
|
||||||
|
|
||||||
|
// YUIDoc is type... and JSDoc is ...type
|
||||||
|
var repeating = false;
|
||||||
|
if (part.match(/[.]{2,}/)) {
|
||||||
|
repeating = true;
|
||||||
|
part = part.replace(/[.]{2,}/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This may happen for some terribly invalid input; ideally this would not be
|
||||||
|
// "handled" here, but trying to work with some not-correct input..
|
||||||
|
part = part.replace(/[^a-zA-Z0-9_$<>.]/g, '');
|
||||||
|
|
||||||
|
var resolved = resolve_single_typename(part, typedescs);
|
||||||
|
if (repeating) {
|
||||||
|
return "..." + resolved
|
||||||
|
} else {
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typenames.length > 1) {
|
||||||
|
return "(" + typenames.join("|") + ")";
|
||||||
|
} else {
|
||||||
|
return typenames[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve_single_typename(typename, typedescs) {
|
||||||
|
|
||||||
|
if (!typename || typename.toLowerCase() == "Any" || typename === "*") {
|
||||||
|
return ""; // "Any"
|
||||||
|
}
|
||||||
|
|
||||||
|
var typedesc = typedescs[typename];
|
||||||
|
if (typedesc) {
|
||||||
|
return typedesc.module + "." + typename;
|
||||||
|
} else {
|
||||||
|
return typename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve_item_name(name, typedesc, typedescs) {
|
||||||
|
var typename = resolve_single_typename(typedesc.name, typedescs);
|
||||||
|
return typename + "#" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function methoddesc_to_attrs(itemdesc, typedesc, typedescs)
|
||||||
|
{
|
||||||
|
var attrs = [];
|
||||||
|
|
||||||
|
if (itemdesc.description) {
|
||||||
|
attrs.push(['description', itemdesc.description]);
|
||||||
|
}
|
||||||
|
attrs.push(['method', resolve_item_name(itemdesc.name, typedesc, typedescs)]);
|
||||||
|
if (itemdesc.params)
|
||||||
|
{
|
||||||
|
itemdesc.params.forEach(function (param, i) {
|
||||||
|
attrs.push(['param', paramdesc_to_str(param, typedescs)]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemdesc['return'])
|
||||||
|
{
|
||||||
|
attrs.push(['return', returndesc_to_string(itemdesc['return'], typedescs)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typedesc.file) {
|
||||||
|
attrs.push(['sourcefile', typedesc.file]);
|
||||||
|
attrs.push(['sourceline', typedesc.line]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function propertydesc_to_attrs(itemdesc, typedesc, typedescs)
|
||||||
|
{
|
||||||
|
var attrs = [];
|
||||||
|
|
||||||
|
if (itemdesc.description) {
|
||||||
|
attrs.push(['description', itemdesc.description]);
|
||||||
|
}
|
||||||
|
attrs.push(['member', resolve_item_name(itemdesc.name, typedesc, typedescs)]);
|
||||||
|
attrs.push(['type', "{" + resolve_typename(itemdesc.type, typedescs) + "}"]);
|
||||||
|
|
||||||
|
var access = itemdesc['access'];
|
||||||
|
if (access) {
|
||||||
|
attrs.push(['access', access]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemdesc['readonly'] !== undefined) {
|
||||||
|
attrs.push(['readonly', '']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemdesc['default'] !== undefined) {
|
||||||
|
attrs.push(['default', itemdesc['default']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typedesc.file) {
|
||||||
|
attrs.push(['sourcefile', typedesc.file]);
|
||||||
|
attrs.push(['sourceline', typedesc.line]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_attr_block (attrs, res) {
|
||||||
|
|
||||||
|
if (attrs) {
|
||||||
|
res.push("/**");
|
||||||
|
|
||||||
|
attrs.forEach(function (attr) {
|
||||||
|
var name = attr[0];
|
||||||
|
var value = attr[1];
|
||||||
|
if (value !== undefined) {
|
||||||
|
res.push("* @" + name + " " + value);
|
||||||
|
} else {
|
||||||
|
res.push("* @" + name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.push("*/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function itemdesc_to_attrs(itemdesc, typedesc, typedescs) {
|
||||||
|
|
||||||
|
if (itemdesc.itemtype === 'method')
|
||||||
|
{
|
||||||
|
return methoddesc_to_attrs(itemdesc, typedesc, typedescs);
|
||||||
|
}
|
||||||
|
else if (itemdesc.itemtype === 'property')
|
||||||
|
{
|
||||||
|
return propertydesc_to_attrs(itemdesc, typedesc, typedescs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function typedesc_to_attrs (typedesc, typedescs) {
|
||||||
|
|
||||||
|
var attrs = [];
|
||||||
|
|
||||||
|
// Bug in PIXI (test) docs has a "static constructor", whoops!
|
||||||
|
if (typedescs.is_constructor || !typedescs['static']) {
|
||||||
|
|
||||||
|
attrs.push(['class', resolve_single_typename(typedesc.name, typedescs)]);
|
||||||
|
|
||||||
|
if (typedesc.description) {
|
||||||
|
attrs.push(['classdesc', typedesc.description]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Not constructor, possibly static ..
|
||||||
|
|
||||||
|
attrs.push(['description', typedesc.description]);
|
||||||
|
attrs.push(['namespace', resolve_single_typename(typedesc.name, typedescs)]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var extendsname = typedesc['extends'];
|
||||||
|
if (extendsname) {
|
||||||
|
var extenddesc = typedescs[extendsname];
|
||||||
|
if (extenddesc) {
|
||||||
|
attrs.push(['augments', resolve_single_typename(extendsname, typedescs)]);
|
||||||
|
} else {
|
||||||
|
attrs.push(['augments', extendsname]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typedesc.params)
|
||||||
|
{
|
||||||
|
typedesc.params.forEach(function (paramdesc, i) {
|
||||||
|
attrs.push(['param', paramdesc_to_str(paramdesc, typedescs)]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typedesc.file) {
|
||||||
|
attrs.push(['sourcefile', typedesc.file]);
|
||||||
|
attrs.push(['sourceline', typedesc.line]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a "data.json" (as JSON, not text) from YUIDoc to an equivalent JSDoc markup.
|
||||||
|
*/
|
||||||
|
function yuidocDatatoJSDoc(data) {
|
||||||
|
|
||||||
|
var typedescs = data.classes;
|
||||||
|
var type_itemdesc_groups = group_typeitems(data.classitems);
|
||||||
|
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
Object.keys(typedescs).forEach(function (name) {
|
||||||
|
var typedesc = typedescs[name];
|
||||||
|
|
||||||
|
var typeattrs = typedesc_to_attrs(typedesc, typedescs);
|
||||||
|
write_attr_block(typeattrs, res);
|
||||||
|
|
||||||
|
var type_itemdesc = type_itemdesc_groups[name];
|
||||||
|
if (type_itemdesc) {
|
||||||
|
type_itemdesc.items.forEach(function (itemdesc, i) {
|
||||||
|
var attrs = itemdesc_to_attrs(itemdesc, typedesc, typedescs);
|
||||||
|
write_attr_block(attrs, res);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("No items for " + name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.convert = function (yuidoc) {
|
||||||
|
|
||||||
|
return yuidocDatatoJSDoc(yuidoc);
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in a new issue