forked from visjs/vis-timeline
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add template for document generation with 'jsdoc'. (#3497)
* Add template for document generation with 'jsdoc'. In essence, it defines the subdirectory `docs` as a `jsdoc` template. Benefits: - allows the usage of partials, in order to DRY common parts of the html files. - makes available the jsdoc-comments, for addition into the documentation. - enables extraction of data from the source code. For example, the list of edge endpoints `['arrow', 'bar', 'circle']` can now be extracted from the source and inserted into the documentation on generation. In this initial version, the only file that has been changed is `docs/data/dataset.html`. In here, partials have been added to illustrate how common page elements can be DRY'd. The template has been set up in such a way, that resource files will be copied and that html files can pass through unchanged if no special template tags (`<?js...?>`) are used. This allows for a gradual transition of the html files to templates. **Usage:** `gulp docs` - The result files are placed in subdirectory `gen/docs/`. **NOTE:** The release procedure will have to be adjusted by adding this gulp command. The docs-files will then have to be taken from `gen/docs`. * Edits to docs/README * Adjusted layout of README.md * Further edits to README.md * Removed pre tags again in README.md - don't work in code block * Linted the gulpfile * Added proof of concept for docs generation from source
- Loading branch information
1 parent
f5c42b8
commit d7efc57
Showing
8 changed files
with
479 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ npm-debug.log | |
# temporary files | ||
.*.sw[op] | ||
.commits.tmp | ||
gen/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
# Command line usage example | ||
|
||
``` | ||
jsdoc -c jsdoc.json -r -t docs -d gen/docs lib | ||
``` | ||
|
||
- `-c`: use this config file for `jsdoc` | ||
- `-r`: Recurse into subdirectories of the specified source directories | ||
- `-t`: Use template in path `docs` | ||
- `-d`: Generated html files put in `gen/docs` | ||
- Source files to parse are taken from directory `lib` | ||
|
||
|
||
## Notes | ||
|
||
The template generation is set up so that: | ||
|
||
- Files ending in `.tmpl` are skipped | ||
- All non-html files are plain copied | ||
- html-files *can* contain `<?js ?>` tags, but this is not required | ||
|
||
|
||
## Intention | ||
|
||
The `docs` directory is treated as a `jsdoc` template, in which the html-files are the template files. This allows for a gradual adaptation of the html-files to templates; unchanged html-files will pass through `jsdoc` unchanged. | ||
|
||
The added value of using `jsdoc` for documentation generation, is that the complete documentation information, as collected by `jsdoc` from the source, is available for usage. This way, it's possible to insert technical notes from the source code into the documentation. | ||
|
||
---- | ||
|
||
# Usage of and Notes on Source Code | ||
|
||
This section contains notes on the usage of `jsdoc` functionality, to aid with the handling of its generated data. | ||
|
||
|
||
## Parameters of `publish()` | ||
|
||
### Parameter `taffyData` | ||
|
||
A table containing *all* data collected from the source code, related to jsdoc generation. See below for more info and example outputs. | ||
|
||
### Parameter `opt` | ||
|
||
Example of `opt` variable: | ||
|
||
```js | ||
{ | ||
"_":["../github/vis/lib/network/"], | ||
"configure":"jsdoc.json", | ||
"recurse":true, | ||
"template":"/home/wim/projects/jsdoc/default", | ||
"destination":"./out/", | ||
"encoding":"utf8" | ||
} | ||
``` | ||
|
||
### Parameter `tutorial` | ||
|
||
This does not appear to be of use for the generation of `vis.js` documentation. | ||
|
||
Example of `tutorial` variable: | ||
|
||
```js | ||
{ | ||
"longname":"", | ||
"name":"", | ||
"title":"", | ||
"content":"", | ||
"parent":null, | ||
"children":[], | ||
"_tutorials":{} | ||
} | ||
``` | ||
|
||
## Global variable `env` | ||
|
||
This contains addition info for the current execution of `jsdoc`. Example of `env` variable: | ||
|
||
```js | ||
{ | ||
"run":{"start":"2017-09-16T05:06:45.621Z","finish":null}, | ||
"args":["-c","jsdoc.json","-r","-t","default","../github/vis/lib/network/"], | ||
"conf":{ | ||
"plugins":["/usr/lib/node_modules/jsdoc/plugins/markdown.js"], | ||
"recurseDepth":10, | ||
"source":{"includePattern":".+\\.js(doc|x)?$","excludePattern":""}, | ||
"sourceType":"module", | ||
"tags":{"allowUnknownTags":true,"dictionaries":["jsdoc","closure"]}, | ||
"templates":{"monospaceLinks":false,"cleverLinks":false} | ||
}, | ||
"dirname":"/usr/lib/node_modules/jsdoc", | ||
"pwd":"/home/wim/projects/jsdoc", | ||
"opts":{ <<same as parameter 'opt' above>> }, | ||
"sourceFiles":[ <<list of full path names of all js-source files used as input>> ], | ||
"version":{"number":"3.5.4","revision":"Fri, 04 Aug 2017 22:05:27 GMT"} | ||
} | ||
``` | ||
|
||
|
||
## taffyData | ||
|
||
This is a parameter to `publish()`. It's a table containing *all* data collected from the source code, related to jsdoc generation. | ||
|
||
I can't find any way to return a list of fields for the data items in the taffyDB docs, therefore below there are examples of items, for better understanding of usage. | ||
|
||
Example usage: | ||
|
||
```js | ||
var data = taffyData; | ||
var tmp = data().filter({name:'Label'}).get(); | ||
``` | ||
|
||
Returns an array with all items with `name === 'Label'`. Example output of one of these items, for a class: | ||
|
||
*In these examples, block comment endings are redacted to ' * /'* | ||
|
||
```js | ||
{ | ||
"comment":"/**\n * A Label to be used for Nodes or Edges.\n * /", | ||
"meta":{ | ||
"range":[3770,41303], | ||
"filename":"Label.js", | ||
"lineno":167, | ||
"columnno":0, | ||
"path":"/home/wim/projects/github/vis/lib/network/modules/components/shared", | ||
"code":{ | ||
"id":"astnode100065034", | ||
"name":"Label", | ||
"type":"ClassDeclaration", | ||
"paramnames":["body","options","edgelabel"] | ||
} | ||
}, | ||
"classdesc":" | ||
A Label to be used for Nodes or Edges. | ||
", | ||
"name":"Label", | ||
"longname":"Label", | ||
"kind":"class", | ||
"scope":"global", | ||
"params":[ | ||
{"type":{"names":["Object"]},"name":"body"}, | ||
{"type":{"names":["Object"]},"name":"options"}, | ||
{"type":{"names":["boolean"]},"optional":true,"defaultvalue":false,"name":"edgelabel"} | ||
], | ||
"___id":"T000002R005289", | ||
"___s":true | ||
} | ||
``` | ||
|
||
Example of item for an instance method: | ||
|
||
```js | ||
var tmp = data().filter({name:'_drawText'}).get(); | ||
``` | ||
|
||
Full output returned: | ||
|
||
```js | ||
[{ | ||
"comment":"/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {boolean} selected\n * @param {boolean} hover\n * @param {number} x\n * @param {number} y\n * @param {string} [baseline='middle']\n * @private\n * /", | ||
"meta":{ | ||
"range":[20060,22269], | ||
"filename":"Label.js", | ||
"lineno":652, | ||
"columnno":2, | ||
"path":"/home/wim/projects/github/vis/lib/network/modules/components/shared", | ||
"code":{ | ||
"id":"astnode100066427", | ||
"name":"Label#_drawText", | ||
"type":"MethodDefinition", | ||
"paramnames":["ctx","selected","hover","x","y","baseline"] | ||
}, | ||
"vars":{"":null} | ||
}, | ||
"params":[ | ||
{"type":{"names":["CanvasRenderingContext2D"]},"name":"ctx"}, | ||
{"type":{"names":["boolean"]},"name":"selected"}, | ||
{"type":{"names":["boolean"]},"name":"hover"}, | ||
{"type":{"names":["number"]},"name":"x"}, | ||
{"type":{"names":["number"]},"name":"y"}, | ||
{"type":{"names":["string"]},"optional":true,"defaultvalue":"'middle'","name":"baseline"} | ||
], | ||
"access":"private", | ||
"name":"_drawText", | ||
"longname":"Label#_drawText", | ||
"kind":"function", | ||
"memberof":"Label", | ||
"scope":"instance", | ||
"___id":"T000002R005388", | ||
"___s":true | ||
}] | ||
``` | ||
|
||
## `jsdoc` template rendering | ||
|
||
See `function createRenderer(fromDir, data)` in code for usage. | ||
|
||
There are two calls for rendering templates: | ||
|
||
- `var html = renderer.render(inFile, docData);` | ||
- `var html = renderer.partial(inFile, docData);` | ||
|
||
The difference is that `render()` will use a default layout template, if present, which will encapsulate all html. This can be set by: | ||
|
||
```js | ||
renderer.layout = 'path/to/default/layout.tmpl'; | ||
``` | ||
|
||
Parameter `docData` is a hash which is used to pass parameters into a template. The standard way of using this appear to be: | ||
|
||
``` | ||
<?js | ||
var data = obj; // Whatever docData is | ||
var self = this; | ||
?> | ||
``` | ||
|
||
But it also appear to be possible to use the elements of docData directly: | ||
|
||
```js | ||
var docData = { | ||
myTitle: 'Hello, pussycat!' | ||
}; | ||
``` | ||
|
||
Within the template: | ||
|
||
``` | ||
<?js= myTitle ?> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/*============================================================================== | ||
Demo template, showing how documentation can be generated for `vis.js`. | ||
------------------------------------------------------------------------------ | ||
## Notes on `jsdoc` code | ||
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness | ||
// doesn't try to hand them out later | ||
indexUrl = helper.getUniqueFilename('index'); | ||
// don't call registerLink() on this one! 'index' is also a valid longname | ||
globalUrl = helper.getUniqueFilename('global'); | ||
helper.registerLink('global', globalUrl); | ||
============================================================================== */ | ||
'use strict'; | ||
//var taffy = require('taffydb').taffy; // not really required here, left for reference | ||
|
||
// Internal modules of `jsdoc` are available here. | ||
// This is not the complete list, there may be more useful stuff in jsdoc | ||
// For all modules scan in: '/usr/lib/node_modules/jsdoc/lib/jsdoc/' (or similar on your system) | ||
var fs = require('jsdoc/fs'); | ||
var path = require('jsdoc/path'); | ||
var template = require('jsdoc/template'); | ||
|
||
|
||
/** | ||
* Set up the template rendering engine. | ||
*/ | ||
function createRenderer(fromDir, data) { | ||
var renderer = new template.Template(fromDir); // Param is the template source directory. | ||
// All template files are relative to this directory! | ||
/** | ||
* Example helper method | ||
* | ||
* This can be called from within a template as follows: | ||
* | ||
* ``` | ||
* <?js | ||
* var self = this; | ||
* ?> | ||
* ... | ||
* <?js= self.helper('hello!') ?> | ||
* ``` | ||
* | ||
* / | ||
renderer.helper = function(val) { | ||
return 'this is a helper! ' + val; | ||
}; | ||
*/ | ||
|
||
/** | ||
* Retrieves jsdoc info for the passed instance method. | ||
*/ | ||
renderer.getComment = function(methodName) { | ||
var tmp = data().filter({longname: methodName}).get()[0]; | ||
//console.log(JSON.stringify(tmp)); | ||
|
||
// Some restructuring, to adapt it to the docs layout | ||
// This needs some work to make it handle 0 and > 1 parameters | ||
var param = tmp.params[0]; | ||
var prototype = tmp.name + '(<code>' + param.type.names.join('|') + ' ' + param.name + '</code>)'; | ||
var returns = tmp.returns[0].type.names; | ||
|
||
return { | ||
prototype: prototype, | ||
returns: returns, | ||
description: tmp.description | ||
} | ||
}; | ||
|
||
return renderer; | ||
} | ||
|
||
|
||
/** | ||
Entry point for the template. | ||
This is called from `jsdoc` during execution | ||
@param {TAFFY} taffyData See <http://taffydb.com/>. | ||
@param {object} opts | ||
@param {Tutorial} tutorials | ||
*/ | ||
exports.publish = function(taffyData, opts, tutorials) { | ||
//console.log(JSON.stringify(opts, null, 2)); | ||
|
||
var fromDir = path.resolve(opts.template); | ||
var toDir = path.join(opts.destination); | ||
var renderer = createRenderer(fromDir, taffyData); | ||
|
||
var docFiles = fs.ls(fromDir, 3); | ||
docFiles.forEach(function(fileName) { | ||
// Template filenames need to be relative to template source dir | ||
var relName = path.relative(fromDir, fileName); | ||
var outFile = path.join(toDir, relName); | ||
|
||
if (/publish.js$/.test(fileName)) return; // Skip self | ||
if (/README.md$/.test(fileName)) return; // Skip own README | ||
if (/\.tmpl$/.test(fileName)) return; // Skip .tmpl files; these are used as partials only | ||
|
||
if (!/\.html$/.test(fileName)) { | ||
// Just plain copy over non-html files | ||
var tmpDir = fs.toDir(outFile); | ||
fs.mkPath(tmpDir); | ||
fs.copyFileSync(fileName, tmpDir); | ||
return; | ||
} | ||
|
||
// Render html files as templates | ||
//console.log(relName); | ||
var html = renderer.partial(relName, {}); | ||
fs.mkPath(fs.toDir(outFile)); | ||
fs.writeFileSync(outFile, html, 'utf8'); | ||
}); | ||
|
||
//console.log(JSON.stringify(env, null, 2)); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?js | ||
var title = obj; | ||
var self = this; | ||
?> | ||
<!DOCTYPE html> | ||
<html lang="en"><head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<meta name="description" content=""> | ||
<meta name="author" content=""> | ||
<link rel="icon" HREF="favicon.ico"> | ||
<title><?js= title ?></title> | ||
|
||
<!-- Bootstrap core CSS --> | ||
<link href="../css/bootstrap.css" rel="stylesheet"> | ||
<!-- Tipue vendor css --> | ||
<link href="../css/tipuesearch.css" rel="stylesheet"> | ||
|
||
<link href="../css/style.css" rel="stylesheet"> | ||
|
||
|
||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> | ||
<!--[if lt IE 9]> | ||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> | ||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> | ||
<![endif]--> | ||
|
||
|
||
<link href="../css/prettify.css" type="text/css" rel="stylesheet"/> | ||
<script type="text/javascript" src="../js/googleAnalytics.js"></script> | ||
<script type="text/javascript" src="../js/prettify/prettify.js"></script> | ||
|
||
<script src="../js/smooth-scroll.min.js"></script> | ||
<script language="JavaScript"> | ||
smoothScroll.init(); | ||
</script> | ||
|
||
<script type="text/javascript" src="../js/toggleTable.js"></script> | ||
<?js /* end tag '</head>' purposely missing here, so that more stuff can be added to header */ ?> |
Oops, something went wrong.