Skip to content

Commit

Permalink
Some documentation about text tags, fix gradient
Browse files Browse the repository at this point in the history
  • Loading branch information
Patbox committed May 31, 2021
1 parent 6b2b0ed commit 30009ba
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 80 deletions.
42 changes: 42 additions & 0 deletions TEXT_FORMATTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# About tags/TextParser
TextParser is a small utility for allowing user to create Text Components in simpler way.
It works in similar way to HTML, however it's structure has some differences.
Tags have structure of `<tag_name>` or `<tag_name:argument>`. Most of tags needs to be closed by using `</tag_name>`,
but there are exceptions from this (which is noted below). Argument can be any string, but it should be
wrapped with `'` symbol (otherwise it might break way more). Additionally, all `:` within it should be escaped with `\` symbol (`\:`)

# List of formatting tags
- \<yellow> - Changes text color to yellow,
- \<dark_blue> - Changes text color to dark blue,
- \<dark_purple> - Changes text color to dark purple,
- \<gold> - Changes text color to gold,
- \<red> - Changes text color to red,
- \<aqua> - Changes text color to aqua,
- \<gray> - Changes text color to gray,
- \<light_purple> - Changes text color to light purple,
- \<white> - Changes text color to white,
- \<dark_gray> - Changes text color to dark gray,
- \<green> - Changes text color to green,
- \<dark_green> - Changes text color to dark green,
- \<blue> - Changes text color to blue,
- \<dark_aqua> - Changes text color to dark aqua,
- \<dark_green> - Changes text color to dark green,
- \<black> - Changes text color to black,
- \<color:\[color name or rgb value]> / \<c:\[arg]> - Changes text color to selected vanilla color or rgb value with `#RRGGBB` format,

- \<strikethrough> - Makes text strikethrough,
- \<underline> - Underlines text,
- \<italic> - Makes text italic,
- \<obfuscated> - Obfuscates text (matrix effect),
- \<bold> - Makes text bold,

- \<click:event_name:'value'> - Adds click even to text (see vanilla [click events here](https://minecraft.fandom.com/wiki/Raw_JSON_text_format))
- \<hover:event_name:'value'> - Adds hover information. For now only `` event is supported. Value uses the same formatting as rest
- \<insert:'value'> - After clicking makes player insert text to their message,

- \<font:font_name> - Changes font to selected one (can be from vanilla or resource pack),
- \<lang:lang_value:'optional arg 1':'optional arg 2'...> - Adds value depending on your lang file. Doesn't need closing tag,
- \<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,

- \<rainbow:\[frequency]:\[saturation]:\[offset]> / \<rb:\[...]> - Makes text within it have rainbow colors (supports inner formatting). All arguments are optional (`<ranbow>` is still valid),
- \<gradient:\[color 1]:\[color 2]:...> / \<gr:\[...]> - Creates a gradient, can have multiple main colors,
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ org.gradle.jvmargs=-Xmx1G

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

# Mod Properties
mod_version = 1.0.0-pre0-1.17-pre1
mod_version = 1.0.0-pre1-1.17-pre2
maven_group = eu.pb4
archives_base_name = placeholder-api

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/eu/pb4/placeholders/TextParser.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.pb4.placeholders;

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

/**
* Returns map of registered tags
*/
public static ImmutableMap<String, TextFormatterHandler> getRegisteredTags() {
return ImmutableMap.copyOf(TAGS);
}

@FunctionalInterface
public interface TextFormatterHandler {
int parse(String tag, String data, MutableText text, String input, Map<String, TextFormatterHandler> handlers, String endAt);
Expand Down
193 changes: 116 additions & 77 deletions src/main/java/eu/pb4/placeholders/util/TextParserUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.minecraft.text.*;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;

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

TextParser.TextFormatterHandler handler = handlers.get(tag);
currentPos = matcher.end();

if (handler != null) {
currentPos = matcher.end();
try {
int toIgnore = handler.parse(tag, data, text, input.substring(currentPos), handlers, end);
currentPos += toIgnore;
Expand Down Expand Up @@ -137,11 +137,16 @@ public static void register() {
});
}

TextParser.register("color", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("").fillStyle(Style.EMPTY.withColor(TextColor.parse(cleanArgument(data))));
text.append(out);
return recursiveParsing(out, input, handlers, endAt);
});
{
TextParser.TextFormatterHandler color = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("").fillStyle(Style.EMPTY.withColor(TextColor.parse(cleanArgument(data))));
text.append(out);
return recursiveParsing(out, input, handlers, endAt);
};

TextParser.register("color", color);
TextParser.register("c", color);
}

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

TextParser.register("rainbow", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("");
String[] val = data.split(":");
float freq = 1;
float saturation = 1;
float offset = 0;

if (val.length >= 1) {
try {
freq = Float.parseFloat(val[0]);
} catch (Exception e) {
{
TextParser.TextFormatterHandler rainbow = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("");
String[] val = data.split(":");
float freq = 1;
float saturation = 1;
float offset = 0;

if (val.length >= 1) {
try {
freq = Float.parseFloat(val[0]);
} catch (Exception e) {
}
}
}
if (val.length >= 2) {
try {
saturation = Float.parseFloat(val[1]);
} catch (Exception e) {
if (val.length >= 2) {
try {
saturation = Float.parseFloat(val[1]);
} catch (Exception e) {
}
}
}
if (val.length >= 3) {
try {
offset = Float.parseFloat(val[2]);
} catch (Exception e) {
if (val.length >= 3) {
try {
offset = Float.parseFloat(val[2]);
} catch (Exception e) {
}
}
}

int toIgnore = recursiveParsing(out, input, handlers, endAt);
String flatString = GeneralUtils.textToString(out);
int toIgnore = recursiveParsing(out, input, handlers, endAt);
String flatString = GeneralUtils.textToString(out);

final float finalFreq = freq;
final float finalOffset = offset;
final float finalSaturation = saturation;
final float finalFreq = freq;
final float finalOffset = offset;
final float finalSaturation = saturation;

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

return toIgnore;
});
return toIgnore;
};

TextParser.register("gradient", (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("");
String[] val = data.split(":");

int toIgnore = recursiveParsing(out, input, handlers, endAt);
String flatString = GeneralUtils.textToString(out);
List<TextColor> textColors = new ArrayList<>();
for (String string : val) {
TextColor color = TextColor.parse(string);
if (color != null) {
textColors.add(color);
}
}
TextParser.register("rainbow", rainbow);
TextParser.register("rb", rainbow);
}

final double step = ((double) textColors.size() - 1) / flatString.length();
final int sectionSize = (textColors.size() - 1) / (flatString.length() + 1);

GeneralUtils.HSV hsv = GeneralUtils.rgbToHsv(textColors.get(0).getRgb());
AtomicDouble hue = new AtomicDouble(hsv.h());
AtomicDouble saturation = new AtomicDouble(hsv.s());
AtomicDouble value = new AtomicDouble(hsv.v());

text.append(GeneralUtils.toGradient(out, (pos) -> {
GeneralUtils.HSV colorA = GeneralUtils.rgbToHsv(textColors.get(pos * sectionSize).getRgb());
GeneralUtils.HSV colorB = GeneralUtils.rgbToHsv(textColors.get(pos * sectionSize + 1).getRgb());
float sym = Math.abs(colorB.h() - colorA.h()) > Math.abs(colorA.h() - colorB.h()) ? -1 : 1;
float h = colorB.h() - colorA.h();
float delta = (h + ((Math.abs(h) > 0.5) ? ((h < 0) ? 1 : -1) : 0));

float localHue = (float) hue.get();
float futureHue = (float) (localHue + delta * step);
if (futureHue < 0) {
futureHue += 1;
{
TextParser.TextFormatterHandler gradient = (String tag, String data, MutableText text, String input, Map<String, TextParser.TextFormatterHandler> handlers, String endAt) -> {
MutableText out = new LiteralText("");
String[] val = data.split(":");

int toIgnore = recursiveParsing(out, input, handlers, endAt);
String flatString = GeneralUtils.textToString(out);
List<TextColor> textColors = new ArrayList<>();
for (String string : val) {
TextColor color = TextColor.parse(string);
if (color != null) {
textColors.add(color);
}
}
if (textColors.size() == 0) {
textColors.add(TextColor.fromFormatting(Formatting.WHITE));
textColors.add(TextColor.fromFormatting(Formatting.WHITE));
} else if (textColors.size() == 1) {
textColors.add(textColors.get(0));
}
hue.set(futureHue);

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

return toIgnore;
});
GeneralUtils.HSV hsv = GeneralUtils.rgbToHsv(textColors.get(0).getRgb());
AtomicDouble hue = new AtomicDouble(hsv.h());
AtomicDouble saturation = new AtomicDouble(hsv.s());
AtomicDouble value = new AtomicDouble(hsv.v());

text.append(GeneralUtils.toGradient(out, (pos) -> {
GeneralUtils.HSV colorA = GeneralUtils.rgbToHsv(textColors.get((int) (pos * sectionSize)).getRgb());
GeneralUtils.HSV colorB = GeneralUtils.rgbToHsv(textColors.get((int) (pos * sectionSize) + 1).getRgb());

float localHue = (float) hue.get();
{
float h = colorB.h() - colorA.h();
float delta = (h + ((Math.abs(h) > 0.50001) ? ((h < 0) ? 1 : -1) : 0));

float futureHue = (float) (localHue + delta * step);
if (futureHue < 0) {
futureHue += 1;
} else if (futureHue > 1) {
futureHue -= 1;
}
hue.set(futureHue);
}

float localSat = (float) saturation.get();
{
float s = colorB.s() - colorA.s();
float futureSat = MathHelper.clamp((float) (localSat + s * step), 0, 1);
saturation.set(futureSat);
}

float localVal = (float) value.get();
{
float v = colorB.v() - colorA.v();
float futureVal = MathHelper.clamp((float) (localVal + v * step), 0, 1);
value.set(futureVal);
}

return TextColor.fromRgb(GeneralUtils.hvsToRgb(
localHue,
localSat,
localVal));
}));

return toIgnore;
};

TextParser.register("gradient", gradient);
TextParser.register("gr", gradient);
}

ESCAPED_CHARS.put("\\\\", "&slsh;");
ESCAPED_CHARS.put("\\<", "&lt;");
Expand Down

0 comments on commit 30009ba

Please sign in to comment.