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

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>.
Alan Knight 2013/11/06 23:54:18 Maybe provide an example of an input and output, j
545 List<String> _tokenizeComplexReference(String curName) {
Alan Knight 2013/11/06 23:54:18 nit: If we're not re-assigning to it, isn't it jus
546 var tokens = [];
547 var append = false;
548 var curIndex = 0;
Alan Knight 2013/11/06 23:54:18 and this could probably just be "index"
549 while(curIndex < curName.length) {
550 if (curName.indexOf(_LESS_THAN, curIndex) == curIndex) {
551 tokens.add(_LESS_THAN);
552 append = false;
553 curIndex += _LESS_THAN.length;
554 } else if (curName[curIndex] == ' ' || curName[curIndex] == ',' ||
555 curName[curIndex] == '>') {
556 tokens.add(curName[curIndex]);
557 append = false;
558 curIndex++;
559 } else {
560 if (append) {
561 tokens[tokens.length - 1] = tokens.last + curName[curIndex];
562 } else {
563 tokens.add(curName[curIndex]);
564 append = true;
565 }
566 curIndex++;
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 markdown.Node fixComplexReference(String name, LibraryMirror currentLibrary,
578 ClassMirror currentClass, MemberMirror currentMember) {
579 // Parse into multiple elements we can try to resolve.
580 var tokens = _tokenizeComplexReference(name);
581
582 // Produce an html representation of our elements. Group unresolved and plain
583 // text are grouped into "link" elements so they display as code.
584 final textElements = [' ', ',', '>', _LESS_THAN];
585 var accumulatedHtml = '';
586 for (var token in tokens) {
587 bool added = false;
588 if (!textElements.contains(token)) {
589 String elementName = findElementInScope(token, currentLibrary,
590 currentClass, currentMember);
591 if (elementName != null) {
592 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text(
593 'a', elementName)]);
594 added = true;
595 }
596 }
597 if (!added) {
598 accumulatedHtml += token;
599 }
600 }
601 return new markdown.Text(accumulatedHtml);
602 }
603
512 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 604 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
513 markdown.Node fixReference(String name, LibraryMirror currentLibrary, 605 markdown.Node fixReference(String name, LibraryMirror currentLibrary,
514 ClassMirror currentClass, MemberMirror currentMember) { 606 ClassMirror currentClass, MemberMirror currentMember) {
515 var reference; 607 // Attempt the look up the whole name up in the scope.
516 var memberScope = currentMember == null ? 608 String elementName =
517 null : currentMember.lookupInScope(name); 609 findElementInScope(name, currentLibrary, currentClass, currentMember);
518 if (memberScope != null) { 610 if (elementName != null) {
519 reference = docName(memberScope); 611 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 } 612 }
531 return new markdown.Element.text('a', reference); 613 return fixComplexReference(name, currentLibrary, currentClass, currentMember);
532 } 614 }
533 615
534 /// Returns a map of [Variable] objects constructed from [mirrorMap]. 616 /// Returns a map of [Variable] objects constructed from [mirrorMap].
535 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { 617 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
536 var data = {}; 618 var data = {};
537 // TODO(janicejl): When map to map feature is created, replace the below with 619 // TODO(janicejl): When map to map feature is created, replace the below with
538 // a filter. Issue(#9590). 620 // a filter. Issue(#9590).
539 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { 621 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
540 _currentMember = mirror; 622 _currentMember = mirror;
541 if (_includePrivate || !_isHidden(mirror)) { 623 if (_includePrivate || !_isHidden(mirror)) {
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 String docName(DeclarationMirror m) { 1320 String docName(DeclarationMirror m) {
1239 if (m is LibraryMirror) { 1321 if (m is LibraryMirror) {
1240 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); 1322 return (m as LibraryMirror).qualifiedName.replaceAll('.','-');
1241 } 1323 }
1242 var owner = m.owner; 1324 var owner = m.owner;
1243 if (owner == null) return m.qualifiedName; 1325 if (owner == null) return m.qualifiedName;
1244 // For the unnamed constructor we just return the class name. 1326 // For the unnamed constructor we just return the class name.
1245 if (m.simpleName == '') return docName(owner); 1327 if (m.simpleName == '') return docName(owner);
1246 return docName(owner) + '.' + m.simpleName; 1328 return docName(owner) + '.' + m.simpleName;
1247 } 1329 }
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