From 611518670e9ce6653cb06a7298411a4a777513b7 Mon Sep 17 00:00:00 2001 From: Aram Date: Tue, 10 Dec 2024 13:46:46 +0100 Subject: [PATCH] Improved Hyperlink Immensly * Still breaks with Color * BUT USES COMPONENT AS PARAMETER --- .../bluelib/markdown/MarkdownParser.java | 3 +- .../bluelib/markdown/syntax/Color.java | 1 - .../bluelib/markdown/syntax/Hyperlink.java | 141 ++++++++++++++---- .../bluelib/utils/math/MiscUtils.java | 1 - 4 files changed, 112 insertions(+), 34 deletions(-) diff --git a/common/src/main/java/software/bluelib/markdown/MarkdownParser.java b/common/src/main/java/software/bluelib/markdown/MarkdownParser.java index 52903e99..fad4cf46 100644 --- a/common/src/main/java/software/bluelib/markdown/MarkdownParser.java +++ b/common/src/main/java/software/bluelib/markdown/MarkdownParser.java @@ -61,7 +61,8 @@ public static MutableComponent parseMarkdown(Component pMessage) { text = new Strikethrough().applyString(text); text = new Underline().applyString(text); text = new Spoiler().applyString(text); - MutableComponent formattedMessage = new Hyperlink().applyComponent(text); + MutableComponent formattedMessage = Component.literal(text); + formattedMessage = new Hyperlink().applyHyperlink(formattedMessage); formattedMessage = new Color().applyColor(formattedMessage); formattedMessage = new CopyToClipboard().applyCopyToClipboard(formattedMessage, textWithoutFormatting); BaseLogger.log(BaseLogLevel.INFO, "Markdown applied to message: " + text + ". Styled message is: " + formattedMessage, true); diff --git a/common/src/main/java/software/bluelib/markdown/syntax/Color.java b/common/src/main/java/software/bluelib/markdown/syntax/Color.java index 694e7c5d..8f2bebee 100644 --- a/common/src/main/java/software/bluelib/markdown/syntax/Color.java +++ b/common/src/main/java/software/bluelib/markdown/syntax/Color.java @@ -166,7 +166,6 @@ public MutableComponent applyColor(MutableComponent pComponent) { return result; } - /** * Overrides the {@link MarkdownFeature#applyFormat(String)} method to apply the formatting logic. *

diff --git a/common/src/main/java/software/bluelib/markdown/syntax/Hyperlink.java b/common/src/main/java/software/bluelib/markdown/syntax/Hyperlink.java index 74ad8575..042216d8 100644 --- a/common/src/main/java/software/bluelib/markdown/syntax/Hyperlink.java +++ b/common/src/main/java/software/bluelib/markdown/syntax/Hyperlink.java @@ -2,6 +2,8 @@ package software.bluelib.markdown.syntax; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.minecraft.network.chat.*; import software.bluelib.markdown.MarkdownFeature; import software.bluelib.utils.logging.BaseLogLevel; @@ -28,7 +30,7 @@ * * * @author MeAlam - * @version 1.4.0 + * @version 1.6.0 * @see MarkdownFeature * @since 1.4.0 */ @@ -77,54 +79,131 @@ public Hyperlink() { * The method returns the formatted message with the Hyperlink applied, or the original message if no valid URL is found. *

* - * @param pMessage {@link String} - The message to format. + * @param pComponent {@link String} - The message to format. * @return {@link MutableComponent} - The formatted message with Hyperlink Markdown applied, or the original message. * @author MeAlam - * @since 1.4.0 + * @since 1.6.0 */ - @Override - public MutableComponent applyComponent(String pMessage) { + public MutableComponent applyHyperlink(MutableComponent pComponent) { if (!isHyperlinkEnabled) { BaseLogger.log(BaseLogLevel.INFO, "Hyperlink formatting is disabled. Returning original content.", true); - return Component.literal(pMessage); + return pComponent; } - MutableComponent finalMessage = Component.empty(); - int currentIndex = 0; + MutableComponent result = Component.empty(); + BaseLogger.log(BaseLogLevel.INFO, "Starting to process component: " + pComponent.getString(), true); + + // Define regex pattern + Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "(.*?)" + Pattern.quote(suffix) + "\\((.*?)\\)"); + BaseLogger.log(BaseLogLevel.INFO, "Using regex pattern: " + pattern.pattern(), true); + + // Handle components with no siblings (single-component case) + if (pComponent.getSiblings().isEmpty()) { + BaseLogger.log(BaseLogLevel.INFO, "No siblings found. Processing the component itself.", true); + String componentText = pComponent.getString(); + + Matcher matcher = pattern.matcher(componentText); + MutableComponent styledComponent = Component.empty(); + int lastIndex = 0; - while (currentIndex < pMessage.length()) { - int openBracketIndex = pMessage.indexOf(prefix, currentIndex); - int closeBracketIndex = pMessage.indexOf(suffix, openBracketIndex); - int openParenIndex = pMessage.indexOf("(", closeBracketIndex); - int closeParenIndex = pMessage.indexOf(")", openParenIndex); + // Process matches in the main component + while (matcher.find()) { + String beforeMatch = componentText.substring(lastIndex, matcher.start()); - if (openBracketIndex == -1 || closeBracketIndex == -1 || openParenIndex == -1 || closeParenIndex == -1) { - finalMessage.append(Component.literal(pMessage.substring(currentIndex))); - break; + // Append unstyled text before match + if (!beforeMatch.isEmpty()) { + BaseLogger.log(BaseLogLevel.INFO, "Appending unstyled text: " + beforeMatch, true); + styledComponent.append(Component.literal(beforeMatch)); + } + + String linkText = matcher.group(1).trim(); + String url = matcher.group(2).trim(); + BaseLogger.log(BaseLogLevel.INFO, "Matched text: " + linkText + ", URL: " + url, true); + + // Validate and apply hyperlink + if (MiscUtils.isValidURL(url)) { + MutableComponent hyperlink = Component.literal(linkText) + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(0x1F5FE1)) + .withUnderlined(true) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))); + styledComponent.append(hyperlink); + } else { + BaseLogger.log(BaseLogLevel.WARNING, "Invalid URL detected: " + url, true); + styledComponent.append(Component.literal(matcher.group(0))); + } + + lastIndex = matcher.end(); } - if (openBracketIndex > currentIndex) { - finalMessage.append(Component.literal(pMessage.substring(currentIndex, openBracketIndex))); + // Append remaining text + String remainingText = componentText.substring(lastIndex); + if (!remainingText.isEmpty()) { + BaseLogger.log(BaseLogLevel.INFO, "Appending remaining text: " + remainingText, true); + styledComponent.append(Component.literal(remainingText)); } - String linkText = pMessage.substring(openBracketIndex + 1, closeBracketIndex).trim(); - String url = pMessage.substring(openParenIndex + 1, closeParenIndex).trim(); + BaseLogger.log(BaseLogLevel.INFO, "Final styled component: " + styledComponent.getString(), true); + result.append(styledComponent); - if (!MiscUtils.isValidURL(url)) { - finalMessage.append(Component.literal(pMessage.substring(openBracketIndex, closeParenIndex + 1))); - currentIndex = closeParenIndex + 1; - continue; - } + } else { // Process siblings as in the original method + for (Component sibling : pComponent.getSiblings()) { + BaseLogger.log(BaseLogLevel.INFO, "Processing sibling: " + sibling.getString(), true); - MutableComponent link = Component.literal(linkText) - .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(0x1F5FE1)).withUnderlined(true) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))); - finalMessage.append(link); + if (sibling instanceof MutableComponent mutableSibling) { + String siblingText = mutableSibling.getString(); + BaseLogger.log(BaseLogLevel.INFO, "Sibling text: " + siblingText, true); - currentIndex = closeParenIndex + 1; + Matcher matcher = pattern.matcher(siblingText); + MutableComponent styledSibling = Component.empty(); + int lastIndex = 0; + + // Process matches + while (matcher.find()) { + String beforeMatch = siblingText.substring(lastIndex, matcher.start()); + + // Append unstyled text before match + if (!beforeMatch.isEmpty()) { + BaseLogger.log(BaseLogLevel.INFO, "Appending unstyled text: " + beforeMatch, true); + styledSibling.append(Component.literal(beforeMatch)); + } + + String linkText = matcher.group(1).trim(); + String url = matcher.group(2).trim(); + BaseLogger.log(BaseLogLevel.INFO, "Matched text: " + linkText + ", URL: " + url, true); + + // Validate and apply hyperlink + if (MiscUtils.isValidURL(url)) { + MutableComponent hyperlink = Component.literal(linkText) + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(0x1F5FE1)) + .withUnderlined(true) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))); + styledSibling.append(hyperlink); + } else { + BaseLogger.log(BaseLogLevel.WARNING, "Invalid URL detected: " + url, true); + styledSibling.append(Component.literal(matcher.group(0))); + } + + lastIndex = matcher.end(); + } + + // Append remaining text + String remainingText = siblingText.substring(lastIndex); + if (!remainingText.isEmpty()) { + BaseLogger.log(BaseLogLevel.INFO, "Appending remaining text: " + remainingText, true); + styledSibling.append(Component.literal(remainingText)); + } + + BaseLogger.log(BaseLogLevel.INFO, "Final styled sibling: " + styledSibling.getString(), true); + result.append(styledSibling); + } else { + BaseLogger.log(BaseLogLevel.INFO, "Sibling is not mutable. Appending as-is: " + sibling.getString(), true); + result.append(sibling); + } + } } - return finalMessage; + BaseLogger.log(BaseLogLevel.INFO, "Final result component: " + result.getString(), true); + return result; } /** diff --git a/common/src/main/java/software/bluelib/utils/math/MiscUtils.java b/common/src/main/java/software/bluelib/utils/math/MiscUtils.java index 1473fa02..01cdb5af 100644 --- a/common/src/main/java/software/bluelib/utils/math/MiscUtils.java +++ b/common/src/main/java/software/bluelib/utils/math/MiscUtils.java @@ -67,7 +67,6 @@ public static boolean isValidURL(String pUrl) { } } - /** * A {@link Boolean} that checks if a string is a valid email address. *