Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/markdown.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
sdk: [3.4, dev]
sdk: [3.9, dev]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c
Expand Down
2 changes: 1 addition & 1 deletion pkgs/markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Fix an issue with nested list structure when indented by tabs (#2172).
* Deprecated `LinkContext` and `BlockParser.standardBlockSyntaxes`.
Implementation members that should never have been made public.
* Require Dart `^3.4.0`.
* Require Dart `^3.9.0`.

## 7.3.0

Expand Down
3 changes: 2 additions & 1 deletion pkgs/markdown/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ linter:
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
- prefer_const_declarations
- prefer_final_locals
- prefer_final_in_for_each
- prefer_final_locals
- remove_deprecations_in_breaking_versions
- unnecessary_await_in_return
- unnecessary_raw_strings
- use_if_null_to_convert_nulls_to_bools
Expand Down
4 changes: 1 addition & 3 deletions pkgs/markdown/example/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ void _switchFlavor(Event e) {
}

extension on NodeList {
List<Node> get items => [
for (var i = 0; i < length; i++) item(i)!,
];
List<Node> get items => [for (var i = 0; i < length; i++) item(i)!];
}

extension on NamedNodeMap {
Expand Down
2 changes: 1 addition & 1 deletion pkgs/markdown/lib/src/assets/case_folding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1312,5 +1312,5 @@ const caseFoldingMap = {
"𞤞": "𞥀",
"𞤟": "𞥁",
"𞤠": "𞥂",
"𞤡": "𞥃"
"𞤡": "𞥃",
};
2 changes: 1 addition & 1 deletion pkgs/markdown/lib/src/assets/html_entities.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2129,5 +2129,5 @@ const htmlEntitiesMap = {
"&zopf;": "𝕫",
"&zscr;": "𝓏",
"&zwj;": "‍",
"&zwnj;": "‌"
"&zwnj;": "‌",
};
12 changes: 4 additions & 8 deletions pkgs/markdown/lib/src/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,15 @@ class Element implements Node {
Element(this.tag, this.children) : attributes = {};

/// Instantiates an empty, self-closing [tag] Element.
Element.empty(this.tag)
: children = null,
attributes = {};
Element.empty(this.tag) : children = null, attributes = {};

/// Instantiates a [tag] Element with no [children].
Element.withTag(this.tag)
: children = const [],
attributes = {};
Element.withTag(this.tag) : children = const [], attributes = {};

/// Instantiates a [tag] Element with a single Text child.
Element.text(this.tag, String text)
: children = [Text(text)],
attributes = {};
: children = [Text(text)],
attributes = {};

/// Whether this element is self-closing.
bool get isEmpty => children == null;
Expand Down
8 changes: 5 additions & 3 deletions pkgs/markdown/lib/src/block_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ class BlockParser {
/// The collection of built-in block parsers.
// TODO(kevmoo): this should be static const and private!
// The fact that it's mutable is a BUG!
@Deprecated('Implementation member. '
'Will be removed or make static in the next release.')
@Deprecated(
'Implementation member. '
'Will be removed or make static in the next release.',
)
final List<BlockSyntax> standardBlockSyntaxes = [
const EmptyBlockSyntax(),
const HtmlBlockSyntax(),
Expand All @@ -71,7 +73,7 @@ class BlockParser {
const UnorderedListSyntax(),
const OrderedListSyntax(),
const LinkReferenceDefinitionSyntax(),
const ParagraphSyntax()
const ParagraphSyntax(),
];

BlockParser(this.lines, this.document) {
Expand Down
11 changes: 7 additions & 4 deletions pkgs/markdown/lib/src/block_syntaxes/alert_block_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ class AlertBlockSyntax extends BlockSyntax {
// a Setext header.
// Because indented code blocks cannot interrupt paragraphs, a line
// matched CodeBlockSyntax is also paragraph continuation text.
final otherMatched =
parser.blockSyntaxes.firstWhere((s) => s.canParse(parser));
final otherMatched = parser.blockSyntaxes.firstWhere(
(s) => s.canParse(parser),
);
if ((otherMatched is ParagraphSyntax &&
!lastLine.isBlankLine &&
!codeFencePattern.hasMatch(lastLine.content)) ||
Expand All @@ -78,8 +79,10 @@ class AlertBlockSyntax extends BlockSyntax {
@override
Node parse(BlockParser parser) {
// Parse the alert type from the first line.
final type =
pattern.firstMatch(parser.current.content)!.group(1)!.toLowerCase();
final type = pattern
.firstMatch(parser.current.content)!
.group(1)!
.toLowerCase();
parser.advance();
final childLines = parseChildLines(parser);
// Recursively parse the contents of the alert.
Expand Down
19 changes: 11 additions & 8 deletions pkgs/markdown/lib/src/block_syntaxes/block_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,18 @@ abstract class BlockSyntax {
/// Gets whether or not [parser]'s current line should end the previous block.
static bool isAtBlockEnd(BlockParser parser) {
if (parser.isDone) return true;
return parser.blockSyntaxes
.any((s) => s.canParse(parser) && s.canEndBlock(parser));
return parser.blockSyntaxes.any(
(s) => s.canParse(parser) && s.canEndBlock(parser),
);
}

/// Generates a valid HTML anchor from the inner text of [element].
static String generateAnchorHash(Element element) =>
element.children!.first.textContent
.toLowerCase()
.trim()
.replaceAll(RegExp('[^a-z0-9 _-]'), '')
.replaceAll(RegExp(r'\s'), '-');
static String generateAnchorHash(Element element) => element
.children!
.first
.textContent
.toLowerCase()
.trim()
.replaceAll(RegExp('[^a-z0-9 _-]'), '')
.replaceAll(RegExp(r'\s'), '-');
}
5 changes: 3 additions & 2 deletions pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ class BlockquoteSyntax extends BlockSyntax {
// a Setext header.
// Because indented code blocks cannot interrupt paragraphs, a line
// matched CodeBlockSyntax is also paragraph continuation text.
final otherMatched =
parser.blockSyntaxes.firstWhere((s) => s.canParse(parser));
final otherMatched = parser.blockSyntaxes.firstWhere(
(s) => s.canParse(parser),
);
if ((otherMatched is ParagraphSyntax &&
!lastLine.isBlankLine &&
!codeFencePattern.hasMatch(lastLine.content)) ||
Expand Down
10 changes: 6 additions & 4 deletions pkgs/markdown/lib/src/block_syntaxes/code_block_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ class CodeBlockSyntax extends BlockSyntax {
break;
}

childLines.add(Line(
parser.current.content.dedent().text,
tabRemaining: parser.current.tabRemaining,
));
childLines.add(
Line(
parser.current.content.dedent().text,
tabRemaining: parser.current.tabRemaining,
),
);

parser.advance();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,19 @@ class FencedCodeBlockSyntax extends BlockSyntax {

final code = Element.text('code', text);
if (languageString != null) {
final processedLanguage = _processAttribute(languageString,
encodeHtml: parser.document.encodeHtml);
final processedLanguage = _processAttribute(
languageString,
encodeHtml: parser.document.encodeHtml,
);
code.attributes['class'] = 'language-$processedLanguage';
}

final pre = Element('pre', [code]);
if (metadataString != null) {
final processedMetadata = _processAttribute(metadataString,
encodeHtml: parser.document.encodeHtml);
final processedMetadata = _processAttribute(
metadataString,
encodeHtml: parser.document.encodeHtml,
);
pre.attributes['data-metadata'] = processedMetadata;
}

Expand Down
10 changes: 4 additions & 6 deletions pkgs/markdown/lib/src/block_syntaxes/footnote_def_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ class FootnoteDefSyntax extends BlockSyntax {
final children = <String>[];
// As one empty line should not split footnote definition, use this flag.
var shouldBeBlock = false;
late final syntaxList = parser.blockSyntaxes
.where((s) => !_excludingPattern.contains(s.pattern));
late final syntaxList = parser.blockSyntaxes.where(
(s) => !_excludingPattern.contains(s.pattern),
);

// Every line is footnote's children util two blank lines or a block.
while (!parser.isDone) {
Expand All @@ -69,10 +70,7 @@ class FootnoteDefSyntax extends BlockSyntax {
}

/// Patterns that would be used to decide if one line is a block.
static final _excludingPattern = {
emptyPattern,
dummyPattern,
};
static final _excludingPattern = {emptyPattern, dummyPattern};

/// Whether this line is any kind of block.
/// If `true`, the footnote block should end.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@ class LinkReferenceDefinitionSyntax extends BlockSyntax {

parser.document.linkReferences.putIfAbsent(
labelString,
() => LinkReference(
labelString,
linkParser.destination!,
linkParser.title,
),
() =>
LinkReference(labelString, linkParser.destination!, linkParser.title),
);

return true;
Expand Down
40 changes: 18 additions & 22 deletions pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import 'ordered_list_with_checkbox_syntax.dart';
import 'unordered_list_with_checkbox_syntax.dart';

class ListItem {
const ListItem(
this.lines, {
this.taskListItemState,
});
const ListItem(this.lines, {this.taskListItemState});

final List<Line> lines;
final TaskListItemState? taskListItemState;
Expand Down Expand Up @@ -78,7 +75,8 @@ abstract class ListSyntax extends BlockSyntax {
final match = pattern.firstMatch(parser.current.content);
final ordered = match![1] != null;

final taskListParserEnabled = this is UnorderedListWithCheckboxSyntax ||
final taskListParserEnabled =
this is UnorderedListWithCheckboxSyntax ||
this is OrderedListWithCheckboxSyntax;
final items = <ListItem>[];
var childLines = <Line>[];
Expand Down Expand Up @@ -123,7 +121,8 @@ abstract class ListSyntax extends BlockSyntax {
int? blankLines;

while (!parser.isDone) {
final currentIndent = parser.current.content.indentation() +
final currentIndent =
parser.current.content.indentation() +
(parser.current.tabRemaining ?? 0);

if (parser.current.isBlankLine) {
Expand All @@ -141,12 +140,14 @@ abstract class ListSyntax extends BlockSyntax {

final indentedLine = parser.current.content.dedent(indent);

childLines.add(Line(
blankLines == null
? indentedLine.text
: parseTaskListItem(indentedLine.text),
tabRemaining: indentedLine.tabRemaining,
));
childLines.add(
Line(
blankLines == null
? indentedLine.text
: parseTaskListItem(indentedLine.text),
tabRemaining: indentedLine.tabRemaining,
),
);
} else if (tryMatch(hrPattern)) {
// Horizontal rule takes precedence to a new list item.
break;
Expand All @@ -164,10 +165,7 @@ abstract class ListSyntax extends BlockSyntax {
textParser.advance();

// See https://spec.commonmark.org/0.30/#ordered-list-marker
final marker = textParser.substring(
markerStart,
textParser.pos,
);
final marker = textParser.substring(markerStart, textParser.pos);

var isBlank = true;
var contentWhitespances = 0;
Expand Down Expand Up @@ -211,7 +209,8 @@ abstract class ListSyntax extends BlockSyntax {
// any indentation past the required whitespace character.
indent = precedingWhitespaces;
} else {
indent = precedingWhitespaces +
indent =
precedingWhitespaces +
contentWhitespances +
(parser.current.tabRemaining ?? 0);
}
Expand All @@ -225,10 +224,7 @@ abstract class ListSyntax extends BlockSyntax {
content = content.prependSpace(2);
}

childLines.add(Line(
content,
tabRemaining: containsTab ? 2 : null,
));
childLines.add(Line(content, tabRemaining: containsTab ? 2 : null));
} else if (BlockSyntax.isAtBlockEnd(parser)) {
// Done with the list.
break;
Expand Down Expand Up @@ -271,7 +267,7 @@ abstract class ListSyntax extends BlockSyntax {
final itemElement = checkboxToInsert == null
? Element('li', children)
: (Element('li', _addCheckbox(children, checkboxToInsert))
..attributes['class'] = taskListClass);
..attributes['class'] = taskListClass);

itemNodes.add(itemElement);
anyEmptyLinesBetweenBlocks =
Expand Down
2 changes: 1 addition & 1 deletion pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class TableSyntax extends BlockSyntax {
}
parser.advance();
final row = [
for (final cell in cells) Element(cellType, [UnparsedContent(cell)])
for (final cell in cells) Element(cellType, [UnparsedContent(cell)]),
];

for (var i = 0; i < row.length && i < alignments.length; i++) {
Expand Down
17 changes: 9 additions & 8 deletions pkgs/markdown/lib/src/document.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ class Document {
this.encodeHtml = true,
this.withDefaultBlockSyntaxes = true,
this.withDefaultInlineSyntaxes = true,
}) : hasCustomInlineSyntaxes = (inlineSyntaxes?.isNotEmpty ?? false) ||
(extensionSet?.inlineSyntaxes.isNotEmpty ?? false) {
}) : hasCustomInlineSyntaxes =
(inlineSyntaxes?.isNotEmpty ?? false) ||
(extensionSet?.inlineSyntaxes.isNotEmpty ?? false) {
if (blockSyntaxes != null) {
_blockSyntaxes.addAll(blockSyntaxes);
}
Expand Down Expand Up @@ -157,8 +158,8 @@ class Document {
final refs = [
for (var i = 0; i < count; i++) ...[
Text(' '),
_ElementExt.footnoteAnchor(ref, i)
]
_ElementExt.footnoteAnchor(ref, i),
],
];
if (children.isEmpty) {
children.addAll(refs);
Expand All @@ -180,10 +181,10 @@ extension _ElementExt on Element {
final e = Element.empty('tag');
e.match;
return Element('a', [
Text('\u21a9'),
if (i > 0)
Element('sup', [Text(num)])..attributes['class'] = 'footnote-ref',
])
Text('\u21a9'),
if (i > 0)
Element('sup', [Text(num)])..attributes['class'] = 'footnote-ref',
])
// Ignore GFM's attributes:
// <data-footnote-backref aria-label="Back to content">.
..attributes['href'] = '#fnref-$ref$suffix'
Expand Down
Loading