Text processing
Text processors are the foundation of the API. We include a default GlobalTextProcessor
which can be accessed with Social.get().getTextProcessor()
. The global text processor stores text parsers and provides a few utilities.
Processing a message
Processing a message with social's registered parsers is possible via the GlobalTextProcessor::parse
method. You'll have to provide a parser context. This is easier than it sounds:
Note
This part of the guide assumes you already know how to get a SocialUser
instance.
// Let's start by building a context
var context = SocialParserContext.builder(user, Component.text("Hello, $(nickname)! :smile:"))
.build();
// Now we can proceed to parse the message
Component message = Social.get().getTextProcessor().parse(context);
Alternative methods
The global text processor provides some alternative methods so that you don't have to build a new context every time. This can be especially useful when you have to parse many messages:
parse(user, channel, message)
: parses a message and returns a Componentuser
must be an instance of SocialUserchannel
must be an instance of ChatChannelmessage
can be a Component or a String
parseAndSend(user, channel, message)
: parses and sends a message to the useruser
must be an instance of SocialUserchannel
must be an instance of ChatChannelmessage
can be a Component or a String
Registering custom placeholders
You can register placeholders in the global text processor by extending the SocialContextualPlaceholder
class or directly using lambda expressions. In this example we'll focus on the latter:
var identifier = "example_placeholder"; // Our placeholder will be $(example_placeholder)
Social.get().getTextProcessor().registerContextualPlaceholder(identifier, context -> {
// Context is a SocialParserContext
return Component.text(context.user().displayName().color(NamedTextColor.GOLD));
});
This placeholder will return the player's display name in gold color.
Registering custom keywords
The process of registering keywords is the same as in the previous example but using the method GlobalTextProcessor::registerContextualKeyword
:
var keyword = "example_keyword"; // Our keyword will be [example_keyword]
Social.get().getTextProcessor().registerContextualKeyword(keyword, context -> {
return Component.text("Click me!")
.clickEvent(ClickEvent.runCommand("/me hello world!"));
});
Tip
Don't forget that keywords are used by players. Make them simple and intuitive, but also fun!
Registering custom formatters
Formatters are a new feature that allow users to add a personal touch to their messages. There are two types of formatters:
- Inline formatters: they require the user to put a prefix in their messages. They can be delimited by using the '\' key.
- Surrounding formatters: they require the user to "surround" their message in a special character.
Formatters are considered an experimental feature right now, so using them requires to extend the SocialInlineFormatter
or SocialSurroundingFormatter
class:
public class ExampleFormatter extends SocialSurroundingFormatter {
@Override
public String characters() {
return "$$";
}
@Override
public Component format(SocialParserContext context) {
return context.message().font(Key.key("custom:font"));
}
}
Note
This example changes the font of the surrounded text, for example: $$Hello!$$ How are you?
.
The last step is registering this parser:
Registering custom parsers
Parsers allow a deeper level of integration but come at the cost of more effort required from the developer. Let's start by implementing the SocialContextualParser
interface:
public class ExampleParser implements SocialContextualParser {
@Override
public Component parse(SocialParserContext context) {
return context.message().replaceText(TextReplacementConfig.builder()
.matchLiteral("try the ketchup")
.replacement(Component.text("try the ketchup").color(NamedTextColor.RED))
.build())
}
}
Customizing parsers
You can configure your parser by implementing additional interfaces. By default, parsers will work with non-player input. To change this you can implement the interface SocialUserInputParser
, which will make the parser work both with player and non-player input. If you want your parser to work only with player input, you can implement SocialFilterLike
instead of SocialUserInputParser
.
Version 0.4 introduces an experimental method to make your parser work with offline players or in instances where you won't need to access the context's user in any way. This can be done by overriding supportsOfflinePlayers()
:
Other registration methods
The global text processor has public static variables for two specific parser groups: early and late parsers. Generally, we recommend using the built-in methods to register parsers, but we do understand and support the fact that there are a lot of use cases for parsers which may not align with the ideas we envisioned for the API.
- Early parsers: they are parsed before registered parsers
- Late parsers: they are parsed after registered parsers
Let's register our ExampleParser
as a late parser: