PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/TextUtilities.java

#
Java | 828 lines | 534 code | 70 blank | 224 comment | 134 complexity | cfbd9d3f417729d5dd8478532373ccfb MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * TextUtilities.java - Various text functions
  3. * Copyright (C) 1998, 2005 Slava Pestov
  4. * :tabSize=8:indentSize=8:noTabs=false:
  5. * :folding=explicit:collapseFolds=1:
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package org.gjt.sp.jedit;
  22. //{{{ Imports
  23. import java.util.*;
  24. import javax.swing.text.Segment;
  25. import org.gjt.sp.jedit.buffer.JEditBuffer;
  26. import org.gjt.sp.jedit.syntax.*;
  27. import org.gjt.sp.util.StandardUtilities;
  28. //}}}
  29. /**
  30. * Contains several text manipulation methods.
  31. *
  32. * <ul>
  33. * <li>Bracket matching
  34. * <li>Word start and end offset calculation
  35. * <li>String comparison
  36. * <li>Converting tabs to spaces and vice versa
  37. * <li>Wrapping text
  38. * <li>String case conversion
  39. * </ul>
  40. *
  41. * @author Slava Pestov
  42. * @version $Id: TextUtilities.java 5485 2006-06-23 22:04:58Z kpouer $
  43. */
  44. public class TextUtilities
  45. {
  46. // to avoid slowdown with large files; only scan 10000 lines either way
  47. public static final int BRACKET_MATCH_LIMIT = 10000;
  48. //{{{ getTokenAtOffset() method
  49. /**
  50. * Returns the token that contains the specified offset.
  51. * @param tokens The token list
  52. * @param offset The offset
  53. * @since jEdit 4.0pre3
  54. */
  55. public static Token getTokenAtOffset(Token tokens, int offset)
  56. {
  57. if(offset == 0 && tokens.id == Token.END)
  58. return tokens;
  59. for(;;)
  60. {
  61. if(tokens.id == Token.END)
  62. throw new ArrayIndexOutOfBoundsException("offset > line length");
  63. if(tokens.offset + tokens.length > offset)
  64. return tokens;
  65. else
  66. tokens = tokens.next;
  67. }
  68. } //}}}
  69. //{{{ getComplementaryBracket() method
  70. /**
  71. * Given an opening bracket, return the corresponding closing bracket
  72. * and store true in <code>direction[0]</code>. Given a closing bracket,
  73. * return the corresponding opening bracket and store false in
  74. * <code>direction[0]</code>. Otherwise, return <code>\0</code>.
  75. * @since jEdit 4.3pre2
  76. */
  77. public static char getComplementaryBracket(char ch, boolean[] direction)
  78. {
  79. switch(ch)
  80. {
  81. case '(': direction[0] = true; return ')';
  82. case ')': direction[0] = false; return '(';
  83. case '[': direction[0] = true; return ']';
  84. case ']': direction[0] = false; return '[';
  85. case '{': direction[0] = true; return '}';
  86. case '}': direction[0] = false; return '{';
  87. default: return '\0';
  88. }
  89. } //}}}
  90. //{{{ findMatchingBracket() method
  91. /**
  92. * Returns the offset of the bracket matching the one at the
  93. * specified offset of the buffer, or -1 if the bracket is
  94. * unmatched (or if the character is not a bracket).
  95. * @param buffer The buffer
  96. * @param line The line
  97. * @param offset The offset within that line
  98. * @since jEdit 2.6pre1
  99. */
  100. public static int findMatchingBracket(JEditBuffer buffer, int line, int offset)
  101. {
  102. if(offset < 0 || offset >= buffer.getLineLength(line))
  103. {
  104. throw new ArrayIndexOutOfBoundsException(offset + ":"
  105. + buffer.getLineLength(line));
  106. }
  107. Segment lineText = new Segment();
  108. buffer.getLineText(line,lineText);
  109. char c = lineText.array[lineText.offset + offset];
  110. // false - backwards, true - forwards
  111. boolean[] direction = new boolean[1];
  112. // corresponding character
  113. char cprime = getComplementaryBracket(c,direction);
  114. // 1 because we've already 'seen' the first bracket
  115. int count = 1;
  116. DefaultTokenHandler tokenHandler = new DefaultTokenHandler();
  117. buffer.markTokens(line,tokenHandler);
  118. // Get the syntax token at 'offset'
  119. // only tokens with the same type will be checked for
  120. // the corresponding bracket
  121. byte idOfBracket = getTokenAtOffset(tokenHandler.getTokens(),offset).id;
  122. boolean haveTokens = true;
  123. int startLine = line;
  124. //{{{ Forward search
  125. if(direction[0])
  126. {
  127. offset++;
  128. for(;;)
  129. {
  130. for(int i = offset; i < lineText.count; i++)
  131. {
  132. char ch = lineText.array[lineText.offset + i];
  133. if(ch == c)
  134. {
  135. if(!haveTokens)
  136. {
  137. tokenHandler.init();
  138. buffer.markTokens(line,tokenHandler);
  139. haveTokens = true;
  140. }
  141. if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket)
  142. count++;
  143. }
  144. else if(ch == cprime)
  145. {
  146. if(!haveTokens)
  147. {
  148. tokenHandler.init();
  149. buffer.markTokens(line,tokenHandler);
  150. haveTokens = true;
  151. }
  152. if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket)
  153. {
  154. count--;
  155. if(count == 0)
  156. return buffer.getLineStartOffset(line) + i;
  157. }
  158. }
  159. }
  160. //{{{ Go on to next line
  161. line++;
  162. if(line >= buffer.getLineCount() || (line - startLine) > BRACKET_MATCH_LIMIT)
  163. break;
  164. buffer.getLineText(line,lineText);
  165. offset = 0;
  166. haveTokens = false;
  167. //}}}
  168. }
  169. } //}}}
  170. //{{{ Backward search
  171. else
  172. {
  173. offset--;
  174. for(;;)
  175. {
  176. for(int i = offset; i >= 0; i--)
  177. {
  178. char ch = lineText.array[lineText.offset + i];
  179. if(ch == c)
  180. {
  181. if(!haveTokens)
  182. {
  183. tokenHandler.init();
  184. buffer.markTokens(line,tokenHandler);
  185. haveTokens = true;
  186. }
  187. if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket)
  188. count++;
  189. }
  190. else if(ch == cprime)
  191. {
  192. if(!haveTokens)
  193. {
  194. tokenHandler.init();
  195. buffer.markTokens(line,tokenHandler);
  196. haveTokens = true;
  197. }
  198. if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket)
  199. {
  200. count--;
  201. if(count == 0)
  202. return buffer.getLineStartOffset(line) + i;
  203. }
  204. }
  205. }
  206. //{{{ Go on to previous line
  207. line--;
  208. if(line < 0 || (startLine - line) > BRACKET_MATCH_LIMIT)
  209. break;
  210. buffer.getLineText(line,lineText);
  211. offset = lineText.count - 1;
  212. haveTokens = false;
  213. //}}}
  214. }
  215. } //}}}
  216. // Nothing found
  217. return -1;
  218. } //}}}
  219. //{{{ findWordStart() method
  220. /**
  221. * Locates the start of the word at the specified position.
  222. * @param line The text
  223. * @param pos The position
  224. * @param noWordSep Characters that are non-alphanumeric, but
  225. * should be treated as word characters anyway
  226. */
  227. public static int findWordStart(String line, int pos, String noWordSep)
  228. {
  229. return findWordStart(line, pos, noWordSep, true, false);
  230. } //}}}
  231. /** Similar to perl's join() method on lists,
  232. * but works with all collections.
  233. *
  234. * @param c An iterable collection of Objects
  235. * @param delim a string to put between each object
  236. * @return a joined toString() representation of the collection
  237. *
  238. * @since jedit 4.3pre3
  239. */
  240. public static String join(Collection c, String delim) {
  241. StringBuffer retval = new StringBuffer();
  242. Iterator itr = c.iterator();
  243. if (itr.hasNext()) {
  244. retval.append( itr.next().toString() );
  245. }
  246. else return "";
  247. while (itr.hasNext()) {
  248. retval.append(delim);
  249. retval.append(itr.next().toString());
  250. }
  251. return retval.toString();
  252. }
  253. //{{{ findWordStart() method
  254. /**
  255. * Locates the start of the word at the specified position.
  256. * @param line The text
  257. * @param pos The position
  258. * @param noWordSep Characters that are non-alphanumeric, but
  259. * should be treated as word characters anyway
  260. * @param joinNonWordChars Treat consecutive non-alphanumeric
  261. * characters as one word
  262. * @since jEdit 4.2pre5
  263. */
  264. public static int findWordStart(String line, int pos, String noWordSep,
  265. boolean joinNonWordChars)
  266. {
  267. return findWordStart(line,pos,noWordSep,joinNonWordChars,false);
  268. } //}}}
  269. //{{{ findWordStart() method
  270. /**
  271. * Locates the start of the word at the specified position.
  272. * @param line The text
  273. * @param pos The position
  274. * @param noWordSep Characters that are non-alphanumeric, but
  275. * should be treated as word characters anyway
  276. * @param joinNonWordChars Treat consecutive non-alphanumeric
  277. * characters as one word
  278. * @param eatWhitespace Include whitespace at start of word
  279. * @since jEdit 4.1pre2
  280. */
  281. public static int findWordStart(String line, int pos, String noWordSep,
  282. boolean joinNonWordChars, boolean eatWhitespace)
  283. {
  284. char ch = line.charAt(pos);
  285. if(noWordSep == null)
  286. noWordSep = "";
  287. //{{{ the character under the cursor changes how we behave.
  288. int type;
  289. if(Character.isWhitespace(ch))
  290. type = WHITESPACE;
  291. else if(Character.isLetterOrDigit(ch)
  292. || noWordSep.indexOf(ch) != -1)
  293. type = WORD_CHAR;
  294. else
  295. type = SYMBOL;
  296. //}}}
  297. loop: for(int i = pos; i >= 0; i--)
  298. {
  299. ch = line.charAt(i);
  300. switch(type)
  301. {
  302. //{{{ Whitespace...
  303. case WHITESPACE:
  304. // only select other whitespace in this case
  305. if(Character.isWhitespace(ch))
  306. break;
  307. // word char or symbol; stop
  308. else
  309. return i + 1; //}}}
  310. //{{{ Word character...
  311. case WORD_CHAR:
  312. // word char; keep going
  313. if(Character.isLetterOrDigit(ch) ||
  314. noWordSep.indexOf(ch) != -1)
  315. {
  316. break;
  317. }
  318. // whitespace; include in word if eating
  319. else if(Character.isWhitespace(ch)
  320. && eatWhitespace)
  321. {
  322. type = WHITESPACE;
  323. break;
  324. }
  325. else
  326. return i + 1; //}}}
  327. //{{{ Symbol...
  328. case SYMBOL:
  329. if(!joinNonWordChars && pos != i)
  330. return i + 1;
  331. // whitespace; include in word if eating
  332. if(Character.isWhitespace(ch))
  333. {
  334. if(eatWhitespace)
  335. {
  336. type = WHITESPACE;
  337. break;
  338. }
  339. else
  340. return i + 1;
  341. }
  342. else if(Character.isLetterOrDigit(ch) ||
  343. noWordSep.indexOf(ch) != -1)
  344. {
  345. return i + 1;
  346. }
  347. else
  348. {
  349. break;
  350. } //}}}
  351. }
  352. }
  353. return 0;
  354. } //}}}
  355. //{{{ findWordEnd() method
  356. /**
  357. * Locates the end of the word at the specified position.
  358. * @param line The text
  359. * @param pos The position
  360. * @param noWordSep Characters that are non-alphanumeric, but
  361. * should be treated as word characters anyway
  362. */
  363. public static int findWordEnd(String line, int pos, String noWordSep)
  364. {
  365. return findWordEnd(line, pos, noWordSep, true);
  366. } //}}}
  367. //{{{ findWordEnd() method
  368. /**
  369. * Locates the end of the word at the specified position.
  370. * @param line The text
  371. * @param pos The position
  372. * @param noWordSep Characters that are non-alphanumeric, but
  373. * should be treated as word characters anyway
  374. * @param joinNonWordChars Treat consecutive non-alphanumeric
  375. * characters as one word
  376. * @since jEdit 4.1pre2
  377. */
  378. public static int findWordEnd(String line, int pos, String noWordSep,
  379. boolean joinNonWordChars)
  380. {
  381. return findWordEnd(line,pos,noWordSep,joinNonWordChars,false);
  382. } //}}}
  383. //{{{ findWordEnd() method
  384. /**
  385. * Locates the end of the word at the specified position.
  386. * @param line The text
  387. * @param pos The position
  388. * @param noWordSep Characters that are non-alphanumeric, but
  389. * should be treated as word characters anyway
  390. * @param joinNonWordChars Treat consecutive non-alphanumeric
  391. * characters as one word
  392. * @param eatWhitespace Include whitespace at end of word
  393. * @since jEdit 4.2pre5
  394. */
  395. public static int findWordEnd(String line, int pos, String noWordSep,
  396. boolean joinNonWordChars, boolean eatWhitespace)
  397. {
  398. if(pos != 0)
  399. pos--;
  400. char ch = line.charAt(pos);
  401. if(noWordSep == null)
  402. noWordSep = "";
  403. //{{{ the character under the cursor changes how we behave.
  404. int type;
  405. if(Character.isWhitespace(ch))
  406. type = WHITESPACE;
  407. else if(Character.isLetterOrDigit(ch)
  408. || noWordSep.indexOf(ch) != -1)
  409. type = WORD_CHAR;
  410. else
  411. type = SYMBOL;
  412. //}}}
  413. loop: for(int i = pos; i < line.length(); i++)
  414. {
  415. ch = line.charAt(i);
  416. switch(type)
  417. {
  418. //{{{ Whitespace...
  419. case WHITESPACE:
  420. // only select other whitespace in this case
  421. if(Character.isWhitespace(ch))
  422. break;
  423. else
  424. return i; //}}}
  425. //{{{ Word character...
  426. case WORD_CHAR:
  427. if(Character.isLetterOrDigit(ch) ||
  428. noWordSep.indexOf(ch) != -1)
  429. {
  430. break;
  431. }
  432. // whitespace; include in word if eating
  433. else if(Character.isWhitespace(ch)
  434. && eatWhitespace)
  435. {
  436. type = WHITESPACE;
  437. break;
  438. }
  439. else
  440. return i; //}}}
  441. //{{{ Symbol...
  442. case SYMBOL:
  443. if(!joinNonWordChars && i != pos)
  444. return i;
  445. // if we see whitespace, set flag.
  446. if(Character.isWhitespace(ch))
  447. {
  448. if(eatWhitespace)
  449. {
  450. type = WHITESPACE;
  451. break;
  452. }
  453. else
  454. return i;
  455. }
  456. else if(Character.isLetterOrDigit(ch) ||
  457. noWordSep.indexOf(ch) != -1)
  458. {
  459. return i;
  460. }
  461. else
  462. {
  463. break;
  464. } //}}}
  465. }
  466. }
  467. return line.length();
  468. } //}}}
  469. //{{{ spacesToTabs() method
  470. /**
  471. * Converts consecutive spaces to tabs in the specified string.
  472. * @param in The string
  473. * @param tabSize The tab size
  474. */
  475. public static String spacesToTabs(String in, int tabSize)
  476. {
  477. StringBuffer buf = new StringBuffer();
  478. int width = 0;
  479. int whitespace = 0;
  480. for(int i = 0; i < in.length(); i++)
  481. {
  482. switch(in.charAt(i))
  483. {
  484. case ' ':
  485. whitespace++;
  486. width++;
  487. break;
  488. case '\t':
  489. int tab = tabSize - (width % tabSize);
  490. width += tab;
  491. whitespace += tab;
  492. break;
  493. case '\n':
  494. if(whitespace != 0)
  495. {
  496. buf.append(StandardUtilities
  497. .createWhiteSpace(whitespace,tabSize,
  498. width - whitespace));
  499. }
  500. whitespace = 0;
  501. width = 0;
  502. buf.append('\n');
  503. break;
  504. default:
  505. if(whitespace != 0)
  506. {
  507. buf.append(StandardUtilities
  508. .createWhiteSpace(whitespace,tabSize,
  509. width - whitespace));
  510. whitespace = 0;
  511. }
  512. buf.append(in.charAt(i));
  513. width++;
  514. break;
  515. }
  516. }
  517. if(whitespace != 0)
  518. {
  519. buf.append(StandardUtilities.createWhiteSpace(whitespace,tabSize,
  520. width - whitespace));
  521. }
  522. return buf.toString();
  523. } //}}}
  524. //{{{ tabsToSpaces() method
  525. /**
  526. * Converts tabs to consecutive spaces in the specified string.
  527. * @param in The string
  528. * @param tabSize The tab size
  529. */
  530. public static String tabsToSpaces(String in, int tabSize)
  531. {
  532. StringBuffer buf = new StringBuffer();
  533. int width = 0;
  534. for(int i = 0; i < in.length(); i++)
  535. {
  536. switch(in.charAt(i))
  537. {
  538. case '\t':
  539. int count = tabSize - (width % tabSize);
  540. width += count;
  541. while(--count >= 0)
  542. buf.append(' ');
  543. break;
  544. case '\n':
  545. width = 0;
  546. buf.append(in.charAt(i));
  547. break;
  548. default:
  549. width++;
  550. buf.append(in.charAt(i));
  551. break;
  552. }
  553. }
  554. return buf.toString();
  555. } //}}}
  556. //{{{ format() method
  557. /**
  558. * Formats the specified text by merging and breaking lines to the
  559. * specified width.
  560. * @param text The text
  561. * @param maxLineLength The maximum line length
  562. * @param tabSize The tab size
  563. */
  564. public static String format(String text, int maxLineLength, int tabSize)
  565. {
  566. StringBuffer buf = new StringBuffer();
  567. int index = 0;
  568. for(;;)
  569. {
  570. int newIndex = text.indexOf("\n\n",index);
  571. if(newIndex == -1)
  572. break;
  573. formatParagraph(text.substring(index,newIndex),
  574. maxLineLength,tabSize,buf);
  575. buf.append("\n\n");
  576. index = newIndex + 2;
  577. }
  578. if(index != text.length())
  579. {
  580. formatParagraph(text.substring(index),
  581. maxLineLength,tabSize,buf);
  582. }
  583. return buf.toString();
  584. } //}}}
  585. //{{{ indexIgnoringWhitespace() method
  586. /**
  587. * Inverse of <code>ignoringWhitespaceIndex()</code>.
  588. * @param str A string
  589. * @param index The index
  590. * @return The number of non-whitespace characters that precede the index.
  591. * @since jEdit 4.3pre2
  592. */
  593. public static int indexIgnoringWhitespace(String str, int index)
  594. {
  595. int j = 0;
  596. for(int i = 0; i < index; i++)
  597. if(!Character.isWhitespace(str.charAt(i))) j++;
  598. return j;
  599. } //}}}
  600. //{{{ ignoringWhitespaceIndex() method
  601. /**
  602. * Inverse of <code>indexIgnoringWhitespace()</code>.
  603. * @param str A string
  604. * @param index The index
  605. * @return The index into the string where the number of non-whitespace
  606. * characters that precede the index is count.
  607. * @since jEdit 4.3pre2
  608. */
  609. public static int ignoringWhitespaceIndex(String str, int index)
  610. {
  611. int j = 0;
  612. for(int i = 0;;i++)
  613. {
  614. if(!Character.isWhitespace(str.charAt(i))) j++;
  615. if(j > index)
  616. return i;
  617. if(i == str.length() - 1)
  618. return i + 1;
  619. }
  620. } //}}}
  621. //{{{ getStringCase() method
  622. public static final int MIXED = 0;
  623. public static final int LOWER_CASE = 1;
  624. public static final int UPPER_CASE = 2;
  625. public static final int TITLE_CASE = 3;
  626. /**
  627. * Returns if the specified string is all upper case, all lower case,
  628. * or title case (first letter upper case, rest lower case).
  629. * @param str The string
  630. * @since jEdit 4.0pre1
  631. */
  632. public static int getStringCase(String str)
  633. {
  634. if(str.length() == 0)
  635. return MIXED;
  636. int state = -1;
  637. char ch = str.charAt(0);
  638. if(Character.isLetter(ch))
  639. {
  640. if(Character.isUpperCase(ch))
  641. state = UPPER_CASE;
  642. else
  643. state = LOWER_CASE;
  644. }
  645. for(int i = 1; i < str.length(); i++)
  646. {
  647. ch = str.charAt(i);
  648. if(!Character.isLetter(ch))
  649. continue;
  650. switch(state)
  651. {
  652. case UPPER_CASE:
  653. if(Character.isLowerCase(ch))
  654. {
  655. if(i == 1)
  656. state = TITLE_CASE;
  657. else
  658. return MIXED;
  659. }
  660. break;
  661. case LOWER_CASE:
  662. case TITLE_CASE:
  663. if(Character.isUpperCase(ch))
  664. return MIXED;
  665. break;
  666. }
  667. }
  668. return state;
  669. } //}}}
  670. //{{{ toTitleCase() method
  671. /**
  672. * Converts the specified string to title case, by capitalizing the
  673. * first letter.
  674. * @param str The string
  675. * @since jEdit 4.0pre1
  676. */
  677. public static String toTitleCase(String str)
  678. {
  679. if(str.length() == 0)
  680. return str;
  681. else
  682. {
  683. return Character.toUpperCase(str.charAt(0))
  684. + str.substring(1).toLowerCase();
  685. }
  686. } //}}}
  687. //{{{ Private members
  688. private static final int WHITESPACE = 0;
  689. private static final int WORD_CHAR = 1;
  690. private static final int SYMBOL = 2;
  691. //{{{ formatParagraph() method
  692. private static void formatParagraph(String text, int maxLineLength,
  693. int tabSize, StringBuffer buf)
  694. {
  695. // align everything to paragraph's leading indent
  696. int leadingWhitespaceCount = StandardUtilities.getLeadingWhiteSpace(text);
  697. String leadingWhitespace = text.substring(0,leadingWhitespaceCount);
  698. int leadingWhitespaceWidth = StandardUtilities.getLeadingWhiteSpaceWidth(text,tabSize);
  699. buf.append(leadingWhitespace);
  700. int lineLength = leadingWhitespaceWidth;
  701. StringTokenizer st = new StringTokenizer(text);
  702. while(st.hasMoreTokens())
  703. {
  704. String word = st.nextToken();
  705. if(lineLength == leadingWhitespaceWidth)
  706. {
  707. // do nothing
  708. }
  709. else if(lineLength + word.length() + 1 > maxLineLength)
  710. {
  711. buf.append('\n');
  712. buf.append(leadingWhitespace);
  713. lineLength = leadingWhitespaceWidth;
  714. }
  715. else
  716. {
  717. buf.append(' ');
  718. lineLength++;
  719. }
  720. buf.append(word);
  721. lineLength += word.length();
  722. }
  723. } //}}}
  724. //{{{ indexIgnoringWhitespace() method
  725. public static void indexIgnoringWhitespace(String text, int maxLineLength,
  726. int tabSize, StringBuffer buf)
  727. {
  728. // align everything to paragraph's leading indent
  729. int leadingWhitespaceCount = StandardUtilities.getLeadingWhiteSpace(text);
  730. String leadingWhitespace = text.substring(0,leadingWhitespaceCount);
  731. int leadingWhitespaceWidth = StandardUtilities.getLeadingWhiteSpaceWidth(text,tabSize);
  732. buf.append(leadingWhitespace);
  733. int lineLength = leadingWhitespaceWidth;
  734. StringTokenizer st = new StringTokenizer(text);
  735. while(st.hasMoreTokens())
  736. {
  737. String word = st.nextToken();
  738. if(lineLength == leadingWhitespaceWidth)
  739. {
  740. // do nothing
  741. }
  742. else if(lineLength + word.length() + 1 > maxLineLength)
  743. {
  744. buf.append('\n');
  745. buf.append(leadingWhitespace);
  746. lineLength = leadingWhitespaceWidth;
  747. }
  748. else
  749. {
  750. buf.append(' ');
  751. lineLength++;
  752. }
  753. buf.append(word);
  754. lineLength += word.length();
  755. }
  756. } //}}}
  757. //}}}
  758. }