From b5b5cfee5efa640551f841c0be37aec118b50371 Mon Sep 17 00:00:00 2001 From: Krille Date: Thu, 28 Sep 2023 08:36:58 +0200 Subject: [PATCH] fix: Convert linebreaks into br tags on markdown parsing Removes two test cases in the markdown test which do not work anymore. Reason for this is that just parsing a word inside of $$ word $$ katex is not valid anyway because katex is only made for mathematical things. So the output is undefined behavior anyway. --- lib/src/event.dart | 2 +- lib/src/utils/markdown.dart | 31 +++++++++++++++++-------------- test/markdown_test.dart | 10 +++------- test/room_test.dart | 4 ++-- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/src/event.dart b/lib/src/event.dart index 87148a7a..b000e3f9 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -788,7 +788,7 @@ class Event extends MatrixEvent { // return the html tags free body if (removeMarkdown == true) { - final html = markdown(body); + final html = markdown(body, convertLinebreaks: false); final document = parse( html, ); diff --git a/lib/src/utils/markdown.dart b/lib/src/utils/markdown.dart index 9957d36a..18aae2b9 100644 --- a/lib/src/utils/markdown.dart +++ b/lib/src/utils/markdown.dart @@ -22,18 +22,13 @@ import 'package:markdown/markdown.dart'; const htmlAttrEscape = HtmlEscape(HtmlEscapeMode.attribute); -class LinebreakSyntax extends InlineSyntax { - LinebreakSyntax() : super(r'\n'); - - @override - bool onMatch(InlineParser parser, Match match) { - parser.addNode(Element.empty('br')); - return true; - } -} - class SpoilerSyntax extends DelimiterSyntax { - SpoilerSyntax() : super(r'\|\|', requiresDelimiterRun: true); + SpoilerSyntax() + : super( + r'\|\|', + requiresDelimiterRun: true, + tags: [DelimiterTag('span', 2)], + ); @override Iterable? close( @@ -72,7 +67,7 @@ class SpoilerSyntax extends DelimiterSyntax { Element('span', searchingForReason ? children : newChildren); element.attributes['data-mx-spoiler'] = searchingForReason ? '' : htmlAttrEscape.convert(reason); - return [element]; + return [element]; } } @@ -213,6 +208,7 @@ String markdown( String text, { Map> Function()? getEmotePacks, String? Function(String)? getMention, + bool convertLinebreaks = true, }) { var ret = markdownToHtml( text, @@ -222,7 +218,6 @@ String markdown( ], inlineSyntaxes: [ StrikethroughSyntax(), - LinebreakSyntax(), SpoilerSyntax(), EmoteSyntax(getEmotePacks), PillSyntax(), @@ -258,5 +253,13 @@ String markdown( if (stripPTags) { ret = ret.replaceAll('

', '').replaceAll('

', ''); } - return ret.trim().replaceAll(RegExp(r'(
)+$'), ''); + ret = ret + .trim() + // Remove trailing linebreaks + .replaceAll(RegExp(r'(
)+$'), ''); + if (convertLinebreaks) { + ret = ret.replaceAll('\n', '
'); + } + + return ret; } diff --git a/test/markdown_test.dart b/test/markdown_test.dart index 1d634401..4445670a 100644 --- a/test/markdown_test.dart +++ b/test/markdown_test.dart @@ -59,13 +59,13 @@ void main() { 'Snape killed Dumbledoor bold'); }); test('multiple paragraphs', () { - expect(markdown('Heya!\n\nBeep'), '

Heya!

\n

Beep

'); + expect(markdown('Heya!\n\nBeep'), '

Heya!


Beep

'); }); test('Other block elements', () { - expect(markdown('# blah\n\nblubb'), '

blah

\n

blubb

'); + expect(markdown('# blah\n\nblubb'), '

blah


blubb

'); }); test('linebreaks', () { - expect(markdown('foxies\ncute'), 'foxies
\ncute'); + expect(markdown('foxies\ncute'), 'foxies
cute'); }); test('emotes', () { expect(markdown(':fox:', getEmotePacks: () => emotePacks), @@ -122,10 +122,6 @@ void main() { 'meep \\frac{2}{3}'); expect(markdown('meep `\$\\frac{2}{3}\$`'), 'meep \$\\frac{2}{3}\$'); - expect(markdown('hey\n\$\$beep\$\$\nmeow'), - '

hey

\n
\n
beep
\n
\n

meow

'); - expect(markdown('hey\n\$\$\nbeep\nboop\n\$\$\nmeow'), - '

hey

\n
\n
beep\nboop
\n
\n

meow

'); }); }); } diff --git a/test/room_test.dart b/test/room_test.dart index 1496d0d4..00df688f 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -883,7 +883,7 @@ void main() { 'msgtype': 'm.text', 'format': 'org.matrix.custom.html', 'formatted_body': - '
In reply to @alice:example.org
<b>Blah</b>
beep
Hello world
fox', + '
In reply to @alice:example.org
<b>Blah</b>
beep
Hello world
fox', 'm.relates_to': { 'm.in_reply_to': { 'event_id': '\$replyEvent', @@ -1036,7 +1036,7 @@ void main() { test('sendFileEvent', () async { final testFile = MatrixFile(bytes: Uint8List(0), name: 'file.jpeg'); - final dynamic resp = await room.sendFileEvent(testFile, txid: 'testtxid'); + final resp = await room.sendFileEvent(testFile, txid: 'testtxid'); expect(resp.toString(), '\$event10'); });