1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 10:38:19 +08:00

feat(msg): add enhanced text support

This commit is contained in:
2025-03-04 04:21:58 +08:00
parent 6434feb980
commit 4df4977733
2 changed files with 69 additions and 27 deletions
@@ -16,11 +16,12 @@ import java.util.stream.IntStream;
public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEIVER, SELF>> {
/**
* Used to match the message insertion
* Used to match the message insertion.
* <p>
* format:
* <br>- to insert parsed line {prefix}#content-id#{offset-above,offset-down}
* <br>- to insert original line {prefix}@content-id@{offset-above,offset-down}
* <br> original lines will not be parsed
* <br> example:
* <ul>
* <li>{- }#content-id#{1,1}</li>
@@ -30,6 +31,21 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
public static final @NotNull Pattern INSERT_PATTERN = Pattern.compile(
"^(?:\\{(?<prefix>.*)})?(?<type>[#@])(?<id>.*)[#@](?:\\{(?<above>-?\\d+)(?:,(?<down>-?\\d+))?})?$"
);
/**
* Used to match the message which can be inserted
* <p>
* format:
* <br>- ?[id]Message content
* <br> example:
* <ul>
* <li>?[click]Click to use this item!</li>
* </ul>
*/
public static final @NotNull Pattern ENABLE_PATTERN = Pattern.compile(
"^\\?\\[(?<id>.+)](?<content>.*)$"
);
public static final @NotNull UnaryOperator<String> DEFAULT_PARAM_BUILDER = s -> "%(" + s + ")";
protected BiFunction<RECEIVER, String, String> parser = (receiver, value) -> value;
@@ -45,7 +61,7 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
/**
* Used to store the insertion of the message
*/
protected @NotNull Map<String, Function<RECEIVER, List<String>>> insertion = new HashMap<>();
protected @NotNull Map<String, @Nullable Function<RECEIVER, List<String>>> insertion = new HashMap<>();
protected boolean disableInsertion = false;
public abstract SELF self();
@@ -139,6 +155,17 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
return self();
}
/**
* Insert the specific contents by the id.
*
* @param id the id of the insertion text
* @return the current {@link ContentHandler} instance
*/
public SELF insert(@NotNull String id) {
this.insertion.put(id, null);
return self();
}
/**
* Insert the specific contents by the id.
*
@@ -205,37 +232,50 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
}
for (String line : contents.lines()) {
Matcher matcher = INSERT_PATTERN.matcher(line);
if (!matcher.matches()) {
lineConsumer.accept(parse(receiver, line));
Matcher insertMatcher = INSERT_PATTERN.matcher(line);
if (insertMatcher.matches()) {
doInsert(insertMatcher, receiver, lineConsumer);
continue;
}
String id = matcher.group("id");
List<String> values = Optional.ofNullable(this.insertion.get(id))
.map(f -> f.apply(receiver))
.orElse(null);
if (values == null || values.isEmpty()) continue;
String prefix = matcher.group("prefix");
String type = matcher.group("type");
boolean original = type.equals("@");
int offsetAbove = Optional.ofNullable(matcher.group("above"))
.map(Integer::parseInt).orElse(0);
int offsetDown = Optional.ofNullable(matcher.group("down"))
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
IntStream.range(0, Math.max(0, offsetAbove)).mapToObj(i -> "").forEach(lineConsumer);
String prefixContent = Optional.ofNullable(prefix).map(p -> parse(receiver, p)).orElse("");
if (original) {
values.stream().map(value -> prefixContent + value).forEach(lineConsumer);
} else {
values.stream().map(value -> prefixContent + parse(receiver, value)).forEach(lineConsumer);
Matcher enableMatcher = ENABLE_PATTERN.matcher(line);
if (enableMatcher.matches()) {
if (this.insertion.containsKey(enableMatcher.group("id"))) {
lineConsumer.accept(parse(receiver, enableMatcher.group("content")));
}
continue;
}
IntStream.range(0, Math.max(0, offsetDown)).mapToObj(i -> "").forEach(lineConsumer);
lineConsumer.accept(parse(receiver, line));
}
}
private void doInsert(Matcher matcher, @Nullable RECEIVER receiver,
@NotNull Consumer<String> lineConsumer) {
String id = matcher.group("id");
List<String> values = Optional.ofNullable(this.insertion.get(id))
.map(f -> f.apply(receiver))
.orElse(null);
if (values == null || values.isEmpty()) return; // No values to insert
String prefix = matcher.group("prefix");
String type = matcher.group("type");
boolean original = type.equals("@");
int offsetAbove = Optional.ofNullable(matcher.group("above"))
.map(Integer::parseInt).orElse(0);
int offsetDown = Optional.ofNullable(matcher.group("down"))
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
IntStream.range(0, Math.max(0, offsetAbove)).mapToObj(i -> "").forEach(lineConsumer);
String prefixContent = Optional.ofNullable(prefix).map(p -> parse(receiver, p)).orElse("");
if (original) {
values.stream().map(value -> prefixContent + value).forEach(lineConsumer);
} else {
values.stream().map(value -> prefixContent + parse(receiver, value)).forEach(lineConsumer);
}
IntStream.range(0, Math.max(0, offsetDown)).mapToObj(i -> "").forEach(lineConsumer);
}
public static String setPlaceholders(@NotNull String messages,
@NotNull Map<String, Object> placeholders) {
if (messages.isEmpty()) return messages;
@@ -20,7 +20,8 @@ public class ParseTest {
lines.add("#guidance#");
lines.add("{- }#websites#{0,1}");
lines.add("Thanks for your reading!");
lines.add("?[click]");
lines.add("?[click]Click to see more!");
Map<String, List<String>> optional = new HashMap<>();
optional.put("guidance", Arrays.asList("To get more information for %(name), see:"));
@@ -35,6 +36,7 @@ public class ParseTest {
msg.placeholder("name", "Carm")
.insert("guidance")
.insert("click")
.insert("websites", "Baidu", "Bilibili", "Google");
System.out.println("----------------------------");