From e90bcb53565bbf17ad9341c9eb1343fb2450008e Mon Sep 17 00:00:00 2001
From: tahmid-23 <60953955+tahmid-23@users.noreply.github.com>
Date: Sun, 25 Jun 2023 18:17:52 -0400
Subject: [PATCH 1/4] add Formatter#join
---
.../minimessage/tag/resolver/Formatter.java | 49 +++++++++++++++++++
.../text/minimessage/tag/FormatterTest.java | 18 +++++++
2 files changed, 67 insertions(+)
diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
index d0bf61a27..2f626eaea 100644
--- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
+++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
@@ -29,7 +29,12 @@
import java.text.NumberFormat;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
+import java.util.Arrays;
import java.util.Locale;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.ComponentLike;
+import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.TagPattern;
import org.jetbrains.annotations.NotNull;
@@ -139,4 +144,48 @@ public static TagResolver booleanChoice(@TagPattern final @NotNull String key, f
return Tag.inserting(context.deserialize(value ? trueCase : falseCase));
});
}
+
+ /**
+ * Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
+ *
+ *
This tag expects a separator as the first argument. A last separator may optionally be provided.
+ *
+ * This replacement is auto-closing, so its style will not influence the style of following components.
+ *
+ * @param key the key
+ * @param components the components to join
+ * @return the placeholder
+ * @since 4.14.0
+ */
+ public static TagResolver join(@TagPattern final @NotNull String key, final @NotNull Iterable extends ComponentLike> components) {
+ return TagResolver.resolver(key, (argumentQueue, context) -> {
+ final String separator = argumentQueue.popOr("Separator expected.").value();
+ final JoinConfiguration.Builder configBuilder = JoinConfiguration.builder().separator(context.deserialize(separator));
+
+ if (argumentQueue.hasNext()) {
+ final String lastSeparator = argumentQueue.pop().value();
+ configBuilder.lastSeparator(context.deserialize(lastSeparator));
+ }
+
+ JoinConfiguration config = configBuilder.build();
+ return Tag.inserting(Component.join(config, components));
+ });
+ }
+
+ /**
+ * Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
+ *
+ * This tag expects a separator as the first argument. A last separator may optionally be provided.
+ *
+ * This replacement is auto-closing, so its style will not influence the style of following components.
+ *
+ * @param key the key
+ * @param components the components to join
+ * @return the placeholder
+ * @since 4.14.0
+ */
+ public static TagResolver join(@TagPattern final @NotNull String key, final @NotNull ComponentLike@NotNull... components) {
+ return join(key, Arrays.asList(components));
+ }
+
}
diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
index b37de3b39..828310568 100644
--- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
+++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
@@ -25,7 +25,10 @@
import java.time.LocalDateTime;
import java.time.Month;
+import java.util.Arrays;
+
import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.AbstractTest;
import org.junit.jupiter.api.Test;
@@ -34,6 +37,7 @@
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.booleanChoice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.choice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.date;
+import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.join;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.number;
public class FormatterTest extends AbstractTest {
@@ -125,4 +129,18 @@ void testBooleanChoice() {
final Component expected = text("bah");
this.assertParsedEquals(expected, input, booleanChoice("first", true), booleanChoice("second", true), booleanChoice("third", true));
}
+
+ @Test
+ void testJoinSeparator() {
+ final String input = "";
+ final Component expected = Component.join(JoinConfiguration.separator(text(", ")), Arrays.asList(text("one"), text("two"), text("three")));
+ this.assertParsedEquals(expected, input, join("list", text("one"), text("two"), text("three")));
+ }
+
+ @Test
+ void testJoinSeparatorWithLastSeparator() {
+ final String input = "";
+ final Component expected = Component.join(JoinConfiguration.separators(text(", "), text(" and ")), Arrays.asList(text("one"), text("two"), text("three")));
+ this.assertParsedEquals(expected, input, join("list", text("one"), text("two"), text("three")));
+ }
}
From c2a11b2ed9d7f32337687dd4d3278bf1fdd93e9f Mon Sep 17 00:00:00 2001
From: tahmid-23 <60953955+tahmid-23@users.noreply.github.com>
Date: Sun, 25 Jun 2023 18:43:23 -0400
Subject: [PATCH 2/4] correct version, join -> joining, checkstyle fixes
---
.../text/minimessage/tag/resolver/Formatter.java | 13 ++++++-------
.../text/minimessage/tag/FormatterTest.java | 7 +++----
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
index 2f626eaea..ad3915c5e 100644
--- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
+++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
@@ -31,7 +31,6 @@
import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
import java.util.Locale;
-
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.JoinConfiguration;
@@ -155,9 +154,9 @@ public static TagResolver booleanChoice(@TagPattern final @NotNull String key, f
* @param key the key
* @param components the components to join
* @return the placeholder
- * @since 4.14.0
+ * @since 4.15.0
*/
- public static TagResolver join(@TagPattern final @NotNull String key, final @NotNull Iterable extends ComponentLike> components) {
+ public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull Iterable extends ComponentLike> components) {
return TagResolver.resolver(key, (argumentQueue, context) -> {
final String separator = argumentQueue.popOr("Separator expected.").value();
final JoinConfiguration.Builder configBuilder = JoinConfiguration.builder().separator(context.deserialize(separator));
@@ -167,7 +166,7 @@ public static TagResolver join(@TagPattern final @NotNull String key, final @Not
configBuilder.lastSeparator(context.deserialize(lastSeparator));
}
- JoinConfiguration config = configBuilder.build();
+ final JoinConfiguration config = configBuilder.build();
return Tag.inserting(Component.join(config, components));
});
}
@@ -182,10 +181,10 @@ public static TagResolver join(@TagPattern final @NotNull String key, final @Not
* @param key the key
* @param components the components to join
* @return the placeholder
- * @since 4.14.0
+ * @since 4.15.0
*/
- public static TagResolver join(@TagPattern final @NotNull String key, final @NotNull ComponentLike@NotNull... components) {
- return join(key, Arrays.asList(components));
+ public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull ComponentLike@NotNull... components) {
+ return joining(key, Arrays.asList(components));
}
}
diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
index 828310568..97d86dc69 100644
--- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
+++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
@@ -26,7 +26,6 @@
import java.time.LocalDateTime;
import java.time.Month;
import java.util.Arrays;
-
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -37,7 +36,7 @@
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.booleanChoice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.choice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.date;
-import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.join;
+import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.joining;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.number;
public class FormatterTest extends AbstractTest {
@@ -134,13 +133,13 @@ void testBooleanChoice() {
void testJoinSeparator() {
final String input = "";
final Component expected = Component.join(JoinConfiguration.separator(text(", ")), Arrays.asList(text("one"), text("two"), text("three")));
- this.assertParsedEquals(expected, input, join("list", text("one"), text("two"), text("three")));
+ this.assertParsedEquals(expected, input, joining("list", text("one"), text("two"), text("three")));
}
@Test
void testJoinSeparatorWithLastSeparator() {
final String input = "";
final Component expected = Component.join(JoinConfiguration.separators(text(", "), text(" and ")), Arrays.asList(text("one"), text("two"), text("three")));
- this.assertParsedEquals(expected, input, join("list", text("one"), text("two"), text("three")));
+ this.assertParsedEquals(expected, input, joining("list", text("one"), text("two"), text("three")));
}
}
From 40fa72aed66b9763648e65d76f27a7053dd4da35 Mon Sep 17 00:00:00 2001
From: tahmid-23 <60953955+tahmid-23@users.noreply.github.com>
Date: Sun, 16 Jul 2023 14:40:27 -0400
Subject: [PATCH 3/4] lastSeparatorIfSerial argument
---
.../minimessage/tag/resolver/Formatter.java | 5 ++++
.../text/minimessage/tag/FormatterTest.java | 27 ++++++++++++++++---
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
index ad3915c5e..9edf0fc37 100644
--- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
+++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
@@ -166,6 +166,11 @@ public static TagResolver joining(@TagPattern final @NotNull String key, final @
configBuilder.lastSeparator(context.deserialize(lastSeparator));
}
+ if (argumentQueue.hasNext()) {
+ final String lastSeparatorIfSerial = argumentQueue.pop().value();
+ configBuilder.lastSeparatorIfSerial(context.deserialize(lastSeparatorIfSerial));
+ }
+
final JoinConfiguration config = configBuilder.build();
return Tag.inserting(Component.join(config, components));
});
diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
index 97d86dc69..8d491dca3 100644
--- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
+++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/FormatterTest.java
@@ -132,14 +132,33 @@ void testBooleanChoice() {
@Test
void testJoinSeparator() {
final String input = "";
- final Component expected = Component.join(JoinConfiguration.separator(text(", ")), Arrays.asList(text("one"), text("two"), text("three")));
- this.assertParsedEquals(expected, input, joining("list", text("one"), text("two"), text("three")));
+ final Iterable extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
+ final Component expected = Component.join(JoinConfiguration.separator(text(", ")), components);
+ this.assertParsedEquals(expected, input, joining("list", components));
}
@Test
void testJoinSeparatorWithLastSeparator() {
final String input = "";
- final Component expected = Component.join(JoinConfiguration.separators(text(", "), text(" and ")), Arrays.asList(text("one"), text("two"), text("three")));
- this.assertParsedEquals(expected, input, joining("list", text("one"), text("two"), text("three")));
+ final Iterable extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
+ final Component expected = Component.join(JoinConfiguration.separators(text(", "), text(" and ")), components);
+ this.assertParsedEquals(expected, input, joining("list", components));
}
+
+ @Test
+ void testJoinSeparatorWithLastSeparatorIfSerialAndManyComponents() {
+ final String input = "";
+ final Iterable extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
+ final Component expected = Component.join(JoinConfiguration.builder().separator(text(", ")).lastSeparator(text(" and ")).lastSeparatorIfSerial(text(", and ")), components);
+ this.assertParsedEquals(expected, input, joining("list", components));
+ }
+
+ @Test
+ void testJoinSeparatorWithLastSeparatorIfSerialAndTwoComponents() {
+ final String input = "";
+ final Iterable extends Component> components = Arrays.asList(text("one"), text("two"));
+ final Component expected = Component.join(JoinConfiguration.builder().separator(text(", ")).lastSeparator(text(" and ")).lastSeparatorIfSerial(text(", and ")), components);
+ this.assertParsedEquals(expected, input, joining("list", components));
+ }
+
}
From 73c9e85256b245493f0f454c071afc4b98cb1972 Mon Sep 17 00:00:00 2001
From: Kieran Wallbanks
Date: Wed, 30 Oct 2024 17:33:09 +0000
Subject: [PATCH 4/4] Update docs and make the first separator optional
---
.../minimessage/tag/resolver/Formatter.java | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
index 9edf0fc37..dbeeae4e2 100644
--- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
+++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java
@@ -147,18 +147,25 @@ public static TagResolver booleanChoice(@TagPattern final @NotNull String key, f
/**
* Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
*
- * This tag expects a separator as the first argument. A last separator may optionally be provided.
+ * This tag has three optional arguments; a separator, a last separator, and a last separator if serial.
+ * Each argument must be provided in order, with all preceding arguments present.
+ * The exact use of these three separators is documented in {@link JoinConfiguration}.
*
* This replacement is auto-closing, so its style will not influence the style of following components.
*
* @param key the key
* @param components the components to join
* @return the placeholder
- * @since 4.15.0
+ * @see JoinConfiguration
+ * @since 4.18.0
*/
public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull Iterable extends ComponentLike> components) {
return TagResolver.resolver(key, (argumentQueue, context) -> {
- final String separator = argumentQueue.popOr("Separator expected.").value();
+ if (!argumentQueue.hasNext()) {
+ return Tag.inserting(Component.join(JoinConfiguration.noSeparators(), components));
+ }
+
+ final String separator = argumentQueue.pop().value();
final JoinConfiguration.Builder configBuilder = JoinConfiguration.builder().separator(context.deserialize(separator));
if (argumentQueue.hasNext()) {
@@ -179,14 +186,17 @@ public static TagResolver joining(@TagPattern final @NotNull String key, final @
/**
* Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
*
- * This tag expects a separator as the first argument. A last separator may optionally be provided.
+ * This tag has three optional arguments; a separator, a last separator, and a last separator if serial.
+ * Each argument must be provided in order, with all preceding arguments present.
+ * The exact use of these three separators is documented in {@link JoinConfiguration}.
*
* This replacement is auto-closing, so its style will not influence the style of following components.
*
* @param key the key
* @param components the components to join
* @return the placeholder
- * @since 4.15.0
+ * @see JoinConfiguration
+ * @since 4.18.0
*/
public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull ComponentLike@NotNull... components) {
return joining(key, Arrays.asList(components));