From 9851b07f433afb862587dcdb317e9a4692f279dc Mon Sep 17 00:00:00 2001 From: JOO200 Date: Sun, 27 Mar 2022 13:44:03 +0200 Subject: [PATCH 1/2] text-minimessage: Handle arguments for PreProcessTags correctly --- .../StringResolvingMatchedTokenConsumer.java | 22 +++++- .../minimessage/tag/PreProcessTagTest.java | 73 +++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/PreProcessTagTest.java diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/match/StringResolvingMatchedTokenConsumer.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/match/StringResolvingMatchedTokenConsumer.java index 559f45c5e..ca7664e09 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/match/StringResolvingMatchedTokenConsumer.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/match/StringResolvingMatchedTokenConsumer.java @@ -23,16 +23,23 @@ */ package net.kyori.adventure.text.minimessage.internal.parser.match; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import net.kyori.adventure.text.minimessage.internal.TagInternals; +import net.kyori.adventure.text.minimessage.internal.parser.Token; import net.kyori.adventure.text.minimessage.internal.parser.TokenParser; import net.kyori.adventure.text.minimessage.internal.parser.TokenParser.TagProvider; import net.kyori.adventure.text.minimessage.internal.parser.TokenType; +import net.kyori.adventure.text.minimessage.internal.parser.node.TagPart; import net.kyori.adventure.text.minimessage.tag.PreProcess; import net.kyori.adventure.text.minimessage.tag.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static net.kyori.adventure.text.minimessage.internal.parser.TokenParser.SEPARATOR; +import static net.kyori.adventure.text.minimessage.internal.parser.TokenParser.tokenize; + /** * A matched token consumer that produces a string and returns a copy of the string with {@link PreProcess} tags resolved. * @@ -68,12 +75,23 @@ public void accept(final int start, final int end, final @NotNull TokenType toke } else { // well, now we need to work out if it's a tag or a placeholder! final String match = this.input.substring(start, end); - final String tag = this.input.substring(start + 1, end - 1); + final String cleanup = this.input.substring(start + 1, end - 1); + + final int index = cleanup.indexOf(SEPARATOR); + final String tag = index == -1 ? cleanup : cleanup.substring(0, index); // we might care if it's a valid tag! if (TagInternals.sanitizeAndCheckValidTagName(tag)) { + final List tokens = tokenize(match); + final List parts = new ArrayList<>(); + final List childs = tokens.isEmpty() ? null : tokens.get(0).childTokens(); + if (childs != null) { + for (int i = 1; i < childs.size(); i++) { + parts.add(new TagPart(match, childs.get(i), this.tagProvider)); + } + } // we might care if it's a pre-process! - final @Nullable Tag replacement = this.tagProvider.resolve(TokenParser.TagProvider.sanitizePlaceholderName(tag)); + final @Nullable Tag replacement = this.tagProvider.resolve(TokenParser.TagProvider.sanitizePlaceholderName(tag), parts, tokens.get(0)); if (replacement instanceof PreProcess) { this.builder.append(Objects.requireNonNull(((PreProcess) replacement).value(), "PreProcess replacements cannot return null")); diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/PreProcessTagTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/PreProcessTagTest.java new file mode 100644 index 000000000..c04e2c0b1 --- /dev/null +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/PreProcessTagTest.java @@ -0,0 +1,73 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2022 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.minimessage.tag; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.AbstractTest; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.junit.jupiter.api.Test; + +import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed; + +public class PreProcessTagTest extends AbstractTest { + + @Test + void checkPreProcessTag() { + final String input = ""; + final Component expected = text("Hello! bla"); + + this.assertParsedEquals( + expected, + input, + TagResolver.resolver("test", ((argumentQueue, context) -> + Tag.preProcessParsed(argumentQueue.pop().value() + argumentQueue.pop().value()))) + ); + } + + @Test + void checkSpecialChars() { + final String input = "'>"; + final Component expected = text("::"); + + this.assertParsedEquals( + expected, + input, + TagResolver.resolver("test", ((argumentQueue, context) -> + Tag.preProcessParsed(argumentQueue.pop().value() + argumentQueue.pop().value()))) + ); + } + + @Test + void recursionTest() { + final String input = "This is !"; + final Component expected = text("This is !"); + + this.assertParsedEquals( + expected, + input, + parsed("recursion", "") + ); + } +} From 75cc158b3594d924c128887e07d9156e381aa008 Mon Sep 17 00:00:00 2001 From: JOO200 Date: Mon, 4 Apr 2022 00:09:53 +0200 Subject: [PATCH 2/2] text-minimessage: Fixed javadocs from PreProcess to allow arguments --- .../net/kyori/adventure/text/minimessage/tag/PreProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/PreProcess.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/PreProcess.java index ffafcee53..b7c810b61 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/PreProcess.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/PreProcess.java @@ -28,7 +28,7 @@ /** * A tag that is applied at the tokenization stage, before the tree is constructed. * - *

Its value must be a MiniMessage string, and cannot accept any arguments

+ *

Its value must be a MiniMessage string.

* * @since 4.10.0 */