diff --git a/api/src/main/java/net/kyori/adventure/text/Component.java b/api/src/main/java/net/kyori/adventure/text/Component.java index 6727b0b36..08ec49754 100644 --- a/api/src/main/java/net/kyori/adventure/text/Component.java +++ b/api/src/main/java/net/kyori/adventure/text/Component.java @@ -2642,6 +2642,19 @@ default boolean hasStyling() { return this.replaceText(b -> b.match(pattern).replacement(replacement).condition(fn)); } + /** + * Split an existing Component into multiple Components based on a separator. + * + *

This will return a list of Components

+ * + * @param separator a separator + * @return a list of components + * @since 4.15.0 + */ + default @NotNull List split(final @NotNull Component separator) { + return ComponentSplit.split(this, separator); + } + @Override default void componentBuilderApply(final @NotNull ComponentBuilder component) { component.append(this); diff --git a/api/src/main/java/net/kyori/adventure/text/ComponentSplit.java b/api/src/main/java/net/kyori/adventure/text/ComponentSplit.java new file mode 100644 index 000000000..c06a942aa --- /dev/null +++ b/api/src/main/java/net/kyori/adventure/text/ComponentSplit.java @@ -0,0 +1,56 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2023 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; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import net.kyori.adventure.text.format.Style; +import org.jetbrains.annotations.NotNull; + +final class ComponentSplit { + private ComponentSplit() { + } + + static @NotNull List split(final @NotNull Component self, final @NotNull Component separator) { + if (self.children().size() == 0) { + return Collections.singletonList(self); + } + + final List result = new ArrayList<>(); + final Component root = self.children(Collections.emptyList()); + TextComponent.Builder build = Component.text(); + build.append(root.style(Style.empty())); + for (final Component child : self.children()) { + if (child.equals(separator)) { + result.add(build.build().applyFallbackStyle(root.style())); + build = Component.text(); + } else { + build.append(child); + } + } + result.add(build.build().applyFallbackStyle(root.style())); + return result; + } +} diff --git a/api/src/test/java/net/kyori/adventure/text/ComponentSplitTest.java b/api/src/test/java/net/kyori/adventure/text/ComponentSplitTest.java new file mode 100644 index 000000000..ce6459e54 --- /dev/null +++ b/api/src/test/java/net/kyori/adventure/text/ComponentSplitTest.java @@ -0,0 +1,55 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2023 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; + +import java.util.Arrays; +import java.util.List; +import net.kyori.adventure.text.format.NamedTextColor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ComponentSplitTest { + @Test + public void testSimple() { + final Component example = Component.text("first", NamedTextColor.RED).appendNewline().append(Component.text("second")); + final List expected = Arrays.asList( + Component.empty().color(NamedTextColor.RED).append(Component.text("first")), + Component.empty().color(NamedTextColor.RED).append(Component.text("second")) + ); + + assertEquals(expected, example.split(Component.newline())); + } + + @Test + public void testAdvanced() { + final Component example = Component.text("first", NamedTextColor.RED).appendNewline().append(Component.text("second", NamedTextColor.BLUE)); + final List expected = Arrays.asList( + Component.empty().color(NamedTextColor.RED).append(Component.text("first")), + Component.empty().color(NamedTextColor.RED).append(Component.text("second", NamedTextColor.BLUE)) + ); + + assertEquals(expected, example.split(Component.newline())); + } +}