From 6f4ab9a55d05a2ed719bd3f27d51e329b730d4c4 Mon Sep 17 00:00:00 2001 From: citricacid2 <61765149+citricacid2@users.noreply.github.com> Date: Mon, 3 Oct 2022 00:00:32 -0400 Subject: [PATCH] feat: added markdown links --- .../markdown_syntax_to_styled_text.dart | 55 +++++++++++++++++++ .../built_in_shortcut_events.dart | 5 ++ 2 files changed, 60 insertions(+) diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart index 4b74145ec0..d0f93fdd73 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart @@ -124,3 +124,58 @@ ShortcutEventHandler backquoteToCodeHandler = (editorState, event) { return KeyEventResult.handled; }; + +/// To create a link, enclose the link text in brackets (e.g., [link text]). +/// Then, immediately follow it with the URL in parentheses (e.g., (https://example.com)). +ShortcutEventHandler markdownLinkToLinkHandler = (editorState, event) { + final selectionService = editorState.service.selectionService; + final selection = selectionService.currentSelection.value; + final textNodes = selectionService.currentSelectedNodes.whereType(); + if (selection == null || !selection.isSingle || textNodes.length != 1) { + return KeyEventResult.ignored; + } + + // find all of the indexs for important characters + final textNode = textNodes.first; + final text = textNode.toRawString(); + final firstOpeningBracket = text.indexOf('['); + final firstClosingBracket = text.indexOf(']'); + + // use regex to validate the format of the link + // note: this enforces that the link has http or https + final regexp = RegExp(r'\[([\w\s\d]+)\]\(((?:\/|https?:\/\/)[\w\d./?=#]+)$'); + final match = regexp.firstMatch(text); + if (match == null) { + return KeyEventResult.ignored; + } + + // extract the text and the url of the link + final linkText = match.group(1); + final linkUrl = match.group(2); + + // Delete the initial opening bracket, + // update the href attribute of the text surrounded by [ ] to the url, + // delete everything after the text, + // and update the cursor position. + TransactionBuilder(editorState) + ..deleteText(textNode, firstOpeningBracket, 1) + ..formatText( + textNode, + firstOpeningBracket, + firstClosingBracket - firstOpeningBracket - 1, + { + BuiltInAttributeKey.href: linkUrl, + }, + ) + ..deleteText(textNode, firstClosingBracket - 1, + selection.end.offset - firstClosingBracket) + ..afterSelection = Selection.collapsed( + Position( + path: textNode.path, + offset: firstOpeningBracket + linkText!.length, + ), + ) + ..commit(); + + return KeyEventResult.handled; +}; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart index 827b057700..569942f635 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart @@ -257,6 +257,11 @@ List builtInShortcutEvents = [ command: 'backquote', handler: backquoteToCodeHandler, ), + ShortcutEvent( + key: 'Markdown link to link', + command: 'shift+parenthesis right', + handler: markdownLinkToLinkHandler, + ), // https://github.com/flutter/flutter/issues/104944 // Workaround: Using space editing on the web platform often results in errors, // so adding a shortcut event to handle the space input instead of using the