Files
sdk/lib/dom/scripts/templateloader.py
T
sra@google.com fc20e9356e Add template comments.
Lines starting with //$ are removed during preprocessing of the template.
This allows comments in the templates that are not copied to the generated text.

Update copyright in template file in anticipation of new uses.

Review URL: https://chromiumcodereview.appspot.com//10694169

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@9616 260f80e4-7a28-3924-810f-c04153c831b5
2012-07-12 21:45:22 +00:00

117 lines
3.4 KiB
Python

#!/usr/bin/python
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# Template loader and preprocessor.
#
# Preprocessor language:
#
# //$ Comment line removed by preprocessor
# $if VAR
# $else
# $endif
#
# VAR must be defined in the conditions dictionary.
import os
class TemplateLoader(object):
"""Loads template files from a path."""
def __init__(self, root, subpaths, conditions = {}):
"""Initializes loader.
Args:
root - a string, the directory under which the templates are stored.
subpaths - a list of strings, subpaths of root in search order.
conditions - a dictionay from strings to booleans. Any conditional
expression must be a key in the map.
"""
self._root = root
self._subpaths = subpaths
self._conditions = conditions
self._cache = {}
def TryLoad(self, name):
"""Returns content of template file as a string, or None of not found."""
if name in self._cache:
return self._cache[name]
for subpath in self._subpaths:
template_file = os.path.join(self._root, subpath, name)
if os.path.exists(template_file):
template = ''.join(open(template_file).readlines())
template = self._Preprocess(template, template_file)
self._cache[name] = template
return template
return None
def Load(self, name):
"""Returns contents of template file as a string, or raises an exception."""
template = self.TryLoad(name)
if template is not None: # Can be empty string
return template
raise Exception("Could not find template '%s' on %s / %s" % (
name, self._root, self._subpaths))
def _Preprocess(self, template, filename):
def error(lineno, message):
raise Exception('%s:%s: %s' % (filename, lineno, message))
lines = template.splitlines(True)
out = []
condition_stack = []
active = True
seen_else = False
for (lineno, full_line) in enumerate(lines):
line = full_line.strip()
if line.startswith('$'):
words = line.split()
directive = words[0]
if directive == '$if':
if len(words) != 2:
error(lineno, '$if does not have single variable')
variable = words[1]
if variable in self._conditions:
condition_stack.append((active, seen_else))
active = self._conditions[variable]
seen_else = False
else:
error(lineno, "Unknown $if variable '%s'" % variable)
elif directive == '$else':
if not condition_stack:
error(lineno, '$else without $if')
if seen_else:
raise error(lineno, 'Double $else')
seen_else = True
active = not active
elif directive == '$endif':
if not condition_stack:
error(lineno, '$endif without $if')
(active, seen_else) = condition_stack.pop()
else:
# Something else, like '$!MEMBERS'
if active:
out.append(full_line)
elif line.startswith('//$'):
pass # Ignore pre-processor comment.
else:
if active:
out.append(full_line)
continue
if condition_stack:
error(len(lines), 'Unterminated $if')
return ''.join(out)