Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions utils/gyb.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ def split_lines(s):
"""
return [l + '\n' for l in s.split('\n')]


# text on a line up to the first '$$', '${', or '%%'
literalText = r'(?: [^$\n%] | \$(?![${]) | %(?!%) )*'
# text on a line up to the first '$$', '${', <{, or '%%'
literalText = r'(?: [^$\n%] | \$(?![${]) | \<(?![<{]) | %(?!%) )*'

# The part of an '%end' line that follows the '%' sign
linesClose = r'[\ \t]* end [\ \t]* (?: \# .* )? $'
Expand Down Expand Up @@ -85,6 +84,10 @@ def split_lines(s):
| (?P<substitutionOpen> \$\{ )
[^}]* \} # Absorb

# Embedded Templates
| (?P<templateOpen> \<\{ )
[^}]* \}

# %% and $$ are literal % and $ respectively
| (?P<symbol>[$%]) (?P=symbol)

Expand Down Expand Up @@ -503,8 +506,11 @@ def token_generator(self, base_tokens):
if not m2:
raise ValueError("Invalid block closure")
next_pos = m2.end(0)
elif (kind == 'substitutionOpen'):
# skip past the closing '}'
next_pos = close_pos + 1
else:
assert kind == 'substitutionOpen'
assert kind == 'templateOpen'
# skip past the closing '}'
next_pos = close_pos + 1

Expand Down Expand Up @@ -622,6 +628,8 @@ def __init__(self, context):
while context.token_kind and not context.close_lines:
if context.token_kind == 'literal':
node = Literal
elif context.token_kind == 'templateOpen':
node = Template
else:
node = Code
self.children.append(node(context))
Expand Down Expand Up @@ -745,6 +753,25 @@ def __str__(self, indent=''):
) + '\n' + indent + '}'
return s + self.format_children(indent)

class Template(ASTNode):

"""An AST node that is evaluated as an embedded Template"""

children = ()
filename = None

def __init__(self, context):
self.filename = context.filename
self.template_filename = os.path.dirname(context.filename) + '/' + context.code_text
self.children += (Block(ParseContext(self.template_filename)),)
context.next_token()

def execute(self, context):
for x in self.children:
x.execute(context)

def __str__(self, indent=''):
return self.filename

def expand(filename, line_directive=_default_line_directive, **local_bindings):
r"""Return the contents of the givepn template file, executed with the given
Expand Down Expand Up @@ -803,7 +830,6 @@ def expand(filename, line_directive=_default_line_directive, **local_bindings):
finally:
os.chdir(d)


def parse_template(filename, text=None):
r"""Return an AST corresponding to the given template file.

Expand Down Expand Up @@ -1225,6 +1251,5 @@ def succ(a):

args.target.write(execute_template(ast, args.line_directive, **bindings))


if __name__ == '__main__':
main()