org.bitbucket.bradleysmithllc.java_cl_parser.StringUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-cl-parser Show documentation
Show all versions of java-cl-parser Show documentation
This parser strives to achieve an elegant, ioc-type interface to make launching command-line projects
effortless.
package org.bitbucket.bradleysmithllc.java_cl_parser;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
public class StringUtil
{
private static final String PUNCTUATION = ".;:'\",`?/\\~!@#$%^&*()-=_+{}[]|<>";
public static List wrapTextToList(String text, int width)
{
if (width <= 1)
{
throw new IllegalArgumentException("Less than two-width is not supported");
}
List list = new ArrayList();
List wordList = splitWords(text);
Stack wordStack = new Stack();
// reverse order so item [0] comes out of the stack first
Collections.reverse(wordList);
wordStack.addAll(wordList);
StringBuilder build = new StringBuilder();
List lineList = new ArrayList();
int currLength = 0;
while (!wordStack.empty())
{
String pop = wordStack.pop();
lineList.add(pop);
currLength += pop.length();
// check if we have exceeded the acceptable length
int minLineLength = currLength + lineList.size() - 1;
if (minLineLength == width)
{
// right on - push it and clear the line
boolean first = true;
for (String word : lineList)
{
if (first)
{
first = false;
}
else
{
build.append(' ');
}
build.append(word);
}
list.add(build.toString());
lineList.clear();
build.setLength(0);
currLength = 0;
}
else if (minLineLength > width)
{
if (lineList.size() == 2)
{
// special case here - just chuck the second and pad to the end
list.add(StringUtils.rightPad(lineList.get(0), width));
wordStack.push(lineList.get(1));
lineList.clear();
build.setLength(0);
currLength = 0;
}
else if (lineList.size() > 1)
{
// take one word off and pad the rest
String lastWord = lineList.remove(lineList.size() - 1);
wordStack.push(lastWord);
currLength -= lastWord.length();
int numGaps = lineList.size() - 1;
int numSpaces = width - currLength;
int numSpacesPerGap = numSpaces / numGaps;
int remainder = numSpaces % numGaps;
for (int wordNum = 0; wordNum < lineList.size(); wordNum++)
{
String word = lineList.get(wordNum);
int numSpacesThisGap = numSpacesPerGap + (wordNum < remainder ? 1 : 0);
build.append(word);
if (wordNum < lineList.size() - 1)
{
for (int spaceNum = 0; spaceNum < numSpacesThisGap; spaceNum++)
{
build.append(' ');
}
}
}
list.add(build.toString());
lineList.clear();
build.setLength(0);
currLength = 0;
}
else
{
// in this case we have a single word which is too big for one line. Hyphenate and continue
build.append(lineList.remove(0));
String fragment = build.substring(0, width - 1) + '-';
build.delete(0, width - 1);
list.add(fragment);
// push it back onto the stack so that it can be processed next, and clear the builder
wordStack.push(build.toString());
build.setLength(0);
currLength = 0;
}
}
}
if (lineList.size() != 0)
{
boolean first = true;
for (String word : lineList)
{
if (first)
{
first = false;
}
else
{
build.append(' ');
}
build.append(word);
}
}
if (build.length() != 0 || list.size() == 0)
{
while (build.length() < width)
{
build.append(' ');
}
list.add(build.toString());
}
return list;
}
/**
* Does two things - strips all non-printable characters and splits on white space
*
* @param text
*/
public static List splitWords(String text)
{
List parts = new ArrayList();
StringBuilder stb = new StringBuilder();
for (int offset = 0; offset < text.length(); offset++)
{
char ch = text.charAt(offset);
boolean javaIdentifierPart = Character.isJavaIdentifierPart(ch);
boolean whitespace = Character.isWhitespace(ch);
boolean punctuation = PUNCTUATION.indexOf(ch) != -1;
// ignore if not in our handled group
if (javaIdentifierPart || whitespace || punctuation)
{
if (!whitespace)
{
stb.append(ch);
}
else
{
if (stb.length() != 0)
{
parts.add(stb.toString());
stb.setLength(0);
}
}
}
}
if (stb.length() != 0)
{
parts.add(stb.toString());
}
return parts;
}
}