diff options
Diffstat (limited to 'infrastructure/rhino1_7R1/examples/jsdoc.js')
-rw-r--r-- | infrastructure/rhino1_7R1/examples/jsdoc.js | 556 |
1 files changed, 556 insertions, 0 deletions
diff --git a/infrastructure/rhino1_7R1/examples/jsdoc.js b/infrastructure/rhino1_7R1/examples/jsdoc.js new file mode 100644 index 0000000..3d44e48 --- /dev/null +++ b/infrastructure/rhino1_7R1/examples/jsdoc.js @@ -0,0 +1,556 @@ +/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Rhino code, released + * May 6, 1999. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1997-1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Norris Boyd + * Roland Pennings + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License Version 2 or later (the "GPL"), in which + * case the provisions of the GPL are applicable instead of those above. If + * you wish to allow use of your version of this file only under the terms of + * the GPL and not to allow others to use your version of this file under the + * MPL, indicate your decision by deleting the provisions above and replacing + * them with the notice and other provisions required by the GPL. If you do + * not delete the provisions above, a recipient may use your version of this + * file under either the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * Process a JavaScript source file and process special comments + * to produce an HTML file of documentation, similar to javadoc. + * @author Norris Boyd + * @see rhinotip.jar + * @lastmodified xx + * @version 1.2 Roland Pennings: Allow multiple files for a function. + * @version 1.3 Roland Pennings: Removes ../.. from the input directory name + */ +defineClass("File") + +var functionDocArray = []; +var inputDirName = ""; +var indexFileArray = []; +var indexFile = ""; +var indexFileName = "index_files"; +var indexFunctionArray = []; +var indexFunction = ""; +var indexFunctionName = "index_functions"; +var FileList = []; +var DirList = []; +var outputdir = null; +var debug = 0; + + + +/** + * Process JavaScript source file <code>f</code>, writing jsdoc to + * file <code>out</code>. + * @param f input file + * @param fname name of the input file (without the path) + * @param inputdir directory of the input file + * @param out output file + */ +function processFile(f, fname, inputdir, out) { + var s; + var firstLine = true; + indexFileArray[fname] = ""; + + // write the header of the output file + out.writeLine('<HTML><HEADER><TITLE>' + fname + '</TITLE><BODY>'); + if (inputdir != null) { + outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> '; + outstr += '<a href=\"' + indexFunction + '\">Index Functions</a></pre><hr>'; + out.writeLine(outstr); + } + + // process the input file + var comment = ""; + while ((s = f.readLine()) != null) { + var m = s.match(/\/\*\*(.*)/); + if (m != null) { + // Found a comment start. + s = "*" + m[1]; + do { + m = s.match(/(.*)\*\//); + if (m != null) { + // Found end of comment. + comment += m[1]; + break; + } + // Strip leading whitespace and "*". + comment += s.replace(/^\s*\*/, ""); + s = f.readLine(); + } while (s != null); + + if (debug) + print("Found comment " + comment); + + if (firstLine) { + // We have a comment for the whole file. + out.writeLine('<H1>File ' + fname + '</H1>'); + out.writeLine(processComment(comment,firstLine,fname)); + out.writeLine('<HR>'); + firstLine = false; + comment = ""; + continue; + } + } + // match the beginning of the function + // NB we also match functions without a comment! + // if we have two comments one after another only the last one will be taken + m = s.match(/^\s*function\s+((\w+)|(\w+)(\s+))\(([^)]*)\)/); + if (m != null) + { + // Found a function start + var htmlText = processFunction(m[1], m[5], comment); // sjm changed from 2nd to 5th arg + + // Save the text in a global variable, so we + // can write out a table of contents first. + functionDocArray[functionDocArray.length] = {name:m[1], text:htmlText}; + + // Store the function also in the indexFunctionArray + // so we can have a separate file with the function table of contents + if (indexFunctionArray[m[1]]) { + // print("ERROR: function: " + m[1] + " is defined more than once!"); + // Allow multiple files for a function + with (indexFunctionArray[m[1]]) { + filename = filename + "|" + fname; + // print("filename = " + filename); + } + } + else { + indexFunctionArray[m[1]] = {filename:fname}; + } + //reset comment + comment = ""; + } + // match a method being bound to a prototype + m = s.match(/^\s*(\w*)\.prototype\.(\w*)\s*=\s*function\s*\(([^)]*)\)/); + if (m != null) + { + // Found a method being bound to a prototype. + var htmlText = processPrototypeMethod(m[1], m[2], m[3], comment); + + // Save the text in a global variable, so we + // can write out a table of contents first. + functionDocArray[functionDocArray.length] = {name:m[1]+".prototype."+m[2], text:htmlText}; + + // Store the function also in the indexFunctionArray + // so we can have a separate file with the function table of contents + if (indexFunctionArray[m[1]]) { + // print("ERROR: function: " + m[1] + " is defined more than once!"); + // Allow multiple files for a function + with (indexFunctionArray[m[1]]) { + filename = filename + "|" + fname; + // print("filename = " + filename); + } + } + else { + indexFunctionArray[m[1]] = {filename:fname}; + } + //reset comment + comment = ""; + } + + + firstLine = false; + } + + // Write table of contents. + for (var i=0; i < functionDocArray.length; i++) { + with (functionDocArray[i]) { + out.writeLine('function <A HREF=#' + name + + '>' + name + '</A><BR>'); + } + } + out.writeLine('<HR>'); + + // Now write the saved function documentation. + for (i=0; i < functionDocArray.length; i++) { + with (functionDocArray[i]) { + out.writeLine('<A NAME=' + name + '>'); + out.writeLine(text); + } + } + out.writeLine('</BODY></HTML>'); + + // Now clean up the doc array + functionDocArray = []; +} + +/** + * Process function and associated comment. + * @param name the name of the function + * @param args the args of the function as a single string + * @param comment the text of the comment + * @return a string for the HTML text of the documentation + */ +function processFunction(name, args, comment) { + if (debug) + print("Processing " + name + " " + args + " " + comment); + return "<H2>Function " + name + "</H2>" + + "<PRE>" + + "function " + name + "(" + args + ")" + + "</PRE>" + + processComment(comment,0,name) + + "<P><BR><BR>"; +} + +/** + * Process a method being bound to a prototype. + * @param proto the name of the prototype + * @param name the name of the function + * @param args the args of the function as a single string + * @param comment the text of the comment + * @return a string for the HTML text of the documentation + */ +function processPrototypeMethod(proto, name, args, comment) { + if (debug) + print("Processing " + proto + ".prototype." + name + " " + args + " " + comment); + return "<H2> Method " + proto + ".prototype." + name + "</H2>" + + "<PRE>" + + proto + ".prototype." + name + " = function(" + args + ")" + + "</PRE>" + + processComment(comment,0,name) + + "<P><BR><BR>"; +} + + +/** + * Process comment. + * @param comment the text of the comment + * @param firstLine shows if comment is at the beginning of the file + * @param fname name of the file (without path) + * @return a string for the HTML text of the documentation + */ +function processComment(comment,firstLine,fname) { + var tags = {}; + // Use the "lambda" form of regular expression replace, + // where the replacement object is a function rather + // than a string. The function is called with the + // matched text and any parenthetical matches as + // arguments, and the result of the function used as the + // replacement text. + // Here we use the function to build up the "tags" object, + // which has a property for each "@" tag that is the name + // of the tag, and whose value is an array of the + // text following that tag. + comment = comment.replace(/@(\w+)\s+([^@]*)/g, + function (s, name, text) { + var a = tags[name] || []; + a.push(text); + tags[name] = a; + return ""; + }); + + // if we have a comment at the beginning of a file + // store the comment for the index file + if (firstLine) { + indexFileArray[fname] = comment; + } + + var out = comment + '<P>'; + if (tags["param"]) { + // Create a table of parameters and their descriptions. + var array = tags["param"]; + var params = ""; + for (var i=0; i < array.length; i++) { + var m = array[i].match(/(\w+)\s+(.*)/); + params += '<TR><TD><I>'+m[1]+'</I></TD>' + + '<TD>'+m[2]+'</TD></TR>'; + } + out += '<TABLE WIDTH="90%" BORDER=1>'; + out += '<TR BGCOLOR=0xdddddddd>'; + out += '<TD><B>Parameter</B></TD>'; + out += '<TD><B>Description</B></TD></TR>'; + out += params; + out += '</TABLE><P>'; + } + if (tags["return"]) { + out += "<DT><B>Returns:</B><DD>"; + out += tags["return"][0] + "</DL><P>"; + } + if (tags["author"]) { + // List the authors together, separated by commas. + out += '<DT><B>Author:</B><DD>'; + var array = tags["author"]; + for (var i=0; i < array.length; i++) { + out += array[i]; + if (i+1 < array.length) + out += ", "; + } + out += '</DL><P>'; + } + if (tags["version"]) { + // Show the version. + out += '<DT><B>Version:</B><DD>'; + var array = tags["version"]; + for (var i=0; i < array.length; i++) { + out += array[i]; + if (i+1 < array.length) + out += "<BR><DD>"; + } + out += '</DL><P>'; + } + if (tags["see"]) { + // List the see modules together, separated by <BR>. + out += '<DT><B>Dependencies:</B><DD>'; + var array = tags["see"]; + for (var i=0; i < array.length; i++) { + out += array[i]; + if (i+1 < array.length) + out += "<BR><DD>"; + } + out += '</DL><P>'; + } + if (tags["lastmodified"]) { + // Shows a last modified description with client-side js. + out += '<DT><B>Last modified:</B><DD>'; + out += '<script><!--\n'; + out += 'document.writeln(document.lastModified);\n'; + out += '// ---></script>\n'; + out += '</DL><P>'; + } + + // additional tags can be added here (i.e., "if (tags["see"])...") + return out; +} + +/** + * Create an html output file + * @param outputdir directory to put the file + * @param htmlfile name of the file +*/ +function CreateOutputFile(outputdir,htmlfile) +{ + if (outputdir==null) + { + var outname = htmlfile; + } + else + { + var separator = Packages.java.io.File.separator; + var outname = outputdir + separator + htmlfile.substring(htmlfile.lastIndexOf(separator),htmlfile.length); + } + print("output file: " + outname); + return new File(outname); +} + +/** + * Process a javascript file. Puts the generated HTML file in the outdir + * @param filename name of the javascript file + * @inputdir input directory of the file (default null) + */ +function processJSFile(filename,inputdir) +{ + if (debug) print("filename = " + filename + " inputdir = " + inputdir); + + if (!filename.match(/\.js$/)) { + print("Expected filename to end in '.js'; had instead " + + filename + ". I don't treat the file."); + } else { + if (inputdir==null) + { + var inname = filename; + } + else + { + var separator = Packages.java.io.File.separator; + var inname = inputdir + separator + filename; + } + print("Processing file " + inname); + + var f = new File(inname); + + // create the output file + var htmlfile = filename.replace(/\.js$/, ".html"); + + var out = CreateOutputFile(outputdir,htmlfile); + + processFile(f, filename, inputdir, out); + out.close(); + } +} + +/** + * Generate index files containing links to the processed javascript files + * and the generated functions + */ +function GenerateIndex(dirname) +{ + // construct the files index file + var out = CreateOutputFile(outputdir,indexFile); + + // write the beginning of the file + out.writeLine('<HTML><HEADER><TITLE>File Index - directory: ' + dirname + '</TITLE><BODY>'); + out.writeLine('<H1>File Index - directory: ' + dirname + '</H1>\n'); + out.writeLine('<TABLE WIDTH="90%" BORDER=1>'); + out.writeLine('<TR BGCOLOR=0xdddddddd>'); + out.writeLine('<TD><B>File</B></TD>'); + out.writeLine('<TD><B>Description</B></TD></TR>'); + + var separator = Packages.java.io.File.separator; + + // sort the index file array + var SortedFileArray = []; + for (var fname in indexFileArray) + SortedFileArray.push(fname); + SortedFileArray.sort(); + + for (var i=0; i < SortedFileArray.length; i++) { + var fname = SortedFileArray[i]; + var htmlfile = fname.replace(/\.js$/, ".html"); + out.writeLine('<TR><TD><A HREF=\"' + htmlfile + '\">' + fname + '</A></TD></TD><TD>'); + if (indexFileArray[fname]) + out.writeLine(indexFileArray[fname]); + else + out.writeLine('No comments'); + out.writeLine('</TD></TR>\n'); + } + out.writeLine('</TABLE></BODY></HTML>'); + out.close(); + + // construct the functions index file + var out = CreateOutputFile(outputdir,indexFunction); + + // write the beginning of the file + out.writeLine('<HTML><HEADER><TITLE>Function Index - directory: ' + dirname + '</TITLE><BODY>'); + out.writeLine('<H1>Function Index - directory: ' + dirname + '</H1>\n'); + out.writeLine('<TABLE WIDTH="90%" BORDER=1>'); + out.writeLine('<TR BGCOLOR=0xdddddddd>'); + out.writeLine('<TD><B>Function</B></TD>'); + out.writeLine('<TD><B>Files</B></TD></TR>'); + + // sort the function array + var SortedFunctionArray = []; + for (var functionname in indexFunctionArray) + SortedFunctionArray.push(functionname); + SortedFunctionArray.sort(); + + for (var j=0; j < SortedFunctionArray.length; j++) { + var funcname = SortedFunctionArray[j]; + with (indexFunctionArray[funcname]) { + var outstr = '<TR><TD>' + funcname + '</TD><TD>'; + var filelst = filename.split("|"); + for (var i in filelst) { + var htmlfile = filelst[i].replace(/\.js$/, ".html"); + outstr += '<A HREF=\"' + htmlfile + '#' + funcname + '\">' + filelst[i] + '</A> '; + } + outstr += '</TD></TR>'; + out.writeLine(outstr); + } + } + out.writeLine('</TABLE></BODY></HTML>'); + out.close(); +} + + +/** + * prints the options for JSDoc +*/ +function PrintOptions() +{ + print("You can use the following options:\n"); + print("-d: specify an output directory for the generated html files\n"); + print("-i: processes all files in an input directory (you can specify several directories)\n"); + quit(); +} + + +// Main Script +// first read the arguments +if (! arguments) + PrintOptions(); + +for (var i=0; i < arguments.length; i++) { + if (debug) print("argument: + \'" + arguments[i] + "\'"); + if (arguments[i].match(/^\-/)) { + if (String(arguments[i])=="-d"){ + // output directory for the generated html files + + outputdir = String(arguments[i+1]); + if (debug) print("outputdir: + \'" + outputdir + "\'"); + + i++; + } + else if (String(arguments[i])=="-i"){ + // process all files in an input directory + + DirList.push(String(arguments[i+1])); +if (debug) print("inputdir: + \'" + arguments[i+1] + "\'"); + i++; + } + else { + print("Unknown option: " + arguments[i] + "\n"); + PrintOptions(); + } + } + else + { + // we have a single file + if (debug) print("file: + \'" + arguments[i] + "\'"); + + FileList.push(String(arguments[i])); + } +} + +// first handle the single files +for (var i in FileList) + processJSFile(FileList[i],null); + +// then handle the input directories +for (var j in DirList) { + var inputdir = String(DirList[j]); + + print("Process input directory: " + inputdir); + + // clean up index arrays + var indexFileArray = []; + var indexFunctionArray = []; + + // for the directory name get rid of ../../ or ..\..\ + inputDirName = inputdir.replace(/\.\.\/|\.\.\\/g,""); + + indexFile = indexFileName + "_" + inputDirName + ".html"; + indexFunction = indexFunctionName + "_" + inputDirName + ".html"; + +print("indexFile = " + indexFile); +print("indexFunction = " + indexFunction); + + // read the files in the directory + var DirFile = new java.io.File(inputdir); + var lst = DirFile.list(); + var separator = Packages.java.io.File.separator; + + for (var i=0; i < lst.length; i++) + { + processJSFile(String(lst[i]),inputdir); + } + + // generate the index files for the input directory + GenerateIndex(inputDirName); +} + + + |