Rewrite ShortcodeConverter (now with modularity!)

This commit is contained in:
JeremyStar™ 2024-07-07 17:34:16 +02:00
parent 1e4a1e04a7
commit d35ae5535c
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
8 changed files with 390 additions and 115 deletions

View file

@ -38,7 +38,6 @@ import de.staropensource.sosengine.base.types.ImmutableMap;
import de.staropensource.sosengine.base.utility.DependencyResolver;
import de.staropensource.sosengine.base.utility.Miscellaneous;
import de.staropensource.sosengine.base.utility.PlaceholderEngine;
import de.staropensource.sosengine.base.utility.ShortcodeConverter;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
@ -166,7 +165,6 @@ public final class Engine implements SubsystemMainClass {
// Sorted in rough order of dependence
new EngineInformation();
new PlaceholderEngine();
new ShortcodeConverter();
EngineInformation.getInstance().load();
}

View file

@ -29,6 +29,7 @@ import de.staropensource.sosengine.base.events.LogEvent;
import de.staropensource.sosengine.base.logging.placeholders.logger.*;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.classes.logging.LogLevel;
import de.staropensource.sosengine.base.logging.implementation.ColoredLoggerImpl;
import de.staropensource.sosengine.base.utility.PlaceholderEngine;
import lombok.Getter;
import lombok.Setter;
@ -72,7 +73,7 @@ public final class Logger {
@NotNull
@Getter
@Setter
private static LoggerImpl loggerImplementation = new DefaultLoggerImpl();
private static LoggerImpl loggerImplementation = new ColoredLoggerImpl();
/**
* Refers to the logging thread.

View file

@ -17,32 +17,33 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.logging;
package de.staropensource.sosengine.base.logging.implementation;
import de.staropensource.sosengine.base.EngineConfiguration;
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.classes.logging.LogLevel;
import de.staropensource.sosengine.base.utility.ShortcodeConverter;
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.utility.converter.AnsiShortcodeConverter;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.jetbrains.annotations.NotNull;
/**
* The default logger implementation for the StarOpenSource Engine.
* Parses and prints colored log output using the Jansi library.
*
* @see Logger
* @see LoggerImpl
* @since 1-alpha0
*/
@SuppressWarnings("resource")
public class DefaultLoggerImpl implements LoggerImpl {
@SuppressWarnings({ "unused" })
public class ColoredLoggerImpl implements LoggerImpl {
/**
* Constructs this class.
*
* @since 1-alpha0
*/
public DefaultLoggerImpl() {}
public ColoredLoggerImpl() {}
/** {@inheritDoc} */
@NotNull
@ -61,10 +62,11 @@ public class DefaultLoggerImpl implements LoggerImpl {
}
/** {@inheritDoc} */
@SuppressWarnings({ "resource" }) // Using try-with-resources will cause issues here
@Override
public void print(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
// Convert to Ansi
Ansi output = ShortcodeConverter.getInstance().process(message, true);
Ansi output = new AnsiShortcodeConverter(message).getAnsi();
// Print message
if (level == LogLevel.ERROR || level == LogLevel.CRASH)

View file

@ -0,0 +1,74 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Contributors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.logging.implementation;
import de.staropensource.sosengine.base.EngineConfiguration;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.classes.logging.LogLevel;
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.utility.converter.EmptyShortcodeConverter;
import org.jetbrains.annotations.NotNull;
/**
* Prints log messages to the console, without any fancy colors or formatting.
*
* @see Logger
* @see LoggerImpl
* @since 1-alpha1
*/
@SuppressWarnings({ "unused" })
public class PlainLoggerImpl implements LoggerImpl {
/**
* Constructs this class.
*
* @since 1-alpha1
*/
public PlainLoggerImpl() {}
/** {@inheritDoc} */
@NotNull
@Override
public String prePlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
// No modifications necessary
return message;
}
/** {@inheritDoc} */
@NotNull
@Override
public String postPlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
// No modifications necessary
return message;
}
/** {@inheritDoc} */
@Override
public void print(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
message = new EmptyShortcodeConverter(message).getClean();
if (level == LogLevel.ERROR || level == LogLevel.CRASH)
if (EngineConfiguration.getInstance().isLoggerForceStandardOutput())
System.out.println(message);
else
System.err.println(message);
else
System.out.println(message);
}
}

View file

@ -0,0 +1,73 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Contributors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.logging.implementation;
import de.staropensource.sosengine.base.EngineConfiguration;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.classes.logging.LogLevel;
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
import de.staropensource.sosengine.base.logging.Logger;
import org.jetbrains.annotations.NotNull;
/**
* Prints log messages to the console, without performing any message changes.
* Does reveal shortcodes as they are not automatically replaced.
*
* @see Logger
* @see LoggerImpl
* @since 1-alpha1
*/
@SuppressWarnings({ "unused" })
public class RawLoggerImpl implements LoggerImpl {
/**
* Constructs this class.
*
* @since 1-alpha1
*/
public RawLoggerImpl() {}
/** {@inheritDoc} */
@NotNull
@Override
public String prePlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
// No modifications necessary
return message;
}
/** {@inheritDoc} */
@NotNull
@Override
public String postPlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
// No modifications necessary
return message;
}
/** {@inheritDoc} */
@Override
public void print(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
if (level == LogLevel.ERROR || level == LogLevel.CRASH)
if (EngineConfiguration.getInstance().isLoggerForceStandardOutput())
System.out.println(message);
else
System.err.println(message);
else
System.out.println(message);
}
}

View file

@ -17,82 +17,80 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.utility;
package de.staropensource.sosengine.base.types;
import de.staropensource.sosengine.base.Engine;
import de.staropensource.sosengine.base.EngineConfiguration;
import de.staropensource.sosengine.base.classes.logging.LogIssuer;
import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.CodePart;
import lombok.Getter;
import org.fusesource.jansi.Ansi;
import org.jetbrains.annotations.NotNull;
/**
* Converts shortcodes like {@code <red>} or {@code <bold>} into ANSI escape sequences.<br/>
* The following shortcodes are supported: {@code fg:<Ansi.Color>, bg:<Ansi.Color>, attr:<Ansi.Attribute>, bold, italic, strikethrough, underline, blink, italic}
*
* @see Ansi
* @see Ansi.Color
* @see Ansi.Attribute
* @since 1-alpha0
*/
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
public class ShortcodeConverter {
/**
* Contains the class instance.
*
* @since 1-alpha0
*
* -- GETTER --
* Returns the class instance.
*
* @return class instance unless {@link Engine} is uninitialized
* @since 1-alpha0
*/
@Getter
private static ShortcodeConverter instance;
import java.util.ArrayList;
import java.util.List;
/**
* The base skeleton for implementing a shortcode parser.
* <p>
* The following shortcodes are available and can be used:
* <ul>
* <li>reset</li>
* <li>fg:[black,red,green,yellow,blue,magenta,cyan,white]</li>
* <li>bg:[black,red,green,yellow,blue,magenta,cyan,white]</li>
* <li>bold</li>
* <li>italic</li>
* <li>strikethrough</li>
* <li>underline</li>
* <li>blink</li>
* <li>negative</li>
* </ul>
*
* @since 1-alpha1
*/
public abstract class ShortcodeParserSkeleton {
/**
* Logger instance.
*
* @see LoggerInstance
* @since 1-alpha0
* @since 1-alpha1
*/
private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
protected final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
/**
* A list of components the parsed string is made out of.
*
* @since 1-alpha1
*/
@NotNull
@Getter
protected final List<String> components;
/**
* Constructs this class.
*
* @since 1-alpha0
* @param string string to parse
* @since 1-alpha1
*/
public ShortcodeConverter() {
// Only allow one instance
if (instance == null)
instance = this;
else {
Logger.crash(new LogIssuer(getClass(), CodePart.ENGINE), "Tried reinitializing " + getClass().getName() + " twice");
}
public ShortcodeParserSkeleton(@NotNull String string) {
components = parse(string);
}
/**
* Converts shortcodes into ANSI escape sequences.
* Parses an input string and spits out all of it's components.
*
* @param text text to process
* @param noErrors prevents printing tag/shortcode errors, overrides the engine configuration setting
* @return {@link Ansi} sequence
* @param string string to parse
* @return list of components
* @see EngineConfiguration#errorShortcodeConverter
* @since 1-alpha0
* @since 1-alpha1
*/
@NotNull
public Ansi process(@NotNull String text, boolean noErrors) {
Ansi ansi = Ansi.ansi();
private List<@NotNull String> parse(@NotNull String string) {
List<String> components = new ArrayList<>(); // List of components
boolean tagActive = false; // Indicates that a tag is being parsed
String part = ""; // Current part. May be a tag, may be regular text
// Iterate through every character
for (char character : text.toCharArray()) {
for (char character : string.toCharArray()) {
if (tagActive) {
// A tag is being parsed
if (character == '>') {
@ -104,15 +102,12 @@ public class ShortcodeConverter {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
try {
System.out.println("SCC textHash=" + text.hashCode() + " tag=fg data=" + part.substring(3).toUpperCase() + " enum=" + Ansi.Color.valueOf(part.substring(3).toUpperCase()));
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=fg data=" + part.substring(3).toUpperCase() + " enum=" + Ansi.Color.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {
System.out.println("SCC textHash=" + text.hashCode() + " tag=fg data=" + part.substring(3).toUpperCase() + " enum=<invalid>");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=fg data=" + part.substring(3).toUpperCase() + " enum=<invalid>");
}
// Convert text to 'Color' value and insert it on the foreground
try {
ansi.fg(Ansi.Color.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {}
components.add("COLOR:FOREGROUND:" + part.substring(3).toUpperCase());
}
// bg:*
@ -120,101 +115,96 @@ public class ShortcodeConverter {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
try {
System.out.println("SCC textHash=" + text.hashCode() + " tag=bg data=" + part.substring(3).toUpperCase() + " enum=" + Ansi.Color.valueOf(part.substring(3).toUpperCase()));
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=bg data=" + part.substring(3).toUpperCase() + " enum=" + Ansi.Color.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {
System.out.println("SCC textHash=" + text.hashCode() + " tag=bg data=" + part.substring(3).toUpperCase() + " enum=<invalid>");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=bg data=" + part.substring(3).toUpperCase() + " enum=<invalid>");
}
// Convert text to 'Color' value and insert it on the background
try {
ansi.bg(Ansi.Color.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {}
}
// attr:*
else if (part.startsWith("attr:")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
try {
System.out.println("SCC textHash=" + text.hashCode() + " tag=attr data=" + part.substring(3).toUpperCase() + " enum=" + Ansi.Attribute.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {
System.out.println("SCC textHash=" + text.hashCode() + " tag=attr data=" + part.substring(3).toUpperCase() + " enum=<invalid>");
}
// Convert text into 'Attribute' value and insert it
try {
ansi.a(Ansi.Attribute.valueOf(part.substring(3).toUpperCase()));
} catch (IllegalArgumentException ignored) {}
components.add("COLOR:BACKGROUND:" + part.substring(3).toUpperCase());
}
// bold
else if (part.equals("bold")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=bold");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=bold");
// Insert attribute
ansi.a(Ansi.Attribute.INTENSITY_BOLD);
components.add("ATTRIBUTE:BOLD");
}
// italic
else if (part.equals("italic")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=italic");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=italic");
// Insert attribute
ansi.a(Ansi.Attribute.ITALIC);
components.add("ATTRIBUTE:ITALIC");
}
// strikethrough
else if (part.equals("strikethrough")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=strikethrough");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=strikethrough");
// Insert attribute
ansi.a(Ansi.Attribute.STRIKETHROUGH_ON);
components.add("ATTRIBUTE:STRIKETHROUGH");
}
// underline
else if (part.equals("underline")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=underline");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=underline");
// Insert attribute
ansi.a(Ansi.Attribute.UNDERLINE);
components.add("ATTRIBUTE:UNDERLINE");
}
// blink
// underline
else if (part.equals("blink")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=blink");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=blink");
// Insert attribute
ansi.a(Ansi.Attribute.BLINK_SLOW);
components.add("ATTRIBUTE:BLINK");
}
// underline
else if (part.equals("negative")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=negative");
// Insert attribute
components.add("ATTRIBUTE:NEGATIVE");
}
// reset
else if (part.equals("reset")) {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println("SCC textHash=" + text.hashCode() + " tag=reset");
System.out.println(getClass().getName() + "#" + string.hashCode() + " tag=reset");
// Insert reset
ansi.reset();
components.add("RESET");
}
// error case
else {
// Print debug message
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println(getClass().getName() + "#" + string.hashCode() + " invalidtag=" + part);
// Complain about invalid shortcode
if (EngineConfiguration.getInstance().isErrorShortcodeConverter())
logger.sarn("Invalid shortcode: " + part);
// Convert tag regular text
ansi.a("<" + part + ">");
components.add("TEXT:" + "<" + part + ">");
}
// Empty 'part'
@ -226,10 +216,15 @@ public class ShortcodeConverter {
} else {
// Regular text is being parsed
if (character == '<') {
if (!part.isEmpty()) {
// Tag is starting, insert previous text
ansi.a(part);
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println(getClass().getName() + "#" + string.hashCode() + " text=" + part);
components.add("TEXT:" + part);
part = "";
}
part = ""; // Empty 'part'
tagActive = true; // Enable tag processing
} else
// Regular text, add character to 'part'
@ -239,20 +234,13 @@ public class ShortcodeConverter {
}
// Processing ended, insert leftover text
ansi.a(part);
if (!part.isEmpty()) {
if (EngineConfiguration.getInstance().isDebugShortcodeConverter())
System.out.println(getClass().getName() + "#" + string.hashCode() + " endtext=" + part);
return ansi;
components.add("TEXT:" + part);
}
/**
* Converts shortcodes into ANSI escape sequences.
*
* @param text text to process
* @return {@link Ansi} sequence
* @since 1-alpha0
*/
@NotNull
public Ansi process(@NotNull String text) {
return process(text, false);
return components;
}
}

View file

@ -0,0 +1,80 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Contributors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.utility.converter;
import de.staropensource.sosengine.base.types.ShortcodeParserSkeleton;
import org.fusesource.jansi.Ansi;
import org.jetbrains.annotations.NotNull;
/**
* Converts shortcodes such as {@code <bold>} or {@code <blink>} into a usable {@link Ansi} escape sequence.
*
* @see ShortcodeParserSkeleton
* @since 1-alpha0
*/
@SuppressWarnings({ "unused" })
public final class AnsiShortcodeConverter extends ShortcodeParserSkeleton {
/**
* Constructs this class.
*
* @param string string to convert
* @since 1-alpha0
*/
public AnsiShortcodeConverter(@NotNull String string) {
super(string);
}
/**
* Returns the parsed string as an {@link Ansi} sequence.
*
* @return {@link Ansi} sequence
* @since 1-alpha0
*/
@NotNull
public Ansi getAnsi() {
Ansi ansi = Ansi.ansi();
for (String component : components)
if (component.equals("RESET"))
ansi.a(Ansi.Attribute.RESET);
else if (component.startsWith("TEXT:"))
ansi.a(component.substring(5));
else if (component.startsWith("COLOR:"))
if (component.startsWith("COLOR:FOREGROUND:"))
ansi.fg(Ansi.Color.valueOf(component.substring(17)));
else if (component.startsWith("COLOR:BACKGROUND:"))
ansi.bg(Ansi.Color.valueOf(component.substring(17)));
else if (component.startsWith("ATTRIBUTE:"))
if (component.startsWith("ATTRIBUTE:BLINK"))
ansi.a(Ansi.Attribute.BLINK_SLOW);
else if (component.startsWith("ATTRIBUTE:BOLD"))
ansi.a(Ansi.Attribute.INTENSITY_BOLD);
else if (component.startsWith("ATTRIBUTE:ITALIC"))
ansi.a(Ansi.Attribute.ITALIC);
else if (component.startsWith("ATTRIBUTE:STRIKETHROUGH"))
ansi.a(Ansi.Attribute.STRIKETHROUGH_ON);
else if (component.startsWith("ATTRIBUTE:UNDERLINE"))
ansi.a(Ansi.Attribute.UNDERLINE);
else if (component.startsWith("ATTRIBUTE:NEGATIVE"))
ansi.a(Ansi.Attribute.NEGATIVE_ON);
return ansi;
}
}

View file

@ -0,0 +1,59 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Contributors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.base.utility.converter;
import de.staropensource.sosengine.base.types.ShortcodeParserSkeleton;
import org.jetbrains.annotations.NotNull;
/**
* Cleans the string of any tags.
*
* @see ShortcodeParserSkeleton
* @since 1-alpha1
*/
@SuppressWarnings({ "unused" })
public final class EmptyShortcodeConverter extends ShortcodeParserSkeleton {
/**
* Constructs this class.
*
* @param string string to convert
* @since 1-alpha1
*/
public EmptyShortcodeConverter(@NotNull String string) {
super(string);
}
/**
* Returns the parsed string without any tags.
*
* @return cleaned input string
* @since 1-alpha1
*/
@NotNull
public String getClean() {
StringBuilder output = new StringBuilder();
for (String component : components)
if (component.startsWith("TEXT:"))
output.append(component.substring(5));
return output.toString();
}
}