diff --git a/README.md b/README.md index 0c0ad1e..c96e7a2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # `linkify` [![pub package](https://img.shields.io/pub/v/linkify.svg)](https://pub.dartlang.org/packages/linkify) -Low-level link (text, URLs, emails) parsing library in Dart. +Low-level link (text, URLs, emails, phone numbers) parsing library in Dart. [Flutter library](https://github.com/Cretezy/flutter_linkify). diff --git a/lib/src/phone_number.dart b/lib/src/phone_number.dart new file mode 100644 index 0000000..a996c40 --- /dev/null +++ b/lib/src/phone_number.dart @@ -0,0 +1,61 @@ +import 'package:linkify/linkify.dart'; + +// matches "any amount of text with a phone number" +final _phoneNumberRegex = RegExp(r'(.*?)((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})', caseSensitive: false, dotAll: true); + +class PhoneNumberLinkifier extends Linkifier { + const PhoneNumberLinkifier(); + + @override + List parse(elements, options) { + final list = []; + + elements.forEach((element) { + if (element is TextElement) { + var match = _phoneNumberRegex.firstMatch(element.text); + + if (match == null) { + list.add(element); + } else { + // create the preceding TextElement + if (match.group(1).isNotEmpty) { + list.add(TextElement(match.group(1))); + } + + // create the PhoneNumberElement + if (match.group(2).isNotEmpty) { + var phoneNumberText = match.group(2); + var phoneNumberURL = "tel:" + phoneNumberText; + + list.add(PhoneNumberElement(phoneNumberText, phoneNumberURL)); + } + + // create the following TextElement + final text = element.text.replaceFirst(match.group(0), ''); + if (text.isNotEmpty) { + list.addAll(parse([TextElement(text)], options)); + } + } + } else { + list.add(element); + } + }); + + return list; + } +} + +class PhoneNumberElement extends LinkableElement { + PhoneNumberElement(String text, String url) : super(text, url); + + @override + String toString() { + return "LinkElement: '$url' ($text)"; + } + + @override + bool operator ==(other) => equals(other); + + @override + bool equals(other) => other is UrlElement && super.equals(other); +} \ No newline at end of file