diff --git a/lib/widgets/markdown_view.dart b/lib/widgets/markdown_view.dart index c0f2eb7a..7c424089 100644 --- a/lib/widgets/markdown_view.dart +++ b/lib/widgets/markdown_view.dart @@ -7,6 +7,10 @@ import 'package:git_touch/widgets/html_view.dart'; import 'package:provider/provider.dart'; import 'package:uri/uri.dart'; import 'package:path/path.dart' as path; +import 'package:markdown/markdown.dart' as md; +import 'package:charcode/charcode.dart'; + +import 'link.dart'; class MarkdownViewData { final Future future; @@ -109,6 +113,18 @@ class MarkdownFlutterView extends StatelessWidget { return Container( padding: padding, child: MarkdownBody( + builders: { + "userProfileLink": UserProfileLinkElementBuilder(), + }, + extensionSet: md.ExtensionSet( + md.ExtensionSet.gitHubFlavored.blockSyntaxes, + [ + UserProfileLink(), + md.EmojiSyntax(), + md.LinkSyntax(), + ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes + ], + ), data: text, selectable: true, imageBuilder: (uri, title, alt) { @@ -212,3 +228,26 @@ class MarkdownFlutterView extends StatelessWidget { ); } } + +class UserProfileLink extends md.InlineSyntax { + // github username regex format + UserProfileLink() + : super(r'\B@([a-z0-9](?:-?[a-z0-9]){0,38})', startCharacter: $at); + + @override + bool onMatch(md.InlineParser parser, Match match) { + var login = match[0].substring(1, match[0].length).trim(); + md.Node el = md.Element.text("userProfileLink", login); + parser.addNode(el); + return true; + } +} + +class UserProfileLinkElementBuilder extends MarkdownElementBuilder { + @override + Widget visitElementAfter(md.Element element, TextStyle prefferedStyle) { + return Link( + url: '/github/${element.textContent}', + child: Text('@' + element.textContent)); + } +}