| /** |
| * Creates database.html, examples.html, and obsolete.html. |
| */ |
| |
| library prettyPrint; |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| import 'util.dart'; |
| |
| String orEmpty(String str) { |
| return str == null ? "" : str; |
| } |
| |
| List<String> sortStringCollection(Iterable<String> collection) { |
| final out = <String>[]; |
| out.addAll(collection); |
| out.sort((String a, String b) => a.compareTo(b)); |
| return out; |
| } |
| |
| int addMissing(StringBuffer sb, String type, Map members) { |
| int total = 0; |
| /** |
| * Add all missing members to the string output and return the number of |
| * missing members. |
| */ |
| void addMissingHelper(String propType) { |
| Map expected = allProps[type][propType]; |
| if (expected != null) { |
| for(final name in sortStringCollection(expected.keys)) { |
| if (!members.containsKey(name)) { |
| total++; |
| sb.write(""" |
| <tr class="missing"> |
| <td>$name</td> |
| <td></td> |
| <td>Could not find documentation for $propType</td> |
| </tr> |
| """); |
| } |
| } |
| } |
| } |
| |
| addMissingHelper('properties'); |
| addMissingHelper('methods'); |
| addMissingHelper('constants'); |
| return total; |
| } |
| |
| void main() { |
| // Database of code documentation. |
| final Map<String, Map> database = JSON.decode( |
| new File('output/database.filtered.json').readAsStringSync()); |
| |
| // Types we have documentation for. |
| matchedTypes = new Set<String>(); |
| int numMissingMethods = 0; |
| int numFoundMethods = 0; |
| int numExtraMethods = 0; |
| int numGen = 0; |
| int numSkipped = 0; |
| final sbSkipped = new StringBuffer(); |
| final sbAllExamples = new StringBuffer(); |
| |
| // Table rows for all obsolete members. |
| final sbObsolete = new StringBuffer(); |
| // Main documentation file. |
| final sb = new StringBuffer(); |
| |
| // TODO(jacobr): switch to using a real template system instead of string |
| // interpolation combined with StringBuffers. |
| sb.write(""" |
| <html> |
| <head> |
| <style type="text/css"> |
| body { |
| background-color: #eee; |
| margin: 10px; |
| font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, |
| Arial, Helvetica, sans-serif; |
| } |
| |
| .debug { |
| color: #888; |
| } |
| |
| .compatibility, .links, .see-also, .summary, .members, .example { |
| border: 1px solid #CCC; |
| margin: 5px; |
| padding: 5px; |
| } |
| |
| .type, #dart_summary { |
| border: 1px solid; |
| margin-top: 10px; |
| margin-bottom: 10px; |
| padding: 10px; |
| overflow: hidden; |
| background-color: white; |
| -moz-box-shadow: 5px 5px 5px #888; |
| -webkit-box-shadow: 5px 5px 5px #888; |
| box-shadow: 5px 5px 5px #888; |
| } |
| |
| #dart_summary { |
| border: 2px solid #00F; |
| margin: 5px; |
| padding: 5px; |
| } |
| |
| th { |
| background-color:#ccc; |
| font-weight: bold; |
| } |
| |
| tr:nth-child(odd) { |
| background-color:#eee; |
| } |
| tr:nth-child(even) { |
| background-color:#fff; |
| } |
| |
| tr:nth-child(odd).unknown { |
| background-color:#dd0; |
| } |
| tr:nth-child(even).unknown { |
| background-color:#ff0; |
| } |
| |
| tr:nth-child(odd).missing { |
| background-color:#d88; |
| } |
| tr:nth-child(even).missing { |
| background-color:#faa; |
| } |
| |
| li.unknown { |
| color: #f00; |
| } |
| |
| td, th { |
| vertical-align: top; |
| } |
| </style> |
| <title>Doc Dump</title> |
| </head> |
| <body> |
| <h1>Doc Dump</h1> |
| <ul> |
| <li><a href="#dart_summary">Summary</a></li> |
| </li> |
| """); |
| for (String type in sortStringCollection(database.keys)) { |
| final entry = database[type]; |
| if (entry == null || entry.containsKey('skipped')) { |
| numSkipped++; |
| sbSkipped.write(""" |
| <li id="$type"> |
| <a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> |
| $type |
| </a> |
| -- |
| Title: ${entry == null ? "???" : entry["title"]} -- Issue: |
| ${entry == null ? "???" : entry['cause']} |
| -- |
| <a target="_blank" href="${entry == null ? "???" : entry["srcUrl"]}"> |
| scraped url |
| </a> |
| </li>"""); |
| continue; |
| } |
| matchedTypes.add(type); |
| numGen++; |
| StringBuffer sbSections = new StringBuffer(); |
| StringBuffer sbMembers = new StringBuffer(); |
| StringBuffer sbExamples = new StringBuffer(); |
| if (entry.containsKey("members")) { |
| Map members = getMembersMap(entry); |
| sbMembers.write(""" |
| <div class="members"> |
| <h3><span class="debug">[dart]</span> Members</h3> |
| <table> |
| <tbody> |
| <tr> |
| <th>Name</th><th>Description</th><th>IDL</th><th>Status</th> |
| </tr> |
| """); |
| for (String name in sortStringCollection(members.keys)) { |
| Map memberData = members[name]; |
| bool unknown = !hasAny(type, name); |
| StringBuffer classes = new StringBuffer(); |
| if (unknown) classes.write("unknown "); |
| if (unknown) { |
| numExtraMethods++; |
| } else { |
| numFoundMethods++; |
| } |
| |
| final sbMember = new StringBuffer(); |
| |
| if (memberData.containsKey('url')) { |
| sbMember.write(""" |
| <td><a href="${memberData['url']}">$name</a></td> |
| """); |
| } else { |
| sbMember.write(""" |
| <td>$name</td> |
| """); |
| } |
| sbMember.write(""" |
| <td>${memberData['help']}</td> |
| <td> |
| <pre>${orEmpty(memberData['idl'])}</pre> |
| </td> |
| <td>${memberData['obsolete'] == true ? "Obsolete" : ""}</td> |
| """); |
| if (memberData['obsolete'] == true) { |
| sbObsolete.write("<tr class='$classes'><td>$type</td>$sbMember</tr>"); |
| } |
| sbMembers.write("<tr class='$classes'>$sbMember</tr>"); |
| } |
| |
| numMissingMethods += addMissing(sbMembers, type, members); |
| |
| sbMembers.write(""" |
| </tbody> |
| </table> |
| </div> |
| """); |
| } |
| for (String sectionName in |
| ["summary", "constructor", "compatibility", "specification", |
| "seeAlso"]) { |
| if (entry.containsKey(sectionName)) { |
| sbSections.write(""" |
| <div class="$sectionName"> |
| <h3><span class="debug">[Dart]</span> $sectionName</h3> |
| ${entry[sectionName]} |
| </div> |
| """); |
| } |
| } |
| if (entry.containsKey("links")) { |
| sbSections.write(""" |
| <div class="links"> |
| <h3><span class="debug">[Dart]</span> Specification</h3> |
| <ul> |
| """); |
| List links = entry["links"]; |
| for (Map link in links) { |
| sbSections.write(""" |
| <li><a href="${link['href']}">${link['title']}</a></li> |
| """); |
| } |
| sbSections.write(""" |
| </ul> |
| </div> |
| """); |
| } |
| if (entry.containsKey("examples")) { |
| for (String example in entry["examples"]) { |
| sbExamples.write(""" |
| <div class="example"> |
| <h3><span class="debug">[Dart]</span> Example</h3> |
| $example |
| </div> |
| """); |
| } |
| } |
| |
| String title = entry['title']; |
| if (title != type) { |
| title = '<h4>Dart type: $type</h4><h2>$title</h2>'; |
| } else { |
| title = '<h2>$title</h2>'; |
| } |
| sb.write(""" |
| <div class='type' id="$type"> |
| <a href='${entry['srcUrl']}'>$title</a> |
| $sbSections |
| $sbExamples |
| $sbMembers |
| </div> |
| """); |
| if (sbExamples.length > 0) { |
| sbAllExamples.write(""" |
| <div class='type' id="$type"> |
| <a href='${entry['srcUrl']}'>$title</a> |
| $sbExamples |
| </div> |
| """); |
| } |
| } |
| |
| for (String type in sortStringCollection(allProps.keys)) { |
| if (!matchedTypes.contains(type) && |
| !database.containsKey(type)) { |
| numSkipped++; |
| sbSkipped.write(""" |
| <li class="unknown" id="$type"> |
| <a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> |
| $type |
| </a> |
| </li> |
| """); |
| } |
| } |
| |
| sb.write(""" |
| <div id="#dart_summary"> |
| <h2>Summary</h2> |
| <h3> |
| Generated docs for $numGen classes out of a possible |
| ${allProps.keys.length} |
| </h3> |
| <h3>Found documentation for $numFoundMethods methods listed in WebKit</h3> |
| <h3> |
| Found documentation for $numExtraMethods methods not listed in WebKit |
| </h3> |
| <h3> |
| Unable to find documentation for $numMissingMethods methods present in |
| WebKit |
| </h3> |
| <h3> |
| Skipped generating documentation for $numSkipped classes due to no |
| plausible matching files |
| </h3> |
| <ul> |
| $sbSkipped |
| </ul> |
| </div> |
| """); |
| sb.write(""" |
| </body> |
| </html> |
| """); |
| |
| writeFileSync("output/database.html", sb.toString()); |
| |
| writeFileSync("output/examples.html", """ |
| <html> |
| <head> |
| <style type="text/css"> |
| body { |
| background-color: #eee; |
| margin: 10px; |
| font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, Arial, |
| Helvetica, sans-serif; |
| } |
| |
| .debug { |
| color: #888; |
| } |
| |
| .example { |
| border: 1px solid #CCC; |
| margin: 5px; |
| padding: 5px; |
| } |
| |
| .type { |
| border: 1px solid; |
| margin-top: 10px; |
| margin-bottom: 10px; |
| padding: 10px; |
| overflow: hidden; |
| background-color: white; |
| -moz-box-shadow: 5px 5px 5px #888; |
| -webkit-box-shadow: 5px 5px 5px #888; |
| box-shadow: 5px 5px 5px #888; |
| } |
| </style> |
| <title>All examples</title> |
| </head> |
| <body> |
| <h1>All examples</h1> |
| $sbAllExamples |
| </body> |
| </html> |
| """); |
| |
| writeFileSync("output/obsolete.html", """ |
| <html> |
| <head> |
| <style type="text/css"> |
| body { |
| background-color: #eee; |
| margin: 10px; |
| font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, |
| Arial, Helvetica, sans-serif; |
| } |
| |
| .debug { |
| color: #888; |
| } |
| |
| .type { |
| border: 1px solid; |
| margin-top: 10px; |
| margin-bottom: 10px; |
| padding: 10px; |
| overflow: hidden; |
| background-color: white; |
| -moz-box-shadow: 5px 5px 5px #888; |
| -webkit-box-shadow: 5px 5px 5px #888; |
| box-shadow: 5px 5px 5px #888; |
| } |
| </style> |
| <title>Methods marked as obsolete</title> |
| </head> |
| <body> |
| <h1>Methods marked as obsolete</h1> |
| <table> |
| <tbody> |
| <tr> |
| <th>Type</th> |
| <th>Name</th> |
| <th>Description</th> |
| <th>IDL</th> |
| <th>Status</th> |
| </tr> |
| $sbObsolete |
| </tbody> |
| </table> |
| </body> |
| </html> |
| """); |
| } |