KyoriPowered / adventure

A user-interface library, formerly known as text, for Minecraft: Java Edition
https://docs.advntr.dev/
MIT License
679 stars 105 forks source link

feat(api): Add split method to Component #886

Open Joo200 opened 1 year ago

Joo200 commented 1 year ago

Add a method to Component to split it into a List.

This can be used to split a Component into a List for a Lore:

MiniMessage.miniMessage().deserialize("<red>Hello world, this is<br>my lore").split(Component.newline());

How Components in the list are formatted

The style of the root component is applied as fallback style to each Component in the list.

    final Component example = Component.text("first", NamedTextColor.RED).appendNewline().append(Component.text("second"));

will translate to the following List:

[TextComponentImpl{
  content="", style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="red", value="#ff5555"}, clickEvent=null, hoverEvent=null, insertion=null, font=null}, 
    children=[
      TextComponentImpl{content="first", style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[]}
    ]
  }, 
TextComponentImpl{
  content="", style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="red", value="#ff5555"}, clickEvent=null, hoverEvent=null, insertion=null, font=null}, 
    children=[
      TextComponentImpl{content="second", style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[]}
    ]
  }
]

This is still a proof of concept. I'm happy on every optimization.

Currently it's not possible to split the Component by some text. E.g. Component.text("mydummytext").split(Component.text("dummy")) will not be split to Component.text("my") and Component.text("text")

However this works fine to split newlines.

CubBossa commented 1 year ago

Hey! I had some issues with the suggested split method in combination with Components parsed from MiniMessage. MiniMessage created TextComponents that had a content like "line1\nline2" and the check for equallity with a Component.newLine() did not match. This is my temporary solution to preserve the style and split a component by its content and a regex. It does not match expressions that go beyond one component though (like <a>x</a>y would not match xy), so it would not be sufficient as actual implementation for a split by regex.

Maybe someone has need of it until there is an official solution https://gist.github.com/CubBossa/8bc84706b7e1e393bebb7dc9cf8a9ed5