close method

  1. @override
Iterable<Node>? close(
  1. InlineParser parser,
  2. covariant SimpleDelimiter opener,
  3. Delimiter? closer, {
  4. String? tag,
  5. required List<Node> getChildren(),
})
override

Attempts to close this tag at the current position.

If a tag cannot be closed at the current position (for example, if a link reference cannot be found for a link tag's label), then null is returned.

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 Iterable includes these children nodes.

Implementation

@override
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 '('
  // means a possible inline link; otherwise a possible reference link).
  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(context, text);
  }

  // Peek at the next character; don't advance, so as to avoid later stepping
  // backward.
  final char = parser.charAt(parser.pos + 1);

  if (char == $lparen) {
    // Maybe an inline link, like `[text](destination)`.
    parser.advanceBy(1);
    final leftParenIndex = parser.pos;
    final inlineLink = _parseInlineLink(parser);
    if (inlineLink != null) {
      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
    // reference link.

    // Reset the parser position.
    parser.pos = leftParenIndex;
    parser.advanceBy(-1);
    return _tryCreateReferenceLink(context, text);
  }

  if (char == $lbracket) {
    parser.advanceBy(1);
    // At this point, we've matched `[...][`. Maybe a *full* reference link,
    // like `[foo][bar]` or a *collapsed* reference link, like `[foo][]`.
    if (parser.pos + 1 < parser.source.length &&
        parser.charAt(parser.pos + 1) == $rbracket) {
      // That opening `[` is not actually part of the link. Maybe a
      // *shortcut* reference link (followed by a `[`).
      parser.advanceBy(1);
      return _tryCreateReferenceLink(context, text);
    }
    final label = _parseReferenceLinkLabel(parser);
    if (label != null) {
      return _tryCreateReferenceLink(context, label, secondary: true);
    }
    return null;
  }

  // The link text (inside `[...]`) was not followed with a opening `(` nor
  // an opening `[`. Perhaps just a simple shortcut reference link (`[...]`).
  return _tryCreateReferenceLink(context, text);
}