blob: 8df4cd92c5846e4e2a8df760aeff626d06abdba7 [file] [log] [blame]
// Copyright (c) 2022, 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 'package:charcode/charcode.dart';
import '../ast.dart';
import '../inline_parser.dart';
import '../util.dart';
import 'inline_syntax.dart';
/// Matches backtick-enclosed inline code blocks.
class CodeSyntax extends InlineSyntax {
// This pattern matches:
//
// * a string of backticks (not followed by any more), followed by
// * a non-greedy string of anything, including newlines, ending with anything
// except a backtick, followed by
// * a string of backticks the same length as the first, not followed by any
// more.
//
// This conforms to the delimiters of inline code, both in Markdown.pl, and
// CommonMark.
static final String _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)';
CodeSyntax() : super(_pattern);
@override
bool tryMatch(InlineParser parser, [int? startMatchPos]) {
if (parser.pos > 0 && parser.charAt(parser.pos - 1) == $backquote) {
// Not really a match! We can't just sneak past one backtick to try the
// next character. An example of this situation would be:
//
// before ``` and `` after.
// ^--parser.pos
return false;
}
final match = pattern.matchAsPrefix(parser.source, parser.pos);
if (match == null) {
return false;
}
parser.writeText();
if (onMatch(parser, match)) parser.consume(match.match.length);
return true;
}
@override
bool onMatch(InlineParser parser, Match match) {
var code = match[2]!.trim().replaceAll('\n', ' ');
if (parser.encodeHtml) code = escapeHtml(code);
parser.addNode(Element.text('code', code));
return true;
}
}