mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2024-11-22 10:25:41 +01:00
Add optional short format for PlaceholderAPI (e.g. %player% instead of {papi: player})
This commit is contained in:
parent
788cdc2c45
commit
5d2c97f194
@ -123,6 +123,22 @@ class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
public static String addEscapes(String string) {
|
||||
StringBuilder output = new StringBuilder(string.length() + 16); // String gets longer with escapes
|
||||
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
char currentChar = string.charAt(i);
|
||||
|
||||
if (isSpecialCharacter(currentChar)) {
|
||||
output.append(ESCAPE_CHAR);
|
||||
}
|
||||
|
||||
output.append(currentChar);
|
||||
}
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private static boolean isSpecialCharacter(char currentChar) {
|
||||
return currentChar == ESCAPE_CHAR
|
||||
|| currentChar == PLACEHOLDER_START_CHAR
|
||||
|
@ -27,6 +27,10 @@ public final class StringWithPlaceholders {
|
||||
return Parser.parse(string, true);
|
||||
}
|
||||
|
||||
public static String addEscapes(@NotNull String string) {
|
||||
return Parser.addEscapes(string);
|
||||
}
|
||||
|
||||
StringWithPlaceholders(@NotNull String string, @Nullable List<Part> parts) {
|
||||
this.string = string;
|
||||
this.parts = parts;
|
||||
@ -71,7 +75,7 @@ public final class StringWithPlaceholders {
|
||||
return replace(player, replaceFunction, StringReplaceFunction.NO_REPLACEMENTS);
|
||||
}
|
||||
|
||||
public @NotNull String replaceStrings(StringReplaceFunction replaceFunction) {
|
||||
public @NotNull String replaceOutsidePlaceholders(StringReplaceFunction replaceFunction) {
|
||||
return replace(null, PlaceholderReplaceFunction.NO_REPLACEMENTS, replaceFunction);
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ class StringWithPlaceholdersTest {
|
||||
Arguments.of(" {p} ", " # "),
|
||||
Arguments.of("{p} {p} {p}", "# # #"),
|
||||
Arguments.of("{{p}}", "{#}"), // Only the innermost placeholder should be replaced
|
||||
Arguments.of("{{p}", "{#"),
|
||||
Arguments.of("{p}}", "#}"),
|
||||
Arguments.of("{p abc", "{p abc"), // Placeholder without closing tag
|
||||
Arguments.of("abc p}", "abc p}") // Placeholder without opening tag
|
||||
);
|
||||
@ -46,7 +48,7 @@ class StringWithPlaceholdersTest {
|
||||
@MethodSource("replaceLiteralPartsTestArguments")
|
||||
void replaceLiteralParts(String input, String expectedOutput) {
|
||||
StringWithPlaceholders s = StringWithPlaceholders.of(input);
|
||||
assertThat(s.replaceStrings(literalPart -> "_")).isEqualTo(expectedOutput);
|
||||
assertThat(s.replaceOutsidePlaceholders(literalPart -> "_")).isEqualTo(expectedOutput);
|
||||
}
|
||||
|
||||
static Stream<Arguments> replaceLiteralPartsTestArguments() {
|
||||
@ -112,7 +114,7 @@ class StringWithPlaceholdersTest {
|
||||
@ParameterizedTest(name = "[{index}] {0} -> {0}")
|
||||
@MethodSource("escapesTestArguments")
|
||||
void preservingEscapes(String input) {
|
||||
String output = StringWithPlaceholders.withEscapes(input).replaceStrings(StringReplaceFunction.NO_REPLACEMENTS);
|
||||
String output = StringWithPlaceholders.withEscapes(input).replaceOutsidePlaceholders(StringReplaceFunction.NO_REPLACEMENTS);
|
||||
assertThat(output).isEqualTo(input);
|
||||
}
|
||||
|
||||
@ -133,4 +135,10 @@ class StringWithPlaceholdersTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addEscapes() {
|
||||
String escaped = StringWithPlaceholders.addEscapes("} { \\");
|
||||
assertThat(escaped).isEqualTo("\\} \\{ \\\\");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,22 +8,25 @@ package me.filoghost.holographicdisplays.plugin.config;
|
||||
import me.filoghost.fcommons.Colors;
|
||||
import me.filoghost.fcommons.MaterialsHelper;
|
||||
import me.filoghost.fcommons.Strings;
|
||||
import me.filoghost.holographicdisplays.core.placeholder.parsing.StringWithPlaceholders;
|
||||
import me.filoghost.holographicdisplays.plugin.format.DisplayFormat;
|
||||
import me.filoghost.holographicdisplays.plugin.internal.hologram.InternalHologramLine;
|
||||
import me.filoghost.holographicdisplays.plugin.internal.hologram.ItemInternalHologramLine;
|
||||
import me.filoghost.holographicdisplays.plugin.internal.hologram.TextInternalHologramLine;
|
||||
import me.filoghost.holographicdisplays.plugin.lib.nbt.parser.MojangsonParseException;
|
||||
import me.filoghost.holographicdisplays.plugin.lib.nbt.parser.MojangsonParser;
|
||||
import me.filoghost.holographicdisplays.core.placeholder.parsing.StringWithPlaceholders;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class InternalHologramLineParser {
|
||||
|
||||
private static final String ICON_PREFIX = "icon:";
|
||||
private static final Pattern PLACEHOLDER_API_SHORT_FORMAT = Pattern.compile("%(.+?)%");
|
||||
|
||||
public static InternalHologramLine parseLine(String serializedLine) throws InternalHologramLoadException {
|
||||
if (serializedLine.toLowerCase(Locale.ROOT).startsWith(ICON_PREFIX)) {
|
||||
@ -32,13 +35,42 @@ public class InternalHologramLineParser {
|
||||
return new ItemInternalHologramLine(serializedLine, icon);
|
||||
|
||||
} else {
|
||||
String displayText = DisplayFormat.apply(serializedLine, false);
|
||||
// Apply colors only outside placeholders
|
||||
displayText = StringWithPlaceholders.withEscapes(displayText).replaceStrings(Colors::colorize);
|
||||
String displayText = parseText(serializedLine);
|
||||
return new TextInternalHologramLine(serializedLine, displayText);
|
||||
}
|
||||
}
|
||||
|
||||
protected static String parseText(String serializedLine) {
|
||||
String displayText = DisplayFormat.apply(serializedLine, false);
|
||||
if (Settings.placeholderAPIExpandShortFormat) {
|
||||
displayText = expandPlaceholderAPIShortFormat(displayText);
|
||||
}
|
||||
// Apply colors only outside placeholders
|
||||
displayText = StringWithPlaceholders.withEscapes(displayText).replaceOutsidePlaceholders(Colors::colorize);
|
||||
return displayText;
|
||||
}
|
||||
|
||||
private static String expandPlaceholderAPIShortFormat(String text) {
|
||||
Matcher matcher = PLACEHOLDER_API_SHORT_FORMAT.matcher(text);
|
||||
boolean foundMatch = matcher.find();
|
||||
|
||||
if (!foundMatch) {
|
||||
return text;
|
||||
}
|
||||
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
while (foundMatch) {
|
||||
String placeholderContent = matcher.group(1);
|
||||
matcher.appendReplacement(result, "");
|
||||
result.append("{papi: ").append(StringWithPlaceholders.addEscapes(placeholderContent)).append("}");
|
||||
foundMatch = matcher.find();
|
||||
}
|
||||
|
||||
matcher.appendTail(result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static ItemStack parseItemStack(String serializedItem) throws InternalHologramLoadException {
|
||||
serializedItem = serializedItem.trim();
|
||||
|
@ -26,6 +26,7 @@ public class Settings {
|
||||
public static boolean updateNotification;
|
||||
|
||||
public static boolean placeholderAPIEnabled;
|
||||
public static boolean placeholderAPIExpandShortFormat;
|
||||
public static int placeholderAPIDefaultRefreshInternalTicks;
|
||||
|
||||
public static String imageSymbol;
|
||||
@ -49,6 +50,7 @@ public class Settings {
|
||||
updateNotification = config.updateNotification;
|
||||
|
||||
placeholderAPIEnabled = config.placeholderAPIEnabled;
|
||||
placeholderAPIExpandShortFormat = config.placeholderAPIShortFormat;
|
||||
placeholderAPIDefaultRefreshInternalTicks = config.placeholderAPIDefaultRefreshIntervalTicks;
|
||||
|
||||
imageSymbol = DisplayFormat.apply(config.imageRenderingSolidPixel);
|
||||
|
@ -27,6 +27,9 @@ public class SettingsModel implements MappedConfig {
|
||||
@Path("placeholders.PlaceholderAPI.enabled")
|
||||
boolean placeholderAPIEnabled = true;
|
||||
|
||||
@Path("placeholders.PlaceholderAPI.expand-short-format")
|
||||
boolean placeholderAPIShortFormat = true;
|
||||
|
||||
@Path("placeholders.PlaceholderAPI.default-refresh-interval-ticks")
|
||||
int placeholderAPIDefaultRefreshIntervalTicks = 200;
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.plugin.config;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
class InternalHologramLineParserTest {
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0} -> {1}")
|
||||
@MethodSource({"parseTextArguments"})
|
||||
void parseText(String input, String expectedOutput) {
|
||||
Settings.placeholderAPIExpandShortFormat = true;
|
||||
String output = InternalHologramLineParser.parseText(input);
|
||||
assertThat(output).isEqualTo(expectedOutput);
|
||||
}
|
||||
|
||||
static Stream<Arguments> parseTextArguments() {
|
||||
return Stream.of(
|
||||
// PlaceholderAPI replacing and escaping
|
||||
Arguments.of("test1 %test2% test3", "test1 {papi: test2} test3"),
|
||||
Arguments.of("%&0colored%", "{papi: &0colored}"),
|
||||
Arguments.of("%test1% {test2} %test3%", "{papi: test1} {test2} {papi: test3}"),
|
||||
Arguments.of("%test_{escape\\this}%", "{papi: test_\\{escape\\\\this\\}}"),
|
||||
Arguments.of("%t{e%s}t", "{papi: t\\{e}s}t"),
|
||||
Arguments.of("{inside %placeholder%}", "{inside {papi: placeholder}}"),
|
||||
Arguments.of("\\{keep escapes\\}", "\\{keep escapes\\}"),
|
||||
Arguments.of("single % symbol", "single % symbol"),
|
||||
|
||||
// Placeholders and colors
|
||||
Arguments.of("&0 {p: &0}", ChatColor.COLOR_CHAR + "0 {p: &0}")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user