OLD | NEW |
| (Empty) |
1 /** | |
2 * Creates database.html, examples.html, and obsolete.html. | |
3 */ | |
4 | |
5 library prettyPrint; | |
6 | |
7 import 'dart:convert'; | |
8 import 'dart:io'; | |
9 import 'util.dart'; | |
10 | |
11 String orEmpty(String str) { | |
12 return str == null ? "" : str; | |
13 } | |
14 | |
15 List<String> sortStringCollection(Iterable<String> collection) { | |
16 final out = <String>[]; | |
17 out.addAll(collection); | |
18 out.sort((String a, String b) => a.compareTo(b)); | |
19 return out; | |
20 } | |
21 | |
22 int addMissing(StringBuffer sb, String type, Map members) { | |
23 int total = 0; | |
24 /** | |
25 * Add all missing members to the string output and return the number of | |
26 * missing members. | |
27 */ | |
28 void addMissingHelper(String propType) { | |
29 Map expected = allProps[type][propType]; | |
30 if (expected != null) { | |
31 for(final name in sortStringCollection(expected.keys)) { | |
32 if (!members.containsKey(name)) { | |
33 total++; | |
34 sb.write(""" | |
35 <tr class="missing"> | |
36 <td>$name</td> | |
37 <td></td> | |
38 <td>Could not find documentation for $propType</td> | |
39 </tr> | |
40 """); | |
41 } | |
42 } | |
43 } | |
44 } | |
45 | |
46 addMissingHelper('properties'); | |
47 addMissingHelper('methods'); | |
48 addMissingHelper('constants'); | |
49 return total; | |
50 } | |
51 | |
52 void main() { | |
53 // Database of code documentation. | |
54 final Map<String, Map> database = JSON.decode( | |
55 new File('output/database.filtered.json').readAsStringSync()); | |
56 | |
57 // Types we have documentation for. | |
58 matchedTypes = new Set<String>(); | |
59 int numMissingMethods = 0; | |
60 int numFoundMethods = 0; | |
61 int numExtraMethods = 0; | |
62 int numGen = 0; | |
63 int numSkipped = 0; | |
64 final sbSkipped = new StringBuffer(); | |
65 final sbAllExamples = new StringBuffer(); | |
66 | |
67 // Table rows for all obsolete members. | |
68 final sbObsolete = new StringBuffer(); | |
69 // Main documentation file. | |
70 final sb = new StringBuffer(); | |
71 | |
72 // TODO(jacobr): switch to using a real template system instead of string | |
73 // interpolation combined with StringBuffers. | |
74 sb.write(""" | |
75 <html> | |
76 <head> | |
77 <style type="text/css"> | |
78 body { | |
79 background-color: #eee; | |
80 margin: 10px; | |
81 font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, | |
82 Arial, Helvetica, sans-serif; | |
83 } | |
84 | |
85 .debug { | |
86 color: #888; | |
87 } | |
88 | |
89 .compatibility, .links, .see-also, .summary, .members, .example { | |
90 border: 1px solid #CCC; | |
91 margin: 5px; | |
92 padding: 5px; | |
93 } | |
94 | |
95 .type, #dart_summary { | |
96 border: 1px solid; | |
97 margin-top: 10px; | |
98 margin-bottom: 10px; | |
99 padding: 10px; | |
100 overflow: hidden; | |
101 background-color: white; | |
102 -moz-box-shadow: 5px 5px 5px #888; | |
103 -webkit-box-shadow: 5px 5px 5px #888; | |
104 box-shadow: 5px 5px 5px #888; | |
105 } | |
106 | |
107 #dart_summary { | |
108 border: 2px solid #00F; | |
109 margin: 5px; | |
110 padding: 5px; | |
111 } | |
112 | |
113 th { | |
114 background-color:#ccc; | |
115 font-weight: bold; | |
116 } | |
117 | |
118 tr:nth-child(odd) { | |
119 background-color:#eee; | |
120 } | |
121 tr:nth-child(even) { | |
122 background-color:#fff; | |
123 } | |
124 | |
125 tr:nth-child(odd).unknown { | |
126 background-color:#dd0; | |
127 } | |
128 tr:nth-child(even).unknown { | |
129 background-color:#ff0; | |
130 } | |
131 | |
132 tr:nth-child(odd).missing { | |
133 background-color:#d88; | |
134 } | |
135 tr:nth-child(even).missing { | |
136 background-color:#faa; | |
137 } | |
138 | |
139 li.unknown { | |
140 color: #f00; | |
141 } | |
142 | |
143 td, th { | |
144 vertical-align: top; | |
145 } | |
146 </style> | |
147 <title>Doc Dump</title> | |
148 </head> | |
149 <body> | |
150 <h1>Doc Dump</h1> | |
151 <ul> | |
152 <li><a href="#dart_summary">Summary</a></li> | |
153 </li> | |
154 """); | |
155 for (String type in sortStringCollection(database.keys)) { | |
156 final entry = database[type]; | |
157 if (entry == null || entry.containsKey('skipped')) { | |
158 numSkipped++; | |
159 sbSkipped.write(""" | |
160 <li id="$type"> | |
161 <a target="_blank" href="http://www.google.com/cse?cx=01719397256594783026
6%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> | |
162 $type | |
163 </a> | |
164 -- | |
165 Title: ${entry == null ? "???" : entry["title"]} -- Issue: | |
166 ${entry == null ? "???" : entry['cause']} | |
167 -- | |
168 <a target="_blank" href="${entry == null ? "???" : entry["srcUrl"]}"> | |
169 scraped url | |
170 </a> | |
171 </li>"""); | |
172 continue; | |
173 } | |
174 matchedTypes.add(type); | |
175 numGen++; | |
176 StringBuffer sbSections = new StringBuffer(); | |
177 StringBuffer sbMembers = new StringBuffer(); | |
178 StringBuffer sbExamples = new StringBuffer(); | |
179 if (entry.containsKey("members")) { | |
180 Map members = getMembersMap(entry); | |
181 sbMembers.write(""" | |
182 <div class="members"> | |
183 <h3><span class="debug">[dart]</span> Members</h3> | |
184 <table> | |
185 <tbody> | |
186 <tr> | |
187 <th>Name</th><th>Description</th><th>IDL</th><th>Status</th> | |
188 </tr> | |
189 """); | |
190 for (String name in sortStringCollection(members.keys)) { | |
191 Map memberData = members[name]; | |
192 bool unknown = !hasAny(type, name); | |
193 StringBuffer classes = new StringBuffer(); | |
194 if (unknown) classes.write("unknown "); | |
195 if (unknown) { | |
196 numExtraMethods++; | |
197 } else { | |
198 numFoundMethods++; | |
199 } | |
200 | |
201 final sbMember = new StringBuffer(); | |
202 | |
203 if (memberData.containsKey('url')) { | |
204 sbMember.write(""" | |
205 <td><a href="${memberData['url']}">$name</a></td> | |
206 """); | |
207 } else { | |
208 sbMember.write(""" | |
209 <td>$name</td> | |
210 """); | |
211 } | |
212 sbMember.write(""" | |
213 <td>${memberData['help']}</td> | |
214 <td> | |
215 <pre>${orEmpty(memberData['idl'])}</pre> | |
216 </td> | |
217 <td>${memberData['obsolete'] == true ? "Obsolete" : ""}</td> | |
218 """); | |
219 if (memberData['obsolete'] == true) { | |
220 sbObsolete.write("<tr class='$classes'><td>$type</td>$sbMember</tr>"); | |
221 } | |
222 sbMembers.write("<tr class='$classes'>$sbMember</tr>"); | |
223 } | |
224 | |
225 numMissingMethods += addMissing(sbMembers, type, members); | |
226 | |
227 sbMembers.write(""" | |
228 </tbody> | |
229 </table> | |
230 </div> | |
231 """); | |
232 } | |
233 for (String sectionName in | |
234 ["summary", "constructor", "compatibility", "specification", | |
235 "seeAlso"]) { | |
236 if (entry.containsKey(sectionName)) { | |
237 sbSections.write(""" | |
238 <div class="$sectionName"> | |
239 <h3><span class="debug">[Dart]</span> $sectionName</h3> | |
240 ${entry[sectionName]} | |
241 </div> | |
242 """); | |
243 } | |
244 } | |
245 if (entry.containsKey("links")) { | |
246 sbSections.write(""" | |
247 <div class="links"> | |
248 <h3><span class="debug">[Dart]</span> Specification</h3> | |
249 <ul> | |
250 """); | |
251 List links = entry["links"]; | |
252 for (Map link in links) { | |
253 sbSections.write(""" | |
254 <li><a href="${link['href']}">${link['title']}</a></li> | |
255 """); | |
256 } | |
257 sbSections.write(""" | |
258 </ul> | |
259 </div> | |
260 """); | |
261 } | |
262 if (entry.containsKey("examples")) { | |
263 for (String example in entry["examples"]) { | |
264 sbExamples.write(""" | |
265 <div class="example"> | |
266 <h3><span class="debug">[Dart]</span> Example</h3> | |
267 $example | |
268 </div> | |
269 """); | |
270 } | |
271 } | |
272 | |
273 String title = entry['title']; | |
274 if (title != type) { | |
275 title = '<h4>Dart type: $type</h4><h2>$title</h2>'; | |
276 } else { | |
277 title = '<h2>$title</h2>'; | |
278 } | |
279 sb.write(""" | |
280 <div class='type' id="$type"> | |
281 <a href='${entry['srcUrl']}'>$title</a> | |
282 $sbSections | |
283 $sbExamples | |
284 $sbMembers | |
285 </div> | |
286 """); | |
287 if (sbExamples.length > 0) { | |
288 sbAllExamples.write(""" | |
289 <div class='type' id="$type"> | |
290 <a href='${entry['srcUrl']}'>$title</a> | |
291 $sbExamples | |
292 </div> | |
293 """); | |
294 } | |
295 } | |
296 | |
297 for (String type in sortStringCollection(allProps.keys)) { | |
298 if (!matchedTypes.contains(type) && | |
299 !database.containsKey(type)) { | |
300 numSkipped++; | |
301 sbSkipped.write(""" | |
302 <li class="unknown" id="$type"> | |
303 <a target="_blank" href="http://www.google.com/cse?cx=01719397256594783026
6%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> | |
304 $type | |
305 </a> | |
306 </li> | |
307 """); | |
308 } | |
309 } | |
310 | |
311 sb.write(""" | |
312 <div id="#dart_summary"> | |
313 <h2>Summary</h2> | |
314 <h3> | |
315 Generated docs for $numGen classes out of a possible | |
316 ${allProps.keys.length} | |
317 </h3> | |
318 <h3>Found documentation for $numFoundMethods methods listed in WebKit</h3> | |
319 <h3> | |
320 Found documentation for $numExtraMethods methods not listed in WebKit | |
321 </h3> | |
322 <h3> | |
323 Unable to find documentation for $numMissingMethods methods present in | |
324 WebKit | |
325 </h3> | |
326 <h3> | |
327 Skipped generating documentation for $numSkipped classes due to no | |
328 plausible matching files | |
329 </h3> | |
330 <ul> | |
331 $sbSkipped | |
332 </ul> | |
333 </div> | |
334 """); | |
335 sb.write(""" | |
336 </body> | |
337 </html> | |
338 """); | |
339 | |
340 writeFileSync("output/database.html", sb.toString()); | |
341 | |
342 writeFileSync("output/examples.html", """ | |
343 <html> | |
344 <head> | |
345 <style type="text/css"> | |
346 body { | |
347 background-color: #eee; | |
348 margin: 10px; | |
349 font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, Arial, | |
350 Helvetica, sans-serif; | |
351 } | |
352 | |
353 .debug { | |
354 color: #888; | |
355 } | |
356 | |
357 .example { | |
358 border: 1px solid #CCC; | |
359 margin: 5px; | |
360 padding: 5px; | |
361 } | |
362 | |
363 .type { | |
364 border: 1px solid; | |
365 margin-top: 10px; | |
366 margin-bottom: 10px; | |
367 padding: 10px; | |
368 overflow: hidden; | |
369 background-color: white; | |
370 -moz-box-shadow: 5px 5px 5px #888; | |
371 -webkit-box-shadow: 5px 5px 5px #888; | |
372 box-shadow: 5px 5px 5px #888; | |
373 } | |
374 </style> | |
375 <title>All examples</title> | |
376 </head> | |
377 <body> | |
378 <h1>All examples</h1> | |
379 $sbAllExamples | |
380 </body> | |
381 </html> | |
382 """); | |
383 | |
384 writeFileSync("output/obsolete.html", """ | |
385 <html> | |
386 <head> | |
387 <style type="text/css"> | |
388 body { | |
389 background-color: #eee; | |
390 margin: 10px; | |
391 font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, | |
392 Arial, Helvetica, sans-serif; | |
393 } | |
394 | |
395 .debug { | |
396 color: #888; | |
397 } | |
398 | |
399 .type { | |
400 border: 1px solid; | |
401 margin-top: 10px; | |
402 margin-bottom: 10px; | |
403 padding: 10px; | |
404 overflow: hidden; | |
405 background-color: white; | |
406 -moz-box-shadow: 5px 5px 5px #888; | |
407 -webkit-box-shadow: 5px 5px 5px #888; | |
408 box-shadow: 5px 5px 5px #888; | |
409 } | |
410 </style> | |
411 <title>Methods marked as obsolete</title> | |
412 </head> | |
413 <body> | |
414 <h1>Methods marked as obsolete</h1> | |
415 <table> | |
416 <tbody> | |
417 <tr> | |
418 <th>Type</th> | |
419 <th>Name</th> | |
420 <th>Description</th> | |
421 <th>IDL</th> | |
422 <th>Status</th> | |
423 </tr> | |
424 $sbObsolete | |
425 </tbody> | |
426 </table> | |
427 </body> | |
428 </html> | |
429 """); | |
430 } | |
OLD | NEW |