Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation Index and subdirectories parsing #65

Merged
merged 43 commits into from
Sep 4, 2014
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ca43acd
index creation feature, need to make it cleaner now
vdeturckheim Sep 2, 2014
ac03949
index example (ugly location)
vdeturckheim Sep 2, 2014
b4f79fa
fix '/' char probleme in export;Github friendly
vdeturckheim Sep 2, 2014
3700130
Update README.md
vdeturckheim Sep 2, 2014
b21a716
Update README.md
vdeturckheim Sep 2, 2014
61dfe50
Update README.md
vdeturckheim Sep 2, 2014
5295b3a
Update README.md
vdeturckheim Sep 2, 2014
5744dab
Update README.md
vdeturckheim Sep 2, 2014
5802878
Update index.md
vdeturckheim Sep 2, 2014
7ec9904
stuff
vdeturckheim Sep 2, 2014
9da1bcf
Merge branch 'master' of github.com:vdeturckheim/jsdox
vdeturckheim Sep 2, 2014
2c75002
idem
vdeturckheim Sep 2, 2014
51a466c
command line OK
vdeturckheim Sep 3, 2014
6e4fc54
add index for live example
vdeturckheim Sep 3, 2014
67f5b10
recursive behavior implemented (-r --recursive)
vdeturckheim Sep 3, 2014
051a517
respect-recursive ok (no doc yet)
vdeturckheim Sep 3, 2014
eb76fe4
testons
vdeturckheim Sep 3, 2014
c052e40
still testing
vdeturckheim Sep 3, 2014
354b645
documentation --rr option ok
vdeturckheim Sep 3, 2014
62f0f11
index is now in the output file
vdeturckheim Sep 3, 2014
c7aff49
fix bug in classes in index
vdeturckheim Sep 3, 2014
41055cb
Update README.md
vdeturckheim Sep 3, 2014
4267cee
unit tests ok
vdeturckheim Sep 3, 2014
e947600
Merge branch 'master' of github.com:vdeturckheim/jsdox
vdeturckheim Sep 3, 2014
8771342
update README
vdeturckheim Sep 3, 2014
80a8603
add example files
vdeturckheim Sep 3, 2014
7e3ee01
fix README
vdeturckheim Sep 3, 2014
47639ae
update README
vdeturckheim Sep 3, 2014
862cf67
fixed test, for everything to change nothing must change
vdeturckheim Sep 3, 2014
8d8a81b
Update README.md
vdeturckheim Sep 3, 2014
5ead8ab
Update .gitignore
vdeturckheim Sep 3, 2014
81c83c9
delete example for pull request
vdeturckheim Sep 3, 2014
7250608
fix tests
vdeturckheim Sep 3, 2014
0678b7b
Merge branch 'master' of github.com:vdeturckheim/jsdox
vdeturckheim Sep 3, 2014
b613458
online examples are back
vdeturckheim Sep 3, 2014
4748f0a
indent fixing #1
vdeturckheim Sep 3, 2014
694639b
indent fixing
vdeturckheim Sep 3, 2014
d07089f
indent fixing
vdeturckheim Sep 3, 2014
c7723c7
fix indent
vdeturckheim Sep 3, 2014
ce8895d
Updating README.md
vdeturckheim Sep 3, 2014
cb1999e
idem
vdeturckheim Sep 3, 2014
d22022b
indent fixing
vdeturckheim Sep 3, 2014
8f51ca4
Update README.md
vdeturckheim Sep 4, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ lib-cov
*.pid
*.gz


pids
logs
output
Expand Down Expand Up @@ -39,4 +40,4 @@ ehthumbs.db
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/
$RECYCLE.BIN/
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ jsdox is a simple jsdoc 3 generator. It pulls documentation tags based on a sub

Relies on the [JSDoc3 parser](https://github.com/mrjoelkemp/jsdoc3-parser) to get the full AST including comments.

### CLI Options
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks much better. Thank you.


Usage: `jsdox [options] <file | directory>`

`--config <file>` (alias `-c`): Configuration JSON file.

`--All` (alias `-A`): Generates documentation for all available elements including internal methods.

`--debug` (alias `-d`): Prints debugging information to the console.

`--help` (alias `-H`): Prints help and quits.

`--version` (alias `-v`): Prints the current version and quits.

`--output` (alias `-o`): Output directory. Default value is 'output'.

`--templateDir` (alias `-t`): Template directory to use instead of built-in ones.

`--index` (alias `-i`): Generates an index with the documentation. A file name can be provided in argument. Default value is 'index'.

`--recursive` (alias `-r`): Generates documentation in all subdirectories of the source folder.

`--respect-recursive` (alias `--rr`): Generate subdirectories and copy the original organization of the sources.


# Resources
* [jsdox](http://jsdox.org) Documentation
* Github [repo](https://github.com/sutoiku/jsdox)
Expand Down
File renamed without changes.
File renamed without changes.
172 changes: 144 additions & 28 deletions jsdox.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,24 @@ var
.options('templateDir', {
alias: 't'
})
.options('index', {
alias: 'i'
})
.options('recursive',{
alias: 'r'
})
.options('respect-recursive', {
alias: 'rr'
})
.argv,
packageJson = require('./package.json'),
jsdocParser = require('jsdoc3-parser'),
analyze = require('./lib/analyze'),
generateMD = require('./lib/generateMD');
generateMD = require('./lib/generateMD'),
index= {
classes: [],
functions: []
};

function inspect(text) {
return util.inspect(text, false, 20);
Expand All @@ -58,13 +71,17 @@ function printHelp(){
console.log('Usage:\tjsdox [options] <file | directory>');
console.log('\tjsdox --All --output docs folder\n');
console.log('Options:');
console.log(' -c, --config \t<file>\t Configuration JSON file.');
console.log(' -A, --All\t\t Generates documentation for all available elements including internal methods.');
console.log(' -d, --debug\t\t Prints debugging information to the console.');
console.log(' -H, --help\t\t Prints this message and quits.');
console.log(' -v, --version\t\t Prints the current version and quits.');
console.log(' -o, --output\t\t Output directory.');
console.log(' -t, --templateDir\t Template directory to use instead of built-in ones.');
console.log(' -c,\t--config \t<file>\t Configuration JSON file.');
console.log(' -A,\t--All\t\t\t Generates documentation for all available elements including internal methods.');
console.log(' -d,\t--debug\t\t\t Prints debugging information to the console.');
console.log(' -H,\t--help\t\t\t Prints this message and quits.');
console.log(' -v,\t--version\t\t Prints the current version and quits.');
console.log(' -o,\t--output\t\t Output directory.');
console.log(' -t,\t--templateDir\t\t Template directory to use instead of built-in ones.');
console.log(' -i,\t--index\t\t\t Generates an index with the documentation. A file name can be provided in argument.');
console.log(' -r,\t--recursive\t\t Generates documentation in all subdirectories of the directory given as argument.');
console.log(' --rr,\t--respect-recursive\t Will generate subdirectories and copy the original organization of the sources.');

process.exit();
}

Expand All @@ -85,8 +102,27 @@ function generateForDir(filename, destination, templateDir, cb, fileCb) {
touched = 0,
error = null;

var readdirSyncRec = function(dir, filelist) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a separate module in lib/ with tests (mock the actual file system interaction for speed).

var files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function(file) {
if (fs.statSync(path.join(dir,file)).isDirectory()) {
filelist = readdirSyncRec(path.join(dir,file), filelist);
}
else {
filelist.push(path.join(dir,file));
}
});
return filelist;
};

function oneFile(directory, file, cb) {
var fullpath = path.join(destination, file);
var fullpath;
if(argv.rr) {
fullpath = path.join(path.join(destination, path.dirname(file)), path.basename(file));
}else{
fullpath = path.join(destination, file);
}
fullpath = fullpath.replace(/\.js$/, '.md');

if (argv.debug) {
Expand All @@ -95,7 +131,7 @@ function generateForDir(filename, destination, templateDir, cb, fileCb) {

waiting++;

jsdocParser(path.join(directory, file), function(err, result) {
jsdocParser(path.join(directory, path.basename(file)), function(err, result) {
if (err) {
console.error('Error generating docs for file', file, err);
waiting--;
Expand All @@ -114,6 +150,28 @@ function generateForDir(filename, destination, templateDir, cb, fileCb) {
var data = analyze(result, argv),
output = generateMD(data, templateDir);


if(argv.index) {
for (var i = 0; i < data.functions.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love for all of this logic to be abstracted into a separate module to keep jsdox.js as clean as possible. It also makes it easier to unit test that module in isolation.

if (data.functions[i].className === undefined) {
var toAddFct = data.functions[i];
toAddFct.file = path.relative(destination,fullpath);
toAddFct.sourcePath = path.relative(destination,path.join(directory,path.basename(file)));
index.functions.push(toAddFct);
}
}
for (var j = 0; j < data.classes.length; j++) {
if (data.functions[j].className === undefined) {
var toAddClass = data.classes[j];
toAddClass.file = path.relative(destination,fullpath);
toAddClass.sourcePath = path.relative(destination,path.join(directory,path.basename(file)));
index.classes.push(toAddClass);
}
}
}



if (output) {
fileCb && fileCb(file, data);
fs.writeFile(fullpath, output, function(err) {
Expand All @@ -140,26 +198,64 @@ function generateForDir(filename, destination, templateDir, cb, fileCb) {
oneFile(path.dirname(filename), path.basename(filename), cb);

} else {
fs.stat(filename, function (err, s) {
if (!err && s.isDirectory()) {
fs.readdir(filename, function(err, files) {
if (err) {
console.error('Error generating docs for files', filename, err);
return cb(err);
}
files.forEach(function(file) {
if (file.match(/\.js$/)) {
oneFile(filename, file, cb), touched++;
if(argv.recursive || argv.rr){
fs.stat(filename, function (err, s) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate module with tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to fix this and prepare a new pull request ?

I plan also to take a look at the line number issue in a short future (depending on my uni obligation)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please. You're the best!

if (!err && s.isDirectory()) {
var contentList=readdirSyncRec(filename);
contentList.forEach(function(fileFullPath) {
if(argv.rr){
//create the sub-directories
try{
fs.mkdirSync(path.join(destination,path.dirname(fileFullPath)));
}catch(err){} //lazy way: if the file already exists, everything is alright.
try {
oneFile(path.dirname(fileFullPath), fileFullPath, cb), touched++;
}catch(err){
console.error('Error generating docs for files', path.basename(fileFullPath), err);
return cb(err);
}
}else {
try{
oneFile(path.dirname(fileFullPath), path.basename(fileFullPath), cb), touched++;
}catch(err){
console.error('Error generating docs for files', path.basename(fileFullPath), err);
return cb(err);
}
}


});
if(!touched) {
cb();
}
});
} else {
cb();
}
});

} else {
cb();
}
});
}else {
fs.stat(filename, function (err, s) {
if (!err && s.isDirectory()) {
fs.readdir(filename, function (err, files) {
if (err) {
console.error('Error generating docs for files', filename, err);
return cb(err);
}
files.forEach(function (file) {
if (file.match(/\.js$/)) {
oneFile(filename, file, cb), touched++;
}
});
if (!touched) {
cb();
}
});
} else {
cb();
}
});
}

}
}

Expand Down Expand Up @@ -214,9 +310,29 @@ function main(){

return deferred.promise;
}))
.then(function () {
console.log('jsdox completed');
});
.then(function(){
//create index
if(argv.index) {
var fileName;
if(argv.index===true){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around operators.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, a bunch of spaces missing. I also like to see spaces after if, before opening {, after , and a few more. Was planning to go through these today, but this might will have to be next week for me now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated my IDE settings to be compliant with spacing rules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. We'll have tooling soon (JSCS) that will have travis-ci fail your PR for the styling violations.

fileName='index';
}else{
fileName=argv.index;
}
if(typeof argv.output === 'string'){
fileName=path.join(argv.output,fileName);
}else{
fileName=path.join('output',fileName);
}
fs.writeFileSync(fileName+'.md', generateMD(index, argv.templateDir, true));
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty spacing.



})
.then(function () {
console.log('jsdox completed');
});
});
} else {
console.error('Error missing input file or directory.');
Expand Down
43 changes: 36 additions & 7 deletions lib/generateMD.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,49 @@ var Mustache = require('mustache'),
* @param {String} templateDir - templates directory (optional)
* @return {String} Markdown output
*/
module.exports = function(ast, templateDir) {
module.exports = function(ast, templateDir, isIndex) {
if (!ast) { throw new Error('no analyzed ast to generate markdown from'); }

var templates;

if (!templateDir) {
templateDir = path.resolve(__dirname, '../templates');
} else {
templateDir = templateDir.replace(/\\/g, '/');
}

var templates = {
file: fs.readFileSync(templateDir + '/file.mustache', 'utf8'),
class: fs.readFileSync(templateDir + '/class.mustache', 'utf8'),
function: fs.readFileSync(templateDir + '/function.mustache', 'utf8')
};
//if ast is an index file, we need to sort the contents and to use the right templates;
if(isIndex){
console.log('Now generating index');
ast.classes.sort(function(a,b){
if(a.name< b.name){
return -1;
}else{
return 1;
}
});
ast.functions.sort(function(a,b){
if(a.name< b.name){
return -1;
}else{
return 1;
}
});

templates = {
index: fs.readFileSync(templateDir + '/index.mustache', 'utf8'),
class: fs.readFileSync(templateDir + '/overview.mustache', 'utf8'),//do we need different overview templates for functions or classes here ?
function: fs.readFileSync(templateDir + '/overview.mustache', 'utf8')
};
return Mustache.render(templates.index, ast, templates);;
}else {

return Mustache.render(templates.file, ast, templates);

templates = {
file: fs.readFileSync(templateDir + '/file.mustache', 'utf8'),
class: fs.readFileSync(templateDir + '/class.mustache', 'utf8'),
function: fs.readFileSync(templateDir + '/function.mustache', 'utf8')
};
return Mustache.render(templates.file, ast, templates);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.