/* WordWrap.java This class provides a static word wrap method. Created: 12 September 1997 Module By: Jonathan Abbey, jonabbey@arlut.utexas.edu ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2010 The University of Texas at Austin Contact information Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package arlut.csd.Util; /*------------------------------------------------------------------------------ class WordWrap ------------------------------------------------------------------------------*/ /** * <P>Handy word wrap module. This class provides the static * {@link arlut.csd.Util.WordWrap#wrap(java.lang.String, int, java.lang.String) wrap()} * method for word-wrapping text strings.</P> * * <P>Used in the Ganymede client and server for utilitarian word-wrapping.</P> * * @version $Id$ * @author Jonathan Abbey, jonabbey@arlut.utexas.edu, ARL:UT */ public class WordWrap { static final boolean debug = false; /* -- */ /** * * This method takes a string and wraps it to a line length of no more than * wrap_length. If prepend is not null, each resulting line will be prefixed * with the prepend string. In that case, resultant line length will be no * more than wrap_length + prepend.length() * */ public static String wrap(String inString, int wrap_length, String prepend) { char[] charAry; int p, p2, offset = 0, marker; StringBuilder result = new StringBuilder(); /* -- */ if (inString == null) { return null; } if (wrap_length < 0) { throw new IllegalArgumentException("bad params"); } if (prepend != null) { result.append(prepend); } if (debug) { System.err.println("String size = " + inString.length()); } charAry = inString.toCharArray(); p = marker = 0; // each time through the loop, p starts out pointing to the same char as marker while (marker < charAry.length) { while (p < charAry.length && (charAry[p] != '\n') && ((p - marker) < wrap_length)) { p++; } if (p == charAry.length) { if (debug) { System.err.println("At completion.."); } result.append(inString.substring(marker, p)); return result.toString(); } if (debug) { System.err.println("Step 1: p = " + p + ", marker = " + marker); } if (charAry[p] == '\n') { /* We've got a newline. This newline is bound to have terminated the while loop above. Step p back one character so that the isspace(*p) check below will detect that it hit the \n, and will do the right thing. */ result.append(inString.substring(marker, p+1)); if (p+1 < charAry.length) { if (prepend != null) { result.append(prepend); } } if (debug) { System.err.println("found natural newline.. current result = " + result.toString()); } p = marker = p+1; continue; } if (debug) { System.err.println("Step 2: hit wrap length, back searching for newline"); } p2 = p-1; /* We've either hit the end of the string, or we've gotten past the wrap_length. Back p2 up to the last space before the wrap_length, if there is such a space. Note that if the next character in the string (the character immediately after the break point) is a space, we don't need to back up at all. We'll just print up to our current location, do the newline, and skip to the next line. */ if (p < charAry.length) { if (isspace(charAry[p])) { offset = 1; /* the next character is white space. We'll want to skip that. */ } else { /* back p2 up to the last white space before the break point */ while ((p2 > marker) && !isspace(charAry[p2])) { p2--; } offset = 0; } } /* If the line was completely filled (no place to break), we'll just copy the whole line out and force a break. */ if (p2 == marker) { p2 = p-1; if (debug) { System.err.println("Step 3: no opportunity for break, forcing.."); } } else { if (debug) { System.err.println("Step 3: found break at column " + p2); } } if (!isspace(charAry[p2])) { /* If weren't were able to back up to a space, copy out the whole line, including the break character (in this case, we'll be making the string one character longer by inserting a newline). */ result.append(inString.substring(marker, p2+1)); } else { /* The break character is whitespace. We'll copy out the characters up to but not including the break character, which we will effectively replace with a newline. */ result.append(inString.substring(marker, p2)); } /* If we have not reached the end of the string, newline */ if (p < charAry.length) { result.append("\n"); if (prepend != null) { result.append(prepend); } } p = marker = p2 + 1 + offset; } return result.toString(); } public static String wrap(String inString, int wrap_length) { return wrap(inString, wrap_length, null); } public static boolean isspace(char c) { return (c == '\n' || c == ' ' || c == '\t'); } /** * <p>This method takes the input String and strips tabs out of it, * replacing them with appropriate spaces.</p> */ public static String deTabify(String input) { StringBuilder result = new StringBuilder(); char characters[] = input.toCharArray(); int j = 0; for (int i = 0; i < characters.length; i++) { if (characters[i] == '\t') { do { result.append(" "); j++; } while (j % 8 != 0); } else { result.append(characters[i]); j++; } } return result.toString(); } public static void main (String args[]) { System.err.println("Word Wrap 20 chars: "); System.err.println(wrap("Mynameisinigomontoyayoukilledmyfatherpreparetodieok?", 20)); System.err.println("Detabify test:"); String input = " Tab A B C D"; System.err.println(deTabify(input)); } }