mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
jsdoc: scripts for generating node.js documentation
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
parent
1079cb7cdd
commit
65a19d1779
60
doxy/node/docgen.js
Normal file
60
doxy/node/docgen.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var xml2js = require('./xml2js')
|
||||
, fs = require('fs')
|
||||
, Promise = require('bluebird')
|
||||
, opts = require('commander')
|
||||
, _ = require('lodash')
|
||||
, mkdirp = require('mkdirp');
|
||||
|
||||
|
||||
// parse command line arguments
|
||||
_.extend(opts, { addOptions: function(module) { return module.addOptions(opts); } });
|
||||
opts
|
||||
.option('-m, --module [module]', 'module name for which to build documentation', 'mraa')
|
||||
.option('-f, --formats [formats]', 'format for js comments', 'jsdoc,yuidoc,ternjs')
|
||||
.option('-o, --outdir [directory]', 'top directory to build documentation', __dirname + '/jsdoc')
|
||||
.addOptions(xml2js)
|
||||
.parse(process.argv);
|
||||
|
||||
|
||||
// use promise-style programming rather than spaghetti callbacks
|
||||
Promise.promisifyAll(fs);
|
||||
|
||||
// TODO: create directory structure if doesn't exist
|
||||
var formats = opts.formats.split(',');
|
||||
formats.forEach(function(format){
|
||||
mkdirp('jsdoc/' + format + '/' + opts.module);
|
||||
});
|
||||
|
||||
// main
|
||||
xml2js.parse().then(function(specjs) {
|
||||
Promise.all(_.map(formats, function(format) {
|
||||
var generateDocs = require(__dirname + '/generators/' + format + '/generator');
|
||||
var outFile = opts.outdir + '/' + format + '/' + specjs.MODULE + '/doc.js';
|
||||
return fs.writeFileAsync(outFile, generateDocs(specjs));
|
||||
}));
|
||||
});
|
7
doxy/node/generators/jsdoc/conf.json
Normal file
7
doxy/node/generators/jsdoc/conf.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"templates": {
|
||||
"default": {
|
||||
"outputSourceFiles": false
|
||||
}
|
||||
}
|
||||
}
|
88
doxy/node/generators/jsdoc/generator.js
Normal file
88
doxy/node/generators/jsdoc/generator.js
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate JSDoc-style documentation
|
||||
function generateDocs(specjs) {
|
||||
var docs = GENERATE_MODULE(specjs.MODULE);
|
||||
docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.CLASSES, function(memo, classSpec, parentClass) {
|
||||
return _.reduce(classSpec.methods, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec, parentClass);
|
||||
}, memo);
|
||||
}, docs);
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// comment wrapper around entire spec
|
||||
function GENERATE_DOC(text) {
|
||||
return '/**\n' + text + ' */\n';
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(module) {
|
||||
return GENERATE_DOC('@module ' + module + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate method spec with parent module/class
|
||||
function GENERATE_METHOD(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@method ' + name + '\n'
|
||||
+ '@instance\n'
|
||||
+ (parent ? ('@memberof ' + parent + '\n') : '')
|
||||
+ _.reduce(spec.params, function(memo, paramSpec, paramName) {
|
||||
return '@param {' + paramSpec.type + '} ' + paramName + ' ' + paramSpec.description + '\n';
|
||||
}, '')
|
||||
+ ( !_.isEmpty(spec.return) ? ('@return {' + spec.return.type + '} ' + spec.return.description + '\n') : ''));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec) {
|
||||
return GENERATE_DOC(spec.description + '\n\n'
|
||||
+ '@var ' + name + '\n'
|
||||
+ '@type Enum(' + spec.type + ')\n'
|
||||
+ '@instance\n');
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// generate link spec
|
||||
function GENERATE_LINK(text) {
|
||||
return '{@link ' + text + '}';
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
110
doxy/node/generators/ternjs/generator.js
Normal file
110
doxy/node/generators/ternjs/generator.js
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate json for ternjs input
|
||||
function generateDocs(specjs) {
|
||||
var docs = GENERATE_MODULE(specjs.MODULE);
|
||||
GENERATE_TYPE = (function(enums) {
|
||||
return function(type) {
|
||||
return (_.contains(enums, type) ? ('Enum ' + type) : type);
|
||||
}
|
||||
})(_.keys(specjs.ENUMS_BY_GROUP));
|
||||
_.each(specjs.ENUMS, function(enumSpec, enumName) {
|
||||
_.extend(docs[specjs.MODULE], GENERATE_ENUM(enumName, enumSpec));
|
||||
});
|
||||
_.each(specjs.METHODS, function(methodSpec, methodName) {
|
||||
_.extend(docs[specjs.MODULE], GENERATE_METHOD(methodName, methodSpec));
|
||||
});
|
||||
_.each(specjs.CLASSES, function(classSpec, parentClass) {
|
||||
var constructor = classSpec.methods[parentClass];
|
||||
_.extend(docs[specjs.MODULE], GENERATE_METHOD(parentClass, constructor ? constructor : { params: {}, return: {}, description: '' } ));
|
||||
_.each(classSpec.enums, function(enumSpec, enumName) {
|
||||
_.extend(docs[specjs.MODULE][parentClass], GENERATE_ENUM(enumName, enumSpec));
|
||||
});
|
||||
docs[specjs.MODULE][parentClass].prototype = {};
|
||||
_.each(_.omit(classSpec.methods, parentClass), function(methodSpec, methodName) {
|
||||
_.extend(docs[specjs.MODULE][parentClass].prototype, GENERATE_METHOD(methodName, methodSpec));
|
||||
});
|
||||
_.each(classSpec.variables, function(variableSpec, variableName) {
|
||||
_.extend(docs[specjs.MODULE][parentClass].prototype, GENERATE_VARIABLE(variableName, variableSpec));
|
||||
});
|
||||
});
|
||||
return JSON.stringify(docs, null, 2);
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(module) {
|
||||
var docs = { '!name': module + 'library' };
|
||||
docs[module] = {};
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// generate method spec
|
||||
function GENERATE_METHOD(name, spec) {
|
||||
var doc = {};
|
||||
doc[name] = {
|
||||
'!type': 'fn(' + GENERATE_PARAMS(spec.params) + ')' + GENERATE_RETURN(spec.return),
|
||||
'!doc': spec.description
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
// generate parameter signatures for method
|
||||
function GENERATE_PARAMS(spec) {
|
||||
return _.map(spec, function(paramSpec, paramName) {
|
||||
return paramName + ': ' + paramSpec.type;
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
|
||||
// generate return signature for method
|
||||
function GENERATE_RETURN(spec) {
|
||||
return (_.isEmpty(spec) ? '' : (' -> ' + spec.type));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec) {
|
||||
var doc = {};
|
||||
doc[name] = 'Enum ' + spec.type ;
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
// generate variable spec
|
||||
function GENERATE_VARIABLE(name, spec) {
|
||||
var doc = {};
|
||||
doc[name]= spec.type ;
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
8
doxy/node/generators/yuidoc/conf.json
Normal file
8
doxy/node/generators/yuidoc/conf.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "UPM",
|
||||
"description": "The UPM API: High Level Sensor Library for Intel IoT Devices Using MRAA",
|
||||
"logo": "http://upload.wikimedia.org/wikipedia/commons/8/8c/Transparent.png",
|
||||
"options": {
|
||||
"outdir": "./html/node"
|
||||
}
|
||||
}
|
117
doxy/node/generators/yuidoc/generator.js
vendored
Normal file
117
doxy/node/generators/yuidoc/generator.js
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate YuiDocs-style documentation
|
||||
function generateDocs(specjs) {
|
||||
var docs = GENERATE_MODULE(specjs.MODULE);
|
||||
GENERATE_TYPE = (function(enums) {
|
||||
return function(type) {
|
||||
return (_.contains(enums, type) ? ('Enum ' + type) : type);
|
||||
}
|
||||
})(_.keys(specjs.ENUMS_BY_GROUP));
|
||||
docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.CLASSES, function(memo, classSpec, parentClass) {
|
||||
return memo
|
||||
+ GENERATE_CLASS(parentClass, classSpec.description)
|
||||
+ _.reduce(classSpec.methods, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec, parentClass);
|
||||
}, '')
|
||||
+ _.reduce(classSpec.variables, function(memo, variableSpec, variableName) {
|
||||
return memo += GENERATE_VAR(variableName, variableSpec, parentClass);
|
||||
}, '')
|
||||
+ _.reduce(classSpec.enums, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec, parentClass);
|
||||
}, '');
|
||||
}, docs);
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// comment wrapper around entire spec
|
||||
function GENERATE_DOC(text) {
|
||||
return '/**\n' + text + ' */\n';
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(module) {
|
||||
return GENERATE_DOC('@module ' + module + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate class spec
|
||||
function GENERATE_CLASS(name, description) {
|
||||
return GENERATE_DOC(description + '\n'
|
||||
+ '@class ' + name + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate method spec with parent module/class
|
||||
function GENERATE_METHOD(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@method ' + name + '\n'
|
||||
+ (parent ? ('@for ' + parent + '\n') : '@for common\n')
|
||||
+ _.reduce(spec.params, function(memo, paramSpec, paramName) {
|
||||
return memo + '@param {' + GENERATE_TYPE(paramSpec.type) + '} ' + paramName + ' ' + paramSpec.description + '\n';
|
||||
}, '')
|
||||
+ ( !_.isEmpty(spec.return) ? ('@return {' + GENERATE_TYPE(spec.return.type) + '} ' + spec.return.description + '\n') : ''));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@property ' + name + '\n'
|
||||
+ '@type Enum ' + spec.type + '\n'
|
||||
+ '@for ' + (parent ? parent : 'common') + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate variable specs
|
||||
function GENERATE_VAR(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@property ' + name + '\n'
|
||||
+ '@type ' + spec.type + '\n'
|
||||
+ '@for ' + parent + '\n');
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// generate link spec
|
||||
function GENERATE_LINK(text) {
|
||||
return '{{#crossLink "' + text + '"}}{{/crossLink}}';
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
45
doxy/node/grammars/xml.peg
Normal file
45
doxy/node/grammars/xml.peg
Normal file
@ -0,0 +1,45 @@
|
||||
document
|
||||
= _ ignore* _ "<doxygen " _ attr:attr* _ ">" body:elements _ "</doxygen>" _ { return body; }
|
||||
|
||||
|
||||
elements
|
||||
= element*
|
||||
|
||||
element
|
||||
= _ "<" startTag:id _ attr:attr* _ ">" _ children:elements _ "</" endTag:id ">" _ {
|
||||
if (startTag != endTag) {
|
||||
throw new Error("Expected </" + startTag + "> but </" + endTag + "> found.");
|
||||
}
|
||||
return {name: startTag, attr: attr, children: children }
|
||||
}
|
||||
/ "<" tag:id _ attr:attr* _ "/>" _ {
|
||||
return {name: tag, attr: attr }
|
||||
}
|
||||
/ _ text:text _ { return text }
|
||||
|
||||
ignore
|
||||
= "<?xml" _ attr* _ "?>" { return }
|
||||
|
||||
attr
|
||||
= name:id _ "=" _ value:string { return { name:name, value:value } }
|
||||
|
||||
string
|
||||
= '"' '"' _ { return ""; }
|
||||
/ "'" "'" _ { return ""; }
|
||||
/ '"' text:quoted '"' _ { return text; }
|
||||
/ "'" text:quoted "'" _ { return text; }
|
||||
|
||||
quoted
|
||||
= chars:[^<>'" \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
text
|
||||
= chars:[^<> \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
id
|
||||
= chars:[^<>/'"=? \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
_ "whitespace"
|
||||
= whitespace*
|
||||
|
||||
whitespace
|
||||
= [ \t\n\r]
|
125
doxy/node/tolower.js
Normal file
125
doxy/node/tolower.js
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Author: Dina M Suehiro <dina.m.suehiro@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var opts = require('commander'), // for command line args
|
||||
fs = require('fs'), // for file system access
|
||||
path = require('path'); // for file path parsing
|
||||
|
||||
// parse command line arguments
|
||||
opts
|
||||
.option('-i, --inputdir [directory]', 'product documents directory', __dirname + '/docs/yuidoc/upm')
|
||||
.parse(process.argv);
|
||||
|
||||
// Set to true for console output
|
||||
var debug = true;
|
||||
|
||||
// Global arrays tracking the files that have been renamed
|
||||
var originalFiles = [];
|
||||
var renamedFiles = [];
|
||||
|
||||
// Filter to get html files from different directories
|
||||
var rootFiles = getHtmlFilenames(opts.inputdir);
|
||||
var classesFiles = getHtmlFilenames(opts.inputdir + "/classes");
|
||||
var modulesFiles = getHtmlFilenames(opts.inputdir + "/modules");
|
||||
|
||||
// Rename files in the classes directory to have lower-cased file names.
|
||||
renameFiles(classesFiles);
|
||||
|
||||
classesFiles = getHtmlFilenames(opts.inputdir + "/classes");
|
||||
|
||||
// Go through the html files and update links to reflect the file names that we changed.
|
||||
renameLinks(rootFiles);
|
||||
renameLinks(classesFiles);
|
||||
renameLinks(modulesFiles);
|
||||
|
||||
// Helper function that returns paths to the html files in the specified directory
|
||||
function getHtmlFilenames (directory)
|
||||
{
|
||||
return fs.readdirSync(directory).map(function (file) {
|
||||
return path.join(directory, file);
|
||||
}).filter(function (file) {
|
||||
return fs.statSync(file).isFile();
|
||||
}).filter(function (file) {
|
||||
return path.extname(file).toLowerCase() == ".html";
|
||||
});
|
||||
}
|
||||
|
||||
// Goes through the files and renames them to be lower-cased and tracks them the
|
||||
// renamed files in the originalFiles[] and renamedFiles[] arrays.
|
||||
function renameFiles(files)
|
||||
{
|
||||
files.forEach(function (file)
|
||||
{
|
||||
var originalName = path.basename(file);
|
||||
var newFileName = originalName.toLowerCase();
|
||||
var directory = path.dirname(file);
|
||||
if (originalName != newFileName)
|
||||
{
|
||||
fs.renameSync(file, directory + "/" + newFileName); //, function(err)
|
||||
|
||||
if (debug)
|
||||
console.log('Renamed: %s --> %s', originalName, newFileName);
|
||||
|
||||
originalFiles.push(originalName);
|
||||
renamedFiles.push(newFileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper function goes through the specified files and does a file/replace of the
|
||||
// originalFiles to the renamedFiles so that the .html links match what has been renamed.
|
||||
function renameLinks (files)
|
||||
{
|
||||
if (originalFiles.length <= 0)
|
||||
{
|
||||
if (debug)
|
||||
console.log("No links to rename.");
|
||||
return;
|
||||
}
|
||||
|
||||
files.forEach(function (file)
|
||||
{
|
||||
// Read the file
|
||||
data = fs.readFileSync(file, 'ascii');
|
||||
|
||||
// Find/replace the file names that were renamed
|
||||
for (var i = 0; i < originalFiles.length; i++)
|
||||
{
|
||||
var findString = '/' + originalFiles[i] + '\"';
|
||||
var replaceString = '/' + renamedFiles[i] + '\"';
|
||||
|
||||
data = data.replace(findString, replaceString);
|
||||
}
|
||||
|
||||
// Write back
|
||||
fs.writeFile(file, data, 'ascii', function (err) {
|
||||
if (err)
|
||||
throw err;
|
||||
});
|
||||
|
||||
if (debug)
|
||||
console.log('Renamed links in: %s', file);
|
||||
});
|
||||
}
|
575
doxy/node/xml2js.js
Normal file
575
doxy/node/xml2js.js
Normal file
@ -0,0 +1,575 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var peg = require('pegjs')
|
||||
, fs = require('fs')
|
||||
, path = require('path')
|
||||
, Promise = require('bluebird')
|
||||
, _ = require('lodash')
|
||||
, util = require('util');
|
||||
|
||||
|
||||
// use promise-style programming rather than spaghetti callbacks
|
||||
Promise.promisifyAll(fs);
|
||||
|
||||
|
||||
var xml2js = {
|
||||
|
||||
// js-format specs
|
||||
// MODULES: <module name>
|
||||
// ENUMS: {
|
||||
// <enum name>: {
|
||||
// type: <enum type>,
|
||||
// description: <enum description>
|
||||
// }, ...
|
||||
// }
|
||||
// ENUMS_BY_GROUP: {
|
||||
// <enum type>: {
|
||||
// description: <enum group description>
|
||||
// members: [ <enum name>, ... ]
|
||||
// }, ...
|
||||
// }
|
||||
// METHODS: {
|
||||
// <method name>: {
|
||||
// description: <method description>,
|
||||
// params: {
|
||||
// <param name>: {
|
||||
// type: <param type>,
|
||||
// description: <param description >
|
||||
// }, ...
|
||||
// },
|
||||
// return: {
|
||||
// type: <return type>,
|
||||
// description: <return description>
|
||||
// }
|
||||
// }, ...
|
||||
// }
|
||||
// CLASSES: {
|
||||
// <class name>: {
|
||||
// description: <class description>,
|
||||
// methods: { ... },
|
||||
// variables: {
|
||||
// <variable name>: {
|
||||
// type: <variable type>,
|
||||
// description: <variable description>
|
||||
// }
|
||||
// },
|
||||
// enums: { ... },
|
||||
// enums_by_group: { ... }
|
||||
// }, ...
|
||||
// }
|
||||
MODULE: '',
|
||||
ENUMS: {},
|
||||
ENUMS_BY_GROUP: {},
|
||||
METHODS: {},
|
||||
CLASSES: {},
|
||||
|
||||
|
||||
// c -> js type mapping
|
||||
TYPEMAPS: {
|
||||
'^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number',
|
||||
'^bool$': 'Boolean',
|
||||
'^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String' // TODO: verify that String mappings work
|
||||
},
|
||||
|
||||
|
||||
// add command line options for this module
|
||||
addOptions: function(opts) {
|
||||
xml2js.opts = opts;
|
||||
return opts
|
||||
.option('-i, --inputdir [directory]', 'directory for xml files', __dirname + '/xml/mraa')
|
||||
.option('-c, --custom [file]', 'json for customizations', __dirname + '/custom.json')
|
||||
.option('-s, --strict', 'leave out methods/variables if unknown type')
|
||||
},
|
||||
|
||||
|
||||
// parse doxygen xml -> js-format specs
|
||||
// TODO: figure out whether we need to document any protected methods/variables
|
||||
parse: function() {
|
||||
var XML_GRAMMAR_SPEC = 'grammars/xml.peg';
|
||||
var NAMESPACE_SPEC = xml2js.opts.inputdir + '/namespace' + xml2js.opts.module + '.xml';
|
||||
var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; }
|
||||
var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml';
|
||||
xml2js.MODULE = xml2js.opts.module;
|
||||
return Promise.join(createXmlParser(XML_GRAMMAR_SPEC),
|
||||
fs.readFileAsync(NAMESPACE_SPEC, 'utf8'),
|
||||
fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null),
|
||||
function(xmlparser, xml, xml_types) {
|
||||
if (xml_types != null) {
|
||||
_.extend(xml2js.ENUMS, getEnums(xmlparser.parse(xml_types)[0], false));
|
||||
_.extend(xml2js.ENUMS_BY_GROUP, getEnums(xmlparser.parse(xml_types)[0], true));
|
||||
}
|
||||
var spec_c = xmlparser.parse(xml)[0];
|
||||
_.extend(xml2js.ENUMS, getEnums(spec_c, false));
|
||||
_.extend(xml2js.ENUMS_BY_GROUP, getEnums(spec_c, true));
|
||||
_.extend(xml2js.METHODS, getMethods(spec_c));
|
||||
return Promise.all(_.map(getClasses(spec_c), function(c) {
|
||||
return fs.readFileAsync(CLASS_SPEC(c), 'utf8').then(function(xml) {
|
||||
try {
|
||||
var spec_c = xmlparser.parse(xml)[0];
|
||||
var className = getClassName(spec_c);
|
||||
xml2js.CLASSES[className] = {
|
||||
description: getClassDescription(spec_c),
|
||||
enums: getEnums(spec_c, false, className),
|
||||
enums_by_group: getEnums(spec_c, true, className),
|
||||
variables: getVariables(spec_c, className),
|
||||
methods: getMethods(spec_c, className),
|
||||
};
|
||||
} catch(e) {
|
||||
console.log(e.toString() + ': ' + c + ' was not parsed correctly.');
|
||||
}
|
||||
});
|
||||
})).then(function() {
|
||||
if (fs.existsSync(xml2js.opts.custom)) {
|
||||
return fs.readFileAsync(xml2js.opts.custom, 'utf8').then(function(custom) {
|
||||
try {
|
||||
customizeMethods(JSON.parse(custom));
|
||||
} catch(e) {
|
||||
console.log('invalid custom.json, ignored. ' + e.toString());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log((xml2js.opts.custom == __dirname + '/custom.json') ? 'No customizations given.' : 'Error: No such customization file exists: ' + xml2js.opts.custom);
|
||||
}
|
||||
}).then(function() {
|
||||
validateMethods();
|
||||
validateVars();
|
||||
return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// create an xml parser
|
||||
function createXmlParser(XML_GRAMMAR_SPEC) {
|
||||
return fs.readFileAsync(XML_GRAMMAR_SPEC, 'utf8').then(function(xmlgrammar) {
|
||||
return peg.buildParser(xmlgrammar);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// override autogenerated methods with custom configuration
|
||||
function customizeMethods(custom) {
|
||||
_.each(custom, function(classMethods, className) {
|
||||
_.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) {
|
||||
return isValidMethodSpec(methodSpec, className + '.' + methodName);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// make sure methods have valid types, otherwise warn (& don't include if strict)
|
||||
function validateMethods() {
|
||||
xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) {
|
||||
hasValidTypes(methodSpec, methodName);
|
||||
});
|
||||
_.each(xml2js.CLASSES, function(classSpec, className) {
|
||||
var valid = _.pick(classSpec.methods, function(methodSpec, methodName) {
|
||||
return hasValidTypes(methodSpec, className + '.' + methodName, className);
|
||||
});
|
||||
if (xml2js.opts.strict) {
|
||||
xml2js.CLASSES[className].methods = valid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// make sure variables have valid types, otherwise warn (& don't include if strict)
|
||||
function validateVars() {
|
||||
_.each(xml2js.CLASSES, function(classSpec, className) {
|
||||
var valid = _.pick(classSpec.variables, function(varSpec, varName) {
|
||||
return ofValidType(varSpec, className + '.' + varName, className);
|
||||
});
|
||||
if (xml2js.opts.strict) {
|
||||
xml2js.CLASSES[className].variables = valid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// verify that the json spec is well formatted
|
||||
function isValidMethodSpec(methodSpec, methodName) {
|
||||
var valid = true;
|
||||
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); });
|
||||
function checkRule(rule, errMsg) {
|
||||
if (!rule) {
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' ' + errMsg);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
checkRule(_.has(methodSpec, 'description'), 'no description given');
|
||||
checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)');
|
||||
_.each(methodSpec.params, function(paramSpec, paramName) {
|
||||
checkRule(_.has(paramSpec, 'type'), 'no type given for param ' + paramName);
|
||||
checkRule(_.has(paramSpec, 'description'), 'no description given for param ' + paramName);
|
||||
});
|
||||
checkRule(_.has(methodSpec, 'return'), 'no return given (specify "return": {} for no return value)');
|
||||
checkRule(_.has(methodSpec.return, 'type'), 'no type given for return value');
|
||||
checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value');
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
// get enum specifications
|
||||
function getEnums(spec_c, bygroup, parent) {
|
||||
var spec_js = {};
|
||||
var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return ((kind == 'enum') || (kind == 'public-type'));
|
||||
});
|
||||
if (enumGroups) {
|
||||
_.each(enumGroups.children, function(enumGroup) {
|
||||
var enumGroupName = getText(getChild(enumGroup, 'name'), 'name');
|
||||
var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description');
|
||||
var enumGroupVals = getChildren(enumGroup, 'enumvalue');
|
||||
if (bygroup) {
|
||||
spec_js[enumGroupName] = {
|
||||
description: enumGroupDescription,
|
||||
members: []
|
||||
};
|
||||
}
|
||||
_.each(enumGroupVals, function(e) {
|
||||
// TODO: get prefix as option
|
||||
var enumName = getText(getChild(e, 'name'), 'name').replace(/^MRAA_/, '');
|
||||
var enumDescription = getText(getChild(e, 'detaileddescription'), 'description');
|
||||
if (!bygroup) {
|
||||
spec_js[enumName] = {
|
||||
type: enumGroupName,
|
||||
description: enumDescription
|
||||
};
|
||||
} else {
|
||||
spec_js[enumGroupName].members.push(enumName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get the classes (xml file names) for the given module
|
||||
function getClasses(spec_c) {
|
||||
return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) {
|
||||
return getAttr(innerclass, 'refid');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get the description of the class
|
||||
function getClassDescription(spec_c) {
|
||||
return getText(getChild(spec_c, 'detaileddescription'), 'description');
|
||||
}
|
||||
|
||||
|
||||
function hasParams(paramsSpec) {
|
||||
return !(_.isEmpty(paramsSpec) ||
|
||||
((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void'));
|
||||
}
|
||||
|
||||
|
||||
// get method specifications for top-level module or a given class
|
||||
// TODO: overloaded functions
|
||||
// TODO: functions w/ invalid parameter(s)/return
|
||||
function getMethods(spec_c, parent) {
|
||||
var spec_js = {};
|
||||
var methods = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return ((kind == 'public-func') || (kind == 'func'));
|
||||
});
|
||||
if (methods) {
|
||||
_.each(methods.children, function(method) {
|
||||
var methodName = getText(getChild(method, 'name'), 'name');
|
||||
if (methodName[0] != '~') { // filter out destructors
|
||||
try {
|
||||
var description = getChild(method, 'detaileddescription');
|
||||
var methodDescription = getText(description, 'description');
|
||||
var paramsSpec = getChildren(method, 'param');
|
||||
var params = {};
|
||||
if (hasParams(paramsSpec)) {
|
||||
params = getParams(paramsSpec, getParamsDetails(description), (parent ? (parent + '.') : '') + methodName);
|
||||
}
|
||||
var returnSpec = getChild(method, 'type');
|
||||
var retval = {};
|
||||
if (!_.isEmpty(returnSpec)) {
|
||||
retval = getReturn(returnSpec, getReturnDetails(description));
|
||||
}
|
||||
spec_js[methodName] = {
|
||||
description: methodDescription,
|
||||
params: params,
|
||||
return: retval
|
||||
};
|
||||
} catch(e) {
|
||||
console.log((parent ? (parent + '.') : '') + methodName + ' is omitted from JS documentation.');
|
||||
console.log(' ' + e.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get variable specifications for a class
|
||||
function getVariables(spec_c, parent) {
|
||||
var spec_js = {};
|
||||
var vars = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return (kind == 'public-attrib');
|
||||
});
|
||||
if (vars) {
|
||||
_.each(_.filter(vars.children, function(variable) {
|
||||
return (getAttr(variable, 'kind') == 'variable');
|
||||
}), function(variable) {
|
||||
var varName = getText(getChild(variable, 'name'), 'name');
|
||||
var varType = getType(getText(getChild(variable, 'type')));
|
||||
var varDescription = getText(getChild(variable, 'detaileddescription'));
|
||||
spec_js[varName] = {
|
||||
type: varType,
|
||||
description: varDescription
|
||||
}
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get return value specs of a method
|
||||
function getReturn(spec_c, details) {
|
||||
var retType = getType(getText(spec_c, 'type'));
|
||||
var retDescription = (details ? getText(details, 'description') : '');
|
||||
return ((retType == 'void') ? {} : {
|
||||
type: retType,
|
||||
description: retDescription
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get paramater specs of a method
|
||||
function getParams(spec_c, details, method) {
|
||||
var spec_js = {};
|
||||
_.each(spec_c, function(param) {
|
||||
try {
|
||||
var paramType = getType(getText(getChild(param, 'type'), 'type'));
|
||||
var paramName = getText(getChild(param, 'declname'), 'name');
|
||||
spec_js[paramName] = { type: paramType };
|
||||
} catch(e) {
|
||||
if (paramType == '...') {
|
||||
spec_js['arguments'] = { type: paramType };
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
_.each(details, function(param) {
|
||||
var getParamName = function(p) { return getText(getChild(getChild(p, 'parameternamelist'), 'parametername'), 'name'); }
|
||||
var paramName = getParamName(param);
|
||||
var paramDescription = getText(getChild(param, 'parameterdescription'), 'description');
|
||||
if (_.has(spec_js, paramName)) {
|
||||
spec_js[paramName].description = paramDescription;
|
||||
} else {
|
||||
var msg = ' has documentation for an unknown parameter: ' + paramName + '. ';
|
||||
var suggestions = _.difference(_.keys(spec_js), _.map(details, getParamName));
|
||||
var msgAddendum = (!_.isEmpty(suggestions) ? ('Did you mean ' + suggestions.join(', or ') + '?') : '');
|
||||
console.log('Warning: ' + method + msg + msgAddendum);
|
||||
}
|
||||
});
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get the equivalent javascript type from the given c type
|
||||
function getType(type_c) {
|
||||
var type_js = type_c;
|
||||
_.find(xml2js.TYPEMAPS, function(to, from) {
|
||||
var pattern = new RegExp(from, 'i');
|
||||
if (type_c.search(pattern) == 0) {
|
||||
type_js = to;
|
||||
}
|
||||
});
|
||||
// TODO: temporary solution
|
||||
// remove extra whitespace from pointers
|
||||
// permanent solution would be to get rid of pointers all together
|
||||
if (type_js.search(/\S+\s*\*$/) != -1) {
|
||||
type_js = type_js.replace(/\s*\*$/, '*');
|
||||
}
|
||||
return type_js;
|
||||
}
|
||||
|
||||
|
||||
// verify that all types associated with the method are valid
|
||||
function hasValidTypes(methodSpec, methodName, parent) {
|
||||
var valid = true;
|
||||
var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).');
|
||||
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); });
|
||||
_.each(methodSpec.params, function(paramSpec, paramName) {
|
||||
if (!isValidType(paramSpec.type, parent)) {
|
||||
valid = false;
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' Error: parameter ' + paramName + ' has invalid type ' + paramSpec.type);
|
||||
}
|
||||
});
|
||||
if (!_.isEmpty(methodSpec.return) && !isValidType(methodSpec.return.type, parent)) {
|
||||
valid = false;
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' Error: returns invalid type ' + methodSpec.return.type);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
// verify that type of variable is valid
|
||||
function ofValidType(varSpec, varName, parent) {
|
||||
if (isValidType(varSpec.type, parent)) {
|
||||
return true;
|
||||
} else {
|
||||
var msgAddendum = (xml2js.opts.strict ? ' Omitted from JS documentation.' : '');
|
||||
console.log('Error: ' + varName + ' is of invalid type ' + varSpec.type + '.' + msgAddendum);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// verify whether the given type is valid JS
|
||||
// TODO: check class-specific types
|
||||
function isValidType(type, parent) {
|
||||
return (_.contains(_.values(xml2js.TYPEMAPS), type) ||
|
||||
_.has(xml2js.CLASSES, type) ||
|
||||
_.has(xml2js.ENUMS_BY_GROUP, type) ||
|
||||
_.contains(['Buffer', 'Function', 'mraa_result_t'], type) ||
|
||||
_.has((parent ? xml2js.CLASSES[parent].enums_by_group : []), type));
|
||||
}
|
||||
|
||||
|
||||
// determines whether a type looks like a c pointer
|
||||
function isPointer(type) {
|
||||
return (type.search(/\w+\s*\*/) != -1);
|
||||
}
|
||||
|
||||
|
||||
// get the detailed description of a method's parameters
|
||||
function getParamsDetails(spec_c) {
|
||||
var paras = getChildren(spec_c, 'para');
|
||||
var details = _.find(_.map(paras, function(para) {
|
||||
return getChild(para, 'parameterlist');
|
||||
}), function(obj) { return (obj != undefined); });
|
||||
return (details ? details.children : undefined);
|
||||
}
|
||||
|
||||
|
||||
// get the detailed description of a method's return value
|
||||
function getReturnDetails(spec_c) {
|
||||
var paras = getChildren(spec_c, 'para');
|
||||
return _.find(_.map(paras, function(para) {
|
||||
return getChild(para, 'simplesect');
|
||||
}), function(obj) { return ((obj != undefined) && (getAttr(obj, 'kind') == 'return')); });
|
||||
}
|
||||
|
||||
|
||||
// get (and flatten) the text of the given object
|
||||
function getText(obj, why) {
|
||||
// TODO: links ignored for now, patched for types for
|
||||
var GENERATE_LINK = function(x) { return x + ' '; }
|
||||
return _.reduce(obj.children, function(text, elem) {
|
||||
if (_.isString(elem)) {
|
||||
return text += elem.trim() + ' ';
|
||||
} else if (_.isPlainObject(elem)) {
|
||||
switch(elem.name) {
|
||||
case 'para':
|
||||
return text += getText(elem, why) + ' \n';
|
||||
case 'ref':
|
||||
return text += GENERATE_LINK(getText(elem, why));
|
||||
case 'parameterlist':
|
||||
case 'simplesect':
|
||||
return text; // to be handled elsewhere
|
||||
case 'programlisting':
|
||||
case 'htmlonly':
|
||||
return text; // ignored
|
||||
// TODO: html doesn't seem to work, using markdown for now
|
||||
case 'itemizedlist':
|
||||
return text += '\n' + getText(elem, why) + '\n';
|
||||
case 'listitem':
|
||||
return text += '+ ' + getText(elem, why) + '\n';
|
||||
case 'bold':
|
||||
return text += '__' + getText(elem, why).trim() + '__ ';
|
||||
case 'ulink':
|
||||
return text += '[' + getText(elem, why).trim() + '](' + getAttr(elem, 'url').trim() + ') ';
|
||||
case 'image':
|
||||
// TODO: copy images over; hard coded for now
|
||||
var fn = getAttr(elem, 'name');
|
||||
return text += ' \n \n ';
|
||||
case 'linebreak':
|
||||
return text += ' \n';
|
||||
case 'ndash':
|
||||
return text += '– ';
|
||||
default:
|
||||
// TODO: incomplete list of doxygen xsd implemented
|
||||
throw new Error('NYI Unknown Object Type: ' + elem.name);
|
||||
}
|
||||
} else {
|
||||
throw new Error('NYI Unknown Type: ' + (typeof elem));
|
||||
}
|
||||
}, '').trim();
|
||||
}
|
||||
|
||||
|
||||
// get the value of attribute with the given name of the given object
|
||||
function getAttr(obj, name) {
|
||||
return _.find(obj.attr, function(item) {
|
||||
return item.name == name;
|
||||
}).value;
|
||||
}
|
||||
|
||||
|
||||
// get the child object with the given name of the given object
|
||||
function getChild(obj, name) {
|
||||
return _.find(obj.children, function(child) {
|
||||
return child.name == name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get all children objects with the given name of the given object
|
||||
function getChildren(obj, name) {
|
||||
return _.filter(obj.children, function(child) {
|
||||
return child.name == name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get the class name from its xml spec
|
||||
function getClassName(spec_c) {
|
||||
return getText(getChild(spec_c, 'compoundname'), 'name').replace(xml2js.opts.module + '::', '');
|
||||
}
|
||||
|
||||
|
||||
// debug helper: print untruncated object
|
||||
function printObj(obj) {
|
||||
console.log(util.inspect(obj, false, null));
|
||||
}
|
||||
|
||||
|
||||
module.exports = xml2js;
|
Loading…
x
Reference in New Issue
Block a user