[Commits] r446 - website

commits at geoext.org commits at geoext.org
Thu Apr 23 02:25:22 CEST 2009


Author: tschaub
Date: 2009-04-23 02:25:21 +0200 (Thu, 23 Apr 2009)
New Revision: 446

Added:
   website/jst.cfg
   website/jst.py
Modified:
   website/pavement.py
Log:
Adding tool to parse rst from js source.

Added: website/jst.cfg
===================================================================
--- website/jst.cfg	                        (rev 0)
+++ website/jst.cfg	2009-04-23 00:25:21 UTC (rev 446)
@@ -0,0 +1,5 @@
+[GeoExt]
+
+root = src/trunk/geoext/lib
+template = src/trunk/docsrc/lib/template.jst
+output = src/trunk/docsrc/lib
\ No newline at end of file

Added: website/jst.py
===================================================================
--- website/jst.py	                        (rev 0)
+++ website/jst.py	2009-04-23 00:25:21 UTC (rev 446)
@@ -0,0 +1,131 @@
+import os
+import re
+import sys
+from ConfigParser import ConfigParser
+from jinja2 import Template
+
+SUFFIX_JS = ".js"
+SUFFIX_JST = ".jst"
+SUFFIX_RST = ".rst"
+
+JST_RE = re.compile(r'^\s*/\*\*\s*jst\s*:\s*(.*?)\s*$')
+COMMENT_RE = re.compile(r'^\s*\*?')
+ENDCOMMENT_RE = re.compile(r'^\s*\*/')
+DEF_RE = re.compile(r"\s*([\w\.]+)\s*=\s*(.*)$")
+
+class DocParser(ConfigParser):
+
+    def __init__(self, defaults=None):
+        ConfigParser.__init__(self, defaults)
+
+    @classmethod
+    def from_fn(cls, fn):
+        """Load up config files in our parser."""
+        worker = cls()
+        if isinstance(fn, basestring):
+            fn = fn,
+        fns = worker.read(fn)
+        assert fns, ValueError("No valid config files: %s" % fns)
+        return worker
+    
+    key_list = () 
+    keys = 'root', 
+
+    def make_cfg(self, section):
+        cfg = dict(self.items(section))
+        for key in self.key_list:
+            val = cfg.setdefault(key, [])
+            if isinstance(val, basestring):
+                cfg[key]=[x for x in val.split() if not x.startswith('#')]
+        for key in self.keys:
+            cfg.setdefault(key, None)
+        return cfg
+    
+    def run(self):
+        sections = self.sections()
+        newfiles = []
+        for section in sections:
+            cfg = self.make_cfg(section)
+            print("Extracting docs for %s" % section)
+            sourcedir = cfg['root']
+            outdir = cfg['output']
+            # assemble all files in source directory according to config
+            for root, dirs, entries in os.walk(sourcedir):
+                for filename in entries:
+                    if filename.endswith(SUFFIX_JS) and not filename.startswith("."):
+                        filepath = os.path.join(root, filename)[len(sourcedir)+1:]
+                        source = SourceFile(sourcedir, filepath)
+                        if source.data:
+                            template_filename = os.path.join(sourcedir, filepath.split(SUFFIX_JS)[0] + SUFFIX_JST)
+                            if not os.path.exists(template_filename):
+                                # throw something if template not given in config here
+                                template_filename = cfg["template"]
+                            template = Template(open(template_filename, "U").read())
+                            out = template.render(source.data)
+                            output_filename = os.path.join(outdir, filepath.split(SUFFIX_JS)[0] + SUFFIX_RST)
+                            f = open(output_filename, "w")
+                            f.write(out)
+                            f.close()
+
+class SourceFile(object):
+    """
+    Represents a Javascript source code file.
+    """
+    def __init__(self, sourcedir, filepath):
+        source = open(os.path.join(sourcedir, filepath), "U").readlines()
+        self.data = {}
+        inblock = False
+        defs = False
+        name = None
+        block = None
+        got_indent = False
+        got_data = False
+        for line in source:
+            if not inblock:
+                m = JST_RE.match(line)
+                if m:
+                    inblock = True
+                    name = m.group(1)
+                    defs = (name == "defs")
+                    block = []
+                    spaces = 0
+                    got_indent = False
+            else:
+                m = ENDCOMMENT_RE.match(line)
+                if m:
+                    inblock = False
+                    got_data = True
+                    if defs:
+                        for defline in block:
+                            m = DEF_RE.match(defline)
+                            if m:
+                                self.data[m.group(1)] = m.group(2)
+                    else:
+                        block = "".join(block)
+                        if name[-2:] == "[]":
+                            short = name[:-2]
+                            if self.data.has_key(short):
+                                if type(self.data[short]) is type([]):
+                                    self.data[short] += [block]
+                                else:
+                                    self.data[short] = [self.data[short], block]
+                            else:
+                                self.data[short] = [block]
+                        else:
+                            self.data[name] = block
+                else:
+                    line = COMMENT_RE.sub("", line)
+                    if not got_indent:
+                        if re.compile(r'.*\S').match(line):
+                            spaces = len(line) - len(line.lstrip())
+                            got_indent = True
+                    if len(line) > spaces:
+                        line = line[spaces:]
+                    block += (line,)
+                        
+        if not got_data:
+            self.data = None
+
+
+
+

Modified: website/pavement.py
===================================================================
--- website/pavement.py	2009-04-22 22:29:31 UTC (rev 445)
+++ website/pavement.py	2009-04-23 00:25:21 UTC (rev 446)
@@ -16,6 +16,7 @@
 from paver.easy import path
 from paver import svn
 import os
+from jst import DocParser
 
 version = '0.0'
 
@@ -106,7 +107,13 @@
     svn.checkup("%s/trunk/docsrc" %options.core_url, "src/trunk/docsrc")
 
 @task
+def parse_docs():
+    parser = DocParser.from_fn("jst.cfg")
+    parser.run()
+
+ at task
 @needs(['checkup_docs',
+        'parse_docs',
         'paver.doctools.html'])
 def build_docs():
     # will need to get smarter with new releases



More information about the Commits mailing list