1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Builds the complete main.html file from the basic components.
"""
from HTMLParser import HTMLParser
import os
import re
import sys
def error(msg):
print 'Error: %s' % msg
sys.exit(1)
class HtmlChecker(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.ids = set()
def handle_starttag(self, tag, attrs):
for (name, value) in attrs:
if name == 'id':
if value in self.ids:
error('Duplicate id: %s' % value)
self.ids.add(value)
class GenerateWebappHtml:
def __init__(self, template_files, js_files):
self.js_files = js_files
self.templates_expected = set()
for template in template_files:
self.templates_expected.add(os.path.basename(template))
self.templates_found = set()
def includeJavascript(self, output):
for js_path in sorted(self.js_files):
js_file = os.path.basename(js_path)
output.write(' <script src="' + js_file + '"></script>\n')
def verifyTemplateList(self):
"""Verify that all the expected templates were found."""
if self.templates_expected > self.templates_found:
extra = self.templates_expected - self.templates_found
print 'Extra templates specified:', extra
return False
return True
def validateTemplate(self, template_path):
template = os.path.basename(template_path)
if template in self.templates_expected:
self.templates_found.add(template)
return True
return False
def processTemplate(self, output, template_file, indent):
with open(template_file, 'r') as input:
first_line = True
skip_header_comment = False
for line in input:
# If the first line is the start of a copyright notice, then
# skip over the entire comment.
# This will remove the copyright info from the included files,
# but leave the one on the main template.
if first_line and re.match(r'<!--', line):
skip_header_comment = True
first_line = False
if skip_header_comment:
if re.search(r'-->', line):
skip_header_comment = False
continue
m = re.match(
r'^(\s*)<meta-include src="(.+)"\s*/>\s*$',
line)
if m:
prefix = m.group(1)
template_name = m.group(2)
if not self.validateTemplate(template_name):
error('Found template not in list of expected templates: %s' %
template_name)
self.processTemplate(output, template_name, indent + len(prefix))
continue
m = re.match(r'^\s*<meta-include type="javascript"\s*/>\s*$', line)
if m:
self.includeJavascript(output)
continue
if line.strip() == '':
output.write('\n')
else:
output.write((' ' * indent) + line)
def show_usage():
print ('Usage: %s <output-file> <input-template> '
'[--templates <template-files...>] '
'[--js <js-files...>]' % sys.argv[0])
print 'where:'
print ' <output-file> Path to HTML output file'
print ' <input-template> Path to input template'
print ' <template-files> The html template files used by <input-template>'
print ' <js-files> The Javascript files to include in HTML <head>'
def main():
if len(sys.argv) < 4:
show_usage()
error('Not enough arguments')
out_file = sys.argv[1]
main_template_file = sys.argv[2]
template_files = []
js_files = []
for arg in sys.argv[3:]:
if arg == '--js' or arg == '--template':
arg_type = arg
elif arg_type == '--js':
js_files.append(arg)
elif arg_type == '--template':
template_files.append(arg)
else:
error('Unrecognized argument: %s' % arg)
# Generate the main HTML file from the templates.
with open(out_file, 'w') as output:
gen = GenerateWebappHtml(template_files, js_files)
gen.processTemplate(output, main_template_file, 0)
# Verify that all the expected templates were found.
if not gen.verifyTemplateList():
error('Extra templates specified')
# Verify that the generated HTML file is valid.
with open(out_file, 'r') as input:
parser = HtmlChecker()
parser.feed(input.read())
if __name__ == '__main__':
sys.exit(main())
|