1 21 22 package org.gjt.sp.jedit; 23 24 import java.util.*; 26 import javax.swing.text.Segment ; 27 import org.gjt.sp.jedit.buffer.JEditBuffer; 28 import org.gjt.sp.jedit.syntax.*; 29 import org.gjt.sp.util.StandardUtilities; 30 32 47 public class TextUtilities 48 { 49 public static final int BRACKET_MATCH_LIMIT = 10000; 51 52 59 public static Token getTokenAtOffset(Token tokens, int offset) 60 { 61 if(offset == 0 && tokens.id == Token.END) 62 return tokens; 63 64 for(;;) 65 { 66 if(tokens.id == Token.END) 67 throw new ArrayIndexOutOfBoundsException ("offset > line length"); 68 69 if(tokens.offset + tokens.length > offset) 70 return tokens; 71 else 72 tokens = tokens.next; 73 } 74 } 76 84 public static char getComplementaryBracket(char ch, boolean[] direction) 85 { 86 switch(ch) 87 { 88 case '(': direction[0] = true; return ')'; 89 case ')': direction[0] = false; return '('; 90 case '[': direction[0] = true; return ']'; 91 case ']': direction[0] = false; return '['; 92 case '{': direction[0] = true; return '}'; 93 case '}': direction[0] = false; return '{'; 94 default: return '\0'; 95 } 96 } 98 108 public static int findMatchingBracket(JEditBuffer buffer, int line, int offset) 109 { 110 if(offset < 0 || offset >= buffer.getLineLength(line)) 111 { 112 throw new ArrayIndexOutOfBoundsException (offset + ":" 113 + buffer.getLineLength(line)); 114 } 115 116 Segment lineText = new Segment (); 117 buffer.getLineText(line,lineText); 118 119 char c = lineText.array[lineText.offset + offset]; 120 boolean[] direction = new boolean[1]; 122 123 char cprime = getComplementaryBracket(c,direction); 125 126 int count = 1; 128 129 DefaultTokenHandler tokenHandler = new DefaultTokenHandler(); 130 buffer.markTokens(line,tokenHandler); 131 132 byte idOfBracket = getTokenAtOffset(tokenHandler.getTokens(),offset).id; 136 137 boolean haveTokens = true; 138 139 int startLine = line; 140 141 if(direction[0]) 143 { 144 offset++; 145 146 for(;;) 147 { 148 for(int i = offset; i < lineText.count; i++) 149 { 150 char ch = lineText.array[lineText.offset + i]; 151 if(ch == c) 152 { 153 if(!haveTokens) 154 { 155 tokenHandler.init(); 156 buffer.markTokens(line,tokenHandler); 157 haveTokens = true; 158 } 159 if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket) 160 count++; 161 } 162 else if(ch == cprime) 163 { 164 if(!haveTokens) 165 { 166 tokenHandler.init(); 167 buffer.markTokens(line,tokenHandler); 168 haveTokens = true; 169 } 170 if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket) 171 { 172 count--; 173 if(count == 0) 174 return buffer.getLineStartOffset(line) + i; 175 } 176 } 177 } 178 179 line++; 181 if(line >= buffer.getLineCount() || (line - startLine) > BRACKET_MATCH_LIMIT) 182 break; 183 buffer.getLineText(line,lineText); 184 offset = 0; 185 haveTokens = false; 186 } 188 } else 191 { 192 offset--; 193 194 for(;;) 195 { 196 for(int i = offset; i >= 0; i--) 197 { 198 char ch = lineText.array[lineText.offset + i]; 199 if(ch == c) 200 { 201 if(!haveTokens) 202 { 203 tokenHandler.init(); 204 buffer.markTokens(line,tokenHandler); 205 haveTokens = true; 206 } 207 if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket) 208 count++; 209 } 210 else if(ch == cprime) 211 { 212 if(!haveTokens) 213 { 214 tokenHandler.init(); 215 buffer.markTokens(line,tokenHandler); 216 haveTokens = true; 217 } 218 if(getTokenAtOffset(tokenHandler.getTokens(),i).id == idOfBracket) 219 { 220 count--; 221 if(count == 0) 222 return buffer.getLineStartOffset(line) + i; 223 } 224 } 225 } 226 227 line--; 229 if(line < 0 || (startLine - line) > BRACKET_MATCH_LIMIT) 230 break; 231 buffer.getLineText(line,lineText); 232 offset = lineText.count - 1; 233 haveTokens = false; 234 } 236 } 238 return -1; 240 } 242 250 public static int findWordStart(String line, int pos, String noWordSep) 251 { 252 return findWordStart(line, pos, noWordSep, true, false); 253 } 255 256 265 public static String join(Collection c, String delim) { 266 StringBuilder retval = new StringBuilder (); 267 Iterator itr = c.iterator(); 268 if (itr.hasNext()) { 269 retval.append( itr.next().toString() ); 270 } 271 else return ""; 272 while (itr.hasNext()) { 273 retval.append(delim); 274 retval.append(itr.next().toString()); 275 } 276 return retval.toString(); 277 } 278 279 290 public static int findWordStart(String line, int pos, String noWordSep, 291 boolean joinNonWordChars) 292 { 293 return findWordStart(line,pos,noWordSep,joinNonWordChars,false); 294 } 296 308 public static int findWordStart(String line, int pos, String noWordSep, 309 boolean joinNonWordChars, boolean eatWhitespace) 310 { 311 char ch = line.charAt(pos); 312 313 if(noWordSep == null) 314 noWordSep = ""; 315 316 int type = getCharType(ch, noWordSep); 318 320 loop: for(int i = pos; i >= 0; i--) 321 { 322 ch = line.charAt(i); 323 switch(type) 324 { 325 case WHITESPACE: 327 if(Character.isWhitespace(ch)) 329 break; 330 else 332 return i + 1; case WORD_CHAR: 335 if(Character.isLetterOrDigit(ch) || 337 noWordSep.indexOf(ch) != -1) 338 { 339 break; 340 } 341 else if(Character.isWhitespace(ch) 343 && eatWhitespace) 344 { 345 type = WHITESPACE; 346 break; 347 } 348 else 349 return i + 1; case SYMBOL: 352 if(!joinNonWordChars && pos != i) 353 return i + 1; 354 355 if(Character.isWhitespace(ch)) 357 { 358 if(eatWhitespace) 359 { 360 type = WHITESPACE; 361 break; 362 } 363 else 364 return i + 1; 365 } 366 else if(Character.isLetterOrDigit(ch) || 367 noWordSep.indexOf(ch) != -1) 368 { 369 return i + 1; 370 } 371 else 372 { 373 break; 374 } } 376 } 377 378 return 0; 379 } 381 389 public static int findWordEnd(String line, int pos, String noWordSep) 390 { 391 return findWordEnd(line, pos, noWordSep, true); 392 } 394 405 public static int findWordEnd(String line, int pos, String noWordSep, 406 boolean joinNonWordChars) 407 { 408 return findWordEnd(line,pos,noWordSep,joinNonWordChars,false); 409 } 411 423 public static int findWordEnd(String line, int pos, String noWordSep, 424 boolean joinNonWordChars, boolean eatWhitespace) 425 { 426 if(pos != 0) 427 pos--; 428 429 char ch = line.charAt(pos); 430 431 if(noWordSep == null) 432 noWordSep = ""; 433 434 int type = getCharType(ch, noWordSep); 436 438 loop: for(int i = pos; i < line.length(); i++) 439 { 440 ch = line.charAt(i); 441 switch(type) 442 { 443 case WHITESPACE: 445 if(Character.isWhitespace(ch)) 447 break; 448 else 449 return i; case WORD_CHAR: 452 if(Character.isLetterOrDigit(ch) || 453 noWordSep.indexOf(ch) != -1) 454 { 455 break; 456 } 457 else if(Character.isWhitespace(ch) 459 && eatWhitespace) 460 { 461 type = WHITESPACE; 462 break; 463 } 464 else 465 return i; case SYMBOL: 468 if(!joinNonWordChars && i != pos) 469 return i; 470 471 if(Character.isWhitespace(ch)) 473 { 474 if(eatWhitespace) 475 { 476 type = WHITESPACE; 477 break; 478 } 479 else 480 return i; 481 } 482 else if(Character.isLetterOrDigit(ch) || 483 noWordSep.indexOf(ch) != -1) 484 { 485 return i; 486 } 487 else 488 { 489 break; 490 } } 492 } 493 494 return line.length(); 495 } 497 505 private static int getCharType(char ch, String noWordSep) { 506 int type; 507 if(Character.isWhitespace(ch)) 508 type = WHITESPACE; 509 else if(Character.isLetterOrDigit(ch) 510 || noWordSep.indexOf(ch) != -1) 511 type = WORD_CHAR; 512 else 513 type = SYMBOL; 514 return type; 515 } 516 517 523 public static String spacesToTabs(String in, int tabSize) 524 { 525 StringBuilder buf = new StringBuilder (); 526 int width = 0; 527 int whitespace = 0; 528 for(int i = 0; i < in.length(); i++) 529 { 530 switch(in.charAt(i)) 531 { 532 case ' ': 533 whitespace++; 534 width++; 535 break; 536 case '\t': 537 int tab = tabSize - (width % tabSize); 538 width += tab; 539 whitespace += tab; 540 break; 541 case '\n': 542 if(whitespace != 0) 543 { 544 buf.append(StandardUtilities 545 .createWhiteSpace(whitespace,tabSize, 546 width - whitespace)); 547 } 548 whitespace = 0; 549 width = 0; 550 buf.append('\n'); 551 break; 552 default: 553 if(whitespace != 0) 554 { 555 buf.append(StandardUtilities 556 .createWhiteSpace(whitespace,tabSize, 557 width - whitespace)); 558 whitespace = 0; 559 } 560 buf.append(in.charAt(i)); 561 width++; 562 break; 563 } 564 } 565 566 if(whitespace != 0) 567 { 568 buf.append(StandardUtilities.createWhiteSpace(whitespace,tabSize, 569 width - whitespace)); 570 } 571 572 return buf.toString(); 573 } 575 581 public static String tabsToSpaces(String in, int tabSize) 582 { 583 StringBuilder buf = new StringBuilder (); 584 int width = 0; 585 for(int i = 0; i < in.length(); i++) 586 { 587 switch(in.charAt(i)) 588 { 589 case '\t': 590 int count = tabSize - (width % tabSize); 591 width += count; 592 while(--count >= 0) 593 buf.append(' '); 594 break; 595 case '\n': 596 width = 0; 597 buf.append(in.charAt(i)); 598 break; 599 default: 600 width++; 601 buf.append(in.charAt(i)); 602 break; 603 } 604 } 605 return buf.toString(); 606 } 608 616 public static String format(String text, int maxLineLength, int tabSize) 617 { 618 StringBuilder buf = new StringBuilder (); 619 620 int index = 0; 621 622 for(;;) 623 { 624 int newIndex = text.indexOf("\n\n",index); 625 if(newIndex == -1) 626 break; 627 628 formatParagraph(text.substring(index,newIndex), 629 maxLineLength,tabSize,buf); 630 buf.append("\n\n"); 631 index = newIndex + 2; 632 } 633 634 if(index != text.length()) 635 { 636 formatParagraph(text.substring(index), 637 maxLineLength,tabSize,buf); 638 } 639 640 return buf.toString(); 641 } 643 651 public static int indexIgnoringWhitespace(String str, int index) 652 { 653 int j = 0; 654 for(int i = 0; i < index; i++) 655 if(!Character.isWhitespace(str.charAt(i))) j++; 656 return j; 657 } 659 668 public static int ignoringWhitespaceIndex(String str, int index) 669 { 670 int j = 0; 671 for(int i = 0;;i++) 672 { 673 if(!Character.isWhitespace(str.charAt(i))) j++; 674 675 if(j > index) 676 return i; 677 if(i == str.length() - 1) 678 return i + 1; 679 } 680 } 682 public static final int MIXED = 0; 684 public static final int LOWER_CASE = 1; 685 public static final int UPPER_CASE = 2; 686 public static final int TITLE_CASE = 3; 687 688 694 public static int getStringCase(String str) 695 { 696 if(str.length() == 0) 697 return MIXED; 698 699 int state = -1; 700 701 char ch = str.charAt(0); 702 if(Character.isLetter(ch)) 703 { 704 if(Character.isUpperCase(ch)) 705 state = UPPER_CASE; 706 else 707 state = LOWER_CASE; 708 } 709 710 for(int i = 1; i < str.length(); i++) 711 { 712 ch = str.charAt(i); 713 if(!Character.isLetter(ch)) 714 continue; 715 716 switch(state) 717 { 718 case UPPER_CASE: 719 if(Character.isLowerCase(ch)) 720 { 721 if(i == 1) 722 state = TITLE_CASE; 723 else 724 return MIXED; 725 } 726 break; 727 case LOWER_CASE: 728 case TITLE_CASE: 729 if(Character.isUpperCase(ch)) 730 return MIXED; 731 break; 732 } 733 } 734 735 return state; 736 } 738 745 public static String toTitleCase(String str) 746 { 747 if(str.length() == 0) 748 return str; 749 else 750 { 751 return Character.toUpperCase(str.charAt(0)) 752 + str.substring(1).toLowerCase(); 753 } 754 } 756 private static final int WHITESPACE = 0; 758 private static final int WORD_CHAR = 1; 759 private static final int SYMBOL = 2; 760 761 private static void formatParagraph(String text, int maxLineLength, 763 int tabSize, StringBuilder buf) 764 { 765 int leadingWhitespaceCount = StandardUtilities.getLeadingWhiteSpace(text); 767 String leadingWhitespace = text.substring(0,leadingWhitespaceCount); 768 int leadingWhitespaceWidth = StandardUtilities.getLeadingWhiteSpaceWidth(text,tabSize); 769 770 buf.append(leadingWhitespace); 771 772 int lineLength = leadingWhitespaceWidth; 773 StringTokenizer st = new StringTokenizer(text); 774 while(st.hasMoreTokens()) 775 { 776 String word = st.nextToken(); 777 if(lineLength == leadingWhitespaceWidth) 778 { 779 } 781 else if(lineLength + word.length() + 1 > maxLineLength) 782 { 783 buf.append('\n'); 784 buf.append(leadingWhitespace); 785 lineLength = leadingWhitespaceWidth; 786 } 787 else 788 { 789 buf.append(' '); 790 lineLength++; 791 } 792 buf.append(word); 793 lineLength += word.length(); 794 } 795 } 797 public static void indexIgnoringWhitespace(String text, int maxLineLength, 799 int tabSize, StringBuffer buf) 800 { 801 int leadingWhitespaceCount = StandardUtilities.getLeadingWhiteSpace(text); 803 String leadingWhitespace = text.substring(0,leadingWhitespaceCount); 804 int leadingWhitespaceWidth = StandardUtilities.getLeadingWhiteSpaceWidth(text,tabSize); 805 806 buf.append(leadingWhitespace); 807 808 int lineLength = leadingWhitespaceWidth; 809 StringTokenizer st = new StringTokenizer(text); 810 while(st.hasMoreTokens()) 811 { 812 String word = st.nextToken(); 813 if(lineLength == leadingWhitespaceWidth) 814 { 815 } 817 else if(lineLength + word.length() + 1 > maxLineLength) 818 { 819 buf.append('\n'); 820 buf.append(leadingWhitespace); 821 lineLength = leadingWhitespaceWidth; 822 } 823 else 824 { 825 buf.append(' '); 826 lineLength++; 827 } 828 buf.append(word); 829 lineLength += word.length(); 830 } 831 } 833 } 835 | Popular Tags |