Skip to content
This repository has been archived by the owner on May 19, 2021. It is now read-only.

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Pita committed May 29, 2011
0 parents commit 0a8b823
Show file tree
Hide file tree
Showing 10 changed files with 540 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .npmignore
@@ -0,0 +1,3 @@
exampleSRC
exampleDOC
README.md
13 changes: 13 additions & 0 deletions README.md
@@ -0,0 +1,13 @@
#About
I created doc.md cause all the jsdoc tools I found were too complex or doesn't do what I wanted. So I decided to create my own jsdoc tool. It creates markdown, this makes it possible to look at the documentation directly in Github.

#Install
`npm install -g doc.md`

#Usage

doc.md $SRCFOLDER $DESTFOLDER

#LICENSE
Apache License v2 <http://www.apache.org/licenses/LICENSE-2.0.html>

37 changes: 37 additions & 0 deletions exampleDOC/blub/test.md
@@ -0,0 +1,37 @@
#blub
`require("./blub/test");`

This is an example module

##Functions

###`test (a, b)`
This is the first test function

* **a** *(String)* Parameter is text
* **b** *(Number)* B is a number, its 42

###`test2 (a, b)`
This is an example module

* **a** *(Number)* a ist 21, the half answer
* **b** We don't know what b ist

###`test3 (d, k, a)`

* **d**
* **k**
* **a**

##Variables

###bla
bla ist another unimportant variable that we export
why? cause we can!

###blink


###foo *(object)*
Just a variable

44 changes: 44 additions & 0 deletions exampleSRC/blub/test.js
@@ -0,0 +1,44 @@
/**
This is an example module
*/

/**
* This is our second test function
* @param b We don't know what b ist
* @param a {Number} a ist 21, the half answer
* @return {void} nothing
* ...
*/
exports.test2=function( a, b)
{
console.log("test2");
}

/**
* This is the first test function
* @param a {String} Parameter is text
* @param b {Number} B is a number, its 42
*/
exports.test = function(a,b)
{
console.log("test");
}

/**
* bla ist another unimportant variable that we export
* why? cause we can!
*/
exports.bla = "content";

/**
* Just a variable
* @type object
*/
exports.foo = {foo: "bar"}

exports.blink = "yeah!";

exports.test3 = function(d ,k , a)
{
console.log("test3");
}
Empty file added exampleSRC/test
Empty file.
Empty file added exampleSRC/test2
Empty file.
87 changes: 87 additions & 0 deletions index.js
@@ -0,0 +1,87 @@
#!/usr/bin/env node

/**
* 2011 Peter 'Pita' Martischka
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var parser = require('./parser');
var writer = require('./writer');
var fs = require("fs");
var path = require("path");

if(process.argv.length != 4)
{
console.error("Usage: doc.md $SRCFOLDER $DESTFOLDER");
process.exit(1);
}

var srcFolder = process.argv[2];
var destFolder = process.argv[3];

//check src Directory
var srcValid = false;
try
{
srcValid = fs.lstatSync(srcFolder).isDirectory();
} catch(e) {};

if(!srcValid)
{
console.error("'"+srcFolder + "' is no directory!");
process.exit(1);
}

//check dest directory
var destValid = false;
try
{
destValid = fs.lstatSync(destFolder).isDirectory();
} catch(e) {};

if(!destValid)
{
console.error("'"+destFolder + "' is no directory!");
process.exit(1);
}

//start recursive function
doFolder(srcFolder, ".");

function doFolder(srcFolder, folder)
{
//get the path and files
var folderPath = path.normalize(srcFolder + "/" + folder);
var files = fs.readdirSync(folderPath);

//go trough all files in this folder
for(var i in files)
{
var absolutePath = path.normalize(folderPath + "/" + files[i]);
var relativePath = path.normalize(folder + "/" + files[i]);
var isDirectory = fs.lstatSync(absolutePath).isDirectory();

//if this is a folder, call function recursively
if(isDirectory)
{
doFolder(srcFolder, relativePath);
}
//if this is a javascript file, parse it
else if(absolutePath.search(/.js$/) != -1)
{
var parsedObj = parser.parseFile(srcFolder, relativePath);
writer.parsedObj2md(destFolder, parsedObj);
}
}
}
11 changes: 11 additions & 0 deletions package.json
@@ -0,0 +1,11 @@
{
"name" : "doc.md",
"description" : "A simple JSDoc documenation tool that creates markdown for node.js modules",
"homepage" : "https://github.com/Pita/doc.md",
"keywords" : ["jsdoc", "documenation", "markdown"],
"author" : "Peter 'Pita' Martischka <petermartischka@googlemail.com>",
"version" : "0.0.1",
"bin" : {
"doc.md" : "./index.js"
}
}
197 changes: 197 additions & 0 deletions parser.js
@@ -0,0 +1,197 @@
var fs = require("fs");

/**
* 2011 Peter 'Pita' Martischka
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* This is the parser, it generates a object out of a javascript file
* @param filename, the file you wanna parse
*/
exports.parseFile = function(baseFolder, filename)
{
console.error("parse file '" + baseFolder + "/" + filename + "'...");

var parsedObj = {};

//get the name of the module
var name = filename.substr(filename.lastIndexOf("/")+1);
name = filename.substr(0,name.lastIndexOf(".js"));
parsedObj.name = name;

//get the require path
var requirePath = "./" + filename.replace(/.js$/,"");
parsedObj.path = requirePath;

//read the file
var code = fs.readFileSync(baseFolder + "/" + filename, "utf8");

//search the comment of the document
var docCommentRegExp = /^\s*\/\*\*((.|\n|\r)*?)\*\//m;
var match = docCommentRegExp.exec(code);
if(match != null)
{
var docComment = match[1];
docComment = docComment.replace(/\n\s*\*\s*/mg, "\n");
docComment = trimStr(docComment);
parsedObj.comment = docComment;
}

//get all exported functions with a regular expression
var functions = [];
var functionsRegExp = /exports.([a-zA-Z_$][0-9a-zA-Z_$]*)\s*=\s*function\s*\(([0-9a-zA-Z_$,\s]*)\)*/gm;
var match = functionsRegExp.exec(code);
while(match != null)
{
functions.push(match);
match = functionsRegExp.exec(code);
}

parsedObj.functions = {};

//go trough the functions and move all information to the parsedObj
for(var i in functions)
{
//create a entry for the name
var functionName = functions[i][1];
parsedObj.functions[functionName] = {param: []};

//get the params
var functionParam = functions[i][2].split(",");

//trim the params and add them to the obj
for(var i in functionParam)
{
var paramName = trimStr(functionParam[i]);

//parsedObj.functions[functionName].param[paramName] = {};
parsedObj.functions[functionName].param.push({name: paramName})
}
}

//get all exported variables with a regular expression
parsedObj.variables = {};
var variableRegExp = /exports.([a-zA-Z_$][0-9a-zA-Z_$]*)\s*=\s*/gm;
var match = variableRegExp.exec(code);
while(match != null)
{
var varname = match[1];

if(!parsedObj.functions[varname])
{
parsedObj.variables[varname] = {};
}

match = variableRegExp.exec(code);
}

//search all jsdoc blocks in front of a exports variable
var jsdocBlocks = {};
var blockRegExp = /(\/\*\*(.|\n|\r)*?\*\/)\s*exports\.([a-zA-Z_$][0-9a-zA-Z_$]*)/mg;
var match = blockRegExp.exec(code);
while(match != null)
{
jsdocBlocks[match[3]] = match[1];
match = blockRegExp.exec(code);
}

//go trough all jsdocblocks
for(var i in jsdocBlocks)
{
//fish all comments out of the jsdoc block
var jsdocBlock = jsdocBlocks[i];
var type = parsedObj.variables[i] ? "var" : "func";
var obj = type == "var" ? parsedObj.variables[i] : parsedObj.functions[i];
var commentRegExp = /\/\*\*((.|\n|\r)*?)(@|\*\/)/m;
var comment = commentRegExp.exec(jsdocBlock)[1];
comment = comment.replace(/\n\s*\*\s*/mg, "\n");
comment = trimStr(comment);

//save the comment
obj.comment = comment;

//search tags in jsdoc block
var tagRegExp = /@([a-zA-Z0-9]+)((.|\n|\r)*?)\*\//mg;
var jsdocBlockEscapedAt = jsdocBlock.replace(/@/g, "*/@");
var match = tagRegExp.exec(jsdocBlockEscapedAt);
while(match != null)
{
var tagType = match[1];
var tagText = match[2];
tagText = tagText.replace(/\n\s*\*\s*/mg, "\n");
tagText = trimStr(tagText);

//if this is a function param
if(tagType == "param" && type == "func")
{
var paramRegExp = /^([a-zA-Z_$][0-9a-zA-Z_$]*)\s*(\{(.*?)\})?\s*((.|\n|\r)*)/m;

var match = paramRegExp.exec(tagText);

var paramName = match[1];
var paramType = match[3];
var paramComment = match[4];

var paramNum = -1;
for(var i in obj.param)
{
if(obj.param[i].name == paramName)
paramNum = i;
}

if(paramNum == -1)
{
console.error("WARN: Parameter does not exist in this function! @param " + paramName);
}
else
{
obj.param[paramNum].comment = paramComment;
obj.param[paramNum].type = paramType;
}
}
//if this is a return tag
else if(tagType == "return" && type == "func")
{
var returnRegExp = /^\s*(\{(.*?)\})?\s*((.|\n|\r)*)/m;

var match = returnRegExp.exec(tagText);

var returnType = match[2];
var returnComment = match[3];

obj.return = {type: returnType, comment: returnComment};
}
else if(tagType == "type" && type == "var")
{
obj.type = tagText;
}
else
{
console.error("WARN: Unknown Tag @"+tagType + ": " + paramComment);
}

match = tagRegExp.exec(jsdocBlockEscapedAt);
}
}

console.log("done");

return parsedObj;
}

function trimStr(str)
{
return str.replace(/^\s*/, "").replace(/\s*$/,"");
}

0 comments on commit 0a8b823

Please sign in to comment.