diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 427ecb67..efc638e8 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -3028,6 +3028,60 @@ as a string value. Displays the result of the expression to the chat. Overrides default `scarpet` behaviour of sending everyting to stderr. +### `format(components, ...)`, `format(l(components, ...))` + +Creates a line of formatted text. Each component is either a string indicating formatting and text it corresponds to +or a decorator affecting the component preceding it. + +Regular formatting components is a string that have the structure of: +`' '`, like `'gi Hi'`, which in this case indicates a grey, italicised word `'Hi'`. The space to separate the format and the text is mandatory. The format can be empty, but the space still +needs to be there otherwise the first word of the text will be used as format, which nobody wants. + +Format is a list of formatting symbols indicating the format. They can be mixed and matched although color will only be +applied once. Available symbols include: + * `i` - _italic_ + * `b` - **bold** + * `s` - ~~strikethrough~~ + * `u` - underline + * `o` - obfuscated + +And colors: + * `w` - White (default) + * `y` - Yellow + * `m` - Magenta (light purple) + * `r` - Red + * `c` - Cyan (aqua) + * `l` - Lime + * `t` - lighT blue + * `f` - dark grayF (weird Flex, but ok) + * `g` - Gray + * `d` - golD + * `p` - PurPle + * `n` - browN (dark red) + * `q` - turQuoise (dark aqua) + * `e` - grEEn + * `v` - naVy blue + * `k` - blaK + * `#FFAACC` - arbitrary RGB color (1.16+), hex notation + +Decorators (listed as extra argument after the component they would affect): + * `'^ '` - hover over tooltip text, appearing when hovering with your mouse over the text below. + * `'?` - command suggestion - a message that will be pasted to chat when text below it is clicked. + * `'!'` - a chat message that will be executed when the text below it is clicked. + +Both suggestions and messages can contain a command, which will be executed as a player that clicks it. + +So far the only usecase for formatted texts is with a `print` command. Otherwise it functions like a normal +string value representing what is actually displayed on screen. + +Example usages: +
+ print(format('rbu Error: ', 'r Stuff happened!'))
+ print(format('w Click ','tb [HERE]', '^di Awesome!', '!/kill', 'w \ button to win $1000'))
+  // the reason why I backslash the second space is that otherwise command parser may contract consecutive spaces
+  // not a problem in apps
+
+ ### `logger(expr)` Prints the message to system logs, and not to chat. diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index db5cba2e..0a752150 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -61,6 +61,60 @@ as a string value. Displays the result of the expression to the chat. Overrides default `scarpet` behaviour of sending everyting to stderr. +### `format(components, ...)`, `format(l(components, ...))` + +Creates a line of formatted text. Each component is either a string indicating formatting and text it corresponds to +or a decorator affecting the component preceding it. + +Regular formatting components is a string that have the structure of: +`' '`, like `'gi Hi'`, which in this case indicates a grey, italicised word `'Hi'`. The space to separate the format and the text is mandatory. The format can be empty, but the space still +needs to be there otherwise the first word of the text will be used as format, which nobody wants. + +Format is a list of formatting symbols indicating the format. They can be mixed and matched although color will only be +applied once. Available symbols include: + * `i` - _italic_ + * `b` - **bold** + * `s` - ~~strikethrough~~ + * `u` - underline + * `o` - obfuscated + +And colors: + * `w` - White (default) + * `y` - Yellow + * `m` - Magenta (light purple) + * `r` - Red + * `c` - Cyan (aqua) + * `l` - Lime + * `t` - lighT blue + * `f` - dark grayF (weird Flex, but ok) + * `g` - Gray + * `d` - golD + * `p` - PurPle + * `n` - browN (dark red) + * `q` - turQuoise (dark aqua) + * `e` - grEEn + * `v` - naVy blue + * `k` - blaK + * `#FFAACC` - arbitrary RGB color (1.16+), hex notation + +Decorators (listed as extra argument after the component they would affect): + * `'^ '` - hover over tooltip text, appearing when hovering with your mouse over the text below. + * `'?` - command suggestion - a message that will be pasted to chat when text below it is clicked. + * `'!'` - a chat message that will be executed when the text below it is clicked. + +Both suggestions and messages can contain a command, which will be executed as a player that clicks it. + +So far the only usecase for formatted texts is with a `print` command. Otherwise it functions like a normal +string value representing what is actually displayed on screen. + +Example usages: +
+ print(format('rbu Error: ', 'r Stuff happened!'))
+ print(format('w Click ','tb [HERE]', '^di Awesome!', '!/kill', 'w \ button to win $1000'))
+  // the reason why I backslash the second space is that otherwise command parser may contract consecutive spaces
+  // not a problem in apps
+
+ ### `logger(expr)` Prints the message to system logs, and not to chat. diff --git a/mergedoc.sh b/mergedoc.sh new file mode 100755 index 00000000..16559437 --- /dev/null +++ b/mergedoc.sh @@ -0,0 +1,2 @@ +cat docs/scarpet/language/Overview.md docs/scarpet/language/VariablesAndConstants.md docs/scarpet/language/Operators.md docs/scarpet/language/Math.md docs/scarpet/language/SystemFunctions.md docs/scarpet/language/LoopsAndHigherOrderFunctions.md docs/scarpet/language/FunctionsAndControlFlow.md docs/scarpet/language/Containers.md docs/scarpet/api/Overview.md docs/scarpet/api/BlocksAndWorldAccess.md docs/scarpet/api/BlockIterations.md docs/scarpet/api/Entities.md docs/scarpet/api/Inventories.md docs/scarpet/api/Events.md docs/scarpet/api/Scoreboard.md docs/scarpet/api/Auxiliary.md docs/scarpet/api/ScriptCommand.md > docs/scarpet/Full.md + diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 3bf675f1..03e42147 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -23,6 +23,7 @@ import carpet.script.exception.ExpressionException; import carpet.script.exception.InternalExpressionException; import carpet.script.value.BlockValue; import carpet.script.value.EntityValue; +import carpet.script.value.FormattedTextValue; import carpet.script.value.FunctionValue; import carpet.script.value.LazyListValue; import carpet.script.value.ListValue; @@ -2677,17 +2678,33 @@ public class CarpetExpression { ServerCommandSource s = ((CarpetContext)c).s; Value res = lv.get(0).evalValue(c); - if (s.getEntity() instanceof PlayerEntity) + if (res instanceof FormattedTextValue) { - Messenger.m((PlayerEntity) s.getEntity(), "w "+ res.getString()); + s.sendFeedback(((FormattedTextValue) res).getText(), false); } else { - Messenger.m(s, "w "+ res.getString()); + if (s.getEntity() instanceof PlayerEntity) + { + Messenger.m((PlayerEntity) s.getEntity(), "w " + res.getString()); + } + else + { + Messenger.m(s, "w " + res.getString()); + } } return (_c, _t) -> res; // pass through for variables }); + this.expr.addLazyFunction("format", -1, (c, t, lv) -> { + if (lv.size() == 0 ) throw new InternalExpressionException("'format' requires at least one component"); + List values = lv.stream().map(lazy -> lazy.evalValue(c)).collect(Collectors.toList()); + if (values.get(0) instanceof ListValue && values.size()==1) + values = ((ListValue) values.get(0)).getItems(); + Value ret = new FormattedTextValue(Messenger.c(values.stream().map(Value::getString).toArray())); + return (cc, tt) -> ret; + }); + //"overidden" native call to cancel if on main thread this.expr.addLazyFunction("task_join", 1, (c, t, lv) -> { if (((CarpetContext)c).s.getMinecraftServer().isOnThread()) diff --git a/src/main/java/carpet/script/value/FormattedTextValue.java b/src/main/java/carpet/script/value/FormattedTextValue.java new file mode 100644 index 00000000..501e3181 --- /dev/null +++ b/src/main/java/carpet/script/value/FormattedTextValue.java @@ -0,0 +1,40 @@ +package carpet.script.value; + +import net.minecraft.text.BaseText; + +public class FormattedTextValue extends StringValue +{ + BaseText text; + public FormattedTextValue(BaseText text) + { + super(null); + this.text = text; + } + + @Override + public String getString() { + return text.getString(); + } + + @Override + public boolean getBoolean() { + return text.getSiblings().size() > 0; + } + + @Override + public Value clone() + { + return new FormattedTextValue(text); + } + + @Override + public String getTypeString() + { + return "text"; + } + + public BaseText getText() + { + return text; + } +} diff --git a/src/main/java/carpet/utils/Messenger.java b/src/main/java/carpet/utils/Messenger.java index 7604d13e..953028f8 100644 --- a/src/main/java/carpet/utils/Messenger.java +++ b/src/main/java/carpet/utils/Messenger.java @@ -116,10 +116,14 @@ public class Messenger { message = "w"+message; } - String[] parts = message.split("\\s", 2); - String desc = parts[0]; + int limit = message.indexOf(' '); + String desc = message; String str = ""; - if (parts.length > 1) str = parts[1]; + if (limit >= 0) + { + desc = message.substring(0, limit); + str = message.substring(limit+1); + } if (desc.charAt(0) == '/') // deprecated { if (previous_message != null)