Skip to content

Commit 607776e

Browse files
committed
preserve user entered newlines in message parsing
1 parent d263ca0 commit 607776e

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

lib/src/markdown_extensions.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,13 @@ class DiasporaAutolinkSyntax extends InlineSyntax {
7373
return true;
7474
}
7575
}
76+
77+
class SingleNewlineBreakSyntax extends InlineSyntax {
78+
SingleNewlineBreakSyntax() : super(r'(?<!\\)(?<! {2})\n', startCharacter: 0x0A);
79+
80+
@override
81+
bool onMatch(InlineParser parser, Match match) {
82+
parser.addNode(Element.empty('br'));
83+
return true;
84+
}
85+
}

lib/src/messages.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class Message extends StatelessWidget with LocalizationHelpers {
7373
final people = mentionedPeople;
7474
return people != null ? people[diasporaId] : null;
7575
}),
76+
mde.SingleNewlineBreakSyntax(),
7677
mde.DiasporaAutolinkSyntax()
7778
],
7879
),
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:insporation/src/client.dart';
3+
import 'package:insporation/src/markdown_extensions.dart' as mde;
4+
import 'package:markdown/markdown.dart' as md;
5+
6+
String renderMessageMarkdown(String body, {Map<String, Person>? mentionedPeople}) {
7+
return md.markdownToHtml(
8+
body,
9+
blockSyntaxes: [
10+
md.TableSyntax(),
11+
md.FencedCodeBlockSyntax(),
12+
],
13+
inlineSyntaxes: [
14+
md.InlineHtmlSyntax(),
15+
mde.SuperscriptSyntax(),
16+
mde.SubscriptSyntax(),
17+
md.StrikethroughSyntax(),
18+
md.AutolinkExtensionSyntax(),
19+
mde.TagLinkSyntax(),
20+
mde.MentionLinkSyntax((diasporaId, inlineName) {
21+
final people = mentionedPeople;
22+
return people != null ? people[diasporaId] : null;
23+
}),
24+
mde.SingleNewlineBreakSyntax(),
25+
mde.DiasporaAutolinkSyntax(),
26+
],
27+
);
28+
}
29+
30+
void main() {
31+
test('single newline in paragraph renders as html break', () {
32+
final html = renderMessageMarkdown('hello\nworld');
33+
34+
expect(html, contains('<br'));
35+
});
36+
37+
test('fenced code block newlines are not converted to html breaks', () {
38+
final html = renderMessageMarkdown('```\nhello\nworld\n```');
39+
40+
expect(html, contains('<pre><code>hello\nworld\n</code></pre>'));
41+
expect(html, isNot(contains('<code>hello<br')));
42+
});
43+
44+
test('hard breaks via trailing spaces keep existing behavior', () {
45+
final html = renderMessageMarkdown('hello \nworld');
46+
47+
expect(html, contains('<p>hello<br />\nworld</p>'));
48+
});
49+
50+
test('inline code does not get newline break conversion', () {
51+
final html = renderMessageMarkdown('`hello\nworld`');
52+
53+
expect(html, contains('<p><code>hello world</code></p>'));
54+
expect(html, isNot(contains('<code>hello<br')));
55+
});
56+
}

0 commit comments

Comments
 (0)