parse method

List<InlineObject> parse()

Implementation

List<InlineObject> parse() {
  _delimiterProcessor = DelimiterProcessor(this, _tree);
  final neverMatch = <InlineSyntax>[];
  final hasLinkSyntax = syntaxes.any((e) => e is LinkSyntax);
  int? dirtyPosition;

  while (!isDone) {
    // A right bracket (']') is special. Hitting this character triggers the
    // "look for link or image" procedure.
    // See https://spec.commonmark.org/0.30/#an-algorithm-for-parsing-nested-emphasis-and-links.
    if (hasLinkSyntax && charAt() == $rbracket) {
      writeText();
      if (_delimiterProcessor.buildLinkOrImage()) {
        _textStart = position;
      }
      continue;
    }

    // See if the current text matches any defined Markdown syntax.
    if (syntaxes.any((syntax) {
      if (dirtyPosition == position && neverMatch.contains(syntax)) {
        return false;
      }

      final match = syntax.tryMatch(this);
      if (match == null) {
        return false;
      }

      writeText();
      final positionBefore = position;
      final node = syntax.parse(this, match);

      // If the position was not changed after parsing, never match this
      // syntax again at the same position.
      //
      // It makes it possible that even though `tryMatch()` matched, the
      // `parse()` still have the chance to regret the match and leave the
      // matched content for other syntaxes.
      //
      // `EmojiSyntax` is an example of this feature.
      if (position > positionBefore) {
        neverMatch.clear();
      } else {
        dirtyPosition = position;
        neverMatch.add(syntax);
      }

      if (node != null) {
        _tree.add(node);
        _textStart = position;
      }

      return true;
    })) continue;

    advance();
  }

  // Write any trailing text content to a Text node.
  writeText();
  _delimiterProcessor.processDelimiterRun(-1);
  _combineAdjacentText(_tree);
  return _tree;
}