visallo-jsdoc-template
Advanced tools
Comparing version
{ | ||
"name": "visallo-jsdoc-template", | ||
"version": "1.0.0", | ||
"version": "1.1.1", | ||
"description": "Visallo JSDoc 3 theme", | ||
@@ -16,4 +16,4 @@ "main": "publish.js", | ||
"devDependencies": { | ||
"browser-sync": "latest", | ||
"jsdoc": "latest", | ||
"browser-sync": "latest", | ||
"watch-run": "latest" | ||
@@ -29,3 +29,6 @@ }, | ||
"template" | ||
] | ||
], | ||
"dependencies": { | ||
"escodegen": "^1.8.1" | ||
} | ||
} |
@@ -0,1 +1,65 @@ | ||
var escodegen = require('escodegen') | ||
exports.astNodeVisitor = { | ||
visitNode: function(node, e, parser, currentSourceName) { | ||
// Find all registry.documentExtensionPoint calls and extract the | ||
// description, validator function automatically | ||
if (node.type === 'CallExpression' && | ||
node.callee.property && | ||
node.callee.property.name === 'documentExtensionPoint') { | ||
const { arguments } = node; | ||
const point = arguments[0].value; | ||
const description = arguments[1].value; | ||
const validatorFn = getValidatorFn(arguments[2]) | ||
const optionsOrUrl = arguments[3]; | ||
var tutorial = null; | ||
if (!point) { | ||
throw new Error('Requires literal extension point name: ' + currentSourceName + ': ' + node.loc.start.line); | ||
} | ||
if (!description) { | ||
throw new Error('Description parameter (2) must be single string: ' + currentSourceName + ': ' + node.loc.start.line); | ||
} | ||
if (optionsOrUrl) { | ||
if (optionsOrUrl.value) { | ||
tutorial = optionsOrUrl.value; | ||
} else if (optionsOrUrl.type === 'ObjectExpression' && optionsOrUrl.properties) { | ||
optionsOrUrl.properties.forEach(p => { | ||
if (p.key && p.key.name === 'url') { | ||
if (p.value && p.value.value) { | ||
tutorial = p.value.value; | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
if (tutorial) { | ||
tutorial = `@tutorial ${tutorial}` | ||
} else { | ||
tutorial = '' | ||
} | ||
var prefix = ''; | ||
if (node.leadingComments && node.leadingComments.length) { | ||
prefix = node.leadingComments.map(c => c.value).join('') | ||
} | ||
e.event = 'jsdocCommentFound'; | ||
e.comment = `/** | ||
${prefix} | ||
* @classdesc ${description} | ||
* @extensionpoint ${point} | ||
* ${tutorial} | ||
* @validator | ||
* ${validatorFn || '// Unable to interpret validator function'} | ||
*/`; | ||
e.filename = currentSourceName; | ||
e.lineno = node.loc.start.line; | ||
} | ||
} | ||
}; | ||
exports.defineTags = function(dictionary) { | ||
@@ -26,9 +90,24 @@ dictionary.defineTag("flight", { | ||
mustHaveValue: true, | ||
canHaveType: true, | ||
mustNotHaveDescription: true, | ||
canHaveType: false, | ||
canHaveName: true, | ||
onTagged: function(doclet, tag) { | ||
doclet.extensionpoints = doclet.extensionpoints || []; | ||
doclet.extensionpoints.push(tag.value); | ||
doclet.kind = 'class' | ||
doclet.isExtension = true | ||
if (!doclet.name) { | ||
doclet.name = tag.value.name | ||
} | ||
(doclet.see || (doclet.see = [])).push('module:registry') | ||
//doclet.extensionpoints = doclet.extensionpoints || []; | ||
//doclet.extensionpoints.push(tag.value); | ||
} | ||
}); | ||
dictionary.defineTag("validator", { | ||
keepsWhitespace: true, | ||
removesIndent: true, | ||
mustHaveValue: true, | ||
onTagged: function(doclet, tag) { | ||
doclet.validator = tag.value | ||
} | ||
}), | ||
dictionary.defineTag("attr", { | ||
@@ -45,1 +124,18 @@ mustHaveValue: true, | ||
function getValidatorFn(validator) { | ||
var validatorFn; | ||
// Rename function name | ||
if (!validator.id) { | ||
validator.id = {}; | ||
} | ||
validator.id.name = 'extensionValidator' | ||
try { | ||
validatorFn = escodegen.generate(validator); | ||
} catch (e) { | ||
console.error('Unable to generate code from AST' + e) | ||
} | ||
return validatorFn; | ||
} |
103
publish.js
@@ -139,2 +139,6 @@ /*global env: true */ | ||
var params = f.params ? addParamAttributes(f.params) : []; | ||
if (f.isExtension) { | ||
params = [`"${f.longname}"`, 'config'] | ||
//params.splice(0, 0, `"${f.longname}"`) | ||
} | ||
f.signature = util.format( '%s(%s)', (f.signature || ''), params.join(', ') ); | ||
@@ -228,2 +232,21 @@ } | ||
function generateList(type, title, docs, filename, resolveLinks) { | ||
resolveLinks = resolveLinks === false ? false : true; | ||
var docData = { | ||
type: type, | ||
title: title, | ||
docs: docs | ||
}; | ||
var outpath = path.join(outdir, filename), | ||
html = view.render('containerlist.tmpl', docData); | ||
if (resolveLinks) { | ||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a> | ||
} | ||
fs.writeFileSync(outpath, html, 'utf8'); | ||
} | ||
function generateSourceFiles(sourceFiles, encoding) { | ||
@@ -344,3 +367,7 @@ encoding = encoding || 'utf8'; | ||
if (itemsNav !== '') { | ||
nav += '<h3>' + itemHeading + '</h3><ul>' + itemsNav + '</ul>'; | ||
if (itemHeading === 'Extension Points') { | ||
nav += '<h3>' + linkto('extensionpoints', itemHeading) + '</h3><ul>' + itemsNav + '</ul>'; | ||
} else { | ||
nav += '<h3>' + itemHeading + '</h3><ul>' + itemsNav + '</ul>'; | ||
} | ||
} | ||
@@ -381,3 +408,26 @@ } | ||
nav += buildMemberNav(members.classes, 'Classes', seen, linkto); | ||
var globals = members.globals.filter(g => !g.isExtension); | ||
if (globals.length) { | ||
var globalNav = ''; | ||
globals.forEach(function(g) { | ||
if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) { | ||
globalNav += '<li>' + linkto(g.longname, g.name) + '</li>'; | ||
} | ||
seen[g.longname] = true; | ||
}); | ||
if (!globalNav) { | ||
// turn the heading into a link so you can actually get to the global page | ||
nav += '<h3>' + linkto('global', 'Global') + '</h3>'; | ||
} | ||
else { | ||
nav += '<h3>Global</h3><ul>' + globalNav + '</ul>'; | ||
} | ||
} | ||
// CLASSES | ||
nav += buildMemberNav(members.classes.filter(c => !c.isExtension), 'Classes', seen, linkto); | ||
// MODULES | ||
nav += buildMemberNav(members.modules.sort(function(a, b) { | ||
@@ -389,2 +439,4 @@ var a1 = a.name, b1 = b.name | ||
}), 'Modules', {}, linkto); | ||
// SERVICES | ||
nav += buildMemberNav(members.modules.filter(function(i) { | ||
@@ -398,5 +450,12 @@ return /^services\//.test(i.name) | ||
}), 'Services', {}, linkto); | ||
// EVENTS | ||
nav += buildMemberNav(members.events.filter(function(event) { | ||
return event.scope && event.scope === 'global' | ||
}), 'Events', seen, linkto); | ||
// EXTENSION POINTS | ||
var extensionPoints = find({ kind: 'class', isExtension: true }) | ||
nav += buildMemberNav(extensionPoints, 'Extension Points', {}, n => linkto(n, n)); | ||
//nav += buildMemberNav(members.namespaces, 'Namespaces', seen, linkto); | ||
@@ -410,21 +469,2 @@ //nav += buildMemberNav(members.mixins, 'Mixins', seen, linkto); | ||
if (members.globals.length) { | ||
var globalNav = ''; | ||
members.globals.forEach(function(g) { | ||
if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) { | ||
globalNav += '<li>' + linkto(g.longname, g.name) + '</li>'; | ||
} | ||
seen[g.longname] = true; | ||
}); | ||
if (!globalNav) { | ||
// turn the heading into a link so you can actually get to the global page | ||
nav += '<h3>' + linkto('global', 'Global') + '</h3>'; | ||
} | ||
else { | ||
nav += '<h3>Global</h3><ul>' + globalNav + '</ul>'; | ||
} | ||
} | ||
return nav; | ||
@@ -456,2 +496,5 @@ } | ||
var extensionPointsUrl = helper.getUniqueFilename('extensionPoints'); | ||
helper.registerLink('extensionpoints', extensionPointsUrl); | ||
// set up templating | ||
@@ -491,2 +534,8 @@ view.layout = conf.default.layoutFile ? | ||
} | ||
if (doclet.validator) { | ||
doclet.validator = { | ||
code: doclet.validator, | ||
caption: '' | ||
} | ||
} | ||
if (doclet.see) { | ||
@@ -639,2 +688,7 @@ doclet.see.forEach(function(seeItem, i) { | ||
var extensionPoints = find({isExtension:true}) | ||
if (extensionPoints.length) { | ||
generateList('', 'Extension Points', extensionPoints, extensionPointsUrl); | ||
} | ||
// index page displays information from package.json and lists files | ||
@@ -664,3 +718,3 @@ var files = find({kind: 'file'}); | ||
var myClasses = helper.find(classes, {longname: longname}); | ||
var myClasses = helper.find(classes, {longname: longname, isExtension: false}); | ||
if (myClasses.length) { | ||
@@ -670,2 +724,7 @@ generate('Class', myClasses[0].name, myClasses, helper.longnameToUrl[longname]); | ||
var myExtensions = helper.find(classes, {longname: longname, isExtension: true}); | ||
if (myExtensions.length) { | ||
generate('Class', longname, myExtensions, helper.longnameToUrl[longname]); | ||
} | ||
var myNamespaces = helper.find(namespaces, {longname: longname}); | ||
@@ -672,0 +731,0 @@ if (myNamespaces.length) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
266839
40.88%47
4.44%4099
3.51%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added