kopia lustrzana https://github.com/c9/core
250 wiersze
7.8 KiB
JavaScript
250 wiersze
7.8 KiB
JavaScript
![]() |
var fs = require('fs');
|
||
|
var marked = require('marked');
|
||
|
var util = require("./util");
|
||
|
var patch = require("./patch.js");
|
||
|
var addLinkTargets = util.addLinkTargets;
|
||
|
var stripHtml = util.stripHtml;
|
||
|
var nodeJSON = JSON.parse(fs.readFileSync(__dirname + "/nodemanual.input.jst", 'UTF-8'));
|
||
|
var builtins = JSON.parse(fs.readFileSync(__dirname + "/../builtin.jst", 'UTF-8'));
|
||
|
var VERSION = "latest";
|
||
|
var URL_PREFIX = "http://nodemanual.org/" + VERSION + "/nodejs_ref_guide/";
|
||
|
var GUID_PREFIX = "nodejs_" + VERSION + ":";
|
||
|
var KIND_PACKAGE = "package";
|
||
|
var KIND_HIDDEN = "hidden";
|
||
|
var KIND_DEFAULT = undefined;
|
||
|
var LINK_TARGET = "c9doc";
|
||
|
|
||
|
marked.setOptions({
|
||
|
gfm: true,
|
||
|
pedantic: false,
|
||
|
sanitize: false,
|
||
|
/* callback for code highlighter
|
||
|
highlight: function(code, lang) {
|
||
|
if (lang === 'js') {
|
||
|
return javascriptHighlighter(code);
|
||
|
}
|
||
|
return code;
|
||
|
}
|
||
|
*/
|
||
|
});
|
||
|
|
||
|
function Container(id) {
|
||
|
this.guid = toC9TypeName(id);
|
||
|
this.properties = {
|
||
|
_prototype: [{
|
||
|
guid: this.guid + "/prototype",
|
||
|
properties: {}
|
||
|
}]
|
||
|
};
|
||
|
this.kind = this.guid.match("/") ? KIND_HIDDEN : KIND_PACKAGE;
|
||
|
console.log(this.guid);
|
||
|
}
|
||
|
|
||
|
Container.prototype.add = function(id, property) {
|
||
|
var props;
|
||
|
if (isStatic(property, this)) {
|
||
|
props = this.properties;
|
||
|
property.guid = this.guid + "/" + property.guid;
|
||
|
// console.log(this.guid + ":" + id);
|
||
|
} else {
|
||
|
props = this.properties._prototype[0].properties;
|
||
|
property.guid = this.guid + "/prototype/" + property.guid;
|
||
|
// console.log(this.guid + "." + id);
|
||
|
}
|
||
|
var targetProps = props["_" + id] = props["_" + id] || [];
|
||
|
targetProps.push(property);
|
||
|
};
|
||
|
|
||
|
function Property(parent, id) {
|
||
|
this.guid = id;
|
||
|
this.properties = {};
|
||
|
}
|
||
|
|
||
|
function extractRoot(root) {
|
||
|
var results = {};
|
||
|
/* Preprocess classes to recognize globals
|
||
|
for (var i = 0; i < root.tree.children.length; i++) {
|
||
|
var child = root.tree.children[i];
|
||
|
if (child.type === "class")
|
||
|
extractItem(child, results);
|
||
|
}
|
||
|
*/
|
||
|
// Process all children
|
||
|
for (var i = 0; i < root.tree.children.length; i++) {
|
||
|
var child = root.tree.children[i];
|
||
|
extractItem(child, results);
|
||
|
}
|
||
|
return results;
|
||
|
}
|
||
|
|
||
|
function extractItem(item, results) {
|
||
|
if (item.id === "Modules") // HACK: Modules is not a class
|
||
|
return;
|
||
|
|
||
|
if (item.type === "class method" || item.type === "class property")
|
||
|
extractProperty(item, results);
|
||
|
else if (item.type === "class")
|
||
|
extractContainer(item, results);
|
||
|
else if (item.type === "constructor")
|
||
|
extractConstructor(item, results);
|
||
|
else if (item.type === "event")
|
||
|
extractEvent(item, results);
|
||
|
else
|
||
|
throw new Error("Unknown item type: " + item.type);
|
||
|
}
|
||
|
|
||
|
function extractContainer(item, results) {
|
||
|
var matcher = item.id.match(/^(.*)\.(.*?)$/);
|
||
|
if (matcher) {
|
||
|
var parentId = matcher[1];
|
||
|
var parentClass = results[toC9TypeName(parentId)];
|
||
|
if (!parentClass)
|
||
|
parentClass = results[toC9TypeName(parentId)] = new Container(parentId);
|
||
|
}
|
||
|
|
||
|
var result = results[toC9TypeName(item.id)] || new Container(item.id);
|
||
|
results[toC9TypeName(item.id)] = result;
|
||
|
|
||
|
// TODO: don't copy doc from class to _prototype??
|
||
|
result.docUrl = result.properties._prototype.docUrl = extractDocUrl(item);
|
||
|
result.doc = result.properties._prototype.doc = extractDoc(item);
|
||
|
|
||
|
if (result.kind === KIND_PACKAGE && (isClassNotPackage(item) || matcher)) {
|
||
|
result.kind = KIND_DEFAULT;
|
||
|
// TODO: prototype chain
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < item.children.length; i++) {
|
||
|
extractItem(item.children[i], results);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function isClassNotPackage(item) {
|
||
|
if (item.metadata) {
|
||
|
if (item.metadata.indexOf)
|
||
|
item.metadata = JSON.parse(item.metadata);
|
||
|
if (item.metadata.type === "global")
|
||
|
return true;
|
||
|
}
|
||
|
// HACK: assume if something is a constructor, it is a class with instance properties
|
||
|
for (var i = 0; i < item.children.length; i++) {
|
||
|
if (item.children[i].type === "constructor")
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function isStatic(property, container) {
|
||
|
// HACK: we don't have metadata for this yet
|
||
|
return container.kind === "package" ||
|
||
|
property.guid.match(/^[A-Z]/) || container.guid.match("(/|:)[a-z][^/]*$");
|
||
|
}
|
||
|
|
||
|
function extractProperty(item, results, isConstructor) {
|
||
|
var matcher = item.id.match(/^(.*)\.(.*?)$/);
|
||
|
var parentId = matcher[1];
|
||
|
var childId = matcher[2];
|
||
|
var parentClass = results[toC9TypeName(parentId)];
|
||
|
if (!parentClass)
|
||
|
parentClass = results[toC9TypeName(parentId)] = new Container(parentId);
|
||
|
|
||
|
var signatures = item.signatures || [{}];
|
||
|
|
||
|
for (var i = 0; i < signatures.length; i++) {
|
||
|
var signature = signatures[i];
|
||
|
var result = new Property(parentClass, childId + "[" + i + "]");
|
||
|
result.docUrl = extractDoc(signature) || extractDocUrl(item);
|
||
|
result.doc = extractDoc(item) || extractDoc(item);
|
||
|
extractSignature(item, signature, result);
|
||
|
if (isConstructor)
|
||
|
extractSignature(item, signature, parentClass);
|
||
|
parentClass.add(childId, result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function extractSignature(item, signature, result) {
|
||
|
var returns = extractType(signature.returns ? signature.returns[0].type : null, true);
|
||
|
|
||
|
if (item.type === "class property") {
|
||
|
result.properties.___proto__ = returns;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
result.properties._return = returns;
|
||
|
result.fargs = [];
|
||
|
result.properties.___proto__ = result.properties.___proto__ || [];
|
||
|
result.properties.___proto__.push("es5:Function/prototype");
|
||
|
|
||
|
if (!signature.args)
|
||
|
return;
|
||
|
|
||
|
extractSignatureArgs(signature, result.fargs);
|
||
|
}
|
||
|
|
||
|
function extractSignatureArgs(signature, results) {
|
||
|
for (var i = 0; i < signature.args.length; i++) {
|
||
|
// TODO: store callback signatures
|
||
|
// for example, see readline.interface.question
|
||
|
// TODO: store function sig like { name: 'callback', args: [], optional: true }
|
||
|
var arg = signature.args[i];
|
||
|
var argFargs = arg.args && extractSignatureArgs(arg, []);
|
||
|
results.push({
|
||
|
id: arg.name,
|
||
|
type: extractType(arg.type, true),
|
||
|
doc: arg.description,
|
||
|
opt: arg.optional,
|
||
|
fargs: argFargs
|
||
|
});
|
||
|
}
|
||
|
return results;
|
||
|
}
|
||
|
|
||
|
function extractConstructor(item, results) {
|
||
|
item.id = item.id.replace(/^new (.*)/, "$1") + ".constructor";
|
||
|
extractProperty(item, results, true);
|
||
|
}
|
||
|
|
||
|
function extractEvent(item, results) {
|
||
|
// TODO: extract events?
|
||
|
}
|
||
|
|
||
|
function extractType(type) {
|
||
|
if (type) {
|
||
|
if (builtins["es5:" + type])
|
||
|
return ["es5:" + type + "/prototype"];
|
||
|
else if (type instanceof Array)
|
||
|
return type.map(extractType);
|
||
|
else
|
||
|
return [toC9TypeName(type) + "/prototype"];
|
||
|
}
|
||
|
else {
|
||
|
return ["es5:Object/prototype"];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function toC9TypeName(typename) {
|
||
|
return GUID_PREFIX + typename.replace(/\./g, "/");
|
||
|
}
|
||
|
|
||
|
function extractDocUrl(item) {
|
||
|
// TODO: why do urls like http://nodemanual.org/latest/nodejs_ref_guide/debugger.html#L145 not exist?
|
||
|
return URL_PREFIX + item.resultingFile;
|
||
|
}
|
||
|
|
||
|
function extractDoc(item) {
|
||
|
if (!item.short_description || item.short_description.match(/^Stability:[^\\]*(\\n[^\\]*)?/))
|
||
|
return null;
|
||
|
// TODO: support (some) documentation links?
|
||
|
var result = marked(item.short_description);
|
||
|
result = result.replace(/\[\[[^ \]]+\s+([^\]]+)\]\]/gm, "$1");
|
||
|
result = result.replace(/\[([^\]]+)\]\([^\)]+\)/gm, "$1");
|
||
|
result = addLinkTargets(result, LINK_TARGET);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
var allResults = extractRoot(nodeJSON);
|
||
|
allResults = patch.patchNodemanual(allResults);
|
||
|
fs.writeFileSync(__dirname + "/../builtin.nodejs.jst", JSON.stringify(allResults, null, 2), "UTF-8");
|
||
|
|