mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Merged @tutorial tag in.
This commit is contained in:
commit
279554f1a3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
build-files/java/build
|
||||
jsdoc.jar
|
||||
test/tutorials/out
|
||||
|
||||
@ -21,6 +21,10 @@
|
||||
{
|
||||
"name": "Michael Mathews",
|
||||
"email": "micmath@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Rafa\u0105 Wrzeszcz",
|
||||
"email": "rafal.wrzeszcz@wrzasq.pl"
|
||||
}
|
||||
],
|
||||
"maintainers": [
|
||||
|
||||
15
jsdoc.js
15
jsdoc.js
@ -142,7 +142,8 @@ function main() {
|
||||
opts: {
|
||||
parser: require('jsdoc/opts/parser'),
|
||||
}
|
||||
};
|
||||
},
|
||||
resolver;
|
||||
|
||||
env.opts = jsdoc.opts.parser.parse(env.args);
|
||||
|
||||
@ -240,6 +241,15 @@ function main() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// load this module anyway to ensure root instance exists
|
||||
// it's not a problem since without tutorials root node will have empty children list
|
||||
resolver = require('jsdoc/tutorial/resolver');
|
||||
|
||||
if (env.opts.tutorials) {
|
||||
resolver.load(env.opts.tutorials);
|
||||
resolver.resolve();
|
||||
}
|
||||
|
||||
env.opts.template = env.opts.template || 'templates/default';
|
||||
|
||||
// should define a global "publish" function
|
||||
@ -248,7 +258,8 @@ function main() {
|
||||
if (typeof publish === 'function') {
|
||||
publish(
|
||||
new (require('typicaljoe/taffy'))(docs),
|
||||
env.opts
|
||||
env.opts,
|
||||
resolver.root
|
||||
);
|
||||
}
|
||||
else { // TODO throw no publish warning?
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "JSDoc",
|
||||
"version": "3.0.0alpha",
|
||||
"revision": "1323214202201",
|
||||
"revision": "1323947228470",
|
||||
"description": "An automatic documentation generator for javascript.",
|
||||
"keywords": [ "documentation", "javascript" ],
|
||||
"licenses": [
|
||||
@ -21,6 +21,10 @@
|
||||
{
|
||||
"name": "Michael Mathews",
|
||||
"email": "micmath@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Rafa\u0105 Wrzeszcz",
|
||||
"email": "rafal.wrzeszcz@wrzasq.pl"
|
||||
}
|
||||
],
|
||||
"maintainers": [
|
||||
|
||||
@ -133,7 +133,7 @@ exports.copyFile = function(inFile, outDir, fileName) {
|
||||
bis.close();
|
||||
};
|
||||
|
||||
function toFile(path) {
|
||||
var toFile = exports.toFile = function(path) {
|
||||
var parts = path.split(/[\\\/]/);
|
||||
return parts.pop();
|
||||
}
|
||||
|
||||
@ -48,6 +48,8 @@
|
||||
members = getMembers(parents[j], docs);
|
||||
for (var k=0, kk=members.length; k<kk; ++k) {
|
||||
member = doop(members[k]);
|
||||
member.inherits = member.longname;
|
||||
member.inherited = true;
|
||||
member.memberof = doc.longname;
|
||||
parts = member.longname.split("#");
|
||||
parts[0] = doc.longname;
|
||||
|
||||
@ -12,7 +12,6 @@ var common = {
|
||||
var argParser = new common.args.ArgParser(),
|
||||
ourOptions,
|
||||
defaults = {
|
||||
template: 'templates/default',
|
||||
destination: './out/'
|
||||
};
|
||||
|
||||
@ -26,6 +25,7 @@ argParser.addOption('r', 'recurse', false, 'Recurse into subdirectories when
|
||||
argParser.addOption('h', 'help', false, 'Print this message and quit.');
|
||||
argParser.addOption('X', 'explain', false, 'Dump all found doclet internals to console and quit.');
|
||||
argParser.addOption('q', 'query', true, 'Provide a querystring to define custom variable names/values to add to the options hash.');
|
||||
argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should search for tutorials.');
|
||||
|
||||
|
||||
// TODO [-R, recurseonly] = a number representing the depth to recurse
|
||||
|
||||
@ -54,6 +54,13 @@ exports.jsdocSchema = {
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"tutorials": { // extended tutorials
|
||||
"type": ["string", "array"],
|
||||
"optional": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deprecated": { // is usage of this symbol deprecated?
|
||||
"type": ["string", "boolean"],
|
||||
|
||||
@ -486,6 +486,14 @@ exports.defineTags = function(dictionary) {
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineTag('tutorial', {
|
||||
mustHaveValue: true,
|
||||
onTagged: function(doclet, tag) {
|
||||
if (!doclet.tutorials) { doclet.tutorials = []; }
|
||||
doclet.tutorials.push(tag.value);
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineTag('type', {
|
||||
mustHaveValue: true,
|
||||
canHaveType: true,
|
||||
|
||||
89
rhino_modules/jsdoc/tutorial.js
Normal file
89
rhino_modules/jsdoc/tutorial.js
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
@overview
|
||||
@author Rafał Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
var mdParser = require('evilstreak/markdown');
|
||||
|
||||
/**
|
||||
@module jsdoc/tutorial
|
||||
*/
|
||||
|
||||
/**
|
||||
@class
|
||||
@classdesc Represents a single JSDoc tutorial.
|
||||
@param {string} name - Tutorial name.
|
||||
@param {string} content - Text content.
|
||||
@param {number} type - Source formating.
|
||||
*/
|
||||
exports.Tutorial = function(name, content, type) {
|
||||
this.title = this.name = name;
|
||||
this.content = content;
|
||||
this.type = type;
|
||||
|
||||
// default values
|
||||
this.parent = null;
|
||||
this.children = [];
|
||||
};
|
||||
|
||||
/** Moves children from current parent to different one.
|
||||
@param {Tutorial} parent - New parent.
|
||||
*/
|
||||
exports.Tutorial.prototype.setParent = function(parent) {
|
||||
// removes node from old parent
|
||||
if (this.parent) {
|
||||
this.parent.removeChild(this);
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
this.parent.addChild(this);
|
||||
};
|
||||
|
||||
/** Removes children from current node.
|
||||
@param {Tutorial} child - Old child.
|
||||
*/
|
||||
exports.Tutorial.prototype.removeChild = function(child) {
|
||||
var index = this.children.indexOf(child);
|
||||
if (index != -1) {
|
||||
this.children.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
/** Adds new children to current node.
|
||||
@param {Tutorial} child - New child.
|
||||
*/
|
||||
exports.Tutorial.prototype.addChild = function(child) {
|
||||
this.children.push(child);
|
||||
};
|
||||
|
||||
/** Prepares source.
|
||||
@return {string} HTML source.
|
||||
*/
|
||||
exports.Tutorial.prototype.parse = function() {
|
||||
switch (this.type) {
|
||||
// nothing to do
|
||||
case exports.TYPES.HTML:
|
||||
return this.content;
|
||||
|
||||
// markdown
|
||||
case exports.TYPES.MARKDOWN:
|
||||
return mdParser.toHTML(this.content)
|
||||
.replace(/&/g, '&') // because markdown escapes these
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
|
||||
// uhm... should we react somehow?
|
||||
// if not then this case can be merged with TYPES.HTML
|
||||
default:
|
||||
return this.content;
|
||||
}
|
||||
};
|
||||
|
||||
/** Tutorial source types.
|
||||
@enum {number}
|
||||
*/
|
||||
exports.TYPES = {
|
||||
HTML: 1,
|
||||
MARKDOWN: 2
|
||||
};
|
||||
126
rhino_modules/jsdoc/tutorial/resolver.js
Normal file
126
rhino_modules/jsdoc/tutorial/resolver.js
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
@overview
|
||||
@author Rafał Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
@module jsdoc/tutorial/resolver
|
||||
*/
|
||||
|
||||
var tutorial = require('jsdoc/tutorial'),
|
||||
fs = require('fs'),
|
||||
conf = {},
|
||||
tutorials = {},
|
||||
finder = /^(.*)\.(x(?:ht)?ml|html?|md|markdown|js(?:on)?)$/i;
|
||||
|
||||
/** Adds new tutorial.
|
||||
@param {tutorial.Tutorial} current - New tutorial.
|
||||
*/
|
||||
exports.addTutorial = function(current) {
|
||||
tutorials[current.name] = current;
|
||||
|
||||
// default temporary parent
|
||||
current.setParent(exports.root);
|
||||
};
|
||||
|
||||
/** Root tutorial.
|
||||
@type tutorial.Tutorial
|
||||
*/
|
||||
exports.root = new tutorial.Tutorial('', '');
|
||||
|
||||
/** Additional instance method for root node.
|
||||
@param {string} name - Tutorial name.
|
||||
@reutrn {tutorial.Tutorial} Tutorial instance.
|
||||
*/
|
||||
exports.root.getByName = function(name) {
|
||||
return tutorials[name];
|
||||
};
|
||||
|
||||
/** Load tutorials from given path.
|
||||
@param {string} path - Tutorials directory.
|
||||
*/
|
||||
exports.load = function(path) {
|
||||
var match,
|
||||
type,
|
||||
name,
|
||||
current,
|
||||
files = fs.ls(path);
|
||||
|
||||
// tutorials handling
|
||||
files.forEach(function(file) {
|
||||
match = file.match(finder);
|
||||
|
||||
// any filetype that can apply to tutorials
|
||||
if (match) {
|
||||
name = fs.toFile(match[1]);
|
||||
content = fs.readFileSync(file);
|
||||
|
||||
switch (match[2].toLowerCase()) {
|
||||
// HTML type
|
||||
case 'xml':
|
||||
case 'xhtml':
|
||||
case 'html':
|
||||
case 'htm':
|
||||
type = tutorial.TYPES.HTML;
|
||||
break;
|
||||
|
||||
// Markdown typs
|
||||
case 'md':
|
||||
case 'markdown':
|
||||
type = tutorial.TYPES.MARKDOWN;
|
||||
break;
|
||||
|
||||
// configuration file
|
||||
case 'js':
|
||||
case 'json':
|
||||
conf[name] = JSON.parse(content);
|
||||
|
||||
// how can it be? check `finder' regexp
|
||||
default:
|
||||
// not a file we want to work with
|
||||
return;
|
||||
}
|
||||
|
||||
current = new tutorial.Tutorial(name, content, type);
|
||||
exports.addTutorial(current);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** Resolves hierarchical structure.
|
||||
@param {object} map - Contents map.
|
||||
*/
|
||||
exports.resolve = function() {
|
||||
var item,
|
||||
current;
|
||||
for (var name in conf) {
|
||||
// should we be restrictive here?
|
||||
// what is someone just wants to keep sample sources in same directory with tutorials?
|
||||
// I've decided to leave such cases alone
|
||||
if (!(name in tutorials)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item = conf[name];
|
||||
current = tutorials[name]
|
||||
|
||||
// set title
|
||||
if (item.title) {
|
||||
current.title = item.title;
|
||||
}
|
||||
|
||||
// add children
|
||||
if (item.children) {
|
||||
item.children.forEach(function(child) {
|
||||
// I really didn't want to throw you an exception in most cases
|
||||
// but now, user, you pissed me off ;)
|
||||
if (!(child in tutorials)) {
|
||||
throw new Error("Missing child tutorial: " + child);
|
||||
}
|
||||
|
||||
tutorials[child].setParent(current);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -8,7 +8,7 @@ var dictionary = require('jsdoc/tag/dictionary');
|
||||
exports.globalName = 'global';
|
||||
exports.fileExtension = '.html';
|
||||
|
||||
/** Find symbol {@link ...} strings in text and turn into html links */
|
||||
/** Find symbol {@link ...} and {@tutorial ...} strings in text and turn into html links */
|
||||
exports.resolveLinks = function(str) {
|
||||
str = str.replace(/(?:\[(.+?)\])?\{@link +(.+?)\}/gi,
|
||||
function(match, content, longname) {
|
||||
@ -16,6 +16,12 @@ exports.resolveLinks = function(str) {
|
||||
}
|
||||
);
|
||||
|
||||
str = str.replace(/(?:\[(.+?)\])?\{@tutorial +(.+?)\}/gi,
|
||||
function(match, content, tutorial) {
|
||||
return toTutorial(tutorial, content);
|
||||
}
|
||||
);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -102,4 +108,40 @@ function toLink(longname, content) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @external {jsdoc.tutorial.Tutorial} */
|
||||
var tutorials;
|
||||
|
||||
/** Sets tutorials map.
|
||||
@param {jsdoc.tutorial.Tutorial} root - Root tutorial node.
|
||||
*/
|
||||
exports.setTutorials = function(root) {
|
||||
tutorials = root;
|
||||
};
|
||||
|
||||
exports.toTutorial = toTutorial = function(tutorial, content) {
|
||||
if (!tutorial) {
|
||||
throw new Error('Missing required parameter: tutorial');
|
||||
}
|
||||
|
||||
var node = tutorials.getByName(tutorial);
|
||||
// no such tutorial
|
||||
if (!node) {
|
||||
return '<em class="disabled">Tutorial: '+tutorial+'</em>';
|
||||
}
|
||||
|
||||
content = content || node.title;
|
||||
|
||||
return '<a href="'+exports.tutorialToUrl(tutorial)+'">'+content+'</a>';
|
||||
}
|
||||
|
||||
exports.longnameToUrl = linkMap.longnameToUrl;
|
||||
|
||||
exports.tutorialToUrl = function(tutorial) {
|
||||
var node = tutorials.getByName(tutorial);
|
||||
// no such tutorial
|
||||
if (!node) {
|
||||
throw new Error('No such tutorial: '+tutorial);
|
||||
}
|
||||
|
||||
return 'tutorial-'+strToFilename(node.name)+exports.fileExtension;
|
||||
};
|
||||
|
||||
@ -13,10 +13,15 @@
|
||||
@global
|
||||
@param {TAFFY} data See <http://taffydb.com/>.
|
||||
@param {object} opts
|
||||
@param {Tutorial} tutorials
|
||||
*/
|
||||
publish = function(data, opts) {
|
||||
publish = function(data, opts, tutorials) {
|
||||
var out = '',
|
||||
containerTemplate = template.render(fs.readFileSync(__dirname + '/templates/default/tmpl/container.tmpl'));
|
||||
containerTemplate = template.render(fs.readFileSync(__dirname + '/templates/default/tmpl/container.tmpl')),
|
||||
tutorialTemplate = template.render(fs.readFileSync(__dirname + '/templates/default/tmpl/tutorial.tmpl'));
|
||||
|
||||
// set up tutorials for helper
|
||||
helper.setTutorials(tutorials);
|
||||
|
||||
function render(tmpl, partialData) {
|
||||
var renderFunction = arguments.callee.cache[tmpl];
|
||||
@ -26,6 +31,7 @@
|
||||
partialData.render = arguments.callee;
|
||||
partialData.find = find;
|
||||
partialData.linkto = linkto;
|
||||
partialData.tutoriallink = tutoriallink;
|
||||
partialData.htmlsafe = htmlsafe;
|
||||
|
||||
return renderFunction.call(partialData, partialData);
|
||||
@ -162,7 +168,7 @@
|
||||
};
|
||||
});
|
||||
}
|
||||
else if (doclet.see) {
|
||||
if (doclet.see) {
|
||||
doclet.see.forEach(function(seeItem, i) {
|
||||
doclet.see[i] = hashToLink(doclet, seeItem);
|
||||
});
|
||||
@ -199,6 +205,10 @@
|
||||
return url? '<a href="'+url+'">'+(linktext || longname)+'</a>' : (linktext || longname);
|
||||
}
|
||||
|
||||
function tutoriallink(tutorial) {
|
||||
return helper.toTutorial(tutorial);
|
||||
}
|
||||
|
||||
var containers = ['class', 'module', 'external', 'namespace', 'mixin'];
|
||||
|
||||
data.forEach(function(doclet) {
|
||||
@ -245,29 +255,29 @@
|
||||
|
||||
var moduleNames = find({kind: 'module'});
|
||||
if (moduleNames.length) {
|
||||
nav = nav + '<h3>Modules</h3><ul>';
|
||||
nav += '<h3>Modules</h3><ul>';
|
||||
moduleNames.forEach(function(m) {
|
||||
if ( !seen.hasOwnProperty(m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
|
||||
seen[m.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
var externalNames = find({kind: 'external'});
|
||||
if (externalNames.length) {
|
||||
nav = nav + '<h3>Externals</h3><ul>';
|
||||
nav += '<h3>Externals</h3><ul>';
|
||||
externalNames.forEach(function(e) {
|
||||
if ( !seen.hasOwnProperty(e.longname) ) nav += '<li>'+linkto( e.longname, e.name.replace(/(^"|"$)/g, '') )+'</li>';
|
||||
seen[e.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
var classNames = find({kind: 'class'});
|
||||
if (classNames.length) {
|
||||
nav = nav + '<h3>Classes</h3><ul>';
|
||||
nav += '<h3>Classes</h3><ul>';
|
||||
classNames.forEach(function(c) {
|
||||
var moduleSameName = find({kind: 'module', longname: c.longname});
|
||||
if (moduleSameName.length) {
|
||||
@ -279,52 +289,61 @@
|
||||
seen[c.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
var namespaceNames = find({kind: 'namespace'});
|
||||
if (namespaceNames.length) {
|
||||
nav = nav + '<h3>Namespaces</h3><ul>';
|
||||
nav += '<h3>Namespaces</h3><ul>';
|
||||
namespaceNames.forEach(function(n) {
|
||||
if ( !seen.hasOwnProperty(n.longname) ) nav += '<li>'+linkto(n.longname, n.name)+'</li>';
|
||||
seen[n.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
// var constantNames = find({kind: 'constants'});
|
||||
// if (constantNames.length) {
|
||||
// nav = nav + '<h3>Constants</h3><ul>';
|
||||
// nav += '<h3>Constants</h3><ul>';
|
||||
// constantNames.forEach(function(c) {
|
||||
// if ( !seen.hasOwnProperty(c.longname) ) nav += '<li>'+linkto(c.longname, c.name)+'</li>';
|
||||
// seen[c.longname] = true;
|
||||
// });
|
||||
//
|
||||
// nav = nav + '</ul>';
|
||||
// nav += '</ul>';
|
||||
// }
|
||||
|
||||
var mixinNames = find({kind: 'mixin'});
|
||||
if (mixinNames.length) {
|
||||
nav = nav + '<h3>Mixins</h3><ul>';
|
||||
nav += '<h3>Mixins</h3><ul>';
|
||||
mixinNames.forEach(function(m) {
|
||||
if ( !seen.hasOwnProperty(m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
|
||||
seen[m.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
if (tutorials.children.length) {
|
||||
nav += '<h3>Tutorials</h3><ul>';
|
||||
tutorials.children.forEach(function(t) {
|
||||
nav += '<li>'+tutoriallink(t.name)+'</li>';
|
||||
});
|
||||
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
var globalNames = find({kind: ['member', 'function', 'constant', 'typedef'], 'memberof': {'isUndefined': true}});
|
||||
|
||||
if (globalNames.length) {
|
||||
nav = nav + '<h3>Global</h3><ul>';
|
||||
nav += '<h3>Global</h3><ul>';
|
||||
globalNames.forEach(function(g) {
|
||||
if ( g.kind !== 'typedef' && !seen.hasOwnProperty(g.longname) ) nav += '<li>'+linkto(g.longname, g.name)+'</li>';
|
||||
seen[g.longname] = true;
|
||||
});
|
||||
|
||||
nav = nav + '</ul>';
|
||||
nav += '</ul>';
|
||||
}
|
||||
|
||||
for (var longname in helper.longnameToUrl) {
|
||||
@ -360,6 +379,7 @@
|
||||
render: render,
|
||||
find: find,
|
||||
linkto: linkto,
|
||||
tutoriallink: tutoriallink,
|
||||
htmlsafe: htmlsafe
|
||||
};
|
||||
|
||||
@ -370,6 +390,39 @@
|
||||
|
||||
fs.writeFileSync(path, html)
|
||||
}
|
||||
|
||||
function generateTutorial(title, tutorial, filename) {
|
||||
var data = {
|
||||
title: title,
|
||||
header: tutorial.title,
|
||||
content: tutorial.parse(),
|
||||
children: tutorial.children,
|
||||
nav: nav,
|
||||
|
||||
// helpers
|
||||
render: render,
|
||||
find: find,
|
||||
linkto: linkto,
|
||||
tutoriallink: tutoriallink,
|
||||
htmlsafe: htmlsafe
|
||||
};
|
||||
|
||||
var path = outdir + '/' + filename,
|
||||
html = tutorialTemplate.call(data, data);
|
||||
|
||||
// yes, you can use {@link} in tutorials too!
|
||||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
||||
|
||||
fs.writeFileSync(path, html)
|
||||
}
|
||||
|
||||
// tutorials can have only one parent so there is no risk for loops
|
||||
function saveChildren(node) {
|
||||
node.children.forEach(function(child) {
|
||||
generateTutorial('Tutorial: '+child.title, child, helper.tutorialToUrl(child.name));
|
||||
});
|
||||
}
|
||||
saveChildren(tutorials);
|
||||
}
|
||||
|
||||
function hashToLink(doclet, hash) {
|
||||
|
||||
@ -254,3 +254,7 @@ h6
|
||||
|
||||
.params th, .props th { border-right: 1px solid #aaa; }
|
||||
.params thead .last, .props thead .last { border-right: 1px solid #ddd; }
|
||||
|
||||
.disabled {
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
@ -61,6 +61,17 @@
|
||||
<dd class="tag-source"><ul class="dummy"><li><?js= meta.filename ?>, line <?js= meta.lineno ?></li></ul></dd>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (this.tutorials && tutorials.length) {?>
|
||||
<dt class="tag-tutorial">Tutorials:</dt>
|
||||
<dd class="tag-tutorial">
|
||||
<ul><?js
|
||||
tutorials.forEach(function(t) {
|
||||
print('<li>'+tutoriallink(t)+'</li>');
|
||||
});
|
||||
?></ul>
|
||||
</dd>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (this.see && see.length) {?>
|
||||
<dt class="tag-see">See:</dt>
|
||||
<dd class="tag-see">
|
||||
|
||||
53
templates/default/tmpl/tutorial.tmpl
Normal file
53
templates/default/tmpl/tutorial.tmpl
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: <?js= title ?></title>
|
||||
|
||||
<script src="http://shjs.sourceforge.net/sh_main.min.js"> </script>
|
||||
<script src="http://shjs.sourceforge.net/lang/sh_javascript.min.js"> </script>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/node-dark.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title"><?js= title ?></h1>
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<?js if (children.length > 0) { ?>
|
||||
<ul><?js
|
||||
children.forEach(function(t) {
|
||||
print('<li>'+tutoriallink(t.name)+'</li>');
|
||||
});
|
||||
?></ul>
|
||||
<?js } ?>
|
||||
|
||||
<h2><?js= header ?></h2>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<?js= content ?>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<?js= nav ?>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/micmath/jsdoc">JSDoc 3</a> on <?js= (new Date()) ?>
|
||||
</footer>
|
||||
|
||||
<script> sh_highlightDocument(); </script>
|
||||
</body>
|
||||
</html>
|
||||
2
test/tutorials/build.sh
Executable file
2
test/tutorials/build.sh
Executable file
@ -0,0 +1,2 @@
|
||||
rm -rf out
|
||||
../../jsdoc -u tutorials src -d out
|
||||
8
test/tutorials/src/x.js
Normal file
8
test/tutorials/src/x.js
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Test {@tutorial test2} {@tutorial dupa}
|
||||
*
|
||||
* @class
|
||||
* @tutorial test
|
||||
* @tutorial jasia
|
||||
*/
|
||||
function Test() {}
|
||||
3
test/tutorials/tutorials/test.html
Normal file
3
test/tutorials/tutorials/test.html
Normal file
@ -0,0 +1,3 @@
|
||||
<h1>Test.html</h1>
|
||||
|
||||
<p>{@link Test}</p>
|
||||
1
test/tutorials/tutorials/test.js
Normal file
1
test/tutorials/tutorials/test.js
Normal file
@ -0,0 +1 @@
|
||||
{"title": "Test tutorial", "children": ["test2"]}
|
||||
1
test/tutorials/tutorials/test2.json
Normal file
1
test/tutorials/tutorials/test2.json
Normal file
@ -0,0 +1 @@
|
||||
{"title": "Test 2"}
|
||||
1
test/tutorials/tutorials/test2.markdown
Normal file
1
test/tutorials/tutorials/test2.markdown
Normal file
@ -0,0 +1 @@
|
||||
# test2.markdown
|
||||
Loading…
x
Reference in New Issue
Block a user