blob: 5b2b1b5fd62776b01267e0295bb27bab6358726d [file] [log] [blame]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import '../ast.dart';
import '../block_parser.dart';
import '../document.dart';
import '../line.dart';
import '../link_parser.dart';
import '../patterns.dart';
import '../util.dart';
import 'block_syntax.dart';
class LinkReferenceDefinitionSyntax extends BlockSyntax {
@override
RegExp get pattern => linkReferenceDefinitionPattern;
@override
bool canEndBlock(BlockParser parser) => false;
const LinkReferenceDefinitionSyntax();
@override
Node? parse(BlockParser parser) {
final lines = <Line>[parser.current];
parser.advance();
while (!BlockSyntax.isAtBlockEnd(parser)) {
lines.add(parser.current);
parser.advance();
}
if (!_parseLinkReferenceDefinition(lines, parser)) {
parser.retreatBy(lines.length);
}
return null;
}
bool _parseLinkReferenceDefinition(List<Line> lines, BlockParser parser) {
final linkParser = LinkParser(lines.map((e) => e.content).join('\n'))
..parseDefinition();
if (!linkParser.valid) {
return false;
}
// Retreat the parsing position back to where the link reference definition
// ends, so that the next syntax can continue parsing from there.
parser.retreatBy(linkParser.unconsumedLines);
final labelString = normalizeLinkLabel(linkParser.label!);
parser.document.linkReferences.putIfAbsent(
labelString,
() => LinkReference(
labelString,
linkParser.destination!,
linkParser.title,
),
);
return true;
}
}