2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
14 STATEMENT_RE
= "\[\[(.*?)\]\]" # [[...]]
15 EXPR_RE
= "\{\{(.*?)\}\}" # {{...}}
17 def TemplateToPython(template
, statement_re
, expr_re
):
18 output
= cStringIO
.StringIO()
19 indent_re
= re
.compile(r
'\s*')
21 for line
in template
.splitlines(1): # 1 => keep line ends
22 m
= statement_re
.match(line
)
24 statement
= m
.group(1)
25 indent_string
= indent_re
.match(statement
).group()
26 if statement
.rstrip()[-1:] == ':':
28 output
.write(statement
+ '\n')
31 while line
and line
[-1] in '\\"\n\r':
32 line_ending
= line
[-1] + line_ending
35 ms
= list(expr_re
.finditer(line
))
37 # Only replace % with %% outside of the expr matches.
41 new_line
+= line
[start
:m
.start()].replace('%', '%%')
42 new_line
+= line
[m
.start():m
.end()]
44 new_line
+= line
[start
:].replace('%', '%%')
47 subst_line
= r
'r"""%s""" %% (%s,)' % (
48 re
.sub(expr_re
, '%s', line
),
49 ', '.join(re
.findall(expr_re
, line
)))
51 subst_line
= r
'r"""%s"""' % line
53 out_string
= r
'%s__outfile__.write(%s + %s)' % (
57 output
.write(out_string
+ '\n')
59 return output
.getvalue()
62 def RunTemplate(srcfile
, dstfile
, template_dict
, statement_re
=None,
64 statement_re
= statement_re
or re
.compile(STATEMENT_RE
)
65 expr_re
= expr_re
or re
.compile(EXPR_RE
)
66 script
= TemplateToPython(srcfile
.read(), statement_re
, expr_re
)
67 template_dict
= copy
.copy(template_dict
)
68 template_dict
['__outfile__'] = dstfile
69 exec script
in template_dict
72 def RunTemplateFile(srcpath
, dstpath
, template_dict
, statement_re
=None,
74 with
open(srcpath
) as srcfile
:
75 with
open(dstpath
, 'w') as dstfile
:
76 RunTemplate(srcfile
, dstfile
, template_dict
, statement_re
, expr_re
)
79 def RunTemplateFileIfChanged(srcpath
, dstpath
, replace
):
80 dststr
= cStringIO
.StringIO()
81 with
open(srcpath
) as srcfile
:
82 RunTemplate(srcfile
, dststr
, replace
)
84 if os
.path
.exists(dstpath
):
85 with
open(dstpath
) as dstfile
:
86 if dstfile
.read() == dststr
.getvalue():
89 with
open(dstpath
, 'w') as dstfile
:
90 dstfile
.write(dststr
.getvalue())
93 def RunTemplateString(src
, template_dict
, statement_re
=None, expr_re
=None):
94 srcstr
= cStringIO
.StringIO(src
)
95 dststr
= cStringIO
.StringIO()
96 RunTemplate(srcstr
, dststr
, template_dict
, statement_re
, expr_re
)
97 return dststr
.getvalue()
101 parser
= optparse
.OptionParser()
102 _
, args
= parser
.parse_args(args
)
106 with
open(args
[0]) as f
:
107 print TemplateToPython(
108 f
.read(), re
.compile(STATEMENT_RE
), re
.compile(EXPR_RE
))
110 if __name__
== '__main__':
111 sys
.exit(main(sys
.argv
[1:]))