Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
WordWrapUtils |
|
| 4.6;4.6 |
1 | package org.apache.fulcrum.util; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | import java.util.NoSuchElementException; | |
23 | import java.util.StringTokenizer; | |
24 | ||
25 | import org.apache.commons.lang.StringUtils; | |
26 | /** | |
27 | * <code>WordWrapUtils</code> is a utility class to assist with word wrapping. | |
28 | * | |
29 | * @author Henri Yandell | |
30 | * @author Stephen Colebourne | |
31 | * @version $Id: WordWrapUtils.java 535465 2007-05-05 06:58:06Z tv $ | |
32 | */ | |
33 | 0 | public class WordWrapUtils { |
34 | ||
35 | // Wrapping | |
36 | //-------------------------------------------------------------------------- | |
37 | ||
38 | /** | |
39 | * Wraps a block of text to a specified line length. | |
40 | * <p> | |
41 | * This method takes a block of text, which might have long lines in it | |
42 | * and wraps the long lines based on the supplied wrapColumn parameter. | |
43 | * It was initially implemented for use by VelocityEmail. If there are tabs | |
44 | * in inString, you are going to get results that are a bit strange, | |
45 | * since tabs are a single character but are displayed as 4 or 8 | |
46 | * spaces. Remove the tabs. | |
47 | * | |
48 | * @param str text which is in need of word-wrapping | |
49 | * @param newline the characters that define a newline | |
50 | * @param wrapColumn the column to wrap the words at | |
51 | * @return the text with all the long lines word-wrapped | |
52 | */ | |
53 | public static String wrapText(String str, String newline, int wrapColumn) { | |
54 | 0 | StringTokenizer lineTokenizer = new StringTokenizer(str, newline, true); |
55 | 0 | StringBuffer stringBuffer = new StringBuffer(); |
56 | ||
57 | 0 | while (lineTokenizer.hasMoreTokens()) { |
58 | try { | |
59 | 0 | String nextLine = lineTokenizer.nextToken(); |
60 | ||
61 | 0 | if (nextLine.length() > wrapColumn) { |
62 | // This line is long enough to be wrapped. | |
63 | 0 | nextLine = wrapLine(nextLine, newline, wrapColumn); |
64 | } | |
65 | ||
66 | 0 | stringBuffer.append(nextLine); |
67 | ||
68 | 0 | } catch (NoSuchElementException nsee) { |
69 | // thrown by nextToken(), but I don't know why it would | |
70 | 0 | break; |
71 | 0 | } |
72 | } | |
73 | ||
74 | 0 | return (stringBuffer.toString()); |
75 | } | |
76 | ||
77 | /** | |
78 | * Wraps a single line of text. | |
79 | * Called by wrapText() to do the real work of wrapping. | |
80 | * | |
81 | * @param line a line which is in need of word-wrapping | |
82 | * @param newline the characters that define a newline | |
83 | * @param wrapColumn the column to wrap the words at | |
84 | * @return a line with newlines inserted | |
85 | */ | |
86 | private static String wrapLine(String line, String newline, int wrapColumn) { | |
87 | 0 | StringBuffer wrappedLine = new StringBuffer(); |
88 | ||
89 | 0 | while (line.length() > wrapColumn) { |
90 | 0 | int spaceToWrapAt = line.lastIndexOf(' ', wrapColumn); |
91 | ||
92 | 0 | if (spaceToWrapAt >= 0) { |
93 | 0 | wrappedLine.append(line.substring(0, spaceToWrapAt)); |
94 | 0 | wrappedLine.append(newline); |
95 | 0 | line = line.substring(spaceToWrapAt + 1); |
96 | } | |
97 | ||
98 | // This must be a really long word or URL. Pass it | |
99 | // through unchanged even though it's longer than the | |
100 | // wrapColumn would allow. This behavior could be | |
101 | // dependent on a parameter for those situations when | |
102 | // someone wants long words broken at line length. | |
103 | else { | |
104 | 0 | spaceToWrapAt = line.indexOf(' ', wrapColumn); |
105 | ||
106 | 0 | if (spaceToWrapAt >= 0) { |
107 | 0 | wrappedLine.append(line.substring(0, spaceToWrapAt)); |
108 | 0 | wrappedLine.append(newline); |
109 | 0 | line = line.substring(spaceToWrapAt + 1); |
110 | } else { | |
111 | 0 | wrappedLine.append(line); |
112 | 0 | line = ""; |
113 | } | |
114 | } | |
115 | 0 | } |
116 | ||
117 | // Whatever is left in line is short enough to just pass through | |
118 | 0 | wrappedLine.append(line); |
119 | ||
120 | 0 | return (wrappedLine.toString()); |
121 | } | |
122 | ||
123 | // Word wrapping | |
124 | //-------------------------------------------------------------------------- | |
125 | ||
126 | /** | |
127 | * Create a word-wrapped version of a String. Wrap at 80 characters and | |
128 | * use newlines as the delimiter. If a word is over 80 characters long | |
129 | * use a - sign to split it. | |
130 | */ | |
131 | public static String wordWrap(String str) { | |
132 | 0 | return wordWrap(str, 80, "\n", "-"); |
133 | } | |
134 | /** | |
135 | * Create a word-wrapped version of a String. Wrap at a specified width and | |
136 | * use newlines as the delimiter. If a word is over the width in lenght | |
137 | * use a - sign to split it. | |
138 | */ | |
139 | public static String wordWrap(String str, int width) { | |
140 | 0 | return wordWrap(str, width, "\n", "-"); |
141 | } | |
142 | /** | |
143 | * Word-wrap a string. | |
144 | * | |
145 | * @param str String to word-wrap | |
146 | * @param width int to wrap at | |
147 | * @param delim String to use to separate lines | |
148 | * @param split String to use to split a word greater than width long | |
149 | * | |
150 | * @return String that has been word wrapped | |
151 | */ | |
152 | public static String wordWrap(String str, int width, String delim, String split) { | |
153 | 0 | int sz = str.length(); |
154 | ||
155 | /// shift width up one. mainly as it makes the logic easier | |
156 | 0 | width++; |
157 | ||
158 | // our best guess as to an initial size | |
159 | 0 | StringBuffer buffer = new StringBuffer(sz / width * delim.length() + sz); |
160 | ||
161 | // every line will include a delim on the end | |
162 | 0 | width = width - delim.length(); |
163 | ||
164 | 0 | int idx = -1; |
165 | 0 | String substr = null; |
166 | ||
167 | // beware: i is rolled-back inside the loop | |
168 | 0 | for (int i = 0; i < sz; i += width) { |
169 | ||
170 | // on the last line | |
171 | 0 | if (i > sz - width) { |
172 | 0 | buffer.append(str.substring(i)); |
173 | 0 | break; |
174 | } | |
175 | ||
176 | // the current line | |
177 | 0 | substr = str.substring(i, i + width); |
178 | ||
179 | // is the delim already on the line | |
180 | 0 | idx = substr.indexOf(delim); |
181 | 0 | if (idx != -1) { |
182 | 0 | buffer.append(substr.substring(0, idx)); |
183 | 0 | buffer.append(delim); |
184 | 0 | i -= width - idx - delim.length(); |
185 | ||
186 | // Erase a space after a delim. Is this too obscure? | |
187 | 0 | if (substr.charAt(idx + 1) != '\n') { |
188 | 0 | if (Character.isWhitespace(substr.charAt(idx + 1))) { |
189 | 0 | i++; |
190 | } | |
191 | } | |
192 | continue; | |
193 | } | |
194 | ||
195 | 0 | idx = -1; |
196 | ||
197 | // figure out where the last space is | |
198 | 0 | char[] chrs = substr.toCharArray(); |
199 | 0 | for (int j = width; j > 0; j--) { |
200 | 0 | if (Character.isWhitespace(chrs[j - 1])) { |
201 | 0 | idx = j; |
202 | 0 | break; |
203 | } | |
204 | } | |
205 | ||
206 | // idx is the last whitespace on the line. | |
207 | 0 | if (idx == -1) { |
208 | 0 | for (int j = width; j > 0; j--) { |
209 | 0 | if (chrs[j - 1] == '-') { |
210 | 0 | idx = j; |
211 | 0 | break; |
212 | } | |
213 | } | |
214 | 0 | if (idx == -1) { |
215 | 0 | buffer.append(substr); |
216 | 0 | buffer.append(delim); |
217 | } else { | |
218 | 0 | if (idx != width) { |
219 | 0 | idx++; |
220 | } | |
221 | 0 | buffer.append(substr.substring(0, idx)); |
222 | 0 | buffer.append(delim); |
223 | 0 | i -= width - idx; |
224 | } | |
225 | } else { | |
226 | // insert spaces | |
227 | 0 | buffer.append(substr.substring(0, idx)); |
228 | 0 | buffer.append(StringUtils.repeat(" ", width - idx)); |
229 | 0 | buffer.append(delim); |
230 | 0 | i -= width - idx; |
231 | } | |
232 | } | |
233 | 0 | return buffer.toString(); |
234 | } | |
235 | ||
236 | } |