-
Notifications
You must be signed in to change notification settings - Fork 204
Implement AlertBlockSyntax
using BlockquoteSyntax
#585
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,3 +97,65 @@ class BlockquoteSyntax extends BlockSyntax { | |
return Element('blockquote', children); | ||
} | ||
} | ||
|
||
/// Parses GitHub Alerts blocks. | ||
/// | ||
/// 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 | ||
class AlertBlockSyntax extends BlockSyntax { | ||
@override | ||
RegExp get pattern => alertPattern; | ||
|
||
const AlertBlockSyntax(); | ||
|
||
@override | ||
List<Line> parseChildLines(BlockParser parser) { | ||
return const BlockquoteSyntax().parseChildLines(parser); | ||
} | ||
|
||
@override | ||
Node parse(BlockParser parser) { | ||
// Parse the alert type from the first line. | ||
final type = | ||
pattern.firstMatch(parser.current.content)!.group(1)!.toLowerCase(); | ||
|
||
final childLines = parseChildLines(parser); | ||
// Until we've parse all the child lines, we can't actually know if this is | ||
// a blockquote containing `[!note]` or if this is an alert-block. | ||
// | ||
// This is because `> [!note]` is not a valid alert-block! | ||
final isBlockquote = childLines.length <= 1; | ||
|
||
if (!isBlockquote) { | ||
// Always remove the first line, this is the line that contained the type. | ||
childLines.removeAt(0); | ||
} | ||
|
||
// Recursively parse the contents of the blockquote. | ||
final children = BlockParser(childLines, parser.document).parseLines( | ||
// The setext heading underline cannot be a lazy continuation line in a | ||
// block quote. | ||
// https://spec.commonmark.org/0.30/#example-93 | ||
disabledSetextHeading: BlockquoteSyntax._lazyContinuation, | ||
parentSyntax: this, | ||
); | ||
|
||
if (isBlockquote) { | ||
return Element('blockquote', children); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is ugly, but I don't see a better way, unless we make I suppose we could in theory make final isAlertSyntaxEnabled = parser.document.blockSyntaxes.any(
(s) => s is AlertBlockSyntax,
); If we could give final isAlertSyntaxEnabled = parser.document.blockSyntaxes.contains(
const AlertBlockSyntax(),
); If inside The point with implementing alert-syntax inside |
||
} | ||
|
||
// Mapping the alert title text. | ||
const typeTextMap = { | ||
'note': 'Note', | ||
'tip': 'Tip', | ||
'important': 'Important', | ||
'caution': 'Caution', | ||
'warning': 'Warning', | ||
}; | ||
final titleText = typeTextMap[type]!; | ||
final titleElement = Element('p', [Text(titleText)]) | ||
..attributes['class'] = 'markdown-alert-title'; | ||
final elementClass = 'markdown-alert markdown-alert-$type'; | ||
return Element('div', [titleElement, ...children]) | ||
..attributes['class'] = elementClass; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this is not a valid alert block? because it is empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, that's how it behaves on github :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But is it the emptiness that makes it invalid, or some other property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example of the empty case
Example of the non-empty case
Note
Hello world
Conclusion
If we have
> [!note]
it's not a special block. But if it's:> ...
indicating that whatever is there belongs inside the blockquote, then it also is special.Otherwise, it's not special, just a normal blockquote.
Notice that
> foo\nbar
is the same as> foo\n> bar
, the line that follows is considered to be a paragraph continuation of the previous line, so the blockquote continues.So yes, as far as I can see, it's emptiness that decides it. Even if you have
> [!note]\n>
it'll still not be rendered as a special alert-block.