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.