| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- //debug();
- //
- // This program generates html documentation for script functions.
- // It merely converts comments with a certain syntax into documentation.
- // Example:
- //
- // /*gm
- // \lib Library Name
- // */
- //
- // /*gm
- // \function Function name
- // \brief Brief description of function
- // \param Parameter description, you should describe type information
- // \return Return value description
- // */
- //
- //
- // \function CreateGMDocumenter
- //
- global CreateGMDocumenter = function()
- {
- documenter = table
- (
- // \function ExtractGmCommentStrings
- // \param fp is source file handle
- // \param commentHandler is a function taking 2 params, comment string and context
- // \param context is passed to comment handler
- ExtractCommentStrings = function(fp, commentHandler, context)
- {
- openGmComment = "/*gm";
- openGmCommentLen = openGmComment.Length();
- closeGmComment = "*/";
- closeGmCommentLen = closeGmComment.Length();
- line = fp.ReadLine();
- while(line)
- {
- pos = line.Find(openGmComment);
- while(pos >= 0)
- {
- pos = pos + openGmCommentLen;
- line = line.Right(line.Length() - pos);
- comment = "";
- // eat up lines untill end of comment
- pos = line.Find(closeGmComment);
- while(pos < 0)
- {
- comment = comment + line;
- line = fp.ReadLine();
- if(line == null)
- {
- pos = 0;
- }
- else
- {
- pos = line.Find(closeGmComment);
- }
- }
- if(line)
- {
- comment = comment + line.Left(pos);
- line = line.Right(line.Length() - (pos + closeGmCommentLen));
- pos = line.Find(openGmComment);
- }
- else
- {
- pos = -1;
- }
- if(comment.Length() > 0)
- {
- // process comment string
- comment = comment.ReplaceCharsInSet(' ', "\r\n\v");
- commentHandler(comment, context);
- }
- }
- line = fp.ReadLine();
- }
- },
- // \function CommentHandler
- // \param comment is an incoming comment string
- // \param context is a table with a m_sections table where each m_section
- // is a function taking the section string and the context
- // context also has a BeginComment() call
- CommentHandler = function(comment, context)
- {
- if(comment and comment.Length())
- {
- commentSet = table();
- foreach(section and sectionHandler in context.m_sections)
- {
- search = comment;
- sectionStart = search.Find(section);
- sectionLength = section.Length();
- offset = 0;
- while(sectionStart >= 0)
- {
- commentSet[offset + sectionStart] = section;
- offset = offset + sectionLength;
- search = search.Right(search.Length() - sectionLength);
- sectionStart = search.Find(section);
- }
- }
- // commentSet is now a table containing the start positions of each comment bit.
- length = comment.Length();
- local j;
- for(i = 0; i < length; i = i + 1)
- {
- if(commentSet[i])
- {
- // find the next comment...
- for(j = i + 1; j < length; j = j + 1)
- {
- if(commentSet[j] or j == (length - 1))
- {
- section = commentSet[i];
- sectionLength = section.Length();
- first = i + sectionLength;
- count = (j - i) - sectionLength;
- subComment = comment.Mid(first, count);
- context.m_sections[section](subComment, context);
- break;
- }
- }
- }
- }
- }
- },
- m_files = table(),
- // \function AddFile will add a file to be documented
- AddFile = function(filename)
- {
- .m_files[tableCount(.m_files)] = filename;
- },
- // \function CreateDocumentation will create documentation for all added files
- // \param path is the output path for the resulting .html docco
- CreateDocumentation = function(filename)
- {
- context = table();
- context.m_sections = table();
- context.m_htmlOut = system.File();
- context.m_xmlOut = system.File();
- context.m_lib = "";
- context.m_sections[`\lib`] = function(comment, context)
- {
- comment = comment.TrimLeft().TrimRight();
- // trim parenthesis
- context.Write("<BR><HR>\n");
- context.Heading(1, comment);
- context.Write("<HR><BR>\n");
- context.m_lib = comment;
- };
- context.m_sections[`\function`] = function(comment, context)
- {
- comment = comment.TrimLeft().TrimRight();
- // trim parenthesis
- context.Write("<HR>\n");
- context.Write(format(`<a name="%s::%s">`,context.m_lib,comment));
- context.Heading(3, comment);
- context.Write(`</a>`);
- context.XMLWrite(format(`<function name="%s::%s"/>`, context.m_lib, comment));
- };
- context.m_sections[`\brief`] = function(comment, context)
- {
- context.Write(format("<B><EM>Brief:</B></EM>%s<BR>", comment));
- };
- context.m_sections[`\param`] = function(comment, context)
- {
- context.Write(format("<B><EM>Param:</B></EM>%s<BR>", comment));
- };
- context.m_sections[`\return`] = function(comment, context)
- {
- context.Write(format("<B><EM>Return:</B></EM>%s<BR>", comment));
- };
- context.m_sections[`\sa`] = function(comment, context)
- {
- context.Write(format("<B><EM>See Also:</B></EM>%s<BR>", comment));
- };
- context.Heading = function(number, string)
- {
- .m_htmlOut.WriteString(format("<H%d>%s</H%d>\n", number, string, number));
- };
- context.m_sections[`\this`] = function(comment, context)
- {
- context.Write(format("<B><EM>This:</B></EM>%s<BR>", comment));
- };
- context.Paragraph = function(string)
- {
- .m_htmlOut.WriteString(format("<P>%s</P>\n", string));
- };
- context.Write = function(string)
- {
- .m_htmlOut.WriteString(string);
- };
- context.XMLWrite = function(string)
- {
- if(.m_xmlOut)
- {
- .m_xmlOut.WriteString(string);
- }
- };
- xmlFilename = filename.SetExtension("xml");
- if(!context.m_xmlOut.Open(xmlFilename, 0))
- {
- print("** ERROR: Failed to open XML output file '",xmlFilename,"' ! **");
- context.m_xmlOut = null;
- }
- context.XMLWrite(`<?xml version="1.0" encoding="utf-8"?>`);
- context.XMLWrite("<functions>");
- //
- if(context.m_htmlOut.Open(filename, 0))
- {
- // write html head
- context.Write("<HTML><HEAD><TITLE>GM Documentation</TITLE></HEAD><BODY>");
- foreach(file in .m_files)
- {
- fp = system.File();
- if(fp.Open(file))
- {
- print(`Documenting`, file, `...`);
- .ExtractCommentStrings(fp,.CommentHandler,context);
- fp.Close();
- }
- }
- context.XMLWrite("</functions>");
- if(context.m_xmlOut)
- {
- context.m_xmlOut.Close();
- }
- context.Write("</BODY></HTML>");
- context.m_htmlOut.Close();
- }
- }
- );
- return documenter;
- };
- /*
- *
- * Entry Point
- *
- */
- print("Starting GMDoc...");
- inFile = arg[0]; // directory/file listings of 'to be documented' files
- outFile = arg[1]; // ouput help files
- documenter = CreateGMDocumenter();
- dirsFile = system.File();
- if(!dirsFile.Open(inFile, 1))
- {
- print("** Failed to open input file! **");
- }
- else
- {
- nextLine = dirsFile.ReadLine();
- while(nextLine)
- {
- nextLine = nextLine.TrimRight(); // carriage return syndrome
- path = nextLine;
- filename = nextLine.GetFilename();
- pos = filename.Find(".cpp",filename.Length() - 5);
- if(pos >= 0) // doc file
- {
- if(system.FileExists(path))
- {
- documenter.AddFile(path);
- }
- }
- else // doc directory
- {
- handle = system.FileFindFirst(path ^ `\*.*`);
- while(handle)
- {
- extension = handle.filename.GetExtension().Lower();
- print(extension);
- if(extension == `cpp` or extension == `gm`)
- {
- if(system.FileExists(path ^ handle.filename))
- {
- documenter.AddFile(path ^ handle.filename);
- }
- }
- handle = system.FileFindNext(handle);
- }
- }
- nextLine = dirsFile.ReadLine(); // read next line
- }
- }
- dirsFile.Close();
- documenter.CreateDocumentation(outFile);
- print(`Done.`);
|