2 # Copyright 2014 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.
6 """Builds the complete main.html file from the basic components.
9 from HTMLParser
import HTMLParser
16 print 'Error: %s' % msg
20 class HtmlChecker(HTMLParser
):
22 HTMLParser
.__init
__(self
)
25 def handle_starttag(self
, tag
, attrs
):
26 for (name
, value
) in attrs
:
29 error('Duplicate id: %s' % value
)
33 class GenerateWebappHtml
:
34 def __init__(self
, template_files
, js_files
):
35 self
.js_files
= js_files
37 self
.templates_expected
= set()
38 for template
in template_files
:
39 self
.templates_expected
.add(os
.path
.basename(template
))
41 self
.templates_found
= set()
43 def includeJavascript(self
, output
):
44 for js_path
in sorted(self
.js_files
):
45 js_file
= os
.path
.basename(js_path
)
46 output
.write(' <script src="' + js_file
+ '"></script>\n')
48 def verifyTemplateList(self
):
49 """Verify that all the expected templates were found."""
50 if self
.templates_expected
> self
.templates_found
:
51 extra
= self
.templates_expected
- self
.templates_found
52 print 'Extra templates specified:', extra
56 def validateTemplate(self
, template_path
):
57 template
= os
.path
.basename(template_path
)
58 if template
in self
.templates_expected
:
59 self
.templates_found
.add(template
)
63 def processTemplate(self
, output
, template_file
, indent
):
64 with
open(template_file
, 'r') as input:
66 skip_header_comment
= False
69 # If the first line is the start of a copyright notice, then
70 # skip over the entire comment.
71 # This will remove the copyright info from the included files,
72 # but leave the one on the main template.
73 if first_line
and re
.match(r
'<!--', line
):
74 skip_header_comment
= True
76 if skip_header_comment
:
77 if re
.search(r
'-->', line
):
78 skip_header_comment
= False
82 r
'^(\s*)<meta-include src="(.+)"\s*/>\s*$',
86 template_name
= m
.group(2)
87 if not self
.validateTemplate(template_name
):
88 error('Found template not in list of expected templates: %s' %
90 self
.processTemplate(output
, template_name
, indent
+ len(prefix
))
93 m
= re
.match(r
'^\s*<meta-include type="javascript"\s*/>\s*$', line
)
95 self
.includeJavascript(output
)
98 if line
.strip() == '':
101 output
.write((' ' * indent
) + line
)
105 print ('Usage: %s <output-file> <input-template> '
106 '[--templates <template-files...>] '
107 '[--js <js-files...>]' % sys
.argv
[0])
109 print ' <output-file> Path to HTML output file'
110 print ' <input-template> Path to input template'
111 print ' <template-files> The html template files used by <input-template>'
112 print ' <js-files> The Javascript files to include in HTML <head>'
116 if len(sys
.argv
) < 4:
118 error('Not enough arguments')
120 out_file
= sys
.argv
[1]
121 main_template_file
= sys
.argv
[2]
125 for arg
in sys
.argv
[3:]:
126 if arg
== '--js' or arg
== '--template':
128 elif arg_type
== '--js':
130 elif arg_type
== '--template':
131 template_files
.append(arg
)
133 error('Unrecognized argument: %s' % arg
)
135 # Generate the main HTML file from the templates.
136 with
open(out_file
, 'w') as output
:
137 gen
= GenerateWebappHtml(template_files
, js_files
)
138 gen
.processTemplate(output
, main_template_file
, 0)
140 # Verify that all the expected templates were found.
141 if not gen
.verifyTemplateList():
142 error('Extra templates specified')
144 # Verify that the generated HTML file is valid.
145 with
open(out_file
, 'r') as input:
146 parser
= HtmlChecker()
147 parser
.feed(input.read())
150 if __name__
== '__main__':