Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Word Wrap 1

Status
Not open for further replies.

timesign

Programmer
May 7, 2002
53
US
Hi,
Has anyone seen a word wrap class - or have word wrap code?

Accept a string, perhaps with paragraph break's and insert the "\r\n" so a word that does not fit on the set length of the line, wraps to the next line. should return a string.
Thanks,
 
I don't have javac with me at work or I would test and debug this myself, but this should put you on the right track. The algorithm is to skip through the spaces until we exceed the line length, then back up to the previous space, insert a new line, rinse & repeat until the string is entirely scanned.

Undebugged semi-pseudocode is something like:

public String WordWrap( String s, int lineLen ) {
int charsThisLine = 0;
int totalChars = 0;
String lhs = new String();
while ( totalChars < s.length() ) {
// Still some string to wrap
while ( charsThisLine < lineLen ) {
charsThisLine = s.indexOf(' ', charsThisLine);
}
// We've run off the end of the line, so
// back up, insert a new line, and continue
charsThisLine = s.lastIndexOf(' ', charsThisLine);
// Keep the space at the end of the line rather
// than the beginning of the next line
charsThisLine++;
lhs = s.substring(0, charsThisLine - 1));
s = lhs & '\n' & s.substring(charsThisLine);
totalChars = totalChars + charsThisLine;
charsThisLine = 0;
lhs = &quot;&quot;;
}
return s;
}
 
THanks a load , I will try to work with this,

Any ideas how I would determine where there is a \n\r (chars 10 and 13 as well as 12, hard page) so that if the string already has some hard returns or hard pages I respect them and start my counter over?

Thanks
 
Thanks for your lead -
Here is what I came up with, I modified it a drop I still think it is buggy and would be very happy if there is someone out there who has the code and can share it.
It does not respect existing Paragraphs...

Code:
public String wordWrap( String s, int lineLen ) {
   int charsThisLine = 0;
   int totalChars = 0;
   String lhs = new String();
   FullBreak:{
   while ( totalChars < s.length() ) {
      // Still some string to wrap
      while ( charsThisLine < totalChars + lineLen ) {
        charsThisLine = s.indexOf(' ', charsThisLine+1);
        if(charsThisLine==-1)
          break FullBreak;
      }
      // We've run off the end of the line, so
      // back up, insert a new line, and continue
      charsThisLine = s.lastIndexOf(' ', charsThisLine-1);
      // Keep the space at the end of the line rather
      // than the beginning of the next line
      charsThisLine++;
      lhs =lhs + s.substring(totalChars, charsThisLine - 1) + &quot;\n\r&quot;;
      //s = lhs + '\n' + s.substring(charsThisLine);

      totalChars = charsThisLine;
      //charsThisLine = totalChars;
      //lhs = &quot;&quot;;
   }
   }//end FullBreak
   lhs =lhs + s.substring(totalChars);
   return lhs;
}
 
Give this a shot. I wasn't sure if you wanted the newline before or after the (char)9 and (char)10(char)13, but in this method it comes before. It can easily be changed to insert after those characters.


Code:
  public String WordWrap( String s, int lineLen ) {
  
    // Inserts a newline character before every
    // (char)12 and (char)10(char)13 as well as
    // before every word that causes the lenght
    // of a line to exceed lineLen
    // If a single word exceeds lineLen, it is
    // preserved on its own line.
  
    int charsThisLine = 0;
    int totalChars = 0;
    char c;
    String lhs;
    for ( int i = 0; i < s.length(); i++ ) {
      // Still some string to wrap
      c = s.charAt(i);
      if (( c == 12 ) || (( c == 10 ) && ( s.charAt(i+1) == 13))) {
        // new line
        lhs = s.substring(0, i);
        s = lhs + '\n' + s.substring(i);
        totalChars = i++;
        charsThisLine = 0;
        continue;
      }
      // Surpassed the end of the line
      if ( charsThisLine > lineLen ) {
        // back up to the last space
        i = s.lastIndexOf(' ', i - 1);

        // If there is no earlier space
        if ( i == -1 ) {
          // Then the first word of the string
          // is huge, and we will break at the
          // next space
          i = s.indexOf(' ', totalChars);
          // If there is no later space
          if ( i == -1 ) {
            // The string is one huge word
            // so break at the end
            i = s.length();
          }
        // There is an earlier space
        // If the space is right in front
        // of a newline, then we have a huge
        // word on this line
        } else if ( s.charAt(i+1) == '\n') {
          // So break on the next space
          i = s.indexOf(' ', i + 1);
          // If there is no later space
          if ( i == -1) {
            // The last word is huge and we
            // will break at the end of the line
            i = s.length();
          } else {
            i++;
          }
        // There is an earlier space
        // It is not in front of a newline
        } else {
          i++;
        }

        // Insert the newline
        lhs = s.substring(0, i);
        s = lhs + '\n' + s.substring(i);
        totalChars = i++;
        charsThisLine = 0;
        continue;
      }
      charsThisLine++;
    }
    return s;
  }
 
Thanks a load,
I really appreciate-
I think I got it from here! :)
 
Sorry to bother you-
Code is working GR-E-A-T!

one question , I am having trouble spliting up a long word.
I want at char (len-1) to put in a &quot;-&quot; and let the rest of the word to scroll on the next line, No word should ever go past length.


If you are out of time, I will keep pluging at it and don't bother, -Only if you have a sec.
Thanks a load.
 
Glad to hear it's working well.

I obviously omitted putting hyphens in regular words at the ends of lines because to do so properly, one must split the word into syllables and put the hyphen somewhere in between.

As far as putting a hyphen in words that are longer than the line, I'll do that this evening. I don't have javac or anything java here at work.
 
See how this fits. I included the boolean parameter to define whether or not long words would be hyphenated since the hypens are just put at the end of the lines rather than in between syllables as they should be.


Code:
 public static String WordWrap( String s, int lineLen, boolean hyphen ) {
 
    StringBuffer str = new StringBuffer(s);
 
    // Inserts a newline character before every
    // (char)12 and (char)10(char)13 as well as
    // before every word that causes the lenght
    // of a line to exceed lineLen
    // If a single word exceeds lineLen, it is
    // preserved on its own line.
  
    int charsThisLine = 0;
    int totalChars = 0;
    int lastSpace = 0;
    char c;
    int i = 0;
    while( i < str.length() ) {
      c = str.charAt(i);
      if ( c == ' ' ) lastSpace = i;
      // Insert a new line before (char)12 or
      // (char)10(char)13
      if (( c == 12 ) || (( c == 10 ) && ( i + 1 < str.length() ) &&
         ( str.charAt( i + 1 ) == 13 ))) { 
        str.insert( i++, '\n');
        i++;
        charsThisLine = 0;
        lastSpace = 0;
        totalChars = i;
	continue;
      }

      // End of the line, we must break
      if (charsThisLine++ > lineLen) {
        // If we exceeded the line length with a space
        // we have to find the previous space
        if ( lastSpace == i ) {
          for( int j = i - 1; j > 0; j-- ) {
	    if ( str.charAt(j) == ' ' ) {
	      lastSpace = j;
              break;
            }
          }
        }
        // lastSpace points to the space after which we
        // will break.  If the next character is already
        // a newline, then set lastSpace = 0 to insert
        // a hyphen or break at the next space.
        if ( lastSpace > 0 ) {
          if (( str.length() > lastSpace + 1) && ( str.charAt(lastSpace + 1) != '\n' )) {
            str.insert(++lastSpace, '\n');
            i = lastSpace;
            charsThisLine = 0;
            lastSpace = 0;
            totalChars = i + 1;            
            continue;
          } else {
            lastSpace = 0;
          }
        }
        if ( lastSpace == 0) {
          // If hyphen == true, then insert a hyphen
          // otherwise break at the next space
          if ( hyphen ) {
            str.insert( totalChars + lineLen - 1, '-' );
            str.insert( totalChars + lineLen, '\n' );
            i = totalChars + lineLen;
            charsThisLine = 0;
            lastSpace = 0;
            totalChars = i;
            continue;
          } else {
            // Insert at the next space
            for( int j = totalChars; j < str.length(); j++ ) {
              if ( str.charAt(j) == ' ' ) {
                lastSpace = j;
                break;
              }
            }
            // lastSpace points to either the space
            // after which we will insert the newline
            // or the end of the string
            if ( lastSpace == str.length() ) {
              str.insert(lastSpace, '\n');
            } else {
              str.insert(++lastSpace, '\n');
            }
            i = lastSpace;
            charsThisLine = 0;
            lastSpace = 0;
            totalChars = i;
            continue;
          }
        }
      }
      i++;
    }
    return str.toString();
  }
 
Thanks !!!
Amazing!!
I've been tweaking with it a drop (I didn't want the white space at the end of the line ... ) Perhaps when I am done I will post my modified version
Thanks again

BTW you may want to consider posting it on sourceforge or something like that so that more people can benefit.
 
Hehe, as I scroll down the page to post a reply, I notice that the code grows by 50% with every post.

I'm glad it is working for you. I'm sure you are aware that by eliminating the space characters before the newlines, the task of de-wrapping the text will be a little more complicated. Of course, that is hardly an issue if you never need to do it.

I hesitate to post the code elsewhere until I've had a chance to properly prove the algorithm. I had a heck of a time keep up with i while traveling back and forth and inserting newlines, so I am in no way confident that the method is infallible.

Perhaps with the holiday tomorrow I'll have some time to do a proof. You might find v.3 is 50% longer again. [shadeshappy]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top