Skip to content

Instantly share code, notes, and snippets.

@CrypticSwarm
Created January 8, 2010 08:48
Show Gist options
  • Save CrypticSwarm/271929 to your computer and use it in GitHub Desktop.
Save CrypticSwarm/271929 to your computer and use it in GitHub Desktop.
var getFromPath = function(obj, path, force) {
var tokens = path === '...' ? [path] : path.split('.');
return tokens.every(function(part){
var isGood = true;
if(obj[part]) obj = obj[part];
else if(force) obj = obj[part] = {};
else isGood = false;
return isGood;
}) ? obj : null;
};
require('./getter').copy((function(){
var cur, toplevel, meta, doced = [];
var addArrayToMeta = function(key, func){
return function(){
if(!meta[key]) meta[key] = [];
meta[key].push(func.apply(this, arguments));
return meta[key];
};
};
var resetCurWrap = function(func) {
return function() {
var prev = cur || this,
metaPrev = meta,
ret = func.apply(this, arguments);
cur = prev;
meta = metaPrev;
return ret;
};
};
var first = function(){ return arguments[0]; };
var docFuncs = {
doc: function(what, desc, func){
var prev = cur || this, ret, path = what;
if(prev === this) path += '.__doc__';
ret = getFromPath(prev, path, true);
meta = getFromPath(ret, 'meta', true);
cur = getFromPath(ret, 'body', true);
if(prev === this) {
toplevel = ret;
doced.push({ name: what, doc: toplevel });
}
if(desc) meta.description = desc;
func();
if(prev === this) toplevel = null;
cur = prev;
return ret;
},
group: resetCurWrap(function(name, func){
var ret;
ret = cur = getFromPath(cur, name, true);
func();
return ret;
}),
arg: resetCurWrap(function(name, type, desc, defaults){
if(name === docFuncs.Any) name = '...';
var ret = cur = getFromPath(cur, name, true);
meta = getFromPath(cur, 'meta', true);
if(desc) meta.description = desc;
if(type) meta.type = type;
if(defaults instanceof Function) {
cur = getFromPath(cur, 'defaults', true);
defaults();
}
else if(defaults) cur.defaults = defaults;
return ret;
}),
inherits: function(paths) {
paths = paths instanceof Array ? paths : [paths];
paths.forEach(function(path){
addArrayToMeta('parent', first)(path);
path += '.__doc__';
var mixin = getFromPath(this, path, true);
var copier = function(to, from){
for(var p in from) {
if (from[p] instanceof Array) {
to[p] = [];
for(var j = 0, l = from[p].length; j < l; ++j) to[p].push(from[p][j]);
}
if (typeof from[p] == 'object') copier(getFromPath(to, p, true), from[p]);
else to[p] = from[p];
}
};
copier(toplevel, mixin);
});
return toplevel;
},
example: addArrayToMeta('examples', function(func){
return ('' + func).replace(/^function\s*\(\)\s*\{\s*/, '').replace(/\s*\}$/, '');
}),
returns: function(type, description) {
meta.returns = { type: (type === docFuncs.Any ? 'Any' : type ), description: description };
},
exception: addArrayToMeta('exceptions', function(type, description){
return {type: type, description: description};
}),
alias: addArrayToMeta('aliases', first),
note: addArrayToMeta('notes', first),
Any: function(){
return Array.prototype.slice.call(arguments);
},
};
docFuncs.key = docFuncs.arg;
docFuncs.getDoced = function(){ return doced; };
docFuncs.clearDoced = function(){ doced = []; };
return docFuncs;
})(), exports);
require('./getter').grabInto(['./docs'], GLOBAL);
var path = './';
exports.generateDocs = function(out, files, format){
files = (files instanceof Array ? files : [files]);
var output = require(format).output;
files.forEach(function(file) {
out('OUTPUTING ' + file + ' starting\n\n');
require(path + file);
getDoced().forEach(function(item) {
output(out, item);
});
clearDoced();
});
};
exports.copy = function(from, to){
for(var p in from) to[p] = from[p];
};
exports.grabInto = function(what, into){
what.forEach(function(item){
exports.copy(require(item), into);
});
};
exports.output = function(out, obj) {
var mainHeader = '===============================',
subHeader = '----------------------------',
name = obj.name;
var nth = function(n) {
return function(){
return arguments[n]; }; };
var first = nth(0);
var link = function() { return '[' + arguments[0] + '][]'; };
var header = function(key, obj){
out('Class: ' + key + ' {#' + key + '}');
out(mainHeader);
if (!obj.meta) return;
if (obj.meta.description) out('\n' + obj.meta.description + '\n');
if (obj.meta.parent) list('### Extends', obj.meta.parent, link, '* ');
if (obj.meta.examples) list('### Syntax', obj.meta.examples, first, '\t');
body(obj.body);
};
var body = function(obj){
for (var key in obj) {
if (typeof obj[key] == 'object') {
if (!obj[key].body && !obj[key].defaults) group(key, obj[key]);
}
}
};
var group = function(key, obj){
var methods = [];
for (var p in obj) {
if (typeof obj[p] == 'object') {
if (obj[p].body) methods.push({ key: p, obj: obj[p] });
}
}
list('### ' + key, methods, method, '');
};
var collect = function(key, obj) {
var collection = [];
for (var p in obj) {
if (typeof obj[p] == 'object') {
if (obj[p][key]) collection.push({ key: p, obj: obj[p] });
}
}
return collection;
};
var method = function(keyobj){
var key = keyobj.key, obj = keyobj.obj, args = collect('meta', obj.body);
out(name + ' Method: ' + key + ' {#' + name + ':' + key + '}');
out(subHeader);
if (obj.meta.description) out('\n' + obj.meta.description + '\n');
if (obj.meta.examples) list('### Syntax', obj.meta.examples, first, '\t');
if (args.length > 0) list('### Arguments', args, function(o){
var req = o.obj.defaults ? 'optional' : 'required';
return o.key + ' - ' + typeAndDescription(o.obj.meta, req);
}, '* ');
if (obj.meta.exceptions) list('### Exceptions', obj.meta.exceptions, typeAndDescription, '* ');
if (obj.meta.returns) list('### Returns', [obj.meta.returns], typeAndDescription, '* ');
return '';
};
var list = function(heading, list, displayfunc, prefix) {
out(heading + '\n');
list.forEach(function(item, num){
out(( prefix == null ? num + 1 : prefix) + displayfunc(item));
});
out('');
};
var typeAndDescription = function(obj, opt) {
var type = obj.type;
if (type instanceof Function) ('' + type).replace(/function\s*(.*)\s*\(/, function(){ type = arguments[1] });
if (opt) type += ' (' + opt + ')';
return '(*' + type + '*) ' + obj.description;
};
header(obj.name, obj.doc);
};

OUTPUTING Request starting

Class: Request {#Request}

Make a (ajax) request.

Syntax

var myRequest = new Request([options]);

public

Request Method: initialize {#Request:initialize}

The constructor

Arguments

  • options - (Object (optional)) Description

Class: Request.HTML {#Request.HTML}

Make a (ajax) request.

Extends

  • [Request][]

Syntax

var myRequest = new Request([options]);

public

Request.HTML Method: initialize {#Request.HTML:initialize}

The constructor

Arguments

  • options - (Object (optional)) Description

Exceptions

  • (Error) description

Returns

  • (Request.HTML) A new Request.HTML instance

Request.HTML Method: stab {#Request.HTML:stab}

Returns the value of first non throwing function.

Arguments

  • ... - (Function (required)) Any number of Functions to call

Returns

  • (Any) The value of the first non throwing function.

Request.HTML Method: send {#Request.HTML:send}

send the request.

Arguments

  • options - (Object (optional)) Description
OUTPUTING Request starting
Request Documentation
meta:
description: Make a (ajax) request.
examples:
0: var myRequest = new Request([options]);
body:
public:
initialize:
meta:
description: The constructor
body:
options:
meta:
description: Description
type: function Object() { [native code] }
defaults:
method:
meta:
description: The HTTP method to use (GET, POST, DELETE, ...).
type: function String() { [native code] }
onRequest:
meta:
description: Fired when the request begins.
type: function Function() { [native code] }
url:
meta:
description: The url to request
type: function String() { [native code] }
headers:
meta:
description: The HTTP headers sent to the backend.
type: function Object() { [native code] }
defaults:
X-Requested-With:
meta:
description: The HTTP X-Requested-With option used by the backend.
type: function String() { [native code] }
Request.HTML Documentation
meta:
description: Make a (ajax) request.
parent:
0: Request
examples:
0: var myRequest = new Request([options]);
body:
public:
initialize:
meta:
description: The constructor
returns:
type: Request.HTML
description: A new Request.HTML instance
exceptions:
0:
type: Error
description: description
aliases:
0: constructor
notes:
0: blah blah blah blah blah blah
body:
options:
meta:
description: Description
type: function Object() { [native code] }
defaults:
method:
meta:
description: The HTTP method to use (GET, POST, DELETE, ...).
type: function String() { [native code] }
onRequest:
meta:
description: Fired when the request begins.
type: function Function() { [native code] }
url:
meta:
description: The url to request
type: function String() { [native code] }
headers:
meta:
description: The HTTP headers sent to the backend.
type: function Object() { [native code] }
defaults:
X-Requested-With:
meta:
description: The HTTP X-Requested-With option used by the backend.
type: function String() { [native code] }
newOpt:
meta:
description: This is a new option
type: function String() { [native code] }
defaults: VALUE
stab:
meta:
description: Returns the value of first non throwing function.
returns:
type: Any
description: The value of the first non throwing function.
body:
...:
meta:
description: Any number of Functions to call
type: function Function() { [native code] }
send:
meta:
description: send the request.
body:
options:
meta:
description: Description
type: function Object() { [native code] }
defaults:
method:
meta:
description: The HTTP method to use (GET, POST, DELETE, ...).
type: function String() { [native code] }
doc('Request', 'Make a (ajax) request.', function(){
group('public', function(){
doc('initialize', 'The constructor', function(){
arg('options', Object, 'Description', function(){
key('method', String, 'The HTTP method to use (GET, POST, DELETE, ...).');
key('onRequest', Function, 'Fired when the request begins.');
key('url', String, 'The url to request');
key('headers', Object, 'The HTTP headers sent to the backend.', function(){
key('X-Requested-With', String, 'The HTTP X-Requested-With option used by the backend.');
});
});
});
});
example(function(){
var myRequest = new Request([options]);
});
});
doc('Request.HTML', 'Send things to other things', function(){
inherits('Request');
group('public', function(){
doc('initialize', null, function(){
arg('options', Object, null, function(){
key('newOpt', String, 'This is a new option', 'VALUE');
});
returns('Request.HTML', 'A new Request.HTML instance');
exception('Error', 'description');
alias('constructor');
note('blah blah blah blah blah blah');
});
doc('stab', 'Returns the value of first non throwing function.', function(){
arg(Any, Function, 'Any number of Functions to call');
returns(Any, 'The value of the first non throwing function.');
});
doc('send', 'send the request.', function(){
arg('options', Object, 'Description', function(){
key('method', String, 'The HTTP method to use (GET, POST, DELETE, ...).');
});
});
});
});
require('./DocumentGen').generateDocs(require('sys').puts, 'Request', './mdDisplay');
exports.output = function(out, obj){
var textDisplay = function(obj, indent){
indent = indent || '';
var type;
for(var p in obj){
type = typeof(obj[p]);
if(textDisplay[type]) {
out(indent + p + ':');
textDisplay[type](obj[p], indent + ' ');
}
else out(indent + p + ': ' + obj[p]);
}
};
textDisplay.object = function(obj, indent) {
textDisplay(obj, indent);
};
out(obj.name + ' Documentation');
textDisplay(obj.doc);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment