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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 | 47 |
48 /** | 48 /** |
49 * The cached lookup-table to associate doc comments with spans. The outer map | 49 * The cached lookup-table to associate doc comments with spans. The outer map |
50 * is from filenames to doc comments in that file. The inner map maps from the | 50 * is from filenames to doc comments in that file. The inner map maps from the |
51 * token positions to doc comments. Each position is the starting offset of the | 51 * token positions to doc comments. Each position is the starting offset of the |
52 * next non-comment token *following* the doc comment. For example, the position | 52 * next non-comment token *following* the doc comment. For example, the position |
53 * for this comment would be the position of the "Map" token below. | 53 * for this comment would be the position of the "Map" token below. |
54 */ | 54 */ |
55 Map<String, Map<int, String>> _comments; | 55 Map<String, Map<int, String>> _comments; |
56 | 56 |
57 /** A callback that returns additional Markdown documentation for a type. */ | |
58 typedef String DocTypeFunction(Type type); | |
59 | |
60 /** A list of callbacks registered for documenting types. */ | |
61 List<DocTypeFunction> _docTypeFns; | |
Bob Nystrom
2011/12/06 23:11:23
How about "Documenter" instead of "Function" and "
nweiz
2011/12/07 19:26:56
Done.
| |
62 | |
63 /** A callback that returns additional Markdown documentation for a method. */ | |
64 typedef String DocMethodFunction(MethodMember method); | |
65 | |
66 /** A list of callbacks registered for documenting methods. */ | |
67 List<DocMethodFunction> _docMethodFns; | |
68 | |
69 /** A callback that returns additional Markdown documentation for a field. */ | |
70 typedef String DocFieldFunction(FieldMember field); | |
71 | |
72 /** A list of callbacks registered for documenting fields. */ | |
73 List<DocFieldFunction> _docFieldFns; | |
74 | |
57 int _totalLibraries = 0; | 75 int _totalLibraries = 0; |
58 int _totalTypes = 0; | 76 int _totalTypes = 0; |
59 int _totalMembers = 0; | 77 int _totalMembers = 0; |
60 | 78 |
61 /** | 79 /** |
62 * Run this from the `utils/dartdoc` directory. | 80 * Run this from the `utils/dartdoc` directory. |
63 */ | 81 */ |
64 void main() { | 82 void main() { |
65 // The entrypoint of the library to generate docs for. | 83 // The entrypoint of the library to generate docs for. |
66 final entrypoint = process.argv[2]; | 84 final entrypoint = process.argv[2]; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 for (final library in world.libraries.getValues()) { | 147 for (final library in world.libraries.getValues()) { |
130 docLibrary(library); | 148 docLibrary(library); |
131 } | 149 } |
132 }); | 150 }); |
133 | 151 |
134 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + | 152 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + |
135 '$_totalMembers members in ${elapsed}msec.'); | 153 '$_totalMembers members in ${elapsed}msec.'); |
136 } | 154 } |
137 | 155 |
138 void initializeDartDoc() { | 156 void initializeDartDoc() { |
157 if (_comments != null) return; | |
139 _comments = <String, Map<int, String>>{}; | 158 _comments = <String, Map<int, String>>{}; |
159 _docTypeFns = <DocTypeFunction>[]; | |
160 _docMethodFns = <DocMethodFunction>[]; | |
161 _docFieldFns = <DocFieldFunction>[]; | |
140 } | 162 } |
141 | 163 |
142 writeHeader(String title) { | 164 writeHeader(String title) { |
143 writeln( | 165 writeln( |
144 ''' | 166 ''' |
145 <!DOCTYPE html> | 167 <!DOCTYPE html> |
146 <html> | 168 <html> |
147 <head> | 169 <head> |
148 <meta charset="utf-8"> | 170 <meta charset="utf-8"> |
149 <title>$title</title> | 171 <title>$title</title> |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 write('<strong>${typeName(type)}</strong>'); | 249 write('<strong>${typeName(type)}</strong>'); |
228 } else { | 250 } else { |
229 write('${a(typeUrl(type), typeName(type))}'); | 251 write('${a(typeUrl(type), typeName(type))}'); |
230 } | 252 } |
231 | 253 |
232 writeln('</li>'); | 254 writeln('</li>'); |
233 } | 255 } |
234 writeln('</ul>'); | 256 writeln('</ul>'); |
235 } | 257 } |
236 | 258 |
259 String _callbacks(var item, List<Function> callbacks) => | |
Bob Nystrom
2011/12/06 23:11:23
Just because you *can* use a functional style does
nweiz
2011/12/07 19:26:56
I'll concede that Member#hashCode and #== were a b
| |
260 Strings.join(map(callbacks, (cb) => cb(item)), '\n\n'); | |
261 | |
237 docLibrary(Library library) { | 262 docLibrary(Library library) { |
238 _totalLibraries++; | 263 _totalLibraries++; |
239 _currentLibrary = library; | 264 _currentLibrary = library; |
240 _currentType = null; | 265 _currentType = null; |
241 | 266 |
242 startFile(libraryUrl(library)); | 267 startFile(libraryUrl(library)); |
243 writeHeader(library.name); | 268 writeHeader(library.name); |
244 writeln('<h1>Library <strong>${library.name}</strong></h1>'); | 269 writeln('<h1>Library <strong>${library.name}</strong></h1>'); |
245 | 270 |
246 // Look for a comment for the entire library. | 271 // Look for a comment for the entire library. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 writeHeader('Library ${type.library.name} / $typeTitle'); | 312 writeHeader('Library ${type.library.name} / $typeTitle'); |
288 writeln( | 313 writeln( |
289 ''' | 314 ''' |
290 <h1>${a(libraryUrl(type.library), | 315 <h1>${a(libraryUrl(type.library), |
291 "Library <strong>${type.library.name}</strong>")}</h1> | 316 "Library <strong>${type.library.name}</strong>")}</h1> |
292 <h2>${type.isClass ? "Class" : "Interface"} | 317 <h2>${type.isClass ? "Class" : "Interface"} |
293 <strong>${typeName(type)}</strong></h2> | 318 <strong>${typeName(type)}</strong></h2> |
294 '''); | 319 '''); |
295 | 320 |
296 docInheritance(type); | 321 docInheritance(type); |
297 docCode(type.span); | 322 docCode(type.span, _callbacks(type, _docTypeFns)); |
298 docConstructors(type); | 323 docConstructors(type); |
299 docMembers(type); | 324 docMembers(type); |
300 | 325 |
301 writeFooter(); | 326 writeFooter(); |
302 endFile(); | 327 endFile(); |
303 } | 328 } |
304 | 329 |
305 void docMembers(Type type) { | 330 void docMembers(Type type) { |
306 // Collect the different kinds of members. | 331 // Collect the different kinds of members. |
307 final methods = []; | 332 final methods = []; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 write('('); | 479 write('('); |
455 final parameters = map(method.parameters, | 480 final parameters = map(method.parameters, |
456 (p) => '${annotation(type, p.type)}${p.name}'); | 481 (p) => '${annotation(type, p.type)}${p.name}'); |
457 write(Strings.join(parameters, ', ')); | 482 write(Strings.join(parameters, ', ')); |
458 write(')'); | 483 write(')'); |
459 | 484 |
460 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" | 485 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" |
461 title="Permalink to ${typeName(type)}.$name">#</a>'''); | 486 title="Permalink to ${typeName(type)}.$name">#</a>'''); |
462 writeln('</h4>'); | 487 writeln('</h4>'); |
463 | 488 |
464 docCode(method.span, showCode: true); | 489 docCode(method.span, _callbacks(method, _docMethodFns), showCode: true); |
465 | 490 |
466 writeln('</div>'); | 491 writeln('</div>'); |
467 } | 492 } |
468 | 493 |
469 /** Documents the field [field] of type [type]. */ | 494 /** Documents the field [field] of type [type]. */ |
470 docField(Type type, FieldMember field) { | 495 docField(Type type, FieldMember field) { |
471 _totalMembers++; | 496 _totalMembers++; |
472 _currentMember = field; | 497 _currentMember = field; |
473 | 498 |
474 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); | 499 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); |
(...skipping 14 matching lines...) Expand all Loading... | |
489 | 514 |
490 write(annotation(type, field.type)); | 515 write(annotation(type, field.type)); |
491 write( | 516 write( |
492 ''' | 517 ''' |
493 <strong>${field.name}</strong> <a class="anchor-link" | 518 <strong>${field.name}</strong> <a class="anchor-link" |
494 href="#${memberAnchor(field)}" | 519 href="#${memberAnchor(field)}" |
495 title="Permalink to ${typeName(type)}.${field.name}">#</a> | 520 title="Permalink to ${typeName(type)}.${field.name}">#</a> |
496 </h4> | 521 </h4> |
497 '''); | 522 '''); |
498 | 523 |
499 docCode(field.span, showCode: true); | 524 docCode(field.span, _callbacks(field, _docFieldFns), showCode: true); |
500 writeln('</div>'); | 525 writeln('</div>'); |
501 } | 526 } |
502 | 527 |
503 /** | 528 /** |
504 * Creates a hyperlink. Handles turning the [href] into an appropriate relative | 529 * Creates a hyperlink. Handles turning the [href] into an appropriate relative |
505 * path from the current file. | 530 * path from the current file. |
506 */ | 531 */ |
507 String a(String href, String contents, [String class]) { | 532 String a(String href, String contents, [String class]) { |
508 final css = class == null ? '' : ' class="$class"'; | 533 final css = class == null ? '' : ' class="$class"'; |
509 return '<a href="${relativePath(href)}"$css>$contents</a>'; | 534 return '<a href="${relativePath(href)}"$css>$contents</a>'; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 // * Type parameters of the enclosing type. | 643 // * Type parameters of the enclosing type. |
619 | 644 |
620 return new md.Element.text('code', name); | 645 return new md.Element.text('code', name); |
621 } | 646 } |
622 | 647 |
623 /** | 648 /** |
624 * Documents the code contained within [span]. Will include the previous | 649 * Documents the code contained within [span]. Will include the previous |
625 * Dartdoc associated with that span if found, and will include the syntax | 650 * Dartdoc associated with that span if found, and will include the syntax |
626 * highlighted code itself if desired. | 651 * highlighted code itself if desired. |
627 */ | 652 */ |
628 docCode(SourceSpan span, [bool showCode = false]) { | 653 docCode(SourceSpan span, String extraDocs, [bool showCode = false]) { |
Bob Nystrom
2011/12/06 23:11:23
"extraMarkdown"
We need to make it clear that thi
nweiz
2011/12/07 19:26:56
Done.
| |
629 if (span == null) return; | 654 if (span == null) return; |
630 | 655 |
631 writeln('<div class="doc">'); | 656 writeln('<div class="doc">'); |
632 final comment = findComment(span); | 657 final comment = findComment(span); |
633 if (comment != null) { | 658 if (comment != null) { |
634 writeln(md.markdownToHtml(comment)); | 659 writeln(md.markdownToHtml('${comment}\n\n${extraDocs}')); |
660 } else { | |
661 writeln(md.markdownToHtml(extraDocs)); | |
635 } | 662 } |
636 | 663 |
637 if (includeSource && showCode) { | 664 if (includeSource && showCode) { |
638 writeln('<pre class="source">'); | 665 writeln('<pre class="source">'); |
639 write(formatCode(span)); | 666 write(formatCode(span)); |
640 writeln('</pre>'); | 667 writeln('</pre>'); |
641 } | 668 } |
642 | 669 |
643 writeln('</div>'); | 670 writeln('</div>'); |
644 } | 671 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 line = line.substring(2, line.length); | 769 line = line.substring(2, line.length); |
743 } else if (line.startsWith('*')) { | 770 } else if (line.startsWith('*')) { |
744 line = line.substring(1, line.length); | 771 line = line.substring(1, line.length); |
745 } | 772 } |
746 | 773 |
747 buf.add(line); | 774 buf.add(line); |
748 buf.add('\n'); | 775 buf.add('\n'); |
749 } | 776 } |
750 | 777 |
751 return buf.toString(); | 778 return buf.toString(); |
752 } | 779 } |
780 | |
781 /** Register a callback to add additional documentation to a type. */ | |
782 registerTypeCallback(DocTypeFunction fn) => _docTypeFns.add(fn); | |
Bob Nystrom
2011/12/06 23:11:23
I'd name this "add" instead of "register" to make
nweiz
2011/12/07 19:26:56
Done.
| |
783 | |
784 /** Register a callback to add additional documentation to a method. */ | |
785 registerMethodCallback(DocMethodFunction fn) => _docMethodFns.add(fn); | |
786 | |
787 /** Register a callback to add additional documentation to a field. */ | |
788 registerFieldCallback(DocFieldFunction fn) => _docFieldFns.add(fn); | |
OLD | NEW |