From efa5a2b7de4dd7823133e3eb867a7ca5799e4741 Mon Sep 17 00:00:00 2001 From: dags- Date: Fri, 3 May 2019 16:58:38 +0100 Subject: [PATCH] improve Text rendering --- build.gradle | 2 +- src/main/java/me/dags/text/MUSpec.java | 9 +- src/main/java/me/dags/text/syntax/Parser.java | 45 +------ .../java/me/dags/text/syntax/Renderer.java | 116 ++++++++++++++++++ 4 files changed, 124 insertions(+), 48 deletions(-) create mode 100644 src/main/java/me/dags/text/syntax/Renderer.java diff --git a/build.gradle b/build.gradle index 9350f95..07c7bab 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } group "me.dags" -version "0.4.0-SNAPSHOT" +version "0.4.1-SNAPSHOT" def spongeAPI = "7.2.0-SNAPSHOT" description = "A markup syntax for Sponge" diff --git a/src/main/java/me/dags/text/MUSpec.java b/src/main/java/me/dags/text/MUSpec.java index d2b066d..7bc647e 100644 --- a/src/main/java/me/dags/text/MUSpec.java +++ b/src/main/java/me/dags/text/MUSpec.java @@ -30,6 +30,7 @@ import me.dags.text.preset.MUPresets; import me.dags.text.syntax.Parser; import me.dags.text.syntax.Property; +import me.dags.text.syntax.Renderer; import me.dags.text.syntax.Writer; import me.dags.text.template.MUTemplate; import org.spongepowered.api.service.permission.Subject; @@ -92,8 +93,7 @@ public Text render(String input) { public Text render(Property.Predicate predicate, String input) { try { - CharReader reader = new CharReader(input); - return new Parser(reader, presets, predicate).parse().build(); + return Parser.parse(input, presets, predicate).build(); } catch (IOException e) { return Text.EMPTY; } @@ -101,8 +101,7 @@ public Text render(Property.Predicate predicate, String input) { public Text render(Property.Predicate predicate, Reader reader) { try { - CharReader charReader = new CharReader(reader); - return new Parser(charReader, presets, predicate).parse().build(); + return Parser.parse(new CharReader(reader), presets, predicate).build(); } catch (IOException e) { return Text.EMPTY; } @@ -118,7 +117,7 @@ public Text render(Subject subject, Text input) { public Text render(Property.Predicate predicate, Text input) { try { - return Parser.parse(input, null, presets, predicate).build(); + return Renderer.render(input, presets, predicate).build(); } catch (IOException e) { return input; } diff --git a/src/main/java/me/dags/text/syntax/Parser.java b/src/main/java/me/dags/text/syntax/Parser.java index 4ec2e9c..384d614 100644 --- a/src/main/java/me/dags/text/syntax/Parser.java +++ b/src/main/java/me/dags/text/syntax/Parser.java @@ -52,11 +52,8 @@ import me.dags.template.CharReader; import me.dags.text.preset.MUPresets; -import org.spongepowered.api.text.LiteralText; import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.format.TextColors; -import javax.annotation.Nullable; import java.io.IOException; public class Parser { @@ -220,46 +217,10 @@ private char readProperty(StringBuilder buffer, StringBuilder raw) throws IOExce public static Text.Builder parse(String input, MUPresets presets, Property.Predicate predicate) throws IOException { CharReader reader = new CharReader(input); - return new Parser(reader, presets, predicate).parse(); + return parse(reader, presets, predicate); } - public static Text.Builder parse(Text text, @Nullable Text.Builder parent, MUPresets presets, Property.Predicate predicate) throws IOException { - Text.Builder builder; - - if (text instanceof LiteralText) { - String content = ((LiteralText) text).getContent(); - if (content.isEmpty()) { - builder = text.toBuilder().removeAll(); - } else { - builder = parse(content, presets, predicate); - if (builder.getColor() == TextColors.NONE) { - builder.color(text.getColor()); - } - if (builder.getStyle().isEmpty()) { - builder.style(text.getStyle()); - } - if (!builder.getHoverAction().isPresent()) { - text.getHoverAction().ifPresent(builder::onHover); - } - if (!builder.getClickAction().isPresent()) { - text.getClickAction().ifPresent(builder::onClick); - } - if (!builder.getShiftClickAction().isPresent()) { - text.getShiftClickAction().ifPresent(builder::onShiftClick); - } - } - } else { - builder = text.toBuilder().removeAll(); - } - - for (Text child : text.getChildren()) { - parse(child, builder, presets, predicate); - } - - if (parent != null) { - parent.append(builder.build()); - } - - return builder; + public static Text.Builder parse(CharReader reader, MUPresets presets, Property.Predicate predicate) throws IOException { + return new Parser(reader, presets, predicate).parse(); } } diff --git a/src/main/java/me/dags/text/syntax/Renderer.java b/src/main/java/me/dags/text/syntax/Renderer.java new file mode 100644 index 0000000..038e90f --- /dev/null +++ b/src/main/java/me/dags/text/syntax/Renderer.java @@ -0,0 +1,116 @@ +package me.dags.text.syntax; + +import me.dags.text.preset.MUPresets; +import org.spongepowered.api.text.LiteralText; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.TranslatableText; +import org.spongepowered.api.text.action.HoverAction; +import org.spongepowered.api.text.action.TextActions; +import org.spongepowered.api.text.format.TextColors; +import org.spongepowered.api.text.translation.Translation; + +import javax.annotation.Nullable; +import java.io.IOException; + +public class Renderer { + + private final MUPresets presets; + private final Property.Predicate predicate; + + public Renderer(MUPresets presets, Property.Predicate predicate) { + this.presets = presets; + this.predicate = predicate; + } + + public Text.Builder render(Text text) throws IOException { + return render(text, null); + } + + private Text.Builder render(Text text, @Nullable Text.Builder parent) throws IOException { + Text.Builder builder; + + if (text instanceof LiteralText) { + builder = toLiteralBuilder((LiteralText) text); + } else if (text instanceof TranslatableText) { + builder = toTranslatableBuilder((TranslatableText) text); + } else { + builder = text.toBuilder().removeAll(); + } + + renderTextActions(builder); + + for (Text child : text.getChildren()) { + render(child, builder); + } + + if (parent != null) { + parent.append(builder.build()); + } + + return builder; + } + + private void inherit(Text text, Text.Builder builder) { + if (builder.getColor() == TextColors.NONE) { + builder.color(text.getColor()); + } + if (builder.getStyle().isEmpty()) { + builder.style(text.getStyle()); + } + if (!builder.getHoverAction().isPresent()) { + text.getHoverAction().ifPresent(builder::onHover); + } + if (!builder.getClickAction().isPresent()) { + text.getClickAction().ifPresent(builder::onClick); + } + if (!builder.getShiftClickAction().isPresent()) { + text.getShiftClickAction().ifPresent(builder::onShiftClick); + } + } + + private void renderTextActions(Text.Builder builder) { + builder.getHoverAction().map(action -> { + if (action instanceof HoverAction.ShowText) { + try { + Text hover = ((HoverAction.ShowText) action).getResult(); + return TextActions.showText(render(hover, null).build()); + } catch (IOException e) { + return action; + } + } + return action; + }).ifPresent(builder::onHover); + } + + private Text.Builder toLiteralBuilder(LiteralText text) throws IOException { + if (text.getContent().isEmpty()) { + return text.toBuilder().removeAll(); + } else { + Text.Builder builder = Parser.parse(text.getContent(), presets, predicate); + inherit(text, builder); + return builder; + } + } + + private Text.Builder toTranslatableBuilder(TranslatableText text) { + Translation translation = text.getTranslation(); + Object[] arguments = text.getArguments().stream().map(o -> { + if (o instanceof Text) { + Text t = (Text) o; + try { + return render(t, null); + } catch (IOException e) { + return t; + } + } + return o; + }).toArray(); + Text.Builder builder = Text.builder(translation, arguments); + inherit(text, builder); + return builder; + } + + public static Text.Builder render(Text text, MUPresets presets, Property.Predicate predicate) throws IOException { + return new Renderer(presets, predicate).render(text); + } +}