Skip to content

Commit 30009ba

Browse files
committed
Some documentation about text tags, fix gradient
1 parent 6b2b0ed commit 30009ba

4 files changed

Lines changed: 169 additions & 80 deletions

File tree

TEXT_FORMATTING.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# About tags/TextParser
2+
TextParser is a small utility for allowing user to create Text Components in simpler way.
3+
It works in similar way to HTML, however it's structure has some differences.
4+
Tags have structure of `<tag_name>` or `<tag_name:argument>`. Most of tags needs to be closed by using `</tag_name>`,
5+
but there are exceptions from this (which is noted below). Argument can be any string, but it should be
6+
wrapped with `'` symbol (otherwise it might break way more). Additionally, all `:` within it should be escaped with `\` symbol (`\:`)
7+
8+
# List of formatting tags
9+
- \<yellow> - Changes text color to yellow,
10+
- \<dark_blue> - Changes text color to dark blue,
11+
- \<dark_purple> - Changes text color to dark purple,
12+
- \<gold> - Changes text color to gold,
13+
- \<red> - Changes text color to red,
14+
- \<aqua> - Changes text color to aqua,
15+
- \<gray> - Changes text color to gray,
16+
- \<light_purple> - Changes text color to light purple,
17+
- \<white> - Changes text color to white,
18+
- \<dark_gray> - Changes text color to dark gray,
19+
- \<green> - Changes text color to green,
20+
- \<dark_green> - Changes text color to dark green,
21+
- \<blue> - Changes text color to blue,
22+
- \<dark_aqua> - Changes text color to dark aqua,
23+
- \<dark_green> - Changes text color to dark green,
24+
- \<black> - Changes text color to black,
25+
- \<color:\[color name or rgb value]> / \<c:\[arg]> - Changes text color to selected vanilla color or rgb value with `#RRGGBB` format,
26+
27+
- \<strikethrough> - Makes text strikethrough,
28+
- \<underline> - Underlines text,
29+
- \<italic> - Makes text italic,
30+
- \<obfuscated> - Obfuscates text (matrix effect),
31+
- \<bold> - Makes text bold,
32+
33+
- \<click:event_name:'value'> - Adds click even to text (see vanilla [click events here](https://minecraft.fandom.com/wiki/Raw_JSON_text_format))
34+
- \<hover:event_name:'value'> - Adds hover information. For now only `` event is supported. Value uses the same formatting as rest
35+
- \<insert:'value'> - After clicking makes player insert text to their message,
36+
37+
- \<font:font_name> - Changes font to selected one (can be from vanilla or resource pack),
38+
- \<lang:lang_value:'optional arg 1':'optional arg 2'...> - Adds value depending on your lang file. Doesn't need closing tag,
39+
- \<key:key_name> - Adds name of clientside control key (see [values here](https://minecraft.fandom.com/wiki/Controls#Configurable_controls)). Doesn't need closing tag,
40+
41+
- \<rainbow:\[frequency]:\[saturation]:\[offset]> / \<rb:\[...]> - Makes text within it have rainbow colors (supports inner formatting). All arguments are optional (`<ranbow>` is still valid),
42+
- \<gradient:\[color 1]:\[color 2]:...> / \<gr:\[...]> - Creates a gradient, can have multiple main colors,

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ org.gradle.jvmargs=-Xmx1G
33

44
# Fabric Properties
55
# check these on https://fabricmc.net/use
6-
minecraft_version=1.17-pre1
7-
yarn_mappings=1.17-pre1+build.1
6+
minecraft_version=1.17-pre2
7+
yarn_mappings=1.17-pre2+build.1
88
loader_version=0.11.3
99

1010
# Mod Properties
11-
mod_version = 1.0.0-pre0-1.17-pre1
11+
mod_version = 1.0.0-pre1-1.17-pre2
1212
maven_group = eu.pb4
1313
archives_base_name = placeholder-api
1414

src/main/java/eu/pb4/placeholders/TextParser.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package eu.pb4.placeholders;
22

3+
import com.google.common.collect.ImmutableMap;
34
import eu.pb4.placeholders.util.TextParserUtils;
45
import net.minecraft.text.MutableText;
56
import net.minecraft.text.Text;
@@ -27,6 +28,13 @@ public static void register(String identifier, TextFormatterHandler handler) {
2728
TAGS.put(identifier, handler);
2829
}
2930

31+
/**
32+
* Returns map of registered tags
33+
*/
34+
public static ImmutableMap<String, TextFormatterHandler> getRegisteredTags() {
35+
return ImmutableMap.copyOf(TAGS);
36+
}
37+
3038
@FunctionalInterface
3139
public interface TextFormatterHandler {
3240
int parse(String tag, String data, MutableText text, String input, Map<String, TextFormatterHandler> handlers, String endAt);

src/main/java/eu/pb4/placeholders/util/TextParserUtils.java

Lines changed: 116 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.minecraft.text.*;
66
import net.minecraft.util.Formatting;
77
import net.minecraft.util.Identifier;
8+
import net.minecraft.util.math.MathHelper;
89

910
import java.util.*;
1011
import java.util.regex.Matcher;
@@ -84,9 +85,8 @@ public static int recursiveParsing(MutableText text, String input, Map<String, T
8485
String end = "</" + tag + ">";
8586

8687
TextParser.TextFormatterHandler handler = handlers.get(tag);
87-
currentPos = matcher.end();
88-
8988
if (handler != null) {
89+
currentPos = matcher.end();
9090
try {
9191
int toIgnore = handler.parse(tag, data, text, input.substring(currentPos), handlers, end);
9292
currentPos += toIgnore;
@@ -137,11 +137,16 @@ public static void register() {
137137
});
138138
}
139139

140-
TextParser.register("color", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
141-
MutableText out = new LiteralText("").fillStyle(Style.EMPTY.withColor(TextColor.parse(cleanArgument(data))));
142-
text.append(out);
143-
return recursiveParsing(out, input, handlers, endAt);
144-
});
140+
{
141+
TextParser.TextFormatterHandler color = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
142+
MutableText out = new LiteralText("").fillStyle(Style.EMPTY.withColor(TextColor.parse(cleanArgument(data))));
143+
text.append(out);
144+
return recursiveParsing(out, input, handlers, endAt);
145+
};
146+
147+
TextParser.register("color", color);
148+
TextParser.register("c", color);
149+
}
145150

146151
TextParser.register("font", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
147152
MutableText out = new LiteralText("").fillStyle(Style.EMPTY.withFont(Identifier.tryParse(cleanArgument(data))));
@@ -209,88 +214,122 @@ public static void register() {
209214
return recursiveParsing(out, input, handlers, endAt);
210215
});
211216

212-
TextParser.register("rainbow", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
213-
MutableText out = new LiteralText("");
214-
String[] val = data.split(":");
215-
float freq = 1;
216-
float saturation = 1;
217-
float offset = 0;
218-
219-
if (val.length >= 1) {
220-
try {
221-
freq = Float.parseFloat(val[0]);
222-
} catch (Exception e) {
217+
{
218+
TextParser.TextFormatterHandler rainbow = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
219+
MutableText out = new LiteralText("");
220+
String[] val = data.split(":");
221+
float freq = 1;
222+
float saturation = 1;
223+
float offset = 0;
224+
225+
if (val.length >= 1) {
226+
try {
227+
freq = Float.parseFloat(val[0]);
228+
} catch (Exception e) {
229+
}
223230
}
224-
}
225-
if (val.length >= 2) {
226-
try {
227-
saturation = Float.parseFloat(val[1]);
228-
} catch (Exception e) {
231+
if (val.length >= 2) {
232+
try {
233+
saturation = Float.parseFloat(val[1]);
234+
} catch (Exception e) {
235+
}
229236
}
230-
}
231-
if (val.length >= 3) {
232-
try {
233-
offset = Float.parseFloat(val[2]);
234-
} catch (Exception e) {
237+
if (val.length >= 3) {
238+
try {
239+
offset = Float.parseFloat(val[2]);
240+
} catch (Exception e) {
241+
}
235242
}
236-
}
237243

238-
int toIgnore = recursiveParsing(out, input, handlers, endAt);
239-
String flatString = GeneralUtils.textToString(out);
244+
int toIgnore = recursiveParsing(out, input, handlers, endAt);
245+
String flatString = GeneralUtils.textToString(out);
240246

241-
final float finalFreq = freq;
242-
final float finalOffset = offset;
243-
final float finalSaturation = saturation;
247+
final float finalFreq = freq;
248+
final float finalOffset = offset;
249+
final float finalSaturation = saturation;
244250

245-
text.append(GeneralUtils.toGradient(out, (pos) -> TextColor.fromRgb(GeneralUtils.hvsToRgb(((pos * finalFreq) / (flatString.length() + 1) + finalOffset) % 1, finalSaturation, 1))));
251+
text.append(GeneralUtils.toGradient(out, (pos) -> TextColor.fromRgb(GeneralUtils.hvsToRgb(((pos * finalFreq) / (flatString.length() + 1) + finalOffset) % 1, finalSaturation, 1))));
246252

247-
return toIgnore;
248-
});
253+
return toIgnore;
254+
};
249255

250-
TextParser.register("gradient", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
251-
MutableText out = new LiteralText("");
252-
String[] val = data.split(":");
253-
254-
int toIgnore = recursiveParsing(out, input, handlers, endAt);
255-
String flatString = GeneralUtils.textToString(out);
256-
List<TextColor> textColors = new ArrayList<>();
257-
for (String string : val) {
258-
TextColor color = TextColor.parse(string);
259-
if (color != null) {
260-
textColors.add(color);
261-
}
262-
}
256+
TextParser.register("rainbow", rainbow);
257+
TextParser.register("rb", rainbow);
258+
}
263259

264-
final double step = ((double) textColors.size() - 1) / flatString.length();
265-
final int sectionSize = (textColors.size() - 1) / (flatString.length() + 1);
266-
267-
GeneralUtils.HSV hsv = GeneralUtils.rgbToHsv(textColors.get(0).getRgb());
268-
AtomicDouble hue = new AtomicDouble(hsv.h());
269-
AtomicDouble saturation = new AtomicDouble(hsv.s());
270-
AtomicDouble value = new AtomicDouble(hsv.v());
271-
272-
text.append(GeneralUtils.toGradient(out, (pos) -> {
273-
GeneralUtils.HSV colorA = GeneralUtils.rgbToHsv(textColors.get(pos * sectionSize).getRgb());
274-
GeneralUtils.HSV colorB = GeneralUtils.rgbToHsv(textColors.get(pos * sectionSize + 1).getRgb());
275-
float sym = Math.abs(colorB.h() - colorA.h()) > Math.abs(colorA.h() - colorB.h()) ? -1 : 1;
276-
float h = colorB.h() - colorA.h();
277-
float delta = (h + ((Math.abs(h) > 0.5) ? ((h < 0) ? 1 : -1) : 0));
278-
279-
float localHue = (float) hue.get();
280-
float futureHue = (float) (localHue + delta * step);
281-
if (futureHue < 0) {
282-
futureHue += 1;
260+
{
261+
TextParser.TextFormatterHandler gradient = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
262+
MutableText out = new LiteralText("");
263+
String[] val = data.split(":");
264+
265+
int toIgnore = recursiveParsing(out, input, handlers, endAt);
266+
String flatString = GeneralUtils.textToString(out);
267+
List<TextColor> textColors = new ArrayList<>();
268+
for (String string : val) {
269+
TextColor color = TextColor.parse(string);
270+
if (color != null) {
271+
textColors.add(color);
272+
}
273+
}
274+
if (textColors.size() == 0) {
275+
textColors.add(TextColor.fromFormatting(Formatting.WHITE));
276+
textColors.add(TextColor.fromFormatting(Formatting.WHITE));
277+
} else if (textColors.size() == 1) {
278+
textColors.add(textColors.get(0));
283279
}
284-
hue.set(futureHue);
285280

286-
return TextColor.fromRgb(GeneralUtils.hvsToRgb(
287-
localHue,
288-
(float) saturation.getAndAdd((colorB.s() - colorA.s()) * step),
289-
(float) value.getAndAdd((colorB.v() - colorA.v()) * step)));
290-
}));
281+
final double step = ((double) textColors.size() - 1) / flatString.length();
282+
final float sectionSize = ((float) textColors.size() - 1) / (flatString.length() + 1);
291283

292-
return toIgnore;
293-
});
284+
GeneralUtils.HSV hsv = GeneralUtils.rgbToHsv(textColors.get(0).getRgb());
285+
AtomicDouble hue = new AtomicDouble(hsv.h());
286+
AtomicDouble saturation = new AtomicDouble(hsv.s());
287+
AtomicDouble value = new AtomicDouble(hsv.v());
288+
289+
text.append(GeneralUtils.toGradient(out, (pos) -> {
290+
GeneralUtils.HSV colorA = GeneralUtils.rgbToHsv(textColors.get((int) (pos * sectionSize)).getRgb());
291+
GeneralUtils.HSV colorB = GeneralUtils.rgbToHsv(textColors.get((int) (pos * sectionSize) + 1).getRgb());
292+
293+
float localHue = (float) hue.get();
294+
{
295+
float h = colorB.h() - colorA.h();
296+
float delta = (h + ((Math.abs(h) > 0.50001) ? ((h < 0) ? 1 : -1) : 0));
297+
298+
float futureHue = (float) (localHue + delta * step);
299+
if (futureHue < 0) {
300+
futureHue += 1;
301+
} else if (futureHue > 1) {
302+
futureHue -= 1;
303+
}
304+
hue.set(futureHue);
305+
}
306+
307+
float localSat = (float) saturation.get();
308+
{
309+
float s = colorB.s() - colorA.s();
310+
float futureSat = MathHelper.clamp((float) (localSat + s * step), 0, 1);
311+
saturation.set(futureSat);
312+
}
313+
314+
float localVal = (float) value.get();
315+
{
316+
float v = colorB.v() - colorA.v();
317+
float futureVal = MathHelper.clamp((float) (localVal + v * step), 0, 1);
318+
value.set(futureVal);
319+
}
320+
321+
return TextColor.fromRgb(GeneralUtils.hvsToRgb(
322+
localHue,
323+
localSat,
324+
localVal));
325+
}));
326+
327+
return toIgnore;
328+
};
329+
330+
TextParser.register("gradient", gradient);
331+
TextParser.register("gr", gradient);
332+
}
294333

295334
ESCAPED_CHARS.put("\\\\", "&slsh;");
296335
ESCAPED_CHARS.put("\\<", "&lt;");

0 commit comments

Comments
 (0)