Autogenerate doxy-header and footer from template in doclib/SConscript
g0dil [Tue, 24 Apr 2007 23:32:21 +0000 (23:32 +0000)]
Adjust search.php and search_paths.php generation

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@232 270642c3-0616-0410-b53a-bc976706d245

SConstruct
doclib/SConscript
doclib/doxy-footer.html [deleted file]
doclib/doxy-header-overview.html [deleted file]
doclib/doxy-header.html [deleted file]
doclib/search_functions.php
doclib/yaptu.py [new file with mode: 0644]
senfscons/SENFSCons.py

index 5ce43a2..7d09e74 100644 (file)
@@ -41,7 +41,6 @@ SENFSCons.Doxygen(env)
 SENFSCons.DoxyXRef(env,
                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
                    HTML_FOOTER = '#/doclib/doxy-footer.html')
-SENFSCons.DoxySearch(env)
 
 # Create Doxyfile.local if not cleaning and the file does not exist
 # otherwise doxygen will barf on this non-existent file
index 0d93b93..ddaa95e 100644 (file)
@@ -5,15 +5,125 @@ import SENFSCons
 
 ###########################################################################
 
-# This is not nice .. really ...
-env.Alias(
-    'all_docs',
-    env.Command('search.php',
-                [ 'doxy-header-overview.html', 'doxy-footer.html', 'html-munge.xsl' ], 
-                [ "sed -e 's/\\$$title/Search results/g' -e 's/\\$$projectname/Overview/g' ${SOURCES[0]} > ${TARGET}.tmp",
-                  'echo "PHPSEARCH" >> ${TARGET}.tmp',
-                  'cat ${SOURCES[1]} >> ${TARGET}.tmp',
-                  'xsltproc --nonet --html --stringparam topdir .. -o - ${SOURCES[2]} ${TARGET}.tmp 2>/dev/null'
-                  + '| sed -e "s/PHPSEARCH/<?php include \'search_functions.php\'; ?><?php search(); ?>/" > $TARGET',
-                  'rm -f ${TARGET}.tmp' ]))
+import yaptu
 
+def modules():
+    global EXTRA_MODULES
+    rv = []
+    ix = len(env.Dir('#').abspath)+1
+    for module in env.Alias('all_docs')[0].sources:
+        if module.name != 'html.stamp' : continue 
+        if not [ x for x in EXTRA_MODULES if env.Dir(x[1]).abspath == module.dir.abspath]:
+            rv.append(('lib%s' % module.dir.dir.dir.name, module.dir.abspath[ix:]))
+    rv.sort()
+    return [ (name, env.Dir(path).abspath[ix:]) for name,path in EXTRA_MODULES ] + rv
+
+def indices():
+    ix = len(env.Dir('#').abspath)+1
+    return [ doc.dir.abspath[ix:]
+             for doc in env.Alias('all_docs')[0].sources
+             if doc.name == "search.idx" ]
+
+def writeTemplate(target = None, source = None, env = None):
+    file(target[0].abspath,"w").write(yaptu.process(env['TEMPLATE'], globals(), env.Dictionary()))
+
+writeTemplate = env.Action(writeTemplate, varlist = [ 'TEMPLATE' ])
+
+###########################################################################
+
+# Extra documentation modules which are handled (named) different from
+# library modules
+EXTRA_MODULES = [
+    ('Overview', '#/doc/html'),
+    ('Examples', '#/Examples/doc/html'),
+    ('SENFScons', '#/senfscons/doc/html') ]
+
+HEADER = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>$title</title>
+<link href="@TOPDIR@/doc/html/doxygen.css" rel="stylesheet" type="text/css">
+<link href="@TOPDIR@/doclib/senf.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+div.tabs ul li.$projectname a {obr} background-color: #EDE497; {cbr}
+</style>
+</head>
+<body>
+
+<div id="head">
+  <div id="search">
+    <form action="@TOPDIR@/doclib/search.php" method="get">
+      Search: <input type="text" name="query" size="20" accesskey="s"/> 
+    </form>
+  </div>
+  <h1>SENF Extensible Network Framework</h1>
+  <h2>{TITLE}</h2>
+</div>
+
+<div id="content1">
+  <div id="content2">
+    <div class="tabs menu">
+      <ul>
+{{ for name, path in modules():
+        <li class="{name}"><a href="@TOPDIR@/{path}/index.html">{name}</a></li>
+}}
+      </ul>
+    </div>"""
+
+FOOTER = """<hr style="width:0px;border:none;clear:both;margin:0;padding:0" />
+  </div>
+</div>
+<div id="footer">
+  <span>
+    <a href="mailto:senf-dev@lists.berlios.de">Contact: senf-dev@lists.berlios.de</a> |
+    Copyright &copy; 2006 Fraunhofer Gesellschaft, SatCom, Stefan Bund
+  </span>
+</div>
+</body></html>"""
+
+OVERVIEW_EXTRA_HEADER="""
+    <div class="tabs">
+      <ul>
+        <li><a href="xref.html">Open Issues</a></li>
+        <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li>
+        <li><a class="ext" href="http://developer.berlios.de/projects/senf">SENF @ BerliOS</a></li>
+        <li><a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li>
+      </ul>
+    </div>"""
+
+SEARCH_PHP="""
+<?php include 'search_functions.php'; ?>
+<?php search(); ?>"""
+
+SEARCH_PATHS_PHP="""<?php
+function paths() {
+  return array(
+{{ for index in indices():
+    "../{index}/",
+}}
+  );
+}
+?>"""
+
+env.Command('doxy-header.html', None, writeTemplate,
+            TEMPLATE = HEADER,
+            TITLE = "Documentation and API reference")
+env.Command('doxy-header-overview.html', None, writeTemplate,
+            TEMPLATE = HEADER+OVERVIEW_EXTRA_HEADER,
+            TITLE = "Introduction and Overview")
+env.Command('doxy-footer.html', None, writeTemplate,
+            TEMPLATE = FOOTER)
+env.Alias('all_docs',
+          env.Command('search.php', 'html-munge.xsl',
+                      [ writeTemplate,
+                        'xsltproc --nonet --html --stringparam topdir .. -o - $SOURCE $TARGET 2>/dev/null'
+                        + r'| sed -e "s/\[\[/</g" -e "s/\]\]/>/g" > ${TARGET}.tmp',
+                        'mv ${TARGET}.tmp ${TARGET}' ],
+                      TEMPLATE = (HEADER
+                                  + OVERVIEW_EXTRA_HEADER
+                                  + SEARCH_PHP.replace('<','[[').replace('>',']]')
+                                  + FOOTER),
+                      TITLE = "Search results"))
+env.Alias('all_docs',
+          env.Command('search_paths.php', None, writeTemplate,
+                      TEMPLATE = SEARCH_PATHS_PHP))
diff --git a/doclib/doxy-footer.html b/doclib/doxy-footer.html
deleted file mode 100644 (file)
index dd3d9bc..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-    <hr style="width:0px;border:none;clear:both;margin:0;padding:0" />
-  </div>
-</div>
-<div id="footer">
-  <span>
-    <a href="mailto:senf-dev@lists.berlios.de">Contact: senf-dev@lists.berlios.de</a> |
-    Copyright &copy; 2006 Fraunhofer Gesellschaft, SatCom, Stefan Bund
-  </span>
-</div>
-</body></html>
diff --git a/doclib/doxy-header-overview.html b/doclib/doxy-header-overview.html
deleted file mode 100644 (file)
index 28f3fa3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>$title</title>
-<link href="@TOPDIR@/doc/html/doxygen.css" rel="stylesheet" type="text/css">
-<link href="@TOPDIR@/doclib/senf.css" rel="stylesheet" type="text/css">
-<style type="text/css">
-div.tabs ul li.$projectname a { background-color: #EDE497; }
-</style>
-</head>
-<body>
-
-<div id="head">
-  <div id="search">
-    <form action="@TOPDIR@/doclib/search.php" method="get">
-      Search: <input type="text" name="query" size="20" accesskey="s"/> 
-    </form>
-  </div>
-  <h1>SENF Extensible Network Framework</h1>
-  <h2>Introduction and Overview</h2>
-</div>
-
-<div id="content1">
-  <div id="content2">
-    <div class="tabs menu">
-      <ul>
-        <li class="Overview"><a href="@TOPDIR@/doc/html/index.html">Overview</a></li>
-        <li class="libSocket"><a href="@TOPDIR@/Socket/doc/html/index.html">libSocket</a></li>
-        <li class="libPackets"><a href="@TOPDIR@/Packets/doc/html/index.html">libPackets</a></li>
-        <li class="libScheduler"><a href="@TOPDIR@/Scheduler/doc/html/index.html">libScheduler</a></li>
-       <li class="libPPI"><a href="@TOPDIR@/PPI/doc/html/index.html">libPPI</a></li>
-        <li class="libUtils"><a href="@TOPDIR@/Utils/doc/html/index.html">libUtils</a></li>
-        <li class="Examples"><a href="@TOPDIR@/Examples/doc/html/index.html">Examples</a></li>
-        <li class="SENFSCons"><a href="@TOPDIR@/senfscons/doc/html/index.html">SENFSCons</a></li>
-      </ul>
-    </div>
-
-    <div class="tabs">
-      <ul>
-        <li><a href="xref.html">Open Issues</a></li>
-        <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li>
-        <li><a class="ext" href="http://developer.berlios.de/projects/senf">SENF @ BerliOS</a></li>
-        <li><a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li>
-      </ul>
-    </div>
\ No newline at end of file
diff --git a/doclib/doxy-header.html b/doclib/doxy-header.html
deleted file mode 100644 (file)
index 9981f18..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>$title</title>
-<link href="@TOPDIR@/doc/html/doxygen.css" rel="stylesheet" type="text/css">
-<link href="@TOPDIR@/doclib/senf.css" rel="stylesheet" type="text/css">
-<style type="text/css">
-div.tabs ul li.$projectname a { background-color: #EDE497; }
-</style>
-</head>
-<body>
-
-<div id="head">
-  <div id="search">
-    <form action="@TOPDIR@/doclib/search.php" method="get">
-      Search: <input type="text" name="query" size="20" accesskey="s"/> 
-    </form>
-  </div>
-  <h1>SENF Extensible Network Framework</h1>
-  <h2>Documentation and API reference</h2>
-</div>
-
-<div id="content1">
-  <div id="content2">
-    <div class="tabs menu">
-      <ul>
-        <li class="Overview"><a href="@TOPDIR@/doc/html/index.html">Overview</a></li>
-        <li class="libSocket"><a href="@TOPDIR@/Socket/doc/html/index.html">libSocket</a></li>
-        <li class="libPackets"><a href="@TOPDIR@/Packets/doc/html/index.html">libPackets</a></li>
-        <li class="libScheduler"><a href="@TOPDIR@/Scheduler/doc/html/index.html">libScheduler</a></li>
-       <li class="libPPI"><a href="@TOPDIR@/PPI/doc/html/index.html">libPPI</a></li>
-        <li class="libUtils"><a href="@TOPDIR@/Utils/doc/html/index.html">libUtils</a></li>
-        <li class="Examples"><a href="@TOPDIR@/Examples/doc/html/index.html">Examples</a></li>
-        <li class="SENFSCons"><a href="@TOPDIR@/senfscons/doc/html/index.html">SENFSCons</a></li>
-      </ul>
-    </div>
index e3205be..d78c6a7 100644 (file)
@@ -1,4 +1,4 @@
-<?php include '../doc/html/search_paths.php'; ?>
+<?php include 'search_paths.php'; ?>
 <?php
 
 function search_results()
diff --git a/doclib/yaptu.py b/doclib/yaptu.py
new file mode 100644 (file)
index 0000000..e3669aa
--- /dev/null
@@ -0,0 +1,97 @@
+"Yet Another Python Templating Utility, Version 1.2"
+
+import sys, re
+from cStringIO import StringIO
+
+# utility stuff to avoid tests in the mainline code
+class _nevermatch:
+    "Polymorphic with a regex that never matches"
+    def match(self, line):
+        return None
+_never = _nevermatch()     # one reusable instance of it suffices
+def identity(string, why):
+    "A do-nothing-special-to-the-input, just-return-it function"
+    return string
+def nohandle(string):
+    "A do-nothing handler that just re-raises the exception"
+    raise
+
+# and now the real thing
+class copier:
+    "Smart-copier (YAPTU) class"
+    def copyblock(self, i=0, last=None):
+        "Main copy method: process lines [i,last) of block"
+        def repl(match, self=self):
+            "return the eval of a found expression, for replacement"
+            # uncomment for debug: print '!!! replacing',match.group(1)
+            expr = self.preproc(match.group(1), 'eval')
+            try: return str(eval(expr, self.globals, self.locals))
+            except: return str(self.handle(expr))
+        block = self.locals['_bl']
+        if last is None: last = len(block)
+        while i<last:
+            line = block[i]
+            match = self.restat.match(line)
+            if match:   # a statement starts "here" (at line block[i])
+                # i is the last line to _not_ process
+                stat = match.string[match.end(0):].strip()
+                j=i+1   # look for 'finish' from here onwards
+                nest=1  # count nesting levels of statements
+                while j<last:
+                    line = block[j]
+                    # first look for nested statements or 'finish' lines
+                    if self.restend.match(line):    # found a statement-end
+                        nest = nest - 1     # update (decrease) nesting
+                        if nest==0: break   # j is first line to _not_ process
+                    elif self.restat.match(line):   # found a nested statement
+                        nest = nest + 1     # update (increase) nesting
+                    elif nest==1:   # look for continuation only at this nesting
+                        match = self.recont.match(line)
+                        if match:                   # found a contin.-statement
+                            nestat = match.string[match.end(0):].strip()
+                            stat = '%s _cb(%s,%s)\n%s' % (stat,i+1,j,nestat)
+                            i=j     # again, i is the last line to _not_ process
+                    j=j+1
+                stat = self.preproc(stat, 'exec')
+                stat = '%s _cb(%s,%s)' % (stat,i+1,j)
+                # for debugging, uncomment...: print "-> Executing: {"+stat+"}"
+                exec stat in self.globals,self.locals
+                i=j+1
+            else:       # normal line, just copy with substitution
+                self.ouf.write(self.regex.sub(repl,line))
+                i=i+1
+    def __init__(self, regex=_never, dict={},
+            restat=_never, restend=_never, recont=_never, 
+            preproc=identity, handle=nohandle, ouf=sys.stdout):
+        "Initialize self's attributes"
+        self.regex   = regex
+        self.globals = dict
+        self.locals  = { '_cb':self.copyblock }
+        self.restat  = restat
+        self.restend = restend
+        self.recont  = recont
+        self.preproc = preproc
+        self.handle  = handle
+        self.ouf     = ouf
+    def copy(self, block=None, inf=sys.stdin):
+        "Entry point: copy-with-processing a file, or a block of lines"
+        if block is None: block = inf.readlines()
+        self.locals['_bl'] = block
+        self.copyblock()
+
+_RE_EXPR = re.compile('{([^{}]+)}')
+_RE_BEGIN = re.compile('{{')
+_RE_END = re.compile('}}')
+_RE_CONT = re.compile(r'\|\|')
+
+def process(text,*args):
+    vardict = {}
+    for arg in args : vardict.update(arg)
+    vardict['obr'] = '{'
+    vardict['cbr'] = '}'
+    output = StringIO()
+    c = copier(_RE_EXPR, vardict, _RE_BEGIN, _RE_END, _RE_CONT,
+               ouf = output)
+    lines = [ line+'\n' for line in text.split("\n") ]
+    c.copy(lines)
+    return output.getvalue()
index 623bbc7..10ca5f7 100644 (file)
@@ -465,20 +465,6 @@ def DoxyXRef(env, docs=None,
     return xref
 
 
-def DoxySearch(env, docs=None):
-    if docs is None:
-        docs = env.Alias('all_docs')[0].sources
-    indices = [ doc for doc in docs if doc.name == "search.idx" ]
-    commands = [ "echo '<?php function paths() { return array(' >$TARGET" ]
-    root = env.Dir('#').abspath
-    commands.extend([ "echo '\"..%s/\",' >>$TARGET" % index.dir.abspath[len(root):]
-                      for index in indices  ])
-    commands.append("echo '); } ?>' >>$TARGET" )
-    target = env.Command("doc/html/search_paths.php", indices, commands)
-    env.Alias('all_docs', target)
-    return target
-
-
 ## \brief Build library
 #
 # This target helper will build the given library. The library will be