jsdoc template: general clean up and implement exporting of packages.js.

This commit is contained in:
Jonathan Puckey 2011-06-01 19:49:50 +02:00
parent 0c6a91a789
commit 4af970ed79
21 changed files with 666 additions and 515 deletions

View file

@ -23,5 +23,5 @@ else
fi
cd jsdoc-toolkit
java -jar jsrun.jar app/run.js -c=conf/$MODE.conf
java -jar jsrun.jar app/run.js -c=conf/$MODE.conf -D="renderMode:$MODE"
cd ..

View file

@ -26,8 +26,5 @@
d: "../../out/docs",
// use this template
t: "templates/jsdoc",
// set variables:
D: "renderMode:docs"
t: "templates/jsdoc"
}

View file

@ -26,8 +26,5 @@
d: "../../out/templates",
// use this template
t: "templates/jsdoc",
// set variables:
D: "renderMode:templatedocs"
t: "templates/jsdoc"
}

View file

@ -0,0 +1,29 @@
var Operator = new function() {
var operators = {
add: '+', subtract: '-', multiply: '*', divide: '/', equals: '==',
modulo: '%'
};
var operatorNames = {
add: 'Addition', subtract: 'Subtraction', multiply: 'Multiplication',
divide: 'Division', equals: 'Comparison', modulo: 'Modulo'
};
return {
isOperator: function(symbol) {
// As a convention, only add non static bean properties to
// the documentation. static properties are all supposed to
// be uppercase and constants.
return symbol.params.length == 1 && !symbol.isStatic && (
/^(add|subtract|multiply|divide|modulo)(\^[0-9])*$/.test(symbol.name)
&& (symbol.operator != 'none')
) || ( // equals
symbol.name == 'equals'
&& symbol.returns.length && symbol.returns[0].type == 'boolean'
);
},
getOperator: function(symbol) {
return operators[symbol.name.replace(/\^[0-9]$/,'')];
}
};
};

View file

@ -0,0 +1,327 @@
var Render = new function() {
var templatesDir = (JSDOC.opt.t || SYS.pwd + '../templates/jsdoc/')
+ 'templates/';
var templates = {
_class: 'class.tmpl',
method: 'method.tmpl',
property: 'property.tmpl',
parameters: 'parameters.tmpl',
parameter: 'parameter.tmpl',
operators: 'operators.tmpl',
returns: 'returns.tmpl',
'return': 'return.tmpl',
seeAlsos: 'seeAlsos.tmpl',
example: 'example.tmpl',
constructor: 'constructor.tmpl',
html: 'html.tmpl',
allClasses: 'allClasses.tmpl',
menu: 'packages.tmpl',
operator: 'operator.tmpl',
packagesjs: 'packagesjs.tmpl'
};
publish.classes = [];
for (var i in templates) {
templates[i] = new JSDOC.JsPlate(templatesDir + templates[i]);
}
var processGroupTitle = function(symbol) {
var matches = symbol.desc.match(/\{@grouptitle ([^}]+)\}/),
groupTitle;
if (matches) {
groupTitle = matches[1];
symbol.desc = symbol.desc.replace(/\{@grouptitle ([^}]+)\}/, '');
}
return groupTitle;
};
var processInlineTags = function(str, param) {
if (!param)
param = {};
// <code>..</code> -> <pre>..</pre>
str = str.replace(/<(\/)*(code)>/g, '<$1pre>');
// <pre> -> <pre class="code">
str = str.replace(/<pre>/g, '<pre class="code">');
// {@link ...} -> html links
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
function(match, symbolName) {
return new Link().toSymbol(symbolName.replace(/[\^]/g, '-'));
}
);
// {@code ...} -> code blocks
str = str.replace(/\{@code[\s]([^}]+)\}/gi,
function(match, code) {
return '<tt>' + code + '</tt>';
}
);
// {@true ...} -> true if.. false otherwise..
str = str.replace(/\{@true[\s]([^}]+)\}/gi,
function(match, text) {
return '<tt>true</tt> ' + text + ', <tt>false</tt> otherwise';
}
);
var lineBreak = java.lang.System.getProperty('line.separator');
// Convert any type of lineBreak to the one we're using now:
str = str.replace(/(\r\n|\n|\r)/g, function(match, lineBreak) {
return lineBreak;
});
// Replace inline <code></code> with <tt></tt>
str = str.replace(/<code>[ \t]*([^\n\r]*?)[ \t]*<\/code>/g, function(match, content) {
return '<tt>' + content + '</tt>';
});
// Put code and pre tags on the same line as the content, as white-space: pre is set:
str = str.replace(/(<(?:code|pre)>)\s*([\u0000-\uffff]*?)\s*(<\/(?:code|pre)>)/g, function(match, open, content, close) {
// Filter out the first white space at the beginning of each line, since
// that stems from the space after the * in the comment and replace <code>
// with <pre>, to fix a IE problem where lighter.js does not receive
// linebreaks from code tags weven when white-space: pre is set.
return '<pre>' + content.replace(/(\r\n|\n|\r) /mg, function(match, lineBreak) {
return lineBreak;
}) + '</pre>';
});
// Empty lines -> Paragraphs
if (!param.stripParagraphs) {
if (param.wrapInParagraphs === undefined || param.wrapInParagraphs)
str = '<p>' + str.trim() + '</p>';
str = str.trim().replace(/(\r\n|\n|\r)\s*(\r\n|\n|\r)/g, function(match, lineBreak) {
return '</p>' + lineBreak + '<p>';
});
// Automatically put </p><p> at the end of sentences with line breaks.
// Match following </p> and <p> tags and swallow them. This happens when
// the original content contains these.
str = str.trim().replace(/([.:?!;])\s*(\r\n|\n|\r)(\s*)(<\/p>|<p>|)/g, function(match, before, lineBreak, whiteSpace, after) {
// Include following whiteSpace as well, since for code blocks they are relevant (e.g. indentation on new line)
return before + '</p>' + lineBreak + whiteSpace + '<p>';
});
// Filter out <p> tags within and around <code> and <pre> blocks again
str = str.replace(/((?:<p>\s*|)<(?:code|pre)[^>]*>[\u0000-\uffff]*<\/(?:code|pre)>(?:\s*<\/p>|))/g, function(match, code) {
return Utils.stripTags(code, 'p');
});
// Filter out empty paragraphs
str = str.replace(/<p><\/p>/g, '');
}
return str;
};
/** Build output for displaying function parameters. */
var makeSignature = function(params) {
if (!params) return '()';
var postString = '';
var first = true;
params = params.filter(
function($) {
return $.name.indexOf('.') == -1; // don't show config params in signature
}
);
var signature = '';
var postSignature = '';
for (var i = 0, l = params.length; i < l; i++) {
var param = params[i];
if (param.isOptional) {
signature += '[';
postSignature += ']';
}
if (i > 0)
signature += ', ';
signature += param.name;
}
return '(' + signature + postSignature + ')';
};
return {
_class: function(symbol) {
var param = {
name: symbol.alias,
description: processInlineTags(symbol.classDesc),
symbol: symbol,
constructors: symbol.getConstructors(),
properties: symbol.getProperties(),
staticProperties: symbol.getStaticProperties(),
methods: symbol.getOwnMethods(),
staticMethods: symbol.getStaticMethods(),
showConstructors: (!(/(Event|Style)/).test(symbol.alias)
&& !symbol.isNamespace && !symbol.ignore
&& symbol.desc.length),
inheritedClasses: symbol.getInheritedClasses()
};
param.inheritedLinks = [];
for (var i in param.inheritedClasses) {
param.inheritedLinks.push(new Link().toSymbol(i));
}
param.inheritedLinks = param.inheritedLinks.join(', ');
// Add the grouped operators to param:
var operators = symbol.getOperators();
if (operators.length) {
param.operators = {};
for (var i = 0, l = operators.length; i < l; i++) {
var operator = operators[i];
var name = operator.name.replace(/\^[0-9]$/, '');
if (!param.operators[name])
param.operators[name] = [];
param.operators[name].push(operator);
}
}
publish.curClass = {
name: symbol.alias,
index: {
'class': {
title: param.name,
text: param.description
}
}
};
publish.classes.push(publish.curClass);
return templates._class.process(param);
},
constructor: function(symbol) {
var param = {
symbol: symbol,
groupTitle: processGroupTitle(symbol),
id: symbol.getId(),
name: symbol.alias.replace(/(#|\^).+$/, ''),
description: processInlineTags(symbol.desc),
signature: makeSignature(symbol.params),
parameters: Render.parameters(symbol),
returns: Render.returns(symbol),
examples: Render.examples(symbol),
seeAlsos: Render.seeAlsos(symbol)
};
if (symbol.returns.length == 0) {
var type = symbol.memberOf ? symbol.memberOf : symbol.alias;
symbol.returns = [{type: type, desc: ''}];
}
publish.curClass.index[param.id] = {
title: param.name,
text: param.description
};
return templates.constructor.process(param);
},
method: function(symbol) {
var name = symbol.name.replace(/\^\d+$/, '');
if (symbol.isStatic)
name = symbol.memberOf + '.' + name;
var param = {
name: name,
groupTitle: processGroupTitle(symbol),
id: symbol.getId(),
signature: makeSignature(symbol.params),
description: processInlineTags(symbol.desc),
symbol: symbol
};
publish.curClass.index[param.id] = {
title: param.name,
text: param.description
};
return templates.method.process(param);
},
property: function(symbol) {
var name = symbol.name.replace(/\^\d+$/, '');
if (symbol.isStatic)
name = symbol.memberOf + '.' + name;
var param = {
name: name,
groupTitle: processGroupTitle(symbol),
id: symbol.getId(),
description: processInlineTags(symbol.desc),
symbol: symbol
};
publish.curClass.index[param.id] = {
title: param.name,
text: param.description
};
return templates.property.process(param);
},
parameters: function(symbol) {
return templates.parameters.process(symbol);
},
parameter: function(symbol) {
return templates.parameter.process({
name: symbol.name,
description: processInlineTags(symbol.desc,
{stripParagraphs: true}),
typeLink: new Link().toSymbol(symbol.type),
symbol: symbol
});
},
operators: function(symbols) {
var operatorCount = 0;
var title = [];
for (var i = 0, l = symbols.length; i < l; i++) {
var type = symbols[i].params[0].type;
type = type.charAt(0).toUpperCase() + type.slice(1);
title.push('<tt><b>' + Operator.getOperator(symbols[i]) + '</b> ' + type + '</tt>');
}
return templates.operators.process({
id: symbols[0].name.toLowerCase().replace(/\^[0-9]$/, ''),
title: title.join(', '),
operators: symbols
});
},
operator: function(symbol, id) {
var type = symbol.params[0].type;
return templates.operator.process({
id: id,
name: Operator.getOperator(symbol),
type: type.charAt(0).toUpperCase() + type.slice(1),
description: processInlineTags(symbol.desc),
symbol: symbol
});
},
returns: function(symbol) {
return templates.returns.process(symbol);
},
'return': function(symbol) {
return templates['return'].process({
name: symbol.name,
description: processInlineTags(symbol.desc,
{stripParagraphs: true}),
typeLink: new Link().toSymbol(symbol.type),
symbol: symbol
});
},
seeAlsos: function(symbol) {
return templates.seeAlsos.process(symbol);
},
examples: function(symbol) {
var out = [],
examples = symbol.example;
for (var i = 0, l = examples.length; i < l; i++) {
var example = examples[i],
lines = example.toString().split('\n'),
description = [];
// The description is the first commented lines:
while (/^[\/]{2}/.test(lines[0])) {
description.push(lines.shift().replace('// ', ''));
}
out.push(Render.example({
description: description.join(' ').trim(),
code: lines.join('\n').trim()
}));
}
return out.join('\n');
},
example: function(param) {
return templates.example.process(param);
},
html: function(content) {
return templates.html.process(content);
},
allClasses: function(symbol) {
return templates.allClasses.process(symbol);
},
menu: function(html) {
return templates.menu.process(html);
},
packagesjs: function() {
return templates.packagesjs.process(publish.classes);
}
};
};

View file

@ -0,0 +1,78 @@
JSDOC.Symbol.prototype.getId = function() {
var id = this.isConstructor
? [this.alias.replace(/([#].+$|[\^][0-9])/g, '').toLowerCase()
.replace(/[.]/, '-')]
: [this.name.toLowerCase().replace(/[\^][0-9]/g, '')];
if (this.params) {
for (var i = 0, l = this.params.length; i < l; i++) {
var param = this.params[i];
if (!param.isOptional)
id.push(param.name);
}
}
return id.join('-');
};
JSDOC.Symbol.prototype.getOwnMethods = function(param) {
if (!param)
param = {};
return this.methods.filter(function($) {
return $.memberOf == this.alias && !$.isNamespace
&& (param.operators ? $.isOperator : !$.isOperator)
&& (param.constructors ? $.isConstructor : !$.isConstructor)
&& (param.statics ? $.isStatic : !$.isStatic);
}, this);
};
JSDOC.Symbol.prototype.getOperators = function() {
return this.getOwnMethods({
operators: true
});
};
JSDOC.Symbol.prototype.getStaticMethods = function() {
return this.getOwnMethods({
statics: true
});
};
JSDOC.Symbol.prototype.getConstructors = function() {
return [this].concat(this.getOwnMethods({
constructors: true
}));
};
JSDOC.Symbol.prototype.getProperties = function(param) {
if (!param)
param = {};
return this.properties.filter(function($) {
return $.memberOf == this.alias && !$.isNamespace && !$.isConstructor
&& (param.statics ? $.isStatic : !$.isStatic);
}, this);
};
JSDOC.Symbol.prototype.getStaticProperties = function() {
return this.getProperties({
statics: true
});
};
JSDOC.Symbol.prototype.getInheritedClasses = function() {
var inheritedClasses = {};
var addInherited = function(symbol) {
if (symbol.memberOf != this.alias) {
var _class = inheritedClasses[symbol.memberOf];
if (!_class) {
_class = inheritedClasses[symbol.memberOf] = {
className: symbol.memberOf,
properties: [],
methods: []
};
}
_class[symbol.isa == "OBJECT" ? 'properties' : 'methods'].push(symbol);
}
};
this.properties.map(addInherited, this);
this.methods.map(addInherited, this);
return inheritedClasses;
};

View file

@ -0,0 +1,109 @@
var Utils = {
isaClass: function(symbol) {
return symbol.is('CONSTRUCTOR') || symbol.isNamespace;
},
stripTags: function(str, tag) {
var tag = tag || '.*?'; // Default: all tags
return str.replace(new RegExp('<' + tag + '>|</' + tag + '>', 'g'), '');
},
copyDirectory: function(sourceLocation, targetLocation) {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
var children = sourceLocation.list();
for (var i = 0; i < children.length; i++) {
Utils.copyDirectory(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
// Copy the file with FileChannels:
targetLocation.createNewFile();
var src = new java.io.FileInputStream(sourceLocation).getChannel();
var dst = new java.io.FileOutputStream(targetLocation).getChannel();
var amount = dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
},
deleteFiles: function(path) {
if (path.isDirectory()) {
var files = path.listFiles();
for (var i = 0, l = files.length; i < l; i++) {
Utils.deleteFiles(files[i]);
}
}
if (!path['delete']())
throw Error('Could not delete ' + path);
},
publishMenu: function() {
load(JSDOC.opt.t + 'classLayout.js');
function parseClassNames(classNames) {
var out = '';
for (var i = 0, l = classNames.length; i < l; i++) {
if (typeof classNames[i] == 'string') {
var name = classNames[i];
out += (name == 'ruler') ? getRuler() : getLink(name);
} else {
for (var j in classNames[i]) {
out += getHeading(j);
out += parseClassNames(classNames[i][j]);
}
}
}
return out;
}
function getLink(name) {
var link = name;
if (name.indexOf(':') > 0) {
var names = name.split(':');
name = names[0];
link = names[1];
}
return '<li><a href="' + link + '.html">' + name + '</a></li>\n';
}
function getRuler() {
return '<li><hr /></li>\n';
}
function getHeading(title) {
return '<li><h3>' + title + '</h3></li>\n';
}
var first = true,
out = '<ul class="package-classes">';
for (var i in classLayout) {
out += '<li' + (first ? ' class="first">' : '>');
out += '<h2>' + i + '</h2></li>\n';
out += parseClassNames(classLayout[i]);
first = false;
}
out += '</ul>';
var classesIndex = Render.menu(out);
IO.saveFile(publish.conf.packagesDir, 'packages.html', classesIndex);
},
makeSortby: function(attribute) {
return function(a, b) {
if (a[attribute] != undefined && b[attribute] != undefined) {
a = a[attribute].toLowerCase();
b = b[attribute].toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
};
},
/** Pull in the contents of an external file at the given path. */
include: function(path) {
var path = publish.conf.templateDir + path;
return IO.readFile(path);
}
};

View file

@ -1,4 +1,9 @@
/** Called automatically by JsDoc Toolkit. */
load(JSDOC.opt.t + 'Symbol.js');
load(JSDOC.opt.t + 'Utils.js');
load(JSDOC.opt.t + 'Operator.js');
load(JSDOC.opt.t + 'Render.js');
function publish(symbolSet) {
var renderMode = JSDOC.opt.D.renderMode;
publish.conf = { // trailing slash expected for dirs
@ -11,27 +16,7 @@ function publish(symbolSet) {
renderMode: renderMode
};
publish.conf.packagesDir = publish.conf.outDir + publish.conf.symbolsDir;
var templatesDir = publish.conf.templateDir + 'templates/';
publish.templates = {
_class: 'class.tmpl',
method: 'method.tmpl',
property: 'property.tmpl',
parameters: 'parameters.tmpl',
operators: 'operators.tmpl',
returns: 'returns.tmpl',
seeAlsos: 'see-alsos.tmpl',
example: 'example.tmpl',
constructor: 'constructor.tmpl',
html: 'html.tmpl',
allClasses: 'allClasses.tmpl',
menu: 'packages.tmpl'
};
for (var i in publish.templates) {
publish.templates[i] = new JSDOC.JsPlate(templatesDir +
publish.templates[i]);
}
if (renderMode == 'docs') {
// Copy over the static files
Utils.copyDirectory(
@ -84,11 +69,11 @@ function publish(symbolSet) {
}
Link.currentSymbol= symbol;
var html = publish.templates._class.process(symbol);
var html = Render._class(symbol);
var name = ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias)
+ publish.conf.ext;
if (renderMode == 'docs') {
html = publish.templates.html.process({
html = Render.html({
content: html,
title: symbol.alias
});
@ -97,298 +82,7 @@ function publish(symbolSet) {
}
if (renderMode == 'docs')
Utils.publishMenu();
}
var Operator = new function() {
var operators = {
add: '+', subtract: '-', multiply: '*', divide: '/', equals: '==',
modulo: '%'
};
var operatorNames = {
add: 'Addition', subtract: 'Subtraction', multiply: 'Multiplication',
divide: 'Division', equals: 'Comparison', modulo: 'Modulo'
};
return {
isOperator: function(symbol) {
// As a convention, only add non static bean properties to
// the documentation. static properties are all supposed to
// be uppercase and constants.
return symbol.params.length == 1 && !symbol.isStatic && (
/^(add|subtract|multiply|divide|modulo)(\^[0-9])*$/.test(symbol.name)
&& (symbol.operator != 'none')
) || ( // equals
symbol.name == 'equals'
&& symbol.returns.length && symbol.returns[0].type == 'boolean'
);
},
getOperator: function(symbol) {
return operators[symbol.name.replace(/\^[0-9]$/,'')];
}
};
};
var Utils = {
getSymbolId: function(symbol) {
var id = [symbol.name.toLowerCase().replace(/[\^][0-9]/g, '')];
if (symbol.params) {
for (var i = 0, l = symbol.params.length; i < l; i++) {
var param = symbol.params[i];
if (!param.isOptional)
id.push(param.name);
}
}
return id.join('-');
},
getConstructorId: function(symbol) {
var id = [symbol.alias.replace(/([#].+$|[\^][0-9])/g, '').toLowerCase()
.replace(/[.]/, '-')];
if (symbol.params) {
for (var i = 0, l = symbol.params.length; i < l; i++) {
var param = symbol.params[i];
if (!param.isOptional)
id.push(param.name);
}
}
return id.join('-');
},
isaClass: function(symbol) {
return symbol.is('CONSTRUCTOR') || symbol.isNamespace;
},
parseExamples: function(symbol) {
var out = [],
examples = symbol.example;
for (var i = 0, l = examples.length; i < l; i++) {
var example = examples[i],
lines = example.toString().split('\n'),
description = [];
// The description is the first commented lines:
while (/^[\/]{2}/.test(lines[0])) {
description.push(lines.shift().replace('// ', ''));
}
out.push(publish.templates.example.process({
description: description.join(' ').trim(),
code: lines.join('\n').trim()
}));
}
return out.join('\n');
},
stripTags: function(str, tag) {
var tag = tag || '.*?'; // Default: all tags
return str.replace(new RegExp('<' + tag + '>|</' + tag + '>', 'g'), '');
},
copyDirectory: function(sourceLocation, targetLocation) {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
var children = sourceLocation.list();
for (var i = 0; i < children.length; i++) {
Utils.copyDirectory(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
// Copy the file with FileChannels:
targetLocation.createNewFile();
var src = new java.io.FileInputStream(sourceLocation).getChannel();
var dst = new java.io.FileOutputStream(targetLocation).getChannel();
var amount = dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
},
deleteFiles: function(path) {
if (path.isDirectory()) {
var files = path.listFiles();
for (var i = 0, l = files.length; i < l; i++) {
Utils.deleteFiles(files[i]);
}
}
if (!path['delete']())
throw Error('Could not delete ' + path);
},
processGroupTitle: function(str, symbol) {
var groupTitle = str.match(/\{@grouptitle ([^}]+)\}/);
if (groupTitle) {
symbol.groupTitle = groupTitle[1];
str = str.replace(/\{@grouptitle ([^}]+)\}/, '');
}
return str;
},
publishMenu: function() {
load(JSDOC.opt.t + 'classLayout.js');
function parseClassNames(classNames) {
var out = '';
for (var i = 0, l = classNames.length; i < l; i++) {
if (typeof classNames[i] == 'string') {
var name = classNames[i];
out += (name == 'ruler') ? getRuler() : getLink(name);
} else {
for (var j in classNames[i]) {
out += getHeading(j);
out += parseClassNames(classNames[i][j]);
}
}
}
return out;
}
function getLink(name) {
var link = name;
if (name.indexOf(':') > 0) {
var names = name.split(':');
name = names[0];
link = names[1];
}
return '<li><a href="' + link + '.html">' + name + '</a></li>\n';
}
function getRuler() {
return '<li><hr /></li>\n';
}
function getHeading(title) {
return '<li><h3>' + title + '</h3></li>\n';
}
var first = true,
out = '<ul class="package-classes">';
for (var i in classLayout) {
out += '<li' + (first ? ' class="first">' : '>');
out += '<h2>' + i + '</h2></li>\n';
out += parseClassNames(classLayout[i]);
first = false;
}
out += '</ul>';
var classesIndex = publish.templates.menu.process(out);
IO.saveFile(publish.conf.packagesDir, 'packages.html', classesIndex);
},
makeSortby: function(attribute) {
return function(a, b) {
if (a[attribute] != undefined && b[attribute] != undefined) {
a = a[attribute].toLowerCase();
b = b[attribute].toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
};
},
/** Pull in the contents of an external file at the given path. */
include: function(path) {
var path = publish.conf.templateDir + path;
return IO.readFile(path);
},
processInlineTags: function(str, param) {
if (!param)
param = {};
// <code>..</code> -> <pre>..</pre>
str = str.replace(/<(\/)*(code)>/g, '<$1pre>');
// <pre> -> <pre class="code">
str = str.replace(/<pre>/g, '<pre class="code">');
// {@link ...} -> html links
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
function(match, symbolName) {
return new Link().toSymbol(symbolName.replace(/[\^]/g, '-'));
}
);
// {@code ...} -> code blocks
str = str.replace(/\{@code[\s]([^}]+)\}/gi,
function(match, code) {
return '<tt>' + code + '</tt>';
}
);
// {@true ...} -> true if.. false otherwise..
str = str.replace(/\{@true[\s]([^}]+)\}/gi,
function(match, text) {
return '<tt>true</tt> ' + text + ', <tt>false</tt> otherwise';
}
);
var lineBreak = java.lang.System.getProperty('line.separator');
// Convert any type of lineBreak to the one we're using now:
str = str.replace(/(\r\n|\n|\r)/g, function(match, lineBreak) {
return lineBreak;
});
// Replace inline <code></code> with <tt></tt>
str = str.replace(/<code>[ \t]*([^\n\r]*?)[ \t]*<\/code>/g, function(match, content) {
return '<tt>' + content + '</tt>';
});
// Put code and pre tags on the same line as the content, as white-space: pre is set:
str = str.replace(/(<(?:code|pre)>)\s*([\u0000-\uffff]*?)\s*(<\/(?:code|pre)>)/g, function(match, open, content, close) {
// Filter out the first white space at the beginning of each line, since
// that stems from the space after the * in the comment and replace <code>
// with <pre>, to fix a IE problem where lighter.js does not receive
// linebreaks from code tags weven when white-space: pre is set.
return '<pre>' + content.replace(/(\r\n|\n|\r) /mg, function(match, lineBreak) {
return lineBreak;
}) + '</pre>';
});
// Empty lines -> Paragraphs
if (!param.stripParagraphs) {
if (param.wrapInParagraphs === undefined || param.wrapInParagraphs)
str = '<p>' + str.trim() + '</p>';
str = str.trim().replace(/(\r\n|\n|\r)\s*(\r\n|\n|\r)/g, function(match, lineBreak) {
return '</p>' + lineBreak + '<p>';
});
// Automatically put </p><p> at the end of sentences with line breaks.
// Match following </p> and <p> tags and swallow them. This happens when
// the original content contains these.
str = str.trim().replace(/([.:?!;])\s*(\r\n|\n|\r)(\s*)(<\/p>|<p>|)/g, function(match, before, lineBreak, whiteSpace, after) {
// Include following whiteSpace as well, since for code blocks they are relevant (e.g. indentation on new line)
return before + '</p>' + lineBreak + whiteSpace + '<p>';
});
// Filter out <p> tags within and around <code> and <pre> blocks again
str = str.replace(/((?:<p>\s*|)<(?:code|pre)[^>]*>[\u0000-\uffff]*<\/(?:code|pre)>(?:\s*<\/p>|))/g, function(match, code) {
return Utils.stripTags(code, 'p');
});
// Filter out empty paragraphs
str = str.replace(/<p><\/p>/g, '');
}
return str;
},
/** Build output for displaying function parameters. */
makeSignature: function(params) {
if (!params) return '()';
var postString = '';
var first = true;
params = params.filter(
function($) {
return $.name.indexOf('.') == -1; // don't show config params in signature
}
);
var signature = '';
var postSignature = '';
for (var i = 0, l = params.length; i < l; i++) {
var param = params[i];
if (param.isOptional) {
signature += '[';
postSignature += ']';
}
if (i > 0)
signature += ', ';
signature += param.name;
}
return '(' + signature + postSignature + ')';
if (renderMode == 'templatedocs') {
IO.saveFile(publish.conf.outDir, 'packages.js', Render.packagesjs());
}
};
}

View file

@ -1,102 +1,57 @@
{!
data.classId = data.alias.toLowerCase();
var constructors = data.methods.filter(function($){return $.memberOf == data.alias && $.isConstructor});
var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace && !$.isStatic && !$.isConstructor});
var staticProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace && $.isStatic && !$.isConstructor});
var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace && !$.isStatic && !$.isOperator && !$.isConstructor});
var staticMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace && $.isStatic && !$.isOperator && !$.isConstructor});
var operatorMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace && !$.isStatic && !$.isConstructor && $.isOperator});
if (operatorMethods.length) {
var operators = {};
for (var i = 0, l = operatorMethods.length; i < l; i++) {
var operator = operatorMethods[i];
var name = operator.name.replace(/\^[0-9]$/, '');
if (!operators[name])
operators[name] = [];
operators[name].push(operator);
}
}
var inheritedProperties = data.properties.filter(function($) {return $.memberOf != data.alias});
var inheritedMethods = data.methods.filter(function($) {return $.memberOf != data.alias});
var inheritedClasses = {};
var inheritedClassLinks = [];
inheritedProperties.concat(inheritedMethods).map(function($) {
if (!inheritedClasses[$.memberOf]) {
inheritedClassLinks.push(new Link().toSymbol($.memberOf));
inheritedClasses[$.memberOf] = {
className: $.memberOf,
properties: [],
methods: []
};
}
});
for (var i = 0, l = inheritedProperties.length; i < l; i++) {
var symbol = inheritedProperties[i];
inheritedClasses[symbol.memberOf].properties.push(symbol);
}
for (var i = 0, l = inheritedMethods.length; i < l; i++) {
var symbol = inheritedMethods[i];
inheritedClasses[symbol.memberOf].methods.push(symbol);
}
!}
<div class="reference-class">
<if test="publish.conf.renderMode == 'docs'"><h1>{+data.alias+}</h1></if>
<if test="inheritedClassLinks.length">
<p> Extends {+ inheritedClassLinks.join(', ') +}</p>
<if test="publish.conf.renderMode == 'docs'"><h1>{+ data.name +}</h1></if>
<if test="data.inheritedLinks">
<p> Extends {+ data.inheritedLinks +}</p>
</if>
{+Utils.processInlineTags(data.classDesc)+}
{+ data.description +}
</div>
<if test="!/(Event|Style)/.test(data.alias) && !data.isNamespace && !data.ignore && data.desc.length">
<if test="data.showConstructors">
<!-- ============================== constructors ========================= -->
<div class="reference-members"><h2>Constructors</h2>
{+ publish.templates.constructor.process(data) +}
<for each="constructor" in="constructors">
{+ publish.templates.constructor.process(constructor) +}
<for each="constructor" in="data.constructors">
{+ Render.constructor(constructor) +}
</for>
</div>
</if>
<if test="defined(operators)">
<if test="defined(data.operators)">
<!-- ============================== properties ========================= -->
<div class="reference-members"><h2>Operators</h2>
<for each="member" in="operators">
{+ publish.templates.operators.process(member) +}
<for each="operator" in="data.operators">
{+ Render.operators(operator) +}
</for>
</div>
</if>
<if test="defined(ownProperties) && ownProperties.length">
<if test="defined(data.properties) && data.properties.length">
<div class="reference-members"><h2>Properties</h2>
<for each="member" in="ownProperties">
{+ publish.templates.property.process(member) +}
<for each="member" in="data.properties">
{+ Render.property(member) +}
</for>
</div>
</if>
<if test="defined(ownMethods) && ownMethods.length">
<if test="defined(data.methods) && data.methods.length">
<!-- ============================== methods ================================ -->
<div class="reference-members"><h2>Functions</h2>
<for each="member" in="ownMethods">
{+ publish.templates.method.process(member) +}
<for each="member" in="data.methods">
{+ Render.method(member) +}
</for>
</div>
</if>
<if test="defined(staticMethods) && staticMethods.length">
<if test="defined(data.staticMethods) && data.staticMethods.length">
<div class="reference-members"><h2>Static Functions</h2>
<for each="member" in="staticMethods">
{+ publish.templates.method.process(member) +}
<for each="member" in="data.staticMethods">
{+ Render.method(member) +}
</for>
</div>
</if>
<for each="inheritedClass" in="inheritedClasses">
<for each="inheritedClass" in="data.inheritedClasses">
<if test="inheritedClass.properties.length">
<!-- =========================== inherited properties ====================== -->
<div class="reference-members"><h2>Properties inherited from {+ new Link().toSymbol(inheritedClass.className) +}</h2>
<for each="member" in="inheritedClass.properties">
{+ publish.templates.property.process(member) +}
{+ Render.property(member, true) +}
</for>
</div>
</if>
@ -104,7 +59,7 @@
<!-- =========================== inherited methods ========================= -->
<div class="reference-members"><h2>Functions inherited from {+ new Link().toSymbol(inheritedClass.className) +}</h2>
<for each="member" in="inheritedClass.methods">
{+ publish.templates.method.process(member) +}
{+ Render.method(member, true) +}
</for>
</div>
</if>

View file

@ -1,31 +1,24 @@
{!
var constructorId = Utils.getConstructorId(data);
var name = data.alias.replace(/(#|\^).+$/, '');
data.desc = Utils.processGroupTitle(data.desc, data);
if (data.returns.length == 0)
data.returns = [{type: data.memberOf ? data.memberOf : data.alias, desc: ''}];
!}
<if test="defined(data.groupTitle)"><h3>{+data.groupTitle+}</h3></if>
<div id="{+constructorId+}" class="member">
<div id="{+constructorId+}-link" class="member-link">
<a name="{+constructorId+}" href="#" onClick="return toggleMember('{+constructorId+}', false);"><tt><b>{+ name +}</b>{+ Utils.makeSignature(data.params) +}</tt></a>
<if test="defined(data.groupTitle)"><h3>{+data.symbol.groupTitle+}</h3></if>
<div id="{+ data.id +}" class="member">
<div id="{+ data.id +}-link" class="member-link">
<a name="{+ data.id +}" href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b>{+ data.signature +}</tt></a>
</div>
<div id="{+constructorId+}-description" class="member-description hidden">
<div id="{+ data.id +}-description" class="member-description hidden">
<div class="member-header">
<div class="member-title">
<div class="member-link">
<a href="#" onClick="return toggleMember('{+constructorId+}', false);"><tt><b>{+ name +}</b>{+ Utils.makeSignature(data.params) +}</tt></a>
<a href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b>{+ data.signature +}</tt></a>
</div>
</div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+constructorId+}', false);"></div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ data.id +}', false);"></div>
<div class="clear"></div>
</div>
<div class="member-text">{+Utils.processInlineTags(data.desc)+}
{+ publish.templates.parameters.process(data) +}
{+ publish.templates.returns.process(data) +}
{+ Utils.parseExamples(data) +}
{+ publish.templates.seeAlsos.process(data) +}
<div class="member-text">
{+ data.description +}
{+ data.parameters +}
{+ data.returns +}
{+ data.examples +}
{+ data.seeAlsos +}
</div>
</div>
</div>

View file

@ -1,33 +1,26 @@
{!
data.desc = Utils.processGroupTitle(data.desc, data);
var memberId = Utils.getSymbolId(data);
var functionTitle = '<b>' + data.name.replace(/\^\d+$/, '') + '</b>' + Utils.makeSignature(data.params);
if (data.isStatic)
functionTitle = '<b>' + data.memberOf + '.</b>' + functionTitle;
!}
<if test="defined(data.groupTitle)">
<h3>{+data.groupTitle+}</h3>
<h3>{+data.groupTitle+}</h3>
</if>
<div id="{+ memberId +}" class="member">
<div id="{+ memberId +}-link" class="member-link">
<a name="{+ memberId +}" href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ functionTitle +}</tt></a>
<div id="{+ data.id +}" class="member">
<div id="{+ data.id +}-link" class="member-link">
<a name="{+ data.id +}" href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b>{+ data.signature +}</tt></a>
</div>
<div id="{+ memberId +}-description" class="member-description hidden">
<div id="{+ data.id +}-description" class="member-description hidden">
<div class="member-header">
<div class="member-title">
<div class="member-link">
<a href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ functionTitle +}</tt></a>
<a href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b>{+ data.signature +}</tt></a>
</div>
</div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ memberId +}', false);"></div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ data.id +}', false);"></div>
<div class="clear"></div>
</div>
<div class="member-text">
{+ Utils.processInlineTags(data.desc) +}
{+ publish.templates.parameters.process(data) +}
{+ publish.templates.returns.process(data) +}
{+ publish.templates.seeAlsos.process(data) +}
{+ Utils.parseExamples(data) +}
{+ data.description +}
{+ Render.parameters(data.symbol) +}
{+ Render.returns(data.symbol) +}
{+ Render.seeAlsos(data.symbol) +}
{+ Render.examples(data.symbol) +}
</div>
</div>
</div>

View file

@ -0,0 +1,17 @@
<div class="member-header">
<div class="member-title">
<div class="member-link">
<a href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b> {+ data.type +}</tt></a>
</div>
</div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ data.id +}', false);"></div>
<div class="clear"></div>
</div>
<if test="data.symbol.type">
<div class="member-text">
{+ data.description +}
{+ Render.returns(data.symbol) +}
{+ Render.seeAlsos(data.symbol) +}
{+ Render.examples(data.symbol) +}
</div>
</if>

View file

@ -1,49 +1,10 @@
{!
var operatorCount = 0;
var operatorTitle = [];
for (var i = 0, l = data.length; i < l; i++) {
var type = data[i].params[0].type;
type = type.charAt(0).toUpperCase() + type.slice(1);
operatorTitle.push('<tt><b>' + Operator.getOperator(data[i]) + '</b> ' + type + '</tt>');
}
operatorTitle = operatorTitle.join(', ');
!}
<for each="operator" in="data">
{!
var type = operator.params[0].type;
type = type.charAt(0).toUpperCase() + type.slice(1);
var functionTitle = '<b>' + Operator.getOperator(operator) + '</b> ' + type;
!}
<if test="operatorCount == 0">
{!
var memberId = operator.name.toLowerCase().replace(/\^[0-9]$/,'');
!}
<div id="{+ memberId +}" class="member">
<div id="{+ memberId +}-link" class="member-link">
<a name="{+ memberId +}" href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ operatorTitle +}</tt></a>
</div>
<div id="{+ memberId +}-description" class="member-description hidden">
</if>
<div class="member-header">
<div class="member-title">
<div class="member-link">
<a href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ functionTitle +}</tt></a>
<div id="{+ data.id +}" class="member">
<div id="{+ data.id +}-link" class="member-link">
<a name="{+ data.id +}" href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt>{+ data.title +}</tt></a>
</div>
<div id="{+ data.id +}-description" class="member-description hidden">
<for each="operator" in="data.operators">
{+ Render.operator(operator, data.id) +}
</for>
</div>
</div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ memberId +}', false);"></div>
<div class="clear"></div>
</div>
<if test="operator.type">
<div class="member-text">
{+ Utils.processInlineTags(operator.desc) +}
{+ publish.templates.returns.process(operator) +}
{+ publish.templates.seeAlsos.process(operator) +}
{+ Utils.parseExamples(operator) +}
</div>
</if>
<if test="operatorCount == data.length - 1">
</div>
</div>
</if>
{! operatorCount++; !}
</for>

View file

@ -0,0 +1 @@
createPackage("Paper", {+ JSON.stringify(data) +});

View file

@ -0,0 +1,6 @@
<li>
<tt>{+ data.name +}:</tt>
{+ data.typeLink +}
<if test="data.description">&mdash;&nbsp;{+ data.description +}</if>
<if test="data.symbol.isOptional">&mdash;&nbsp;optional</if><if test="data.symbol.defaultValue">, default: <tt>{+data.symbol.defaultValue+}</tt></if>
</li>

View file

@ -1,12 +1,7 @@
<if test="data.params.length">
<ul><b>Parameters:</b>
<for each="parameter" in="data.params">
<li>
<tt>{+ parameter.name +}:</tt>
{+ new Link().toSymbol(parameter.type) +}
<if test="parameter.desc">&mdash;&nbsp;{+Utils.processInlineTags(parameter.desc, {stripParagraphs: true})+}</if>
<if test="parameter.isOptional">&mdash;&nbsp;optional</if><if test="parameter.defaultValue">, default: <tt>{+parameter.defaultValue+}</tt></if>
</li>
</for>
</ul>
<ul><b>Parameters:</b>
<for each="parameter" in="data.params">
{+ Render.parameter(parameter) +}
</for>
</ul>
</if>

View file

@ -1,49 +1,40 @@
{!
data.desc = Utils.processGroupTitle(data.desc, data);
var memberId = Utils.getSymbolId(data);
var title = '<b>' + data.name.replace(/\^\d+$/, '') + '</b>';
if (data.isStatic)
title = '<b>' + data.memberOf + '.</b>' + title;
!}
<if test="defined(data.groupTitle)">
<h3>{+data.groupTitle+}</h3>
<h3>{+ data.groupTitle +}</h3>
</if>
<div id="{+ memberId +}" class="member">
<div id="{+ memberId +}-link" class="member-link">
<a name="{+ memberId +}" href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ title +}</tt></a>
<div id="{+ data.id +}" class="member">
<div id="{+ data.id +}-link" class="member-link">
<a name="{+ data.id +}" href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b></tt></a>
</div>
<div id="{+ memberId +}-description" class="member-description hidden">
<div id="{+ data.id +}-description" class="member-description hidden">
<div class="member-header">
<div class="member-title">
<div class="member-link">
<a href="#" onClick="return toggleMember('{+ memberId +}', false);"><tt>{+ title +}</tt></a>
<a href="#" onClick="return toggleMember('{+ data.id +}', false);"><tt><b>{+ data.name +}</b></tt></a>
</div>
</div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ memberId +}', false);"></div>
<div class="member-close"><input type="button" value="Close" onClick="toggleMember('{+ data.id +}', false);"></div>
<div class="clear"></div>
</div>
<if test="data.type">
<if test="data.symbol.type">
<div class="member-text">
{+ Utils.processInlineTags(data.desc) +}
{+ data.description +}
<if test="data.readOnly">
<p>Read only.</p>
</if>
<if test="data.defaultValue">
<if test="data.symbol.defaultValue">
<ul><b>Default:</b>
<li>
<tt>{+data.defaultValue+}</tt>
<tt>{+ data.symbol.defaultValue +}</tt>
</li>
</ul>
</if>
<ul><b>Type:</b>
<li>
<tt>{+new Link().toSymbol(data.type)+}</tt>
<tt>{+new Link().toSymbol(data.symbol.type)+}</tt>
</li>
</ul>
{+ publish.templates.seeAlsos.process(data) +}
{+ Utils.parseExamples(data) +}
{+ Render.seeAlsos(data.symbol) +}
{+ Render.examples(data.symbol) +}
</div>
</if>
</div>

View file

@ -0,0 +1,3 @@
<li>
<tt><if test="data.typeLink">{+ data.typeLink +}</tt><if test="data.description">&nbsp;&mdash;&nbsp;</if></if>{+ data.description +}
</li>

View file

@ -1,9 +1,7 @@
<if test="data.returns.length">
<ul><b>Returns:</b>
<for each="item" in="data.returns">
<li>
<tt><if test="defined(item.type)">{+ new Link().toSymbol(item.type) +}</tt><if test="item.desc">&nbsp;&mdash;&nbsp;</if></if>{+Utils.processInlineTags(item.desc, { stripParagraphs: true })+}
</li>
<for each="symbol" in="data.returns">
{+ Render['return'](symbol) +}
</for>
</ul>
</if>

View file

@ -0,0 +1,7 @@
<if test="data.see.length">
<p><b>See also:</b>
<for each="item" in="data.see">
<tt>{+ new Link().toSymbol(item) +}</tt>
</for>
</p>
</if>