X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=doclib%2FSConscript;h=b83c09c0e6db97e4e6eb9c0a8a21a724835ffd3a;hb=fe5837b37f112fdcd379e96ce248ca5b5f8b4d98;hp=fd5ba396eb235d3cc52f3028101673bf1eb973c5;hpb=6a11fb9e93c0c48b6d5c6d7093082bff101740ad;p=senf.git diff --git a/doclib/SConscript b/doclib/SConscript index fd5ba39..b83c09c 100644 --- a/doclib/SConscript +++ b/doclib/SConscript @@ -1,23 +1,167 @@ # -*- python -*- +# +# The documentation generation process is tightly integrated with the +# scons build framework: +# +# * SCons analyzes the Doxyfile's to find all the documentation +# dependencies. This happens in the doxygen builder in +# senfscons/Doxygen.py. +# +# * the doclib/doxy-header.html and/or doclib/doxy-footer.html files +# are regenerated +# +# * If any documentation is out-of-date with respect to it's source +# files, the documentation is regenerated. +# +# * To fix some link errors, the additional 'linklint' and 'fixlinks' +# targets are used +# +# +# 1. Scanning the Doxyfile's +# +# The doxygen builder scans all documentation source files which have +# the text 'doxyfile' in any case in their name. It understands +# @INCLUDE directives and will find all the dependencies of the +# documentation: +# +# * All the source files as selected by INPUT, INPUT_PATTERN, +# RECURSIVE and so on. +# +# * Any referenced tag-files +# +# * Documentation header and/or footer +# +# * The INPUT_FILTER program +# +# * Any included doxygen configuration files +# +# +# 2. Regenerating header and/or footer +# +# If needed, the doxy-header.html and/or doxy-footer.html file will be +# regenerated. The header and/or footer are generated from templates +# using a simple python based templating system called yaptu which is +# included in site_scons/lib/. +# +# +# 3. Calling doxygen +# +# The doxygen call itself is quite complex since there is some pre- +# and post-processing going on. We can separate this step into two +# steps +# +# * Building prerequisites (e.g. images) +# +# * The processing done by the Doxygen builder and +# site_scon/lib/doxygen.sh +# +# +# 3.1. Building prerequisites +# +# The prerequisites are images referenced by the documentation. These +# images are mostly generated using the Dia2Png builder. +# +# +# 3.2. The main doxygen build (Doxygen builder) +# +# The Doxygen builder will call the doxygen command to build the +# documentation. +# +# The doxygen command is configured as 'site_scon/lib/doxygen.sh' which +# does some additional processing in addition to calling doxygen +# proper +# +# * it sets environment variables depending on command line arguments. +# These variables are then used in the Doxyfile's +# +# * after doxygen is finished, 'installdox' is called to resolve +# tag file references. +# +# * the HTML documentation is post-processed using some sed, tidy, and +# an XSLT template +# +# * a generated tag file is post-processed using an XSLT template +# +# (see site_scon/lib/doxygen.sh for more information). The Doxygen +# configuration is set up such, that +# +# * doxygen calls 'site_scons/lib/filter.pl' on each source file. This +# filter will strip excess whitespace from the beginning of lines in +# '\code' and '
' blocks. Additionally it will expand all tabs, +# tab width is 8 spaces (there should be no tabs in the source but +# ...) +# +# * 'site_scons/lib/filter.pl' calls 'site_scons/lib/makeDiaImageMap.py' +# whenever finding a '\diaimage' command. This will create an image +# map (in an encoded form which will be fixed by html-munge.xsl +# later) +# +# * doxygen calls 'site_scons/lib/dot' to generate the 'dot' images. +# +# * 'site_scons/lib/dot' calls 'site_scons/lib/dot-munge.pl' on the +# .dot files. dot-munge.pl changes the font and font-size and adds +# line-breaks to long labels +# +# * 'site_scons/lib/dot' calls the real dot binary. If the resulting +# image is more than 800 pixels wide, dot is called again, this time +# using the oposite rank direction (top-bottom vs. left-right). The +# image with the smaller width is selected and returned. +# +# +# 4. Fixing broken links +# +# After the documentation has been generated, additional calls first +# to the 'linklint' and then to the 'fixlinks' target will try to fix +# broken links generated by doxygen. First, 'linklint' will call the +# linklint tool to check for broken links in the documentation. +# +# 'fixlinks' is then called which calls 'doclib/fixlinks.py' which +# scans *all* html files, builds an index of all (unique) anchors and +# then fixes the url part of all links with correct anchor but bad +# file name. +# + Import('env') -import SENFSCons +import SENFSCons, datetime, os ########################################################################### import yaptu def modules(): + # Naja ... etwas rumgehackt aber was solls ... global EXTRA_MODULES - rv = [] - ix = len(env.Dir('#').abspath)+1 - ex = dict((env.Dir(p).abspath,True) for n,p in EXTRA_MODULES) + mods = {} + pathbase = env.Dir('#/senf').abspath + pathbasel = len(pathbase)+1 for module in env.Alias('all_docs')[0].sources: if module.name != 'html.stamp' : continue - if not ex.get(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 + if not module.dir.dir.dir.abspath.startswith(pathbase): continue + mods[module.dir.dir.dir.abspath] = [ module.dir.dir.dir.abspath[pathbasel:].replace('/','_'), + module.dir.dir.dir.name, + module.dir.abspath[pathbasel:], + 0 ] + + rv = [] + keys = mods.keys() + keys.sort() + for mod in keys: + i = 0 + while i < len(rv): + if len(rv[i]) > pathbasel and mod.startswith(rv[i] + '/'): + level = mods[rv[i]][-1] + 1 + i += 1 + while i < len(rv) and mods[rv[i]][2] >= level: + i += 1 + rv[i:i] = [ mod ] + mods[mod][-1] = level + break + i += 1 + if i == len(rv): + rv.append(mod) + + return ( tuple(mods[mod]) for mod in rv ) def indices(): ix = len(env.Dir('#').abspath)+1 @@ -26,68 +170,76 @@ def indices(): if doc.name == "search.idx" ] def writeTemplate(target = None, source = None, env = None): - file(target[0].abspath,"w").write(yaptu.process(str(env['TEMPLATE']), globals(), env.Dictionary())) + file(target[0].abspath,"w").write(processTemplate(env)) + +def processTemplate(env): + return yaptu.process(str(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 = """$title +-- ++++++ ++SENF Extensible Network Framework
++-+
- Home
+- Download
+- Wiki
+- BerliOS
+- ChangeLog
+- Browse SVN
+- Bug Tracker
+SENF Extensible Network Framework
-${TITLE}
""" @@ -106,25 +258,64 @@ function paths() { } ?>""" -env.Command('doxy-header.html', None, writeTemplate, - TEMPLATE = Literal(HEADER), - TITLE = "Documentation and API reference") -env.Command('doxy-header-overview.html', None, writeTemplate, - TEMPLATE = Literal(HEADER+OVERVIEW_EXTRA_HEADER), - TITLE = "Introduction and Overview") -env.Command('doxy-footer.html', None, writeTemplate, - TEMPLATE = Literal(FOOTER)) +env.SetDefault( + DOXYGEN = "doxygen" +) + +env.Append( ENV = { + 'TODAY' : str(datetime.date.today()), +}) + +env.PhonyTarget('linklint', [], [ + 'rm -rf doc/linklint', + 'linklint -doc doc/linklint -limit 99999999 `find -type d -name html -printf "/%P/@ "`', + '[ ! -r doc/linklint/errorX.html ] || python doclib/linklint_addnames.py+ """ -OVERVIEW_EXTRA_HEADER=""" --""" - FOOTER = """-
-- Open Issues
-- SVN ChangeLog
-- SENF @ BerliOS
-- Wiki
-
doc/linklint/errorX.html.new', + '[ ! -r doc/linklint/errorX.html.new ] || mv doc/linklint/errorX.html.new doc/linklint/errorX.html', + '[ ! -r doc/linklint/errorAX.html ] || python doclib/linklint_addnames.py doc/linklint/errorAX.html.new', + '[ ! -r doc/linklint/errorAX.html.new ] || mv doc/linklint/errorAX.html.new doc/linklint/errorAX.html', +]) + +env.PhonyTarget('fixlinks', [], [ + 'python doclib/fix-links.py -v -s .svn -s linklint -s debian doc/linklint/errorX.txt doc/linklint/errorAX.txt', +]) + +header = env.Command('doxy-header.html', 'SConscript', writeTemplate, + TEMPLATE = Literal(HEADER), + TITLE = "Documentation and API reference") +env.Depends(header, env.Value(repr(list(modules())))) + +footer = env.Command('doxy-footer.html', 'SConscript', writeTemplate, + TEMPLATE = Literal(FOOTER)) + env.Alias('all_docs', - env.Command('search.php', 'html-munge.xsl', + env.Command('search.php', [ '#/site_scons/lib/html-munge.xsl', 'SConscript' ], [ writeTemplate, 'xsltproc --nonet --html --stringparam topdir .. -o - $SOURCE $TARGET 2>/dev/null' - + r'| sed -e "s/\[\[//g" -e "s/\]\]/?>/g" > ${TARGET}.tmp', + + "| sed" + + r" -e 's/\[\[//g' -e 's/\]\]/?>/g'" + + r" -e 's/\$$projectname/Overview/g'" + + r" -e 's/\$$title/Search results/g'" + + "> ${TARGETS[0]}.tmp", 'mv ${TARGET}.tmp ${TARGET}' ], TEMPLATE = Literal(HEADER - + OVERVIEW_EXTRA_HEADER + SEARCH_PHP.replace('','[[').replace('?>',']]') + FOOTER), TITLE = "Search results")) env.Alias('all_docs', - env.Command('search_paths.php', None, writeTemplate, + env.Command('search_paths.php', 'SConscript', writeTemplate, TEMPLATE = Literal(SEARCH_PATHS_PHP))) + +env.Alias('install_all', + env.Install( '$DOCINSTALLDIR/doclib', [ 'favicon.ico', + 'logo-head.png', + 'search.php', + 'search_functions.php', + 'search_paths.php', + 'senf.css' ] )) + +env.Clean('all', 'doxy-header.html') # I should not need this but I do ... +env.Clean('all_docs', 'doxy-header.html') # I should not need this but I do ... + +env.Install('${DOCINSTALLDIR}', 'index.html') + +env.Depends(SENFSCons.Doxygen(env, output_directory="../doc"), env.Value(env['ENV']['REVISION']))