Edgewall Software

GenshiRecipes/SconsXIncludeScanner

Version 1 (modified by robinbryce@…, 8 years ago)

minimal scons integration for markup

why would you want this recipe ? You need to integrate markup sources into a scons based build system and you would like implicit dependencies for xi:include directives.

file SConscript:

import sys
from markup.filters import IncludeFilter
from markup.template import Template,TemplateLoader

def markup_xinclude_scan(node, env, path, arg):
    t=Template(node.get_contents())
    loader=TemplateLoader('.'.split())
    t.filters.insert(0, IncludeFilter(loader))
    t.generate().render()
    return loader._cache.keys()

markup_scanner = Scanner(
    name='markup',
    function=markup_xinclude_scan,
    argument=None,
    skeys = '.xhtml .html .xml'.split())
scanners = Environment().Dictionary('SCANNERS')
env = Environment(SCANNERS = scanners + [markup_scanner])

env.Command('page-out', 'page.html', './render $SOURCES $TARGET')

So, assuming page.html references another file, say base.html, using the Xinclude recipe, any edit to base.html will cause scons to consider page-out to be out of date. After an edit of either page.html or base.html scons -f SConscript will be sufficient to bring page-out up to date.

render is a trivial wrapper script that renders the final output using markup for a single source file. Mine looks like this:

#!/usr/bin/python
import sys
try: import wingdbstub
except ImportError: pass
from markup.filters import IncludeFilter
from markup.template import Template,TemplateLoader
t=Template(file(sys.argv[1]).read())
t.filters.insert(0, IncludeFilter(TemplateLoader('.'.split())))
outf = sys.stdout
if len(sys.argv) > 2:
    outf=file(sys.argv[2], 'w')
print >> outf, t.generate().render()

There may be slicker ways of doing this. If you know them then please update this recipe.