Search in sources :

Example 1 with Tag

use of net.kyori.adventure.text.minimessage.tag.Tag in project adventure by KyoriPowered.

the class GradientTag method create.

static Tag create(final ArgumentQueue args, final Context ctx) {
    float phase = 0;
    final List<TextColor> textColors;
    if (args.hasNext()) {
        textColors = new ArrayList<>();
        while (args.hasNext()) {
            final Tag.Argument arg = args.pop();
            // last argument? maybe this is the phase?
            if (!args.hasNext()) {
                final OptionalDouble possiblePhase = arg.asDouble();
                if (possiblePhase.isPresent()) {
                    phase = (float) possiblePhase.getAsDouble();
                    if (phase < -1f || phase > 1f) {
                        throw ctx.newException(String.format("Gradient phase is out of range (%s). Must be in the range [-1.0f, 1.0f] (inclusive).", phase), args);
                    }
                    break;
                }
            }
            final TextColor parsedColor = ColorTagResolver.resolveColor(arg.value(), ctx);
            textColors.add(parsedColor);
        }
        if (textColors.size() < 2) {
            throw ctx.newException("Invalid gradient, not enough colors. Gradients must have at least two colors.", args);
        }
    } else {
        textColors = Collections.emptyList();
    }
    return new GradientTag(phase, textColors);
}
Also used : TextColor(net.kyori.adventure.text.format.TextColor) Tag(net.kyori.adventure.text.minimessage.tag.Tag) OptionalDouble(java.util.OptionalDouble)

Example 2 with Tag

use of net.kyori.adventure.text.minimessage.tag.Tag in project adventure by KyoriPowered.

the class MiniMessageParser method treeToComponent.

@NotNull
Component treeToComponent(@NotNull final ElementNode node, @NotNull final ContextImpl context) {
    Component comp = Component.empty();
    Tag tag = null;
    if (node instanceof ValueNode) {
        comp = Component.text(((ValueNode) node).value());
    } else if (node instanceof TagNode) {
        final TagNode tagNode = (TagNode) node;
        tag = tagNode.tag();
        // special case for gradient and stuff
        if (tag instanceof Modifying) {
            final Modifying modTransformation = (Modifying) tag;
            // first walk the tree
            this.visitModifying(modTransformation, tagNode, 0);
            modTransformation.postVisit();
        }
        if (tag instanceof Inserting) {
            comp = ((Inserting) tag).value();
        }
    }
    if (!node.unsafeChildren().isEmpty()) {
        final List<Component> children = new ArrayList<>(comp.children().size() + node.children().size());
        children.addAll(comp.children());
        for (final ElementNode child : node.unsafeChildren()) {
            children.add(this.treeToComponent(child, context));
        }
        comp = comp.children(children);
    }
    // special case for gradient and stuff
    if (tag instanceof Modifying) {
        comp = this.handleModifying((Modifying) tag, comp, 0);
    }
    final Consumer<String> debug = context.debugOutput();
    if (debug != null) {
        debug.accept("==========\ntreeToComponent \n");
        debug.accept(node.toString());
        debug.accept("\n");
        debug.accept(comp.examine(MultiLineStringExaminer.simpleEscaping()).collect(Collectors.joining("\n")));
        debug.accept("\n==========\n");
    }
    return comp;
}
Also used : Modifying(net.kyori.adventure.text.minimessage.tag.Modifying) ValueNode(net.kyori.adventure.text.minimessage.internal.parser.node.ValueNode) ArrayList(java.util.ArrayList) Tag(net.kyori.adventure.text.minimessage.tag.Tag) Component(net.kyori.adventure.text.Component) ElementNode(net.kyori.adventure.text.minimessage.internal.parser.node.ElementNode) TagNode(net.kyori.adventure.text.minimessage.internal.parser.node.TagNode) Inserting(net.kyori.adventure.text.minimessage.tag.Inserting) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with Tag

use of net.kyori.adventure.text.minimessage.tag.Tag in project adventure by KyoriPowered.

the class MiniMessageParser method parseToTree.

@NotNull
RootNode parseToTree(@NotNull final ContextImpl context) {
    final TagResolver combinedResolver = TagResolver.resolver(this.tagResolver, context.extraTags());
    final String processedMessage = context.preProcessor().apply(context.message());
    final Consumer<String> debug = context.debugOutput();
    if (debug != null) {
        debug.accept("Beginning parsing message ");
        debug.accept(processedMessage);
        debug.accept("\n");
    }
    final TokenParser.TagProvider transformationFactory;
    if (debug != null) {
        transformationFactory = (name, args, token) -> {
            try {
                debug.accept("Attempting to match node '");
                debug.accept(name);
                debug.accept("'");
                if (token != null) {
                    debug.accept(" at column ");
                    debug.accept(String.valueOf(token.startIndex()));
                }
                debug.accept("\n");
                @Nullable final Tag transformation = combinedResolver.resolve(name, new ArgumentQueueImpl<>(context, args), context);
                if (transformation == null) {
                    debug.accept("Could not match node '");
                    debug.accept(name);
                    debug.accept("'\n");
                } else {
                    debug.accept("Successfully matched node '");
                    debug.accept(name);
                    debug.accept("' to tag ");
                    debug.accept(transformation instanceof Examinable ? ((Examinable) transformation).examinableName() : transformation.getClass().getName());
                    debug.accept("\n");
                }
                return transformation;
            } catch (final ParsingException e) {
                if (token != null && e instanceof ParsingExceptionImpl) {
                    final ParsingExceptionImpl impl = (ParsingExceptionImpl) e;
                    if (impl.tokens().length == 0) {
                        impl.tokens(new Token[] { token });
                    }
                }
                debug.accept("Could not match node '");
                debug.accept(name);
                debug.accept("' - ");
                debug.accept(e.getMessage());
                debug.accept("\n");
                return null;
            }
        };
    } else {
        transformationFactory = (name, args, token) -> {
            try {
                return combinedResolver.resolve(name, new ArgumentQueueImpl<>(context, args), context);
            } catch (final ParsingException ignored) {
                return null;
            }
        };
    }
    final Predicate<String> tagNameChecker = name -> {
        final String sanitized = TokenParser.TagProvider.sanitizePlaceholderName(name);
        return combinedResolver.has(sanitized);
    };
    final String preProcessed = TokenParser.resolvePreProcessTags(processedMessage, transformationFactory);
    context.message(preProcessed);
    // Then, once MiniMessage placeholders have been inserted, we can do the real parse
    final RootNode root = TokenParser.parse(transformationFactory, tagNameChecker, preProcessed, processedMessage, context.strict());
    if (debug != null) {
        debug.accept("Text parsed into element tree:\n");
        debug.accept(root.toString());
    }
    return root;
}
Also used : Tag(net.kyori.adventure.text.minimessage.tag.Tag) ElementNode(net.kyori.adventure.text.minimessage.internal.parser.node.ElementNode) Token(net.kyori.adventure.text.minimessage.internal.parser.Token) RootNode(net.kyori.adventure.text.minimessage.internal.parser.node.RootNode) Predicate(java.util.function.Predicate) TagNode(net.kyori.adventure.text.minimessage.internal.parser.node.TagNode) Collectors(java.util.stream.Collectors) ParsingExceptionImpl(net.kyori.adventure.text.minimessage.internal.parser.ParsingExceptionImpl) ArrayList(java.util.ArrayList) Objects(java.util.Objects) Consumer(java.util.function.Consumer) Examinable(net.kyori.examination.Examinable) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) TokenParser(net.kyori.adventure.text.minimessage.internal.parser.TokenParser) Component(net.kyori.adventure.text.Component) MultiLineStringExaminer(net.kyori.examination.string.MultiLineStringExaminer) BiConsumer(java.util.function.BiConsumer) TokenType(net.kyori.adventure.text.minimessage.internal.parser.TokenType) ValueNode(net.kyori.adventure.text.minimessage.internal.parser.node.ValueNode) NotNull(org.jetbrains.annotations.NotNull) Modifying(net.kyori.adventure.text.minimessage.tag.Modifying) Inserting(net.kyori.adventure.text.minimessage.tag.Inserting) TagResolver(net.kyori.adventure.text.minimessage.tag.resolver.TagResolver) RootNode(net.kyori.adventure.text.minimessage.internal.parser.node.RootNode) TagResolver(net.kyori.adventure.text.minimessage.tag.resolver.TagResolver) TokenParser(net.kyori.adventure.text.minimessage.internal.parser.TokenParser) Token(net.kyori.adventure.text.minimessage.internal.parser.Token) Tag(net.kyori.adventure.text.minimessage.tag.Tag) ParsingExceptionImpl(net.kyori.adventure.text.minimessage.internal.parser.ParsingExceptionImpl) Nullable(org.jetbrains.annotations.Nullable) Examinable(net.kyori.examination.Examinable) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with Tag

use of net.kyori.adventure.text.minimessage.tag.Tag in project adventure by KyoriPowered.

the class StringResolvingMatchedTokenConsumer method accept.

@Override
public void accept(final int start, final int end, @NotNull final TokenType tokenType) {
    super.accept(start, end, tokenType);
    if (tokenType != TokenType.OPEN_TAG) {
        // just add it normally, we don't care about other tags
        this.builder.append(this.input, start, end);
    } else {
        // well, now we need to work out if it's a tag or a placeholder!
        final String match = this.input.substring(start, end);
        final String cleanup = this.input.substring(start + 1, end - 1);
        final int index = cleanup.indexOf(SEPARATOR);
        final String tag = index == -1 ? cleanup : cleanup.substring(0, index);
        // we might care if it's a valid tag!
        if (TagInternals.sanitizeAndCheckValidTagName(tag)) {
            final List<Token> tokens = tokenize(match);
            final List<TagPart> parts = new ArrayList<>();
            final List<Token> childs = tokens.isEmpty() ? null : tokens.get(0).childTokens();
            if (childs != null) {
                for (int i = 1; i < childs.size(); i++) {
                    parts.add(new TagPart(match, childs.get(i), this.tagProvider));
                }
            }
            // we might care if it's a pre-process!
            @Nullable final Tag replacement = this.tagProvider.resolve(TokenParser.TagProvider.sanitizePlaceholderName(tag), parts, tokens.get(0));
            if (replacement instanceof PreProcess) {
                this.builder.append(Objects.requireNonNull(((PreProcess) replacement).value(), "PreProcess replacements cannot return null"));
                return;
            }
        }
        // if we get here, the placeholder wasn't found or was null
        this.builder.append(match);
    }
}
Also used : PreProcess(net.kyori.adventure.text.minimessage.tag.PreProcess) ArrayList(java.util.ArrayList) Token(net.kyori.adventure.text.minimessage.internal.parser.Token) Tag(net.kyori.adventure.text.minimessage.tag.Tag) Nullable(org.jetbrains.annotations.Nullable) TagPart(net.kyori.adventure.text.minimessage.internal.parser.node.TagPart)

Example 5 with Tag

use of net.kyori.adventure.text.minimessage.tag.Tag in project adventure by KyoriPowered.

the class TransitionTag method create.

static Tag create(final ArgumentQueue args, final Context ctx) {
    float phase = 0;
    final List<TextColor> textColors;
    if (args.hasNext()) {
        textColors = new ArrayList<>();
        while (args.hasNext()) {
            final Tag.Argument arg = args.pop();
            // last argument? maybe this is the phase?
            if (!args.hasNext()) {
                final OptionalDouble possiblePhase = arg.asDouble();
                if (possiblePhase.isPresent()) {
                    phase = (float) possiblePhase.getAsDouble();
                    if (phase < -1f || phase > 1f) {
                        throw ctx.newException(String.format("Gradient phase is out of range (%s). Must be in the range [-1.0f, 1.0f] (inclusive).", phase), args);
                    }
                    break;
                }
            }
            final String argValue = arg.value();
            final TextColor parsedColor;
            if (argValue.charAt(0) == '#') {
                parsedColor = TextColor.fromHexString(argValue);
            } else {
                parsedColor = NamedTextColor.NAMES.value(arg.lowerValue());
            }
            if (parsedColor == null) {
                throw ctx.newException(String.format("Unable to parse a color from '%s'. Please use named colors or hex (#RRGGBB) colors.", argValue), args);
            }
            textColors.add(parsedColor);
        }
        if (textColors.size() < 2) {
            throw ctx.newException("Invalid transition, not enough colors. Transitions must have at least two colors.", args);
        }
    } else {
        textColors = Collections.emptyList();
    }
    return new TransitionTag(phase, textColors);
}
Also used : TextColor(net.kyori.adventure.text.format.TextColor) NamedTextColor(net.kyori.adventure.text.format.NamedTextColor) Tag(net.kyori.adventure.text.minimessage.tag.Tag) OptionalDouble(java.util.OptionalDouble)

Aggregations

Tag (net.kyori.adventure.text.minimessage.tag.Tag)7 ArrayList (java.util.ArrayList)5 ElementNode (net.kyori.adventure.text.minimessage.internal.parser.node.ElementNode)4 TagNode (net.kyori.adventure.text.minimessage.internal.parser.node.TagNode)4 Inserting (net.kyori.adventure.text.minimessage.tag.Inserting)4 Component (net.kyori.adventure.text.Component)3 Token (net.kyori.adventure.text.minimessage.internal.parser.Token)3 RootNode (net.kyori.adventure.text.minimessage.internal.parser.node.RootNode)3 ValueNode (net.kyori.adventure.text.minimessage.internal.parser.node.ValueNode)3 Modifying (net.kyori.adventure.text.minimessage.tag.Modifying)3 NotNull (org.jetbrains.annotations.NotNull)3 Nullable (org.jetbrains.annotations.Nullable)3 List (java.util.List)2 Objects (java.util.Objects)2 OptionalDouble (java.util.OptionalDouble)2 BiConsumer (java.util.function.BiConsumer)2 Consumer (java.util.function.Consumer)2 Predicate (java.util.function.Predicate)2 Collectors (java.util.stream.Collectors)2 TextColor (net.kyori.adventure.text.format.TextColor)2