OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * To use it, from this directory, run: | 6 * To use it, from this directory, run: |
7 * | 7 * |
8 * $ dartdoc <path to .dart file> | 8 * $ dartdoc <path to .dart file> |
9 * | 9 * |
10 * This will create a "docs" directory with the docs for your libraries. To | 10 * This will create a "docs" directory with the docs for your libraries. To |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 | 56 |
57 int _totalLibraries = 0; | 57 int _totalLibraries = 0; |
58 int _totalTypes = 0; | 58 int _totalTypes = 0; |
59 int _totalMembers = 0; | 59 int _totalMembers = 0; |
60 | 60 |
61 /** | 61 /** |
62 * Run this from the `utils/dartdoc` directory. | 62 * Run this from the `utils/dartdoc` directory. |
63 */ | 63 */ |
64 void main() { | 64 void main() { |
65 // The entrypoint of the library to generate docs for. | 65 // The entrypoint of the library to generate docs for. |
66 final libPath = process.argv[2]; | 66 final entrypoint = process.argv[2]; |
67 | 67 |
68 // Parse the dartdoc options. | 68 // Parse the dartdoc options. |
69 for (int i = 3; i < process.argv.length; i++) { | 69 for (int i = 3; i < process.argv.length; i++) { |
70 final arg = process.argv[i]; | 70 final arg = process.argv[i]; |
71 switch (arg) { | 71 switch (arg) { |
72 case '--no-code': | 72 case '--no-code': |
73 includeSource = false; | 73 includeSource = false; |
74 break; | 74 break; |
75 | 75 |
76 default: | 76 default: |
77 print('Unknown option: $arg'); | 77 print('Unknown option: $arg'); |
78 } | 78 } |
79 } | 79 } |
80 | 80 |
81 files = new NodeFileSystem(); | 81 files = new NodeFileSystem(); |
82 parseOptions('../../frog', [] /* args */, files); | 82 parseOptions('../../frog', [] /* args */, files); |
83 options.dietParse = true; | |
83 | 84 |
84 // Patch in support for [:...:]-style code to the markdown parser. | 85 // Patch in support for [:...:]-style code to the markdown parser. |
85 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? | 86 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? |
86 md.InlineParser.syntaxes.insertRange(0, 1, | 87 md.InlineParser.syntaxes.insertRange(0, 1, |
87 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); | 88 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); |
88 | 89 |
89 md.setImplicitLinkResolver(resolveNameReference); | 90 md.setImplicitLinkResolver(resolveNameReference); |
90 | 91 |
91 final elapsed = time(() { | 92 final elapsed = time(() { |
92 initializeDartDoc(); | 93 initializeDartDoc(); |
93 | 94 |
94 initializeWorld(files); | 95 initializeWorld(files); |
95 | 96 |
96 world.processDartScript(libPath); | 97 // Handle the built-in entrypoints. |
98 switch (entrypoint) { | |
99 case 'corelib': | |
Siggi Cherem (dart-lang)
2011/12/06 17:29:57
+2 >> (indentation seems odd for the body of the s
Bob Nystrom
2011/12/06 19:25:05
Done.
| |
100 world.getOrAddLibrary('dart:core'); | |
101 world.getOrAddLibrary('dart:coreimpl'); | |
102 world.process(); | |
103 break; | |
104 | |
105 case 'dom': | |
106 world.getOrAddLibrary('dart:core'); | |
107 world.getOrAddLibrary('dart:coreimpl'); | |
108 world.getOrAddLibrary('dart:dom'); | |
109 world.process(); | |
110 break; | |
111 | |
112 case 'html': | |
113 world.getOrAddLibrary('dart:core'); | |
114 world.getOrAddLibrary('dart:coreimpl'); | |
115 world.getOrAddLibrary('dart:dom'); | |
116 world.getOrAddLibrary('dart:html'); | |
117 world.process(); | |
118 break; | |
119 | |
120 default: | |
121 // Normal entrypoint script. | |
122 world.processDartScript(entrypoint); | |
123 } | |
124 | |
97 world.resolveAll(); | 125 world.resolveAll(); |
98 | 126 |
99 // Generate the docs. | 127 // Generate the docs. |
128 docIndex(); | |
100 for (final library in world.libraries.getValues()) { | 129 for (final library in world.libraries.getValues()) { |
101 docLibrary(library); | 130 docLibrary(library); |
102 } | 131 } |
103 | |
104 docIndex(world.libraries.getValues()); | |
105 }); | 132 }); |
106 | 133 |
107 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + | 134 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + |
108 '$_totalMembers members in ${elapsed}msec.'); | 135 '$_totalMembers members in ${elapsed}msec.'); |
109 } | 136 } |
110 | 137 |
111 void initializeDartDoc() { | 138 void initializeDartDoc() { |
112 _comments = <String, Map<int, String>>{}; | 139 _comments = <String, Map<int, String>>{}; |
113 } | 140 } |
114 | 141 |
115 docIndex(List<Library> libraries) { | |
116 startFile('index.html'); | |
117 // TODO(rnystrom): Need to figure out what this should look like. | |
118 writeln( | |
119 ''' | |
120 <html><head> | |
121 <title>Index</title> | |
122 <link rel="stylesheet" type="text/css" href="styles.css" /> | |
123 </head> | |
124 <body> | |
125 <div class="content"> | |
126 <ul> | |
127 '''); | |
128 | |
129 final sorted = new List<Library>.from(libraries); | |
130 sorted.sort((a, b) => a.name.compareTo(b.name)); | |
131 | |
132 for (final library in sorted) { | |
133 writeln( | |
134 ''' | |
135 <li>${a(libraryUrl(library), "Library ${library.name}")}</li> | |
136 '''); | |
137 } | |
138 | |
139 writeln( | |
140 ''' | |
141 </ul> | |
142 </div> | |
143 </body></html> | |
144 '''); | |
145 | |
146 endFile(); | |
147 } | |
148 | |
149 writeHeader(String title) { | 142 writeHeader(String title) { |
150 writeln( | 143 writeln( |
151 ''' | 144 ''' |
152 <!DOCTYPE html> | 145 <!DOCTYPE html> |
153 <html> | 146 <html> |
154 <head> | 147 <head> |
155 <meta charset="utf-8"> | 148 <meta charset="utf-8"> |
156 <title>$title</title> | 149 <title>$title</title> |
157 <link rel="stylesheet" type="text/css" | 150 <link rel="stylesheet" type="text/css" |
158 href="${relativePath('styles.css')}" /> | 151 href="${relativePath('styles.css')}" /> |
159 <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,8 00" rel="stylesheet" type="text/css"> | 152 <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,8 00" rel="stylesheet" type="text/css"> |
160 <script src="${relativePath('interact.js')}"></script> | 153 <script src="${relativePath('interact.js')}"></script> |
161 </head> | 154 </head> |
162 <body> | 155 <body> |
163 <div class="page"> | 156 <div class="page"> |
164 '''); | 157 '''); |
165 docNavigation(); | 158 docNavigation(); |
166 writeln('<div class="content">'); | 159 writeln('<div class="content">'); |
167 } | 160 } |
168 | 161 |
169 writeFooter() { | 162 writeFooter() { |
170 writeln( | 163 writeln( |
171 ''' | 164 ''' |
172 </div> | 165 </div> |
173 <div class="footer"</div> | 166 <div class="footer"</div> |
174 </body></html> | 167 </body></html> |
175 '''); | 168 '''); |
176 } | 169 } |
177 | 170 |
171 docIndex() { | |
172 startFile('index.html'); | |
173 | |
174 writeHeader('Dart Documentation'); | |
175 | |
176 writeln('<h1>Dart Documentation</h1>'); | |
177 writeln('<h3>Libraries</h3>'); | |
178 | |
179 for (final library in orderByName(world.libraries)) { | |
180 writeln( | |
181 ''' | |
182 <h4>${a(libraryUrl(library), "Library ${library.name}")}</h4> | |
183 '''); | |
184 } | |
185 | |
186 writeFooter(); | |
187 endFile(); | |
188 } | |
189 | |
178 docNavigation() { | 190 docNavigation() { |
179 writeln( | 191 writeln( |
180 ''' | 192 ''' |
181 <div class="nav"> | 193 <div class="nav"> |
182 <h1>Libraries</h1> | 194 <h1>${a("index.html", "Dart Documentation")}</h1> |
183 '''); | 195 '''); |
184 | 196 |
185 for (final library in orderValuesByKeys(world.libraries)) { | 197 for (final library in orderByName(world.libraries)) { |
186 write('<h2><div class="icon-library"></div> '); | 198 write('<h2><div class="icon-library"></div>'); |
187 | 199 |
188 if ((_currentLibrary == library) && (_currentType == null)) { | 200 if ((_currentLibrary == library) && (_currentType == null)) { |
189 write('<strong>${library.name}</strong>'); | 201 write('<strong>${library.name}</strong>'); |
190 } else { | 202 } else { |
191 write('${a(libraryUrl(library), library.name)}'); | 203 write('${a(libraryUrl(library), library.name)}'); |
192 } | 204 } |
193 write('</h2>'); | 205 write('</h2>'); |
194 | 206 |
195 final types = orderValuesByKeys(library.types); | 207 // Only expand classes in navigation for current library. |
196 if (types.length > 0) { | 208 if (_currentLibrary == library) docLibraryNavigation(library); |
197 writeln('<ul>'); | |
198 for (final type in types) { | |
199 if (type.isTop) continue; | |
200 if (type.name.startsWith('_')) continue; | |
201 | |
202 var icon = type.isClass ? 'icon-class' : 'icon-interface'; | |
203 write('<li><div class="$icon"></div> '); | |
204 | |
205 if (_currentType == type) { | |
206 write('<strong>${type.name}</strong>'); | |
207 } else { | |
208 write('${a(typeUrl(type), type.name)}'); | |
209 } | |
210 | |
211 writeln('</li>'); | |
212 } | |
213 | |
214 writeln('</ul>'); | |
215 } | |
216 } | 209 } |
217 | 210 |
218 writeln('</div>'); | 211 writeln('</div>'); |
219 } | 212 } |
220 | 213 |
214 /** Writes the navigation for the types contained by the given library. */ | |
215 docLibraryNavigation(Library library) { | |
216 final types = orderByName(library.types).filter( | |
217 (type) => !type.isTop && !type.name.startsWith('_')); | |
218 | |
219 if (types.length == 0) return; | |
220 | |
221 writeln('<ul>'); | |
222 for (final type in types) { | |
223 var icon = type.isClass ? 'icon-class' : 'icon-interface'; | |
224 write('<li><div class="$icon"></div>'); | |
225 | |
226 if (_currentType == type) { | |
227 write('<strong>${typeName(type)}</strong>'); | |
228 } else { | |
229 write('${a(typeUrl(type), typeName(type))}'); | |
230 } | |
231 | |
232 writeln('</li>'); | |
233 } | |
234 writeln('</ul>'); | |
235 } | |
236 | |
221 docLibrary(Library library) { | 237 docLibrary(Library library) { |
222 _totalLibraries++; | 238 _totalLibraries++; |
223 _currentLibrary = library; | 239 _currentLibrary = library; |
224 _currentType = null; | 240 _currentType = null; |
225 | 241 |
226 startFile(libraryUrl(library)); | 242 startFile(libraryUrl(library)); |
227 writeHeader(library.name); | 243 writeHeader(library.name); |
228 writeln('<h1>Library <strong>${library.name}</strong></h1>'); | 244 writeln('<h1>Library <strong>${library.name}</strong></h1>'); |
229 | 245 |
230 // Look for a comment for the entire library. | 246 // Look for a comment for the entire library. |
231 final comment = findCommentInFile(library.baseSource, _libraryDoc); | 247 final comment = findCommentInFile(library.baseSource, _libraryDoc); |
232 if (comment != null) { | 248 if (comment != null) { |
233 final html = md.markdownToHtml(comment); | 249 final html = md.markdownToHtml(comment); |
234 writeln('<div class="doc">$html</div>'); | 250 writeln('<div class="doc">$html</div>'); |
235 } | 251 } |
236 | 252 |
237 // Document the top-level members. | 253 // Document the top-level members. |
238 docMembers(library.topType); | 254 docMembers(library.topType); |
239 | 255 |
240 // TODO(rnystrom): Link to types. | |
241 writeln('<h3>Types</h3>'); | 256 writeln('<h3>Types</h3>'); |
242 | 257 |
243 for (final type in orderValuesByKeys(library.types)) { | 258 for (final type in orderByName(library.types)) { |
244 if (type.isTop) continue; | 259 if (type.isTop) continue; |
245 if (type.name.startsWith('_')) continue; | 260 if (type.name.startsWith('_')) continue; |
246 writeln( | 261 writeln( |
247 ''' | 262 ''' |
248 <div class="type"> | 263 <div class="type"> |
249 <h4> | 264 <h4> |
250 ${type.isClass ? "class" : "interface"} | 265 ${type.isClass ? "class" : "interface"} |
251 ${a(typeUrl(type), "<strong>${typeName(type)}</strong>")} | 266 ${a(typeUrl(type), "<strong>${typeName(type)}</strong>")} |
252 </h4> | 267 </h4> |
253 </div> | 268 </div> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 | 300 |
286 writeFooter(); | 301 writeFooter(); |
287 endFile(); | 302 endFile(); |
288 } | 303 } |
289 | 304 |
290 void docMembers(Type type) { | 305 void docMembers(Type type) { |
291 // Collect the different kinds of members. | 306 // Collect the different kinds of members. |
292 final methods = []; | 307 final methods = []; |
293 final fields = []; | 308 final fields = []; |
294 | 309 |
295 for (final member in orderValuesByKeys(type.members)) { | 310 for (final member in orderByName(type.members)) { |
296 if (member.name.startsWith('_')) continue; | 311 if (member.name.startsWith('_')) continue; |
297 | 312 |
298 if (member.isProperty) { | 313 if (member.isProperty) { |
299 if (member.canGet) methods.add(member.getter); | 314 if (member.canGet) methods.add(member.getter); |
300 if (member.canSet) methods.add(member.setter); | 315 if (member.canSet) methods.add(member.setter); |
301 } else if (member.isMethod) { | 316 } else if (member.isMethod) { |
302 methods.add(member); | 317 methods.add(member); |
303 } else if (member.isField) { | 318 } else if (member.isField) { |
304 fields.add(member); | 319 fields.add(member); |
305 } | 320 } |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
728 } else if (line.startsWith('*')) { | 743 } else if (line.startsWith('*')) { |
729 line = line.substring(1, line.length); | 744 line = line.substring(1, line.length); |
730 } | 745 } |
731 | 746 |
732 buf.add(line); | 747 buf.add(line); |
733 buf.add('\n'); | 748 buf.add('\n'); |
734 } | 749 } |
735 | 750 |
736 return buf.toString(); | 751 return buf.toString(); |
737 } | 752 } |
OLD | NEW |