user2288625
user2288625

Reputation: 255

Set line length for a string

The problem I'm trying to solve is given a string that may contain carriage returns, insert additional carriage returns such that each line does not exceed a set number of characters. Also it should try to keep a word intact if possible.

Is there a library in either Java or Scala that does what I need?

Upvotes: 2

Views: 2587

Answers (4)

user2288625
user2288625

Reputation: 255

If anybody is interested my final solution used Apache Commons WordUtils, thanks to Joni for pointing the WordUtils out to me.

private static String wrappify(String source, int lineLength, String eolMarker){
    String[] lines = source.split(eolMarker);
    StringBuffer wrappedStr = new StringBuffer();

    for (String line : lines) {
        if(line.length() <= lineLength){
            wrappedStr.append(line + eolMarker);
        }else{
            wrappedStr.append(WordUtils.wrap(line, lineLength, eolMarker, true) + eolMarker);
        }

    }

    return wrappedStr.replace(wrappedStr.lastIndexOf(eolMarker), wrappedStr.length(), "").toString();
}

Upvotes: 0

eric.frigot
eric.frigot

Reputation: 90

I think you can start with something like that. Note that you will have to handle the special case when a word is more than the MAX_LINE_LENGTH.

package com.ekse.nothing;

public class LimitColumnSize {

private static String DATAS = "It was 1998 and the dot-com boom was in full effect. I was making websites as a 22 year old freelance programmer in NYC. I charged my first client $1,400. My second client paid $5,400. The next paid $24,000. I remember the exact amounts — they were the largest checks I’d seen up til that point.\n"
                + "Then I wrote a proposal for $340,000 to help an online grocery store with their website. I had 5 full time engineers at that point (all working from my apartment) but it was still a ton of dough. The client approved, but wanted me to sign a contract — everything had been handshakes up til then.\n"
                + "No prob. Sent the contract to my lawyer. She marked it up, sent it to the client. Then the client marked it up and sent it back to my lawyer. And so on, back and forth for almost a month. I was inexperienced and believed that this is just how business was done."
                + "Annoyed by my lawyering, the client eventually gave up and hired someone else.";

private static int MAX_LINE_LENGTH = 80;

private static char[] BREAKING_CHAR = {' ', ',', ';', '!', '?', ')', ']', '}'}; // Probably some others

public static void main(String[] args) {
    String current = DATAS;
    String result = "";
    while (current.length() != 0) {
        for (int i = (current.length() - 1) < MAX_LINE_LENGTH ? current.length() - 1 : MAX_LINE_LENGTH; i >= 0; i--) {
            if (current.charAt(i) == '\n') {
                result += current.substring(0, i);
                current = current.substring(i + 1);
                break;
            } else if (isBreakingChar(current.charAt(i))) {
                result += current.substring(0, i) + "\n";    
                current = current.substring(i + 1);
                break;
            } else if (i == 0 && (current.length() - 1) < MAX_LINE_LENGTH) {
                result += current;
                current = "";
            } else {
                // Line cannot be break, try to go to the right and find the next BREAKING_CHAR
            }
        }
    }
    System.out.println(result);
}

private static boolean isBreakingChar(char c) {
    for (int i = 0; i < BREAKING_CHAR.length; ++i) {
        if (c == BREAKING_CHAR[i]) {
            return true;
        }
    }
    return false;
}

}

Upvotes: 0

Cruncher
Cruncher

Reputation: 7812

    public static String addReturns(String s, int maxLength)
    {
        String newString = "";
        int ind = 0;
        while(ind < s.length())
        {
            String temp = s.substring(ind, Math.min(s.length(), ind+maxLength));
            int lastSpace = temp.lastIndexOf(" ");
            int firstNewline = temp.indexOf("\n");
            if(firstNewline>-1)
            {
                newString += temp.substring(0, firstNewline + 1);
                ind += firstNewline + 1;
            }
            else if(lastSpace>-1)
            {
                newString += temp.substring(0, lastSpace + 1) + "\n";
                ind += lastSpace + 1;
            }
            else
            {
                newString += temp + "\n";
                ind += maxLength;
            }


        }
        return newString;
    }

This will do the trick if you don't want to use regular expressions.

System.out.println(addReturns("Hi there, I'm testing to see if this\nalgorithm is going to work or not. Let's see. ThisIsAReallyLongWordThatShouldGetSplitUp", 20));

Output:

Hi there, I'm 
testing to see if 
this
algorithm is going 
to work or not. 
Let's see. 
ThisIsAReallyLongWor
dThatShouldGetSplitU
p

Upvotes: 0

Joni
Joni

Reputation: 111299

There is a BreakIterator class in the java.text package that can tell you where you could insert a line break, but it's a little complicated to use. A regular expression like this can do 80% of the job:

str += "\n"; // Needed to handle last line correctly
// insert line break after max 50 chars on a line
str = str.replaceAll("(.{1,50})\\s+", "$1\n");

The Apache commons lang library has a WordUtils class, which includes a wrap method, to wrap a long line of text to several lines of given length on word boundaries.

Upvotes: 3

Related Questions