parseDefinition method

void parseDefinition()

Parses source to a link reference definition.

Implementation

void parseDefinition() {
  if (!parseLabel() || isDone || charAt() != $colon) {
    return;
  }

  // Advance to the next character after the colon.
  advance();
  if (!_parseDestination()) {
    return;
  }

  var precedingWhitespaces = moveThroughWhitespace();
  if (isDone) {
    _valid = true;
    return;
  }

  final multiline = charAt() == $lf;
  precedingWhitespaces += moveThroughWhitespace(multiLine: true);

  // The title must be preceded by whitespaces.
  if (precedingWhitespaces == 0 || isDone) {
    _valid = isDone;
    return;
  }

  final hasValidTitle = _parseTitle();
  // For example: `[foo]: <bar> "baz` is a invalid definition, but this one is
  // valid:
  // ```
  // [foo]: <bar>
  // "baz
  // ```
  if (!hasValidTitle && !multiline) {
    return;
  }

  if (hasValidTitle) {
    moveThroughWhitespace();
    if (!isDone && charAt() != $lf) {
      // It is not a valid definition if the title is followed by
      // non-whitespace characters, for example: `[foo]: <bar> "baz" hello`.
      // See https://spec.commonmark.org/0.30/#example-209.
      if (!multiline) {
        return;
      }
      // But it is a valid link reference definition if this definition is
      // multiline, see https://spec.commonmark.org/0.30/#example-210.
      _title = null;
    }
  }

  final linesUnconsumed = source.substring(pos).split('\n');
  if (linesUnconsumed.isNotEmpty && linesUnconsumed.first.isBlank) {
    linesUnconsumed.removeAt(0);
  }
  _unconsumedLines = linesUnconsumed.length;

  _valid = true;
}