Migrate SimpleTAL templates to Kid/Genshi

# -*- coding: utf-8 -*-

"""Prepare SimpleTAL templates for migration to Kid or Genshi.

:Copyright: 2007-2008 Jochen Kupperschmidt
:Date: 14-Aug-2008
:License: MIT
"""

from __future__ import with_statement
import re

from simpletal import simpleTAL


CP_KID_EXPRSUB = re.compile(r'\$\{(.+?)\}')
CP_KID_CONTENT = re.compile(r'py:content="(.+?)"')
CP_KID_FOR = re.compile(r'py:for="(\S+?) in (.+?)"')
CP_KID_IF = re.compile(r'py:if="(.+?)"')
CP_KID_REPLACE = re.compile(r'py:replace="(.+?)"')

def preparse_template(string):
    """Replace Kid-style template expressions with their
    TAL equivalents.

    # The first only works outside of elements!
    ${x}            ->  <tal:block replace="python:x"/>
    py:content="x"  ->  tal:content="python:x"
    py:for="x in y" ->  tal:repeat="x python:y"
    py:if="x"       ->  tal:condition="python:x"
    py:replace="x"  ->  tal:replace="python:x"
    """
    for cp, sub in (
        (CP_KID_EXPRSUB, r'<tal:block replace="python:\1"/>'),
        (CP_KID_CONTENT, r'tal:content="python:\1"'),
        (CP_KID_FOR, r'tal:repeat="\1 python:\2"'),
        (CP_KID_IF, r'tal:condition="python:\1"'),
        (CP_KID_REPLACE, r'tal:replace="python:\1"'),
    ):
        string = cp.sub(sub, string)
    return string

def load_template(name):
    """Read, compile and return the template.

    This is the function you probably want to call yourself.
    """
    with open('/path/to/your/templates/%s.tpl' % name) as f:
        string = f.read()
    string = preparse_template(string)
    return simpleTAL.compileXMLTemplate(string)