Return list for link nodes creation (dart-lang/markdown#452)

* Return list for link parsing

* fixup pr

* fixup naming

Co-authored-by: lindeer <le.chang118@gmail.com>
diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md
index 99a96d7..58e4ab0 100644
--- a/pkgs/markdown/CHANGELOG.md
+++ b/pkgs/markdown/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 7.0.0-dev
+
+* **Breaking change**: `close()` of `DelimiterSyntax` and `LinkSyntax`
+  returns multiple nodes instead of single one.
+
 ## 6.0.2-dev
 
 * Fix a crash in checkbox lists when mixing checkbox items with
diff --git a/pkgs/markdown/lib/src/inline_parser.dart b/pkgs/markdown/lib/src/inline_parser.dart
index 71986a4..e0f08c6 100644
--- a/pkgs/markdown/lib/src/inline_parser.dart
+++ b/pkgs/markdown/lib/src/inline_parser.dart
@@ -157,7 +157,7 @@
     final syntax = delimiter.syntax;
     if (syntax is LinkSyntax && syntaxes.any((e) => e is LinkSyntax)) {
       final nodeIndex = _tree.lastIndexWhere((n) => n == delimiter.node);
-      final linkNode = syntax.close(this, delimiter, null, getChildren: () {
+      final linkNodes = syntax.close(this, delimiter, null, getChildren: () {
         _processDelimiterRun(index);
         // All of the nodes which lie past [index] are children of this
         // link/image.
@@ -165,14 +165,14 @@
         _tree.removeRange(nodeIndex + 1, _tree.length);
         return children;
       });
-      if (linkNode != null) {
+      if (linkNodes != null) {
         _delimiterStack.removeAt(index);
         if (delimiter.char == $lbracket) {
           for (final d in _delimiterStack.sublist(0, index)) {
             if (d.char == $lbracket) d.isActive = false;
           }
         }
-        _tree[nodeIndex] = linkNode;
+        _tree.replaceRange(nodeIndex, _tree.length, linkNodes);
         advanceBy(1);
         start = pos;
       } else {
@@ -242,7 +242,7 @@
         final openerTextNodeIndex = _tree.indexOf(openerTextNode);
         final closerTextNode = closer.node;
         var closerTextNodeIndex = _tree.indexOf(closerTextNode);
-        final node = opener.syntax.close(
+        final nodes = opener.syntax.close(
           this,
           opener,
           closer,
@@ -257,7 +257,7 @@
         _tree.replaceRange(
           openerTextNodeIndex + 1,
           closerTextNodeIndex,
-          [node!],
+          nodes!,
         );
         // Slide [closerTextNodeIndex] back accordingly.
         closerTextNodeIndex = openerTextNodeIndex + 2;
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
index a616cfb..712883f 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
@@ -83,15 +83,15 @@
   ///
   /// If a tag can be closed at the current position, then this method calls
   /// [getChildren], in which [parser] parses any nested text into child nodes.
-  /// The returned [Node] incorpororates these child nodes.
-  Node? close(
+  /// The returned [Iterable] includes these children nodes.
+  Iterable<Node>? close(
     InlineParser parser,
     Delimiter opener,
     Delimiter closer, {
     required String tag,
     required List<Node> Function() getChildren,
   }) {
-    return Element(tag, getChildren());
+    return [Element(tag, getChildren())];
   }
 }
 
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
index 7522036..b44923f 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
@@ -9,6 +9,16 @@
 import '../util.dart';
 import 'delimiter_syntax.dart';
 
+/// A helper class holds params of link context.
+/// Footnote creation needs other info in [_tryCreateReferenceLink].
+class LinkContext {
+  final InlineParser parser;
+  final SimpleDelimiter opener;
+  final List<Node> Function() getChildren;
+
+  const LinkContext(this.parser, this.opener, this.getChildren);
+}
+
 /// Matches links like `[blah][label]` and `[blah](url)`.
 class LinkSyntax extends DelimiterSyntax {
   static final _entirelyWhitespacePattern = RegExp(r'^\s*$');
@@ -23,13 +33,14 @@
         super(pattern, startCharacter: startCharacter);
 
   @override
-  Node? close(
+  Iterable<Node>? close(
     InlineParser parser,
     covariant SimpleDelimiter opener,
     Delimiter? closer, {
     String? tag,
     required List<Node> Function() getChildren,
   }) {
+    final context = LinkContext(parser, opener, getChildren);
     final text = parser.source.substring(opener.endPos, parser.pos);
     // The current character is the `]` that closed the link text. Examine the
     // next character, to determine what type of link we might have (a '('
@@ -37,7 +48,7 @@
     if (parser.pos + 1 >= parser.source.length) {
       // The `]` is at the end of the document, but this may still be a valid
       // shortcut reference link.
-      return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+      return _tryCreateReferenceLink(context, text);
     }
 
     // Peek at the next character; don't advance, so as to avoid later stepping
@@ -50,11 +61,13 @@
       final leftParenIndex = parser.pos;
       final inlineLink = _parseInlineLink(parser);
       if (inlineLink != null) {
-        return _tryCreateInlineLink(
-          parser,
-          inlineLink,
-          getChildren: getChildren,
-        );
+        return [
+          _tryCreateInlineLink(
+            parser,
+            inlineLink,
+            getChildren: getChildren,
+          ),
+        ];
       }
       // At this point, we've matched `[...](`, but that `(` did not pan out to
       // be an inline link. We must now check if `[...]` is simply a shortcut
@@ -63,7 +76,7 @@
       // Reset the parser position.
       parser.pos = leftParenIndex;
       parser.advanceBy(-1);
-      return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+      return _tryCreateReferenceLink(context, text);
     }
 
     if (char == $lbracket) {
@@ -75,18 +88,18 @@
         // That opening `[` is not actually part of the link. Maybe a
         // *shortcut* reference link (followed by a `[`).
         parser.advanceBy(1);
-        return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+        return _tryCreateReferenceLink(context, text);
       }
       final label = _parseReferenceLinkLabel(parser);
       if (label != null) {
-        return _tryCreateReferenceLink(parser, label, getChildren: getChildren);
+        return _tryCreateReferenceLink(context, label);
       }
       return null;
     }
 
     // The link text (inside `[...]`) was not followed with a opening `(` nor
     // an opening `[`. Perhaps just a simple shortcut reference link (`[...]`).
-    return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+    return _tryCreateReferenceLink(context, text);
   }
 
   /// Resolve a possible reference link.
@@ -148,17 +161,23 @@
 
   /// Tries to create a reference link node.
   ///
-  /// Returns the link if it was successfully created, `null` otherwise.
-  Node? _tryCreateReferenceLink(
-    InlineParser parser,
-    String label, {
-    required List<Node> Function() getChildren,
-  }) {
-    return _resolveReferenceLink(
+  /// Returns the nodes if it was successfully created, `null` otherwise.
+  Iterable<Node>? _tryCreateReferenceLink(
+    LinkContext context,
+    String label,
+  ) {
+    final parser = context.parser;
+    final getChildren = context.getChildren;
+    final link = _resolveReferenceLink(
       label,
       parser.document.linkReferences,
       getChildren: getChildren,
     );
+    if (link != null) {
+      return [link];
+    }
+    // TODO: add footnote creation here
+    return null;
   }
 
   // Tries to create an inline link node.
diff --git a/pkgs/markdown/lib/src/version.dart b/pkgs/markdown/lib/src/version.dart
index 1806888..0c814be 100644
--- a/pkgs/markdown/lib/src/version.dart
+++ b/pkgs/markdown/lib/src/version.dart
@@ -1,2 +1,2 @@
 // Generated code. Do not modify.
-const packageVersion = '6.0.2-dev';
+const packageVersion = '7.0.0-dev';
diff --git a/pkgs/markdown/pubspec.yaml b/pkgs/markdown/pubspec.yaml
index 470875d..b44329b 100644
--- a/pkgs/markdown/pubspec.yaml
+++ b/pkgs/markdown/pubspec.yaml
@@ -1,5 +1,5 @@
 name: markdown
-version: 6.0.2-dev
+version: 7.0.0-dev
 
 description: A portable Markdown library written in Dart that can parse
  Markdown into HTML.