@@ -13,7 +13,6 @@ import 'package:dartdoc/src/element_type.dart';
1313import 'package:dartdoc/src/model/model.dart' ;
1414import 'package:dartdoc/src/tuple.dart' ;
1515import 'package:dartdoc/src/warnings.dart' ;
16- import 'package:html/parser.dart' show parse;
1716import 'package:markdown/markdown.dart' as md;
1817
1918const validHtmlTags = [
@@ -757,23 +756,23 @@ class _MarkdownCommentReference {
757756 }
758757}
759758
760- String _linkDocReference (String codeRef, Warnable warnable,
759+ md. Node _makeLinkNode (String codeRef, Warnable warnable,
761760 List <ModelCommentReference > commentRefs) {
762- MatchingLinkResult result;
763- result = _getMatchingLinkElement (codeRef, warnable, commentRefs);
761+ MatchingLinkResult result =
762+ _getMatchingLinkElement (codeRef, warnable, commentRefs);
763+ final textContent = htmlEscape.convert (codeRef);
764764 final ModelElement linkedElement = result.element;
765765 if (linkedElement != null ) {
766- var classContent = '' ;
767- if (linkedElement.isDeprecated) {
768- classContent = 'class="deprecated" ' ;
769- }
770- // This would be linkedElement.linkedName, but link bodies are slightly
771- // different for doc references.
772- if (linkedElement.href == null ) {
773- return '<code>${htmlEscape .convert (codeRef )}</code>' ;
774- } else {
775- return '<a ${classContent }href="${linkedElement .href }">${htmlEscape .convert (codeRef )}</a>' ;
766+ if (linkedElement.href != null ) {
767+ var anchor = md.Element .text ('a' , textContent);
768+ if (linkedElement.isDeprecated) {
769+ anchor.attributes['class' ] = 'deprecated' ;
770+ }
771+ anchor.attributes['href' ] = linkedElement.href;
772+ return anchor;
776773 }
774+ // else this would be linkedElement.linkedName, but link bodies are slightly
775+ // different for doc references, so fall out.
777776 } else {
778777 if (result.warn) {
779778 // Avoid claiming documentation is inherited when it comes from the
@@ -784,8 +783,9 @@ String _linkDocReference(String codeRef, Warnable warnable,
784783 ? null
785784 : warnable.documentationFrom);
786785 }
787- return '<code>${htmlEscape .convert (codeRef )}</code>' ;
788786 }
787+
788+ return md.Element .text ('code' , textContent);
789789}
790790
791791// Maximum number of characters to display before a suspected generic.
@@ -800,7 +800,7 @@ final RegExp allAfterLastNewline = RegExp(r'\n.*$', multiLine: true);
800800// (like, [Apple<int>]). @Hixie asked for a warning when there's something, that looks
801801// like a non HTML tag (a generic?) outside of a `[]` block.
802802// https://github.com/dart-lang/dartdoc/issues/1250#issuecomment-269257942
803- void _showWarningsForGenericsOutsideSquareBracketsBlocks (
803+ void showWarningsForGenericsOutsideSquareBracketsBlocks (
804804 String text, Warnable element) {
805805 List <int > tagPositions = findFreeHangingGenericsPositions (text);
806806 if (tagPositions.isNotEmpty) {
@@ -851,6 +851,21 @@ List<int> findFreeHangingGenericsPositions(String string) {
851851}
852852
853853class MarkdownDocument extends md.Document {
854+ factory MarkdownDocument .withElementLinkResolver (
855+ Canonicalization element, List <ModelCommentReference > commentRefs) {
856+ md.Node linkResolver (String name, [String _]) {
857+ if (name.isEmpty) {
858+ return null ;
859+ }
860+ return _makeLinkNode (name, element, commentRefs);
861+ }
862+
863+ return MarkdownDocument (
864+ inlineSyntaxes: _markdown_syntaxes,
865+ blockSyntaxes: _markdown_block_syntaxes,
866+ linkResolver: linkResolver);
867+ }
868+
854869 MarkdownDocument (
855870 {Iterable <md.BlockSyntax > blockSyntaxes,
856871 Iterable <md.InlineSyntax > inlineSyntaxes,
@@ -864,43 +879,24 @@ class MarkdownDocument extends md.Document {
864879 linkResolver: linkResolver,
865880 imageLinkResolver: imageLinkResolver);
866881
867- /// Returns a tuple of longHtml, shortHtml. longHtml is NULL if [processFullDocs] is true.
868- static Tuple2 <String , String > _renderNodesToHtml (
869- List <md.Node > nodes, bool processFullDocs) {
870- var rawHtml = md.HtmlRenderer ().render (nodes);
871- var asHtmlDocument = parse (rawHtml);
872- for (var s in asHtmlDocument.querySelectorAll ('script' )) {
873- s.remove ();
874- }
875- for (var pre in asHtmlDocument.querySelectorAll ('pre' )) {
876- if (pre.children.isNotEmpty &&
877- pre.children.length != 1 &&
878- pre.children.first.localName != 'code' ) {
879- continue ;
880- }
881-
882- if (pre.children.isNotEmpty && pre.children.first.localName == 'code' ) {
883- var code = pre.children.first;
884- pre.classes
885- .addAll (code.classes.where ((name) => name.startsWith ('language-' )));
882+ /// Returns a tuple of List<md.Node> and hasExtendedContent
883+ Tuple2 <List <md.Node >, bool > parseMarkdownText (
884+ String text, bool processFullText) {
885+ bool hasExtendedContent = false ;
886+ List <String > lines = LineSplitter .split (text).toList ();
887+ md.Node firstNode;
888+ List <md.Node > nodes = [];
889+ for (md.Node node
890+ in IterableBlockParser (lines, this ).parseLinesGenerator ()) {
891+ if (firstNode != null ) {
892+ hasExtendedContent = true ;
893+ if (! processFullText) break ;
886894 }
887-
888- bool specifiesLanguage = pre.classes.isNotEmpty;
889- // Assume the user intended Dart if there are no other classes present.
890- if (! specifiesLanguage) pre.classes.add ('language-dart' );
891- }
892- String asHtml;
893- String asOneLiner;
894-
895- if (processFullDocs) {
896- // `trim` fixes issue with line ending differences between mac and windows.
897- asHtml = asHtmlDocument.body.innerHtml? .trim ();
895+ firstNode ?? = node;
896+ nodes.add (node);
898897 }
899- asOneLiner = asHtmlDocument.body.children.isEmpty
900- ? ''
901- : asHtmlDocument.body.children.first.innerHtml;
902-
903- return Tuple2 (asHtml, asOneLiner);
898+ _parseInlineContent (nodes);
899+ return Tuple2 (nodes, hasExtendedContent);
904900 }
905901
906902 // From package:markdown/src/document.dart
@@ -919,112 +915,6 @@ class MarkdownDocument extends md.Document {
919915 }
920916 }
921917 }
922-
923- /// Returns a tuple of longHtml, shortHtml (longHtml is NULL if !processFullDocs)
924- Tuple3 <String , String , bool > renderLinesToHtml (
925- List <String > lines, bool processFullDocs) {
926- bool hasExtendedDocs = false ;
927- md.Node firstNode;
928- List <md.Node > nodes = [];
929- for (md.Node node
930- in IterableBlockParser (lines, this ).parseLinesGenerator ()) {
931- if (firstNode != null ) {
932- hasExtendedDocs = true ;
933- if (! processFullDocs) break ;
934- }
935- firstNode ?? = node;
936- nodes.add (node);
937- }
938- _parseInlineContent (nodes);
939-
940- String shortHtml;
941- String longHtml;
942- if (processFullDocs) {
943- Tuple2 htmls = _renderNodesToHtml (nodes, processFullDocs);
944- longHtml = htmls.item1;
945- shortHtml = htmls.item2;
946- } else {
947- if (firstNode != null ) {
948- Tuple2 htmls = _renderNodesToHtml ([firstNode], processFullDocs);
949- shortHtml = htmls.item2;
950- } else {
951- shortHtml = '' ;
952- }
953- }
954- return Tuple3 <String , String , bool >(longHtml, shortHtml, hasExtendedDocs);
955- }
956- }
957-
958- class Documentation {
959- final Canonicalization _element;
960-
961- Documentation .forElement (this ._element);
962-
963- bool _hasExtendedDocs;
964-
965- bool get hasExtendedDocs {
966- if (_hasExtendedDocs == null ) {
967- _renderHtmlForDartdoc (_element.isCanonical && _asHtml == null );
968- }
969- return _hasExtendedDocs;
970- }
971-
972- String _asHtml;
973-
974- String get asHtml {
975- if (_asHtml == null ) {
976- assert (_asOneLiner == null || _element.isCanonical);
977- _renderHtmlForDartdoc (true );
978- }
979- return _asHtml;
980- }
981-
982- String _asOneLiner;
983-
984- String get asOneLiner {
985- if (_asOneLiner == null ) {
986- assert (_asHtml == null );
987- _renderHtmlForDartdoc (_element.isCanonical);
988- }
989- return _asOneLiner;
990- }
991-
992- List <ModelCommentReference > get commentRefs => _element.commentRefs;
993-
994- void _renderHtmlForDartdoc (bool processAllDocs) {
995- Tuple3 <String , String , bool > renderResults =
996- _renderMarkdownToHtml (processAllDocs);
997- if (processAllDocs) {
998- _asHtml = renderResults.item1;
999- }
1000- if (_asOneLiner == null ) {
1001- _asOneLiner = renderResults.item2;
1002- }
1003- if (_hasExtendedDocs != null ) {
1004- assert (_hasExtendedDocs == renderResults.item3);
1005- }
1006- _hasExtendedDocs = renderResults.item3;
1007- }
1008-
1009- /// Returns a tuple of longHtml, shortHtml, hasExtendedDocs
1010- /// (longHtml is NULL if !processFullDocs)
1011- Tuple3 <String , String , bool > _renderMarkdownToHtml (bool processFullDocs) {
1012- md.Node _linkResolver (String name, [String _]) {
1013- if (name.isEmpty) {
1014- return null ;
1015- }
1016- return md.Text (_linkDocReference (name, _element, commentRefs));
1017- }
1018-
1019- String text = _element.documentation;
1020- _showWarningsForGenericsOutsideSquareBracketsBlocks (text, _element);
1021- MarkdownDocument document = MarkdownDocument (
1022- inlineSyntaxes: _markdown_syntaxes,
1023- blockSyntaxes: _markdown_block_syntaxes,
1024- linkResolver: _linkResolver);
1025- List <String > lines = LineSplitter .split (text).toList ();
1026- return document.renderLinesToHtml (lines, processFullDocs);
1027- }
1028918}
1029919
1030920class _InlineCodeSyntax extends md.InlineSyntax {
0 commit comments