From 1f19f0db46df3d1960f6387c82ddb45027181a92 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Sat, 20 Apr 2024 20:18:18 -0700 Subject: [PATCH] Added logic to open any 'src' in a tag --- .../markor/format/ActionButtonBase.java | 24 +++++++++++++- .../net/gsantner/opoc/format/GsTextUtils.java | 33 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java index 3bbd78a9c8..8ae75db190 100644 --- a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java +++ b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java @@ -7,6 +7,8 @@ #########################################################*/ package net.gsantner.markor.format; +import static android.util.Patterns.WEB_URL; + import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; @@ -40,6 +42,7 @@ import net.gsantner.markor.ApplicationObject; import net.gsantner.markor.R; +import net.gsantner.markor.activity.DocumentActivity; import net.gsantner.markor.frontend.AttachLinkOrFileDialog; import net.gsantner.markor.frontend.DatetimeFormatDialog; import net.gsantner.markor.frontend.MarkorDialogFactory; @@ -54,6 +57,7 @@ import net.gsantner.opoc.util.GsFileUtils; import net.gsantner.opoc.wrapper.GsCallback; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -696,7 +700,25 @@ protected final boolean runCommonAction(final @StringRes int action) { final int sel = TextViewUtils.getSelection(_hlEditor)[0]; final String line = TextViewUtils.getSelectedLines(_hlEditor, sel); final int cursor = sel - TextViewUtils.getLineStart(_hlEditor.getText(), sel); - String url = GsTextUtils.tryExtractUrlAroundPos(line, cursor); + + // First try to pull a resource + String url = null; + final String resource = GsTextUtils.tryExtractResourceAroundPos(line, cursor); + if (resource != null) { + if (WEB_URL.matcher(resource).matches()) { + url = resource; + } else { + final File f = GsFileUtils.makeAbsolute(resource, _document.getFile().getParentFile()); + if (f.canRead()) { + DocumentActivity.handleFileClick(getActivity(), f, null); + return true; + } + } + + } + + // Then try to pull a tag + url = url == null ? GsTextUtils.tryExtractUrlAroundPos(line, cursor) : url; if (url != null) { if (url.endsWith(")")) { url = url.substring(0, url.length() - 1); diff --git a/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java b/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java index 1a29c8486d..f3f923ad15 100644 --- a/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java +++ b/app/src/main/java/net/gsantner/opoc/format/GsTextUtils.java @@ -24,11 +24,18 @@ import java.util.Date; import java.util.List; import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @SuppressWarnings({"unused", "SpellCheckingInspection"}) public class GsTextUtils { public static String UTF8 = "UTF-8"; + // Regex patterns used for finding resources in tags + public final static Pattern SELF_CLOSING_TAG = Pattern.compile("<(\\w+)([^>]*?)src='([^']+)'([^>]*?)/>"); + public final static Pattern REGULAR_TAG = Pattern.compile("<(\\w+)([^>]*?)src='([^']+)'([^>]*?)>(.*?)"); + + /** * This is a simple method that tries to extract an URL around a given index. * It doesn't do any validation. Separation by whitespace or end. Detects http and https. @@ -55,6 +62,32 @@ public static String tryExtractUrlAroundPos(final String text, int pos) { return null; } + + /** + * This is a simple method that tries to extract the value of the 'src' attribute + * for any tag in the text which surrounds pos. + * It doesn't do any validation. Separation by whitespace or end. + * + * @param text Text to extract from + * @param pos Position to start searching from (backwards) + * @return Extracted resource path or {@code null} if none found + */ + public static String tryExtractResourceAroundPos(final String text, int pos) { + + for (final Pattern pattern : Arrays.asList(SELF_CLOSING_TAG, REGULAR_TAG)) { + final Matcher matcher = pattern.matcher(text); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + if (pos >= start && pos <= end) { + return matcher.group(3); + } + } + } + + return null; // Return null if no enclosing tag with src attribute is found + } + /** * find '\n' to the right and left of text[pos] .. text[posEnd]. * If left does not exist 0 (begin of text) is used.