personthecat.catlib.util.LibStringUtils Maven / Gradle / Ivy
Show all versions of catlib-quilt Show documentation
package personthecat.catlib.util;
import lombok.experimental.UtilityClass;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
* Contains any utilities needed by the library for manipulating miscellaneous
* string values. Currently provides a single utility for wrapping text onto
* multiple lines, but additional methods may be provided at some point in the
* future.
*/
@UtilityClass
public class LibStringUtils {
private static final Random RAND = new Random();
/**
* Wraps the given text onto multiple lines when given a line length.
*
* @param text The string value being manipulated.
* @param l The maximum number of characters per line.
* @return The wrapped lines as a list of strings.
*/
public static List wrapLines(final String text, final int l) {
if (text.length() < l) return Collections.singletonList(text);
final String normalized = text.replaceAll("\\s+", " ");
final List lines = new ArrayList<>();
int index = 0;
while (index < normalized.length()) {
lines.add(normalized.substring(index, index = getEndOfLine(normalized, index, index + l)));
index++;
}
return lines;
}
/**
* Returns the closest index of a whitespace character, iterating backwards
* from index
.
*
* @param text The normalized body of text, containing only single spaces.
* @param last The last index that was matched by the wrapper.
* @param index The last possible index when given a maximum line length.
* @return The last index of this line.
*/
private static int getEndOfLine(final String text, final int last, final int index) {
if (index > text.length()) {
return text.length();
}
int i = index;
while (--i > last) {
if (text.charAt(i) == ' ') {
return i;
}
}
// Word is longer than the line. Get the whole word.
i = index;
while (++i < text.length()) {
if (text.charAt(i) == ' ') {
return i;
}
}
return text.length();
}
/**
* Generates a random string of characters (a ~ z) of the given length.
*
* @param length The number of characters in the string.
* @return A new string random characters.
*/
public static String randId(final int length) {
final char[] chars = new char[length];
for (int i = 0; i < length; i++) {
chars[i] = (char) (RAND.nextInt(26) + 'a');
}
return new String(chars);
}
/**
* Converts a string in lower case or snake case to title case.
*
* Note that this method does not support camel or pascal
* case by default. You must provide an additional argument to
* optionally support this feature.
*
* @param text The text in lower case or snake case.
* @return The equivalent message in title case.
*/
public static String toTitleCase(final String text) {
return toTitleCase(text, false);
}
/**
* Converts a string in lower, snake, camel, or pascal case to title case.
*
* @param text The text in lower case or snake case.
* @param camel Whether to explicitly support camel and or pascal case.
* @return The equivalent message in title case.
*/
public static String toTitleCase(final String text, final boolean camel) {
if (text.isEmpty()) return "";
final StringBuilder sb = new StringBuilder(text.length());
boolean capitalize = false;
sb.append(Character.toUpperCase(text.charAt(0)));
for (int i = 1; i < text.length(); i++) {
final char c = text.charAt(i);
if (c == ' ' || c == '_' || c == '-') {
capitalize = true;
sb.append(' ');
} else if (capitalize) {
sb.append(Character.toUpperCase(c));
capitalize = false;
} else if (camel && Character.isUpperCase(c)) {
sb.append(' ').append(c);
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Converts a single word to capital case.
*
* @param word The single word of text in any case.
* @return The same word in capital case.
*/
public static String capitalize(final String word) {
if (word.isEmpty()) return "";
if (word.length() == 1) return String.valueOf(Character.toUpperCase(word.charAt(0)));
return Character.toUpperCase(word.charAt(0)) + word.substring(1);
}
/**
* Separates a continuous string of alphanumeric characters into an array
* of words.
*
*
* For example, the following input:
*
* oneTwoThree
*
*
* Will be converted to this array:
*
* [ "one", "Two", "Three" ]
*
*
* @param camel The input text in either camel or pascal case.
* @return An array of words extracted from the text.
*/
public static List tokenize(final String camel) {
if (camel.isEmpty()) return Collections.emptyList();
final List tokens = new ArrayList<>();
int index = 0;
while (index < camel.length()) {
tokens.add(camel.substring(index, index = getNextWord(camel, index)));
}
return tokens;
}
/**
* Returns the next index of a word in the given text.
*
* Note that the given text is assumed to contain no whitespace.
* For this reason, the algorithm may not be ideal for the majority
* of use cases and thus is not exposed here.
*
* @param camel The input text in camel or pascal case.
* @param index The starting index to begin searching from.
* @return The next word, or else the end of the text.
*/
private static int getNextWord(final String camel, int index) {
char c = camel.charAt(index);
int numCapital = 0;
while (Character.isUpperCase(c) && index < camel.length() - 1) {
c = camel.charAt(++index);
numCapital++;
}
// The last character in abbreviations is usually a new word
if (numCapital > 1) {
index--;
} else {
while (Character.isLowerCase(c) && index < camel.length() - 1) {
c = camel.charAt(++index);
}
}
// Get exclusive range for last word.
return index == camel.length() - 1 ? camel.length() : index;
}
}