diff --git a/CHANGELOG.md b/CHANGELOG.md index 06888f0..c8e9d84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.5 + +- **FIXED**: Fixed parsing url such as `[text](https://domain.com/path(with)brackets)`. + ## 0.0.4 - **CHANGED**: Improved link tap handling. diff --git a/lib/src/parser.dart b/lib/src/parser.dart index d35f6d5..0addd8e 100644 --- a/lib/src/parser.dart +++ b/lib/src/parser.dart @@ -326,15 +326,21 @@ List _parseInlineSpans(String text) { // find closing ')' var urlEnd = -1; - for (var k = urlIdx + 1; k < codes.length; k++) { + for (var k = urlIdx + 1, opens = 0; k < codes.length; k++) { final ck = codes[k]; if (ck == esc) { k++; - continue; + continue; // skip escaped char } - if (ck == url$end) { - urlEnd = k; - break; + if (ck == url$start) { + opens++; // count opening '(' + } else if (ck == url$end) { + if (opens > 0) { + opens--; // count closing ')' + } else { + urlEnd = k; // found the closing ')' + break; + } } } diff --git a/pubspec.yaml b/pubspec.yaml index 17cad6a..e7c17b6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,7 +8,7 @@ description: > Markdown library written in Dart. It can parse and display Markdown. -version: 0.0.4 +version: 0.0.5 homepage: https://github.com/DoctorinaAI/md repository: https://github.com/DoctorinaAI/md diff --git a/test/parser/parser_test.dart b/test/parser/parser_test.dart index 3e6221f..d4bba9d 100644 --- a/test/parser/parser_test.dart +++ b/test/parser/parser_test.dart @@ -117,6 +117,72 @@ void main() => group('Parse', () { ); }); + test('Urls', () { + var markdown = markdownDecoder.convert('[text](url)'); + expect( + markdown.text, + allOf( + isNotEmpty, + equals('text'), + ), + ); + expect( + markdown.blocks, + allOf( + isNotEmpty, + hasLength(equals(1)), + everyElement(isA()), + ), + ); + expect( + markdown.blocks.single, + isA().having( + (p) => p.spans, + 'spans', + allOf( + isNotEmpty, + hasLength(equals(1)), + everyElement(isA() + .having((s) => s.style, 'style', equals(MD$Style.link)) + .having((s) => s.extra, 'extra', containsPair('url', 'url'))), + ), + ), + ); + + // Should be with url: `url()` + markdown = markdownDecoder.convert('[text](url(with)brackets)'); + expect( + markdown.text, + allOf( + isNotEmpty, + equals('text'), + ), + ); + expect( + markdown.blocks, + allOf( + isNotEmpty, + hasLength(equals(1)), + everyElement(isA()), + ), + ); + expect( + markdown.blocks.single, + isA().having( + (p) => p.spans, + 'spans', + allOf( + isNotEmpty, + hasLength(equals(1)), + everyElement(isA() + .having((s) => s.style, 'style', equals(MD$Style.link)) + .having((s) => s.extra, 'extra', + containsPair('url', 'url(with)brackets'))), + ), + ), + ); + }); + test('Empty input', () { expect(markdownDecoder.convert('').blocks, isEmpty); });