Skip to content

Commit a99b7c8

Browse files
committed
Fixing DOM checker
1 parent 87ffb7f commit a99b7c8

File tree

2 files changed

+180
-49
lines changed

2 files changed

+180
-49
lines changed

_includes/foot.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
·
88
<span>Last built {{ site.time }}</span>
99
</small>
10-
<div class="ftr-links">
10+
<div>
1111
<a href="mailto:{{site.author.email}}" aria-label="Mail the author"><i class="far fa-envelope" aria-hidden="true"></i></a>
1212
|
1313
<a href="{{site.author.github}}" aria-label="Author's GitHub repository"><i class="fab fa-github" aria-hidden="true"></i></a>

bin/check-dom.py

Lines changed: 179 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,94 +10,225 @@
1010

1111

1212
KNOWN = {
13-
'a': {'aria-label', 'class', 'href', 'title'},
13+
'a': {
14+
'aria-label': None,
15+
'class': {'doi', 'dropdown-item'},
16+
'href': None,
17+
'title': None
18+
},
1419
'blockquote': {},
15-
'body': {'class'},
20+
'body': {
21+
'class': {'draft'}
22+
},
1623
'br': {},
1724
'caption': {},
1825
'cite': {},
19-
'code': {'class'},
20-
'dd': {'class'},
21-
'div': {'class', 'id'},
22-
'dl': {'class'},
23-
'dt': {'class', 'id'},
26+
'code': {
27+
'class': {
28+
'language-html',
29+
'language-js',
30+
'language-make',
31+
'language-out',
32+
'language-py',
33+
'language-sh',
34+
'language-txt',
35+
'language-yml'
36+
}
37+
},
38+
'dd': {
39+
'class': None
40+
},
41+
'div': {
42+
'class': {
43+
'glossary',
44+
'callout',
45+
'centered',
46+
'container',
47+
'content',
48+
'dropdown',
49+
'dropdown-content',
50+
'file-link',
51+
'terms'
52+
},
53+
'id': None
54+
},
55+
'dl': {
56+
'class': {
57+
'bibliography',
58+
'glossary'
59+
}
60+
},
61+
'dt': {
62+
'class': {
63+
'bibliography',
64+
'glossary'
65+
},
66+
'id': None
67+
},
2468
'em': {},
2569
'figcaption': {},
26-
'figure': {'class', 'id', 'slug'},
70+
'figure': {
71+
'class': None,
72+
'id': None,
73+
'slug': None
74+
},
2775
'footer': {},
28-
'h1': {'class', 'slug'},
29-
'h2': {'class', 'id'},
30-
'h3': {'id'},
76+
'h1': {
77+
'class': {
78+
'landing-title',
79+
'nochaptertitle',
80+
'page-title'
81+
},
82+
'slug': None
83+
},
84+
'h2': {
85+
'class': {
86+
'landing-subtitle'
87+
},
88+
'id': None
89+
},
90+
'h3': {
91+
'id': None
92+
},
3193
'head': {},
3294
'header': {},
3395
'hr': {},
34-
'html': {'lang'},
35-
'i': {'aria-hidden', 'class'},
36-
'img': {'alt', 'class', 'src'},
96+
'html': {
97+
'lang': {
98+
'en'
99+
}
100+
},
101+
'i': {
102+
'aria-hidden': None,
103+
'class': None
104+
},
105+
'img': {
106+
'alt': None,
107+
'class': {
108+
'iconlink'
109+
},
110+
'src': None
111+
},
37112
'li': {},
38-
'link': {'href', 'rel', 'type'},
113+
'link': {
114+
'href': None,
115+
'rel': {
116+
'icon',
117+
'shortcut',
118+
'stylesheet',
119+
'image/x-icon',
120+
'text/css'
121+
},
122+
'type': None
123+
},
39124
'main': {},
40-
'meta': {'charset', 'content', 'name'},
41-
'nav': {'class'},
125+
'meta': {
126+
'charset': None,
127+
'content': None,
128+
'name': None
129+
},
130+
'nav': {
131+
'class': {
132+
'nav-main'
133+
}
134+
},
42135
'ol': {},
43-
'p': {'class'},
44-
'pre': {'class', 'title'},
45-
'script': {'async', 'crossorigin', 'src', 'type'},
136+
'p': {
137+
'class': {
138+
'continue'
139+
}
140+
},
141+
'pre': {
142+
'class': None,
143+
'title': None
144+
},
145+
'script': {
146+
'async': None,
147+
'crossorigin': None,
148+
'src': None,
149+
'type': None
150+
},
46151
'small': {},
47-
'span': {'class', 'f', 'g', 'i', 't', 'x'},
152+
'span': {
153+
'class': {
154+
'copyright',
155+
'navtitle',
156+
'nowrap'
157+
},
158+
'f': None,
159+
'g': None,
160+
'i': None,
161+
't': None,
162+
'x': None
163+
},
48164
'strong': {},
49-
'table': {'class', 'id'},
165+
'table': {
166+
'class': {
167+
'links'
168+
},
169+
'id': None
170+
},
50171
'tbody': {},
51-
'td': {'style'},
52-
'th': {'style'},
172+
'td': {
173+
'style': None
174+
},
175+
'th': {
176+
'style': None
177+
},
53178
'thead': {},
54-
'time': {'datetime'},
179+
'time': {
180+
'datetime': None
181+
},
55182
'title': {},
56183
'tr': {},
57-
'ul': {'class'}
184+
'ul': {
185+
'class': {
186+
'toc'
187+
}
188+
}
58189
}
59190

60191

61192
def check_dom(options):
62193
'''Main driver.'''
63-
elements = set()
64-
attributes = {}
194+
problems = {}
65195
for filename in options.sources:
66196
with open(filename, 'r') as reader:
67197
doc = bs4.BeautifulSoup(reader, features='lxml')
68198
for node in doc.descendants:
69199
if isinstance(node, bs4.element.Tag):
70-
check(elements, attributes, node)
71-
report(elements, attributes)
200+
check(problems, filename, node)
201+
report(problems)
72202

73203

74-
def check(elements, attributes, node):
204+
def check(problems, filename, node):
75205
'''Check individual element.'''
76206
if node.name not in KNOWN:
77-
elements.add(node.name)
207+
problems[node.name] = f'unknown ({filename})'
78208
return
79209
for attr in node.attrs:
80210
if attr not in KNOWN[node.name]:
81-
if node.name not in attributes:
82-
attributes[node.name] = set()
83-
attributes[node.name].add(attr)
211+
if node.name not in problems:
212+
problems[node.name] = []
213+
problems[node.name].append(f'unknown attribute "{attr}" in {filename}')
214+
elif KNOWN[node.name][attr] is not None:
215+
values = node[attr] if isinstance(node[attr], list) else [node[attr]]
216+
for value in values:
217+
if value not in KNOWN[node.name][attr]:
218+
if node.name not in problems:
219+
problems[node.name] = []
220+
problems[node.name].append(f'"{attr}" has unknown value "{value}" in {filename}')
84221

85222

86-
def report(elements, attributes):
223+
def report(problems):
87224
'''Report results.'''
88-
if (not elements) and (not attributes):
225+
if not problems:
89226
return
90-
print('- unknown')
91-
if elements:
92-
print(' - elements')
93-
for name in sorted(elements):
94-
print(f' - {name}')
95-
if attributes:
96-
print(' - attributes')
97-
for name in sorted(attributes.keys()):
98-
print(f' - {name}')
99-
for attr in sorted(attributes[name]):
100-
print(f' - {attr}')
227+
print('- DOM')
228+
for name in sorted(problems.keys()):
229+
print(f' - {name}')
230+
for problem in problems[name]:
231+
print(f' - {problem}')
101232

102233

103234
if __name__ == '__main__':

0 commit comments

Comments
 (0)