123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- var fs = require('jsdoc/fs');
- var path = require('jsdoc/path');
- var helper = require('jsdoc/util/templateHelper');
- var markdown = require('jsdoc/util/markdown').getParser();
- var hbs = require('./handlebarsHelper');
- var lunr = require('./lunrHelper');
- var processor = require('./postProcessor');
- var sanitizeHtml = require('sanitize-html');
- var extend = require('extend');
- var moment = require('moment');
- var kinds = exports.kinds = {
- custom: ['readme', 'global', 'source', 'tutorial', 'list'],
- pages: ['readme', 'global', 'source', 'tutorial', 'list', 'class', 'external', 'mixin', 'module', 'namespace', 'interface'],
- symbols: ['tutorial', 'class', 'external', 'event', 'mixin', 'module', 'namespace', 'interface', 'member', 'function', 'constant', 'typedef'],
- global: ['member', 'function', 'constant', 'typedef']
- };
- var options = exports.options = extend({
- includeDate: true,
- dateFormat: "Do MMM YYYY",
- systemName: "FooDoc",
- systemSummary: "A Bootstrap and Handlebars based template for JSDoc3.",
- systemLogo: "",
- systemColor: "",
- navMembers: [],
- footer: "",
- copyright: "FooDoc Copyright © 2016 The contributors to the JSDoc3 and FooDoc projects.",
- linenums: true,
- collapseSymbols: true,
- inverseNav: true,
- inlineNav: false,
- outputSourceFiles: true,
- sourceRootPath: null,
- disablePackagePath: true,
- outputSourcePath: false,
- showTableOfContents: true,
- showAccessFilter: true,
- analytics: null,
- methodHeadingReturns: true,
- sort: "linenum, longname, version, since",
- search: true,
- favicon: null,
- stylesheets: [],
- scripts: []
- }, env.conf.templates || {});
- if (!options.navMembers.length){
- options.navMembers = [
- {"kind": "class", "title": "Classes", "summary": "All documented classes."},
- {"kind": "external", "title": "Externals", "summary": "All documented external members."},
- {"kind": "global", "title": "Globals", "summary": "All documented globals."},
- {"kind": "mixin", "title": "Mixins", "summary": "All documented mixins."},
- {"kind": "interface", "title": "Interfaces", "summary": "All documented interfaces."},
- {"kind": "module", "title": "Modules", "summary": "All documented modules."},
- {"kind": "namespace", "title": "Namespaces", "summary": "All documented namespaces."},
- {"kind": "tutorial", "title": "Tutorials", "summary": "All available tutorials."}
- ];
- }
- var faviconTypes = {
- '.ico': 'image/x-icon',
- '.png': 'image/png',
- '.jpg': 'image/jpeg',
- '.jpeg': 'image/jpeg',
- '.gif': 'image/gif'
- };
- var config = exports.config = {
- debug: false,
- raw: env.opts,
- version: env.version.number,
- date: moment().format(options.dateFormat),
- faviconType: options.favicon ? faviconTypes[path.extname(options.favicon)] : null,
- dir: {
- root: null,
- tmpl: null,
- static: null,
- output: env.opts.destination,
- images: path.join( env.opts.destination, 'img' ),
- tutorials: env.opts.tutorials
- }
- };
- var raw = exports.raw = {
- data: null,
- opts: {},
- tutorials: []
- };
- var configured = false;
- exports.configure = function(taffyData, opts, tutorials){
- raw.data = helper.prune(taffyData);
- raw.opts = opts;
- raw.tutorials = tutorials;
- config.dir.root = opts.templates;
- config.dir.tmpl = path.join(opts.template, 'tmpl');
- config.dir.static = path.join(opts.template, 'static');
- configured = true;
- return config;
- };
- var navbar = exports.navbar = {};
- exports.postProcess = function(){
- processor.registerReadme();
- processor.registerModules();
- processor.registerGlobals();
- processor.registerDoclets();
- processor.registerSources();
- processor.registerTutorials();
- processor.registerLists();
- processor.process();
- processor.buildNavbar(navbar);
- };
- exports.publish = function(){
- generateStaticFiles();
- generateDocs();
- lunr.writeFilesSync(true);
- };
- exports.sanitize = function(html){
- if (typeof html !== 'string') return;
- return sanitizeHtml(html, {allowedTags: [], allowedAttributes: []}).replace(/\s+/g, ' ').trim();
- };
- /**
- * @summary Find items in the current TaffyDB that match the specified key-value pairs.
- * @param {Object|function} spec - An object of key-value pairs to match against (e.g. `{longname:"foo"}`), or a function that returns `true` if a value matches.
- * @returns {Array.<Object>} The matching items.
- * @example {@caption The following shows supplying an object to perform a by example search against the data.}
- * var foo = helper.find({longname:"foo"}).first(); // get the first doclet with a longname of `foo`
- * var children = helper.find({memberof:"foo"}); // get all doclets which belong to the `foo` doclet.
- */
- var find = exports.find = function (spec, sort) {
- if (!configured) return [];
- return sort ? raw.data(spec).order(sort).get() : raw.data(spec).get();
- };
- var linkto = exports.linkto = function(longname, linkText){
- var text = (linkText || longname)+'';
- // if no linkText was supplied lookup the longname and use the `linkText` property for the doclet.
- if (typeof linkText !== 'string'){
- var found = find({longname: longname});
- if (found.length && found[0].kind){
- var doclet = found[0];
- text = doclet.linkText || text;
- if (doclet.kind === 'tutorial'){
- return helper.toTutorial(doclet.longname, text, { tag: 'em', classname: 'disabled' });
- }
- }
- }
- return helper.linkto(longname, text);
- };
- var getPages = exports.getPages = function(sort){
- var members = {};
- kinds.pages.forEach(function(kind){
- members[kind] = find({kind: kind}, sort);
- });
- return members;
- };
- var generateStaticFiles = exports.generateStaticFiles = function(){
- // first copy all files within the templates 'static' directory to the output directory
- var files = fs.ls(config.dir.static, 3);
- files.forEach(function(fileName){
- var toDir = fs.toDir( fileName.replace( config.dir.static, config.dir.output ) );
- fs.mkPath( toDir );
- fs.copyFileSync( fileName, toDir );
- });
- // then copy the systemLogo file if one was supplied and update the option with the output file path
- if (options.systemLogo){
- var stats = fs.lstatSync(options.systemLogo);
- if (stats.isFile()){
- fs.mkPath(config.dir.images);
- fs.copyFileSync(options.systemLogo, config.dir.images);
- options.systemLogo = 'img/'+path.basename(options.systemLogo);
- }
- }
- // same for the favicon
- if (options.favicon){
- var stats = fs.lstatSync(options.favicon);
- if (stats.isFile()){
- fs.copyFileSync(options.favicon, env.opts.destination, 'favicon' + path.extname(options.favicon));
- options.favicon = 'favicon' + path.extname(options.favicon);
- }
- }
- // then copy all user supplied files
- var userFiles;
- if (options.default && (userFiles = options.default.staticFiles)) {
- // The canonical property name is `include`. We accept `paths` for backwards compatibility with a bug in JSDoc 3.2.x.
- var paths = userFiles.include || userFiles.paths || [];
- var filter = new (require('jsdoc/src/filter')).Filter(userFiles);
- var scanner = new (require('jsdoc/src/scanner')).Scanner();
- paths.forEach(function(filePath) {
- var files = scanner.scan([filePath], 10, filter);
- files.forEach(function(fileName) {
- var from = fs.toDir(filePath);
- var toDir = fs.toDir( fileName.replace(from, config.dir.output) );
- fs.mkPath(toDir);
- fs.copyFileSync(fileName, toDir);
- });
- });
- }
- };
- var generateDocs = exports.generateDocs = function(){
- var pages = getPages();
- Object.keys(pages).forEach(function(kind){
- if (pages[kind].length){
- pages[kind].forEach(function(doclet){
- var filename = doclet.kind === 'tutorial' ? helper.tutorialToUrl(doclet.longname) : helper.longnameToUrl[doclet.longname];
- if (!filename) return;
- if (doclet.kind === 'list' && !doclet.members.length) return;
- var output = path.join(config.dir.output, filename),
- html = hbs.render(doclet, doclet.kind !== 'source');
- if (html === null) return;
- fs.writeFileSync(output, html, 'utf8');
- if (doclet.kind !== 'source'){
- lunr.add(doclet, html);
- }
- });
- }
- });
- };
- var hasNavMember = exports.hasNavMember = function(kind){
- return options.navMembers.findIndex(function(member){
- return member.kind == kind;
- }) != -1;
- };
- exports.createCrumbs = function(doclet){
- var crumbs = [];
- if (doclet.kind === 'readme' || doclet.kind === 'source') return crumbs;
- crumbs.push(linkto("index", "Home"));
- if (doclet.kind !== 'list' && doclet.kind !== 'global' && hasNavMember(doclet.kind)){
- crumbs.push(linkto("list:"+doclet.kind));
- }
- if (doclet.kind === 'tutorial'){
- helper.getAncestors(raw.data, doclet).forEach(function(ancestor){
- crumbs.push(linkto(ancestor.longname));
- });
- crumbs.push(doclet.title || doclet.name);
- } else {
- crumbs.push(doclet.ancestors.join('') + doclet.name);
- }
- return crumbs;
- };
|