Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Commit c3a5e66

Browse files
committed
Implement AlertBlockSyntax using BlockquoteSyntax
As I understand the alert-block syntax, it is an extension on the orignal blockquote support in markdown. Basically, it's a blockquote that is rendered differently. That means that if alert-block syntax isn't supported a markdown parser will render it as a blockquote. This provides a nice graceful fallback. It also means that if you're implementing it, you really should implement it the same way you implement blockquote parsing.
1 parent d735b0b commit c3a5e66

File tree

5 files changed

+72
-112
lines changed

5 files changed

+72
-112
lines changed

lib/markdown.dart

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import 'src/version.dart';
4242

4343
export 'src/ast.dart';
4444
export 'src/block_parser.dart';
45-
export 'src/block_syntaxes/alert_block_syntax.dart';
4645
export 'src/block_syntaxes/block_syntax.dart';
4746
export 'src/block_syntaxes/blockquote_syntax.dart';
4847
export 'src/block_syntaxes/code_block_syntax.dart';

lib/src/block_syntaxes/alert_block_syntax.dart

-110
This file was deleted.

lib/src/block_syntaxes/blockquote_syntax.dart

+62
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,65 @@ class BlockquoteSyntax extends BlockSyntax {
9797
return Element('blockquote', children);
9898
}
9999
}
100+
101+
/// Parses GitHub Alerts blocks.
102+
///
103+
/// See also: https://docs.github.com/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
104+
class AlertBlockSyntax extends BlockSyntax {
105+
@override
106+
RegExp get pattern => alertPattern;
107+
108+
const AlertBlockSyntax();
109+
110+
@override
111+
List<Line> parseChildLines(BlockParser parser) {
112+
return const BlockquoteSyntax().parseChildLines(parser);
113+
}
114+
115+
@override
116+
Node parse(BlockParser parser) {
117+
// Parse the alert type from the first line.
118+
final type =
119+
pattern.firstMatch(parser.current.content)!.group(1)!.toLowerCase();
120+
121+
final childLines = parseChildLines(parser);
122+
// Until we've parse all the child lines, we can't actually know if this is
123+
// a blockquote containing `[!note]` or if this is an alert-block.
124+
//
125+
// This is because `> [!note]` is not a valid alert-block!
126+
final isBlockquote = childLines.length <= 1;
127+
128+
if (!isBlockquote) {
129+
// Always remove the first line, this is the line that contained the type.
130+
childLines.removeAt(0);
131+
}
132+
133+
// Recursively parse the contents of the blockquote.
134+
final children = BlockParser(childLines, parser.document).parseLines(
135+
// The setext heading underline cannot be a lazy continuation line in a
136+
// block quote.
137+
// https://spec.commonmark.org/0.30/#example-93
138+
disabledSetextHeading: BlockquoteSyntax._lazyContinuation,
139+
parentSyntax: this,
140+
);
141+
142+
if (isBlockquote) {
143+
return Element('blockquote', children);
144+
}
145+
146+
// Mapping the alert title text.
147+
const typeTextMap = {
148+
'note': 'Note',
149+
'tip': 'Tip',
150+
'important': 'Important',
151+
'caution': 'Caution',
152+
'warning': 'Warning',
153+
};
154+
final titleText = typeTextMap[type]!;
155+
final titleElement = Element('p', [Text(titleText)])
156+
..attributes['class'] = 'markdown-alert-title';
157+
final elementClass = 'markdown-alert markdown-alert-$type';
158+
return Element('div', [titleElement, ...children])
159+
..attributes['class'] = elementClass;
160+
}
161+
}

lib/src/extension_set.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import 'block_syntaxes/alert_block_syntax.dart';
21
import 'block_syntaxes/block_syntax.dart';
2+
import 'block_syntaxes/blockquote_syntax.dart';
33
import 'block_syntaxes/fenced_code_block_syntax.dart';
44
import 'block_syntaxes/footnote_def_syntax.dart';
55
import 'block_syntaxes/header_with_id_syntax.dart';

test/extensions/alert_extension.unit

+9
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,12 @@ Additional markdown text.
129129
with two lines.</p>
130130
</div>
131131
<p>Additional markdown text.</p>
132+
>>> #584
133+
> [!CAUTION]
134+
>
135+
> some warning
136+
<<<
137+
<div class="markdown-alert markdown-alert-caution">
138+
<p class="markdown-alert-title">Caution</p>
139+
<p>some warning</p>
140+
</div>

0 commit comments

Comments
 (0)