Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: pkg/docgen/lib/docgen.dart

Issue 62353004: Properly escape angle brackets and find their corresponding links in docgen. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/docgen/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /// **docgen** is a tool for creating machine readable representations of Dart 5 /// **docgen** is a tool for creating machine readable representations of Dart
6 /// code metadata, including: classes, members, comments and annotations. 6 /// code metadata, including: classes, members, comments and annotations.
7 /// 7 ///
8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files.
9 /// 9 ///
10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR]
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; 502 if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
503 if (mdnType['srcUrl'] == null) return ''; 503 if (mdnType['srcUrl'] == null) return '';
504 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); 504 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']);
505 } 505 }
506 506
507 String _htmlMdn(String content, String url) { 507 String _htmlMdn(String content, String url) {
508 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' 508 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
509 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; 509 '<a href="' + url.trim() + '">from Mdn</a></p></div>';
510 } 510 }
511 511
512 /// Look for the specified name starting with the current member, and
513 /// progressively working outward to the current library scope.
514 String findElementInScope(String name, LibraryMirror currentLibrary,
515 ClassMirror currentClass, MemberMirror currentMember) {
516 var memberScope = currentMember == null ?
517 null : currentMember.lookupInScope(name);
518 if (memberScope != null) {
519 return docName(memberScope);
520 } else {
521 var classScope = currentClass == null ?
522 null : currentClass.lookupInScope(name);
523 if (classScope != null) {
524 return docName(classScope);
525 } else {
526 var libraryScope = currentLibrary == null ?
527 null : currentLibrary.lookupInScope(name);
528 if (libraryScope != null) {
529 return docName(libraryScope);
530 }
531 }
532 }
533 return null;
534 }
535
536 // HTML escaped version of '<' character.
537 final _LESS_THAN = '&lt;';
538
539 /// Chunk the provided name into individual parts to be resolved. We take a
540 /// simplistic approach to chunking, though, we break at " ", ",", "&lt;"
541 /// and ">". All other characters are grouped into the name to be resolved.
542 /// As a result, these characters will all be treated as part of the item to be
543 /// resolved (aka the * is interpreted literally as a *, not as an indicator for
544 /// bold <em>.
545 List<String> _tokenizeComplexReference(String name) {
546 var tokens = [];
547 var append = false;
548 var index = 0;
549 while(index < name.length) {
550 if (name.indexOf(_LESS_THAN, index) == index) {
551 tokens.add(_LESS_THAN);
552 append = false;
553 index += _LESS_THAN.length;
554 } else if (name[index] == ' ' || name[index] == ',' ||
555 name[index] == '>') {
556 tokens.add(name[index]);
557 append = false;
558 index++;
559 } else {
560 if (append) {
561 tokens[tokens.length - 1] = tokens.last + name[index];
562 } else {
563 tokens.add(name[index]);
564 append = true;
565 }
566 index++;
567 }
568 }
569 return tokens;
570 }
571
572 /// This is a more complex reference. Try to break up if its of the form A<B>
573 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"),
574 /// or of the form A<B>. Note: unlike other the other markdown-style links, all
575 /// text inside the square brackets is treated as part of the link (aka the * is
576 /// interpreted literally as a *, not as a indicator for bold <em>.
577 ///
578 /// Example: [foo&lt;_bar_>] will produce
579 /// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized
580 /// version of resolvedBar.
581 markdown.Node _fixComplexReference(String name, LibraryMirror currentLibrary,
582 ClassMirror currentClass, MemberMirror currentMember) {
583 // Parse into multiple elements we can try to resolve.
584 var tokens = _tokenizeComplexReference(name);
585
586 // Produce an html representation of our elements. Group unresolved and plain
587 // text are grouped into "link" elements so they display as code.
588 final textElements = [' ', ',', '>', _LESS_THAN];
589 var accumulatedHtml = '';
590
591 for (var token in tokens) {
592 bool added = false;
593 if (!textElements.contains(token)) {
594 String elementName = findElementInScope(token, currentLibrary,
595 currentClass, currentMember);
596 if (elementName != null) {
597 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text(
598 'a', elementName)]);
599 added = true;
600 }
601 }
602 if (!added) {
603 accumulatedHtml += token;
604 }
605 }
606 return new markdown.Text(accumulatedHtml);
607 }
608
512 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 609 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
513 markdown.Node fixReference(String name, LibraryMirror currentLibrary, 610 markdown.Node fixReference(String name, LibraryMirror currentLibrary,
514 ClassMirror currentClass, MemberMirror currentMember) { 611 ClassMirror currentClass, MemberMirror currentMember) {
515 var reference; 612 // Attempt the look up the whole name up in the scope.
516 var memberScope = currentMember == null ? 613 String elementName =
517 null : currentMember.lookupInScope(name); 614 findElementInScope(name, currentLibrary, currentClass, currentMember);
518 if (memberScope != null) { 615 if (elementName != null) {
519 reference = docName(memberScope); 616 return new markdown.Element.text('a', elementName);
520 } else {
521 var classScope = currentClass == null ?
522 null : currentClass.lookupInScope(name);
523 if (classScope != null) {
524 reference = docName(classScope);
525 } else {
526 var libraryScope = currentLibrary == null ?
527 null : currentLibrary.lookupInScope(name);
528 reference = libraryScope != null ? docName(libraryScope) : name;
529 }
530 } 617 }
531 return new markdown.Element.text('a', reference); 618 return _fixComplexReference(name, currentLibrary, currentClass, currentMember) ;
532 } 619 }
533 620
534 /// Returns a map of [Variable] objects constructed from [mirrorMap]. 621 /// Returns a map of [Variable] objects constructed from [mirrorMap].
535 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { 622 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
536 var data = {}; 623 var data = {};
537 // TODO(janicejl): When map to map feature is created, replace the below with 624 // TODO(janicejl): When map to map feature is created, replace the below with
538 // a filter. Issue(#9590). 625 // a filter. Issue(#9590).
539 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { 626 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
540 _currentMember = mirror; 627 _currentMember = mirror;
541 if (_includePrivate || !_isHidden(mirror)) { 628 if (_includePrivate || !_isHidden(mirror)) {
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 String docName(DeclarationMirror m) { 1325 String docName(DeclarationMirror m) {
1239 if (m is LibraryMirror) { 1326 if (m is LibraryMirror) {
1240 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); 1327 return (m as LibraryMirror).qualifiedName.replaceAll('.','-');
1241 } 1328 }
1242 var owner = m.owner; 1329 var owner = m.owner;
1243 if (owner == null) return m.qualifiedName; 1330 if (owner == null) return m.qualifiedName;
1244 // For the unnamed constructor we just return the class name. 1331 // For the unnamed constructor we just return the class name.
1245 if (m.simpleName == '') return docName(owner); 1332 if (m.simpleName == '') return docName(owner);
1246 return docName(owner) + '.' + m.simpleName; 1333 return docName(owner) + '.' + m.simpleName;
1247 } 1334 }
OLDNEW
« no previous file with comments | « no previous file | pkg/docgen/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698