Author: sebastien.lelong
Date: Fri Sep  5 11:30:39 2008
New Revision: 275

Added:
    trunk/tools/gcwiki.tmpl
    trunk/tools/jalapi.py
    trunk/tools/jalapi_generate.sh   (contents, props changed)
    trunk/tools/jalapi_html.tmpl
Modified:
    trunk/tools/Makefile

Log:
jalapi api doc generator script + html/gcwiki template

Modified: trunk/tools/Makefile
==============================================================================
--- trunk/tools/Makefile        (original)
+++ trunk/tools/Makefile        Fri Sep  5 11:30:39 2008
@@ -22,6 +22,8 @@
        find ${SAMPLIR_DIR} -name \*.err -exec rm {} \;
        find ${SAMPLIR_DIR} -name \*.obj -exec rm {} \;
        find ${SAMPLIR_DIR} -name \*.asm -exec rm {} \;
+       # clean python bytecode
+       find ./ -name \*.pyc -exec rm {} \;
                
  test :
        # run testsuite
@@ -42,3 +44,5 @@
                ./jsg_validator.py $$f ;\
        done

+doc:
+       ./jalapi_generate.sh ../${ENV}

Added: trunk/tools/gcwiki.tmpl
==============================================================================
--- (empty file)
+++ trunk/tools/gcwiki.tmpl     Fri Sep  5 11:30:39 2008
@@ -0,0 +1,120 @@
+
+#def head
+       ## Single line header: strip
+       #set title = $dhead['Title'].strip()
+       #set author = $dhead['Author'].strip()
+       #set adapted_by = $dhead['Adapted-by'].strip()
+       #set compiler = $dhead['Compiler'].strip()
+       ## Multiline header
+       #set description = $dhead['Description'].split("\n")
+       #if $dhead.has_key('Sources') and $dhead['Sources']
+               #set sources = $dhead['Sources'].split("\n")
+       #else
+               #set sources = []
+       #end if
+       #if $dhead.has_key('Notes') and $dhead['Notes']
+               #set notes = $dhead['Notes'].split("\n")
+       #else
+               #set notes = []
+       #end if
+\#summary $title
+## Force labels so jalapi doc can be filtered from wiki page list
+\#labels Phase-Implementation, Type-Jalapi
+
+= $libname =
+
+
+|| *Author* || $author ||
+|| *Adapted-by* || $adapted_by ||
+|| *Compiler* || $compiler ||
+
+
+*Description*
+
+## Indent multiline content
+#for d in description
+  $d
+#end for
+
+
+#if $sources
+*Sources*
+
+#for s in $sources
+  $s
+#end for
+#end if
+
+
+#if $notes
+*Notes*
+
+#for n in $notes
+  $n
+#end for
+#end if
+
+
+*Dependencies*
+
+#for d in $ddeps.keys()
+  * [$wikiwordify($d) $d]
+#end for
+
+#end def
+
+#def display_dict(title,ddict)
+
+== $title ==
+
+#for v,doc in $ddict.items()
+       #if doc
+               #set dsplit = doc.split("\n")
+       #else
+               #set dsplit = []
+       #end if
+ * *`$v.strip()`*
+
+#for d in dsplit
+   $d
+#end for
+
+#end for
+
+#end def
+
+#def api
+
+= API =
+
+$display_dict("Global variables/contants",$dvarconst)
+$display_dict("Procedures",$dproc)
+$display_dict("Functions",$dfunc)
+
+#end def
+
+#def samples
+
+= Related samples =
+
+#if $dsamples
+Here are the list of samples which use this library:
+
+       #for file,url in $dsamples.items()
+ * [$url $file]
+       #end for
+#else
+_No sample found..._
+#end if
+
+#end def
+
+#def main
+$head
+
+$api
+
+$samples
+#end def
+
+$main

Added: trunk/tools/jalapi.py
==============================================================================
--- (empty file)
+++ trunk/tools/jalapi.py       Fri Sep  5 11:30:39 2008
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+#
+#
+# Title: jalapi documentation generator
+# Author: Sebastien Lelong, Copyright (c) 2008, all rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license  
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: this script takes a jal library file as argument and  
parse/extract
+# JSG headers and procedure/function comments to build a googlecode wiki  
page.
+# It also search for samples using this library.
+# Used to produce API documentation.
+#
+# Notes: jal library file must first pass the JSG validator script before  
using this one
+# This script also uses wikify.py script to generate html from GoogleCode  
(and potentially
+# other wikis) wiki. Can be found here:
+#      * http://cspace.googlecode.com/svn/wiki/wikify.py
+# You may have to adjust your PYTHONPATH, so it includes wikify's dir, to  
run this script
+#
+#
+
+import sys, os
+import re
+import wikify
+import jsg_validator
+
+SVN_BROWSER_ROOT = "http://code.google.com/p/jallib/source/browse";
+
+def extract_comments(i,origline,content):
+       doc = []
+       stillcomment = re.compile("^--\s")
+       for _,line in content:
+               if not stillcomment.match(line) or line.strip() == "":
+                       break
+               doc.append(stillcomment.sub("",line))
+       # no comment found
+       if not doc:
+               print >> sys.stderr, "No documentation found for %s (line %s)" 
%  
(repr(origline),i)
+               return None
+       # back to human readable content
+       doc.reverse()
+       return "".join(doc) or None
+
+def extract_doc(filename):
+       # deals with header
+       # jsg wants line number...
+       content = [(i + 1,l) for i,l in 
enumerate(open(filename,"r").readlines())]
+       header = jsg_validator.extract_header(content)
+       dhead = {}
+       for field_dict in jsg_validator.FIELDS:
+               dhead[field_dict['field']] =  
jsg_validator.validate_field(header,**field_dict)
+       
+       # now deals with procedure/function definitions
+       # and global variables/constant
+       # get comment above
+       content.reverse()
+       proc = re.compile("^procedure\s+(.*)\s+is")
+       func = re.compile("^function\s+(.*)\s+is")
+       var_const = re.compile("^(var|const)")
+       include = re.compile("^include\s+(\w+)")
+       dfunc = {}
+       dproc = {}
+       dvarconst = {}
+       ddeps = {}
+       doc = None
+       # re-enumerate with content indexes
+       for i,(_,line) in enumerate(content):
+               # strip line once matched, else loose ident
+               if func.match(line):
+                       doc = extract_comments(i,line.strip(),content[i+1:])
+                       dfunc[func.match(line).groups()[0]] = doc
+               if proc.match(line):
+                       doc = extract_comments(i,line.strip(),content[i+1:])
+                       dproc[proc.match(line).groups()[0]] = doc
+               if var_const.match(line):
+                       doc = extract_comments(i,line.strip(),content[i+1:])
+                       dvarconst[line] = doc
+               if include.match(line):
+                       dep = include.match(line).groups()[0]
+                       ddeps[dep] = True
+                               
+       return (dhead,dproc,dfunc,dvarconst,ddeps)
+
+def get_samples_info(samples):
+       dsamples = {}
+       for sample in samples:
+               # yeah, that's a system call again, for svn...
+               # en english please so we can parse...
+               stdin,stdout,stderr = os.popen3("LANG=C svn info %s | grep 
^URL:" %  
sample)
+               stderr = stderr.read()
+               if stderr:
+                       print >> sys.stderr, "Skip extracting SVN URL for 
sample %s  
because: %s" % (sample,stderr)
+                       continue
+               fullurl = stdout.read().replace("URL:","").strip()
+               stdin,stdout,stderr = os.popen3("LANG=C svn info %s | grep 
^Repository\  
Root:" % sample)
+               stderr = stderr.read()
+               if stderr:
+                       print >> sys.stderr, "Skip extracting SVN Repository 
Root for sample %s  
because: %s" % (sample,stderr)
+               reposroot = stdout.read().replace("Repository Root:","").strip()
+               svnbrowserurl = fullurl.replace(reposroot,SVN_BROWSER_ROOT)
+               dsamples[os.path.basename(sample)] = svnbrowserurl
+       
+       return dsamples
+
+
+def html_linker(lib):
+       return "%s.html" % lib
+
+
+if __name__ == '__main__':
+       import Cheetah.Template
+       try:
+               tmpl_file = sys.argv[1]
+               filename = sys.argv[2]
+       except IndexError:
+               print >> sys.stderr, "Please provide a template and jal library 
file"
+               sys.exit(255)
+
+       # first validate it !
+       jsg_validator.validate(filename)
+       if jsg_validator.errors:
+               print >> sys.stderr, "%s does not pass JSG, cannot generate API 
 
documentation" % filename
+               sys.exit(1)
+
+       # ok, it's valid, I'll do my job...
+
+       # find sample using this lib
+       try:
+               SAMPLEDIR = os.environ['SAMPLEDIR']
+       except KeyError:
+               print >> sys.stderr, "Set SAMPLEDIR env. variable, so I can 
search for  
sample using %s" % filename
+               sys.exit(2)
+       # yeah, that's a grep, this should be re-implemened in pure python
+       # to be used under MS win.
+       libname = re.sub("\.jal$","",os.path.basename(filename))
+       stdin,stdout,stderr = os.popen3("""grep -R -l ^include\ %s %s | grep  
\.jal\$""" % (libname,SAMPLEDIR))
+       stderr = stderr.read()
+       stdout = stdout.read()
+       if stderr:
+               print >> sys.stderr, "Can't find sample using %s because: %s" % 
 
(filename,stderr)
+               sys.exit(3)
+       print >> sys.stderr, "Samples using %s:\n%s" % (filename,stdout)
+       sample_files = stdout.split()
+       dsamples = get_samples_info(sample_files)
+
+       # extract doc
+       dhead,dproc,dfunc,dvarconst,ddeps = extract_doc(filename)
+       # generate doc
+       tmplsrc = "".join(file(tmpl_file,"r").readlines())
+       klass = Cheetah.Template.Template.compile(tmplsrc)
+       wikifier = wikify.Wikifier(wikify.GoogleCodeWikiFormat,suffix=".html")
+       tmpl = klass()
+       tmpl.dhead = dhead
+       tmpl.dproc = dproc
+       tmpl.dfunc = dfunc
+       tmpl.dvarconst = dvarconst
+       tmpl.ddeps = ddeps
+       tmpl.libname = libname
+       tmpl.dsamples = dsamples
+       tmpl.html_linker = html_linker
+       tmpl.wikifier = wikifier
+
+       print tmpl.main()
+
+       print >> sys.stderr, "Success !"
+       sys.exit(0)
+

Added: trunk/tools/jalapi_generate.sh
==============================================================================
--- (empty file)
+++ trunk/tools/jalapi_generate.sh      Fri Sep  5 11:30:39 2008
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+ROOT=$1
+DOCDIR="$ROOT/doc"
+HTMLDOCDIR="$DOCDIR/html"
+
+MENU=$HTMLDOCDIR/menu.html
+
+export SAMPLEDIR=$ROOT/sample
+
+echo "<!-- sorted -->" > $MENU
+
+for jalfile in `find $ROOT/include -name \*.jal`
+do
+       basefile=`basename $jalfile`
+       htmlfile="`echo $basefile | sed 's#\.jal$#.html#'`"
+       libname=`echo $basefile | sed 's#\.jal$##'`
+       echo -n "Generating doc for $basefile... "
+       python jalapi.py jalapi_html.tmpl $jalfile > $HTMLDOCDIR/$htmlfile
+       status=$?
+       if [ "X$status" = "X0" ]
+       then
+               echo done
+               notinsvn=`svn st $HTMLDOCDIR/$htmlfile| grep -c ^?`
+               if [ "X$notinsvn" = "X1" ]
+               then
+                       svn add $HTMLDOCDIR/$htmlfile
+               fi
+               svn ps svn:mime-type text/html $HTMLDOCDIR/$htmlfile > 
/dev/null 2>&1
+               echo "<a href='$htmlfile' target='lib_desc'>$libname</a><br/>" 
>> $MENU
+       else
+               rm $HTMLDOCDIR/$htmlfile
+               echo ERROR
+       fi
+done
+
+# sort lib: this should be ok
+sort $MENU > $MENU.tmp
+echo "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01  
Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd";>
+<html>
+    <head>
+               <title>Libraries - jallib API doc</title>
+       </head>
+       
+       <body>
+" > $MENU
+cat $MENU.tmp >> $MENU
+rm $MENU.tmp
+echo "</body>
+</html>" >> $MENU
+

Added: trunk/tools/jalapi_html.tmpl
==============================================================================
--- (empty file)
+++ trunk/tools/jalapi_html.tmpl        Fri Sep  5 11:30:39 2008
@@ -0,0 +1,205 @@
+## Use to generate safe anchor
+#import md5
+
+#def wiki2html(what)
+       ## Convert GC wiki to html, *BUT* keep line feed as <br> !
+       $wikifier.wikify($what).replace("\n","<br/>")
+#end def
+
+#def header
+       ## Single line header: strip
+       #set title = $dhead['Title'].strip()
+       #set author = $dhead['Author'].strip()
+       #set adapted_by = $dhead['Adapted-by'].strip()
+       #set compiler = $dhead['Compiler'].strip()
+       ## Multiline header
+       #set description = $dhead['Description']
+       #if $dhead.has_key('Sources') and $dhead['Sources']
+               #set sources = $dhead['Sources']
+       #else
+               #set sources = ""
+       #end if
+       #if $dhead.has_key('Notes') and $dhead['Notes']
+               #set notes = $dhead['Notes']
+       #else
+               #set notes = ""
+       #end if
+
+    <h1>$libname</h1>
+
+    <div>
+               <font size="+1"><i>$title</i></font>
+       </div>
+
+       <br/>
+
+    <div class="narrow">
+
+       <table>
+       <tr>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       <b>Author</b>
+               </td>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       $author
+               </td>
+       </tr>
+       <tr>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       <b>Adapted-by</b>
+               </td>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       $adapted_by
+               </td>
+       </tr>
+       <tr>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       <b>Compiler</b>
+               </td>
+               <td style="border: 1px solid #aaa; padding: 5px;">
+                       $compiler
+               </td>
+       </tr>
+       </table>
+
+       <br/>
+       
+       <b>Description</b>
+       <p>
+       $wiki2html($description)
+       </p>
+       <br/>
+
+       #if $sources
+       <b>Sources</b>
+       <p>
+       $wiki2html($sources)
+       </p>
+       <br/>
+       #end if
+
+       #if $notes
+       <b>Notes</b>
+       <p>
+       $wiki2html($notes)
+       </p>
+       <br/>
+       #end if
+       
+       <b>Dependencies</b>
+       <p>
+       #if $ddeps
+               <ul>
+               #for d in $ddeps.keys()
+                       <li><a href="$html_linker($d)">$d</a></li>
+               #end for
+               </ul>
+       #else
+               <i>No depency found</i>
+       </p>
+       <br/>
+       #end if
+
+#end def
+
+#def _create_anchor(s)
+       #return md5.md5(s).hexdigest()
+#end def
+
+#def _display(ltup,short)
+       <ul>
+       #for v,doc in ltup
+               <li>
+                       #set anchor = $_create_anchor($v)
+                       #if short
+                               <b><code name="code" class="python"><a  
href="#$anchor">$v</a></code></b>
+                       #else
+                               <b><code name="code" class="python"><a 
name="$anchor"  
href="#summary">$v</a></code></b>
+                               #if doc
+                               <p>$wiki2html($doc)</p>
+                               #else
+                               <p><i>No documentation found</i></p>
+                               #end if
+                       #end if
+               </li>
+       #end for
+       </ul>
+#end def
+
+#def display_dict(title,ddict,short=False)
+       <h3><a name="$title">$title</a></h3>
+       #set private = [(v,doc) for v,doc in $ddict.items() if 
v.startswith("_")]
+       #set public = [(v,doc) for v,doc in $ddict.items() if not  
v.startswith("_")]
+       $_display($public,$short)
+       #if private
+       <i><small>Private</small></i>
+       $_display($private,$short)
+       <br/>
+       #end if
+#end def
+
+
+#def api
+       <h2><a name="api">API details</a></h2>
+
+       $display_dict("Global variables/contants",$dvarconst)
+       $display_dict("Procedures",$dproc)
+       $display_dict("Functions",$dfunc)
+#end def
+
+#def summary
+       <h2><a name="summary">Summary</a></h2>
+
+       $display_dict("Global variables/contants",$dvarconst,short=True)
+       $display_dict("Procedures",$dproc,short=True)
+       $display_dict("Functions",$dfunc,short=True)
+#end def
+
+#def samples
+       <h2><a name="related_samples">Related samples</a></h2>
+       #if $dsamples
+       Here are the list of samples which use this library:<br/><br/>
+       <ul>
+       #for file,url in $dsamples.items()
+               <li><a href="$url" target="_blank">$file</a></li>
+       #end for
+       </ul>
+       #else
+               <i>No sample found</i>
+       #end if
+#end def
+
+
+
+#def content
+        <div id="page">
+
+            <div id="pagecontent">
+
+                       $header
+                       <br/>
+                       $summary
+                       <br/>
+                       $api
+                       <br/>
+                       $samples
+                       <br/>
+
+            </div>
+        </div>
+
+#end def
+
+
+#def main
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+    <head>
+    </head>
+    <body>
+               $content
+       </body>
+</html>
+#end def
+
+

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/jallib?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to