Source Code Cross Referenced for TextUtilities.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jEdit » org.gjt.sp.jedit 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * TextUtilities.java - Various text functions
003:         * Copyright (C) 1998, 2005 Slava Pestov
004:         * :tabSize=8:indentSize=8:noTabs=false:
005:         * :folding=explicit:collapseFolds=1:
006:         *
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License
009:         * as published by the Free Software Foundation; either version 2
010:         * of the License, or any later version.
011:         *
012:         * This program is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015:         * GNU General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU General Public License
018:         * along with this program; if not, write to the Free Software
019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020:         */
021:
022:        package org.gjt.sp.jedit;
023:
024:        //{{{ Imports
025:        import java.util.*;
026:        import javax.swing.text.Segment;
027:        import org.gjt.sp.jedit.buffer.JEditBuffer;
028:        import org.gjt.sp.jedit.syntax.*;
029:        import org.gjt.sp.util.StandardUtilities;
030:
031:        //}}}
032:
033:        /**
034:         * Contains several text manipulation methods.
035:         *
036:         * <ul>
037:         * <li>Bracket matching
038:         * <li>Word start and end offset calculation
039:         * <li>String comparison
040:         * <li>Converting tabs to spaces and vice versa
041:         * <li>Wrapping text
042:         * <li>String case conversion
043:         * </ul>
044:         *
045:         * @author Slava Pestov
046:         * @version $Id: TextUtilities.java 9134 2007-03-13 05:30:18Z vanza $
047:         */
048:        public class TextUtilities {
049:            // to avoid slowdown with large files; only scan 10000 lines either way
050:            public static final int BRACKET_MATCH_LIMIT = 10000;
051:
052:            //{{{ getTokenAtOffset() method
053:            /**
054:             * Returns the token that contains the specified offset.
055:             * @param tokens The token list
056:             * @param offset The offset
057:             * @since jEdit 4.0pre3
058:             */
059:            public static Token getTokenAtOffset(Token tokens, int offset) {
060:                if (offset == 0 && tokens.id == Token.END)
061:                    return tokens;
062:
063:                for (;;) {
064:                    if (tokens.id == Token.END)
065:                        throw new ArrayIndexOutOfBoundsException(
066:                                "offset > line length");
067:
068:                    if (tokens.offset + tokens.length > offset)
069:                        return tokens;
070:                    else
071:                        tokens = tokens.next;
072:                }
073:            } //}}}
074:
075:            //{{{ getComplementaryBracket() method
076:            /**
077:             * Given an opening bracket, return the corresponding closing bracket
078:             * and store true in <code>direction[0]</code>. Given a closing bracket,
079:             * return the corresponding opening bracket and store false in
080:             * <code>direction[0]</code>. Otherwise, return <code>\0</code>.
081:             * @since jEdit 4.3pre2
082:             */
083:            public static char getComplementaryBracket(char ch,
084:                    boolean[] direction) {
085:                switch (ch) {
086:                case '(':
087:                    if (direction != null)
088:                        direction[0] = true;
089:                    return ')';
090:                case ')':
091:                    if (direction != null)
092:                        direction[0] = false;
093:                    return '(';
094:                case '[':
095:                    if (direction != null)
096:                        direction[0] = true;
097:                    return ']';
098:                case ']':
099:                    if (direction != null)
100:                        direction[0] = false;
101:                    return '[';
102:                case '{':
103:                    if (direction != null)
104:                        direction[0] = true;
105:                    return '}';
106:                case '}':
107:                    if (direction != null)
108:                        direction[0] = false;
109:                    return '{';
110:                default:
111:                    return '\0';
112:                }
113:            } //}}}
114:
115:            //{{{ findMatchingBracket() method
116:            /**
117:             * Returns the offset of the bracket matching the one at the
118:             * specified offset of the buffer, or -1 if the bracket is
119:             * unmatched (or if the character is not a bracket).
120:             * @param buffer The buffer
121:             * @param line The line
122:             * @param offset The offset within that line
123:             * @since jEdit 2.6pre1
124:             */
125:            public static int findMatchingBracket(JEditBuffer buffer, int line,
126:                    int offset) {
127:                if (offset < 0 || offset >= buffer.getLineLength(line)) {
128:                    throw new ArrayIndexOutOfBoundsException(offset + ":"
129:                            + buffer.getLineLength(line));
130:                }
131:
132:                Segment lineText = new Segment();
133:                buffer.getLineText(line, lineText);
134:
135:                char c = lineText.array[lineText.offset + offset];
136:                // false - backwards, true - forwards
137:                boolean[] direction = new boolean[1];
138:
139:                // corresponding character
140:                char cprime = getComplementaryBracket(c, direction);
141:
142:                if (cprime == '\0') { // c is no bracket
143:                    return -1;
144:                }
145:
146:                // 1 because we've already 'seen' the first bracket
147:                int count = 1;
148:
149:                DefaultTokenHandler tokenHandler = new DefaultTokenHandler();
150:                buffer.markTokens(line, tokenHandler);
151:
152:                // Get the syntax token at 'offset'
153:                // only tokens with the same type will be checked for
154:                // the corresponding bracket
155:                byte idOfBracket = getTokenAtOffset(tokenHandler.getTokens(),
156:                        offset).id;
157:
158:                boolean haveTokens = true;
159:
160:                int startLine = line;
161:
162:                //{{{ Forward search
163:                if (direction[0]) {
164:                    offset++;
165:
166:                    for (;;) {
167:                        for (int i = offset; i < lineText.count; i++) {
168:                            char ch = lineText.array[lineText.offset + i];
169:                            if (ch == c) {
170:                                if (!haveTokens) {
171:                                    tokenHandler.init();
172:                                    buffer.markTokens(line, tokenHandler);
173:                                    haveTokens = true;
174:                                }
175:                                if (getTokenAtOffset(tokenHandler.getTokens(),
176:                                        i).id == idOfBracket)
177:                                    count++;
178:                            } else if (ch == cprime) {
179:                                if (!haveTokens) {
180:                                    tokenHandler.init();
181:                                    buffer.markTokens(line, tokenHandler);
182:                                    haveTokens = true;
183:                                }
184:                                if (getTokenAtOffset(tokenHandler.getTokens(),
185:                                        i).id == idOfBracket) {
186:                                    count--;
187:                                    if (count == 0)
188:                                        return buffer.getLineStartOffset(line)
189:                                                + i;
190:                                }
191:                            }
192:                        }
193:
194:                        //{{{ Go on to next line
195:                        line++;
196:                        if (line >= buffer.getLineCount()
197:                                || (line - startLine) > BRACKET_MATCH_LIMIT)
198:                            break;
199:                        buffer.getLineText(line, lineText);
200:                        offset = 0;
201:                        haveTokens = false;
202:                        //}}}
203:                    }
204:                } //}}}
205:                //{{{ Backward search
206:                else {
207:                    offset--;
208:
209:                    for (;;) {
210:                        for (int i = offset; i >= 0; i--) {
211:                            char ch = lineText.array[lineText.offset + i];
212:                            if (ch == c) {
213:                                if (!haveTokens) {
214:                                    tokenHandler.init();
215:                                    buffer.markTokens(line, tokenHandler);
216:                                    haveTokens = true;
217:                                }
218:                                if (getTokenAtOffset(tokenHandler.getTokens(),
219:                                        i).id == idOfBracket)
220:                                    count++;
221:                            } else if (ch == cprime) {
222:                                if (!haveTokens) {
223:                                    tokenHandler.init();
224:                                    buffer.markTokens(line, tokenHandler);
225:                                    haveTokens = true;
226:                                }
227:                                if (getTokenAtOffset(tokenHandler.getTokens(),
228:                                        i).id == idOfBracket) {
229:                                    count--;
230:                                    if (count == 0)
231:                                        return buffer.getLineStartOffset(line)
232:                                                + i;
233:                                }
234:                            }
235:                        }
236:
237:                        //{{{ Go on to previous line
238:                        line--;
239:                        if (line < 0
240:                                || (startLine - line) > BRACKET_MATCH_LIMIT)
241:                            break;
242:                        buffer.getLineText(line, lineText);
243:                        offset = lineText.count - 1;
244:                        haveTokens = false;
245:                        //}}}
246:                    }
247:                } //}}}
248:
249:                // Nothing found
250:                return -1;
251:            } //}}}
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:             */
261:            public static int findWordStart(String line, int pos,
262:                    String noWordSep) {
263:                return findWordStart(line, pos, noWordSep, true, false);
264:            } //}}}
265:
266:            /** Similar to perl's join() method on lists,
267:             *    but works with all collections.
268:             *
269:             * @param c An iterable collection of Objects
270:             * @param delim a string to put between each object
271:             * @return a joined toString() representation of the collection
272:             *
273:             * @since jedit 4.3pre3
274:             */
275:            public static String join(Collection c, String delim) {
276:                StringBuilder retval = new StringBuilder();
277:                Iterator itr = c.iterator();
278:                if (itr.hasNext()) {
279:                    retval.append(itr.next().toString());
280:                } else
281:                    return "";
282:                while (itr.hasNext()) {
283:                    retval.append(delim);
284:                    retval.append(itr.next().toString());
285:                }
286:                return retval.toString();
287:            }
288:
289:            //{{{ findWordStart() method
290:            /**
291:             * Locates the start of the word at the specified position.
292:             * @param line The text
293:             * @param pos The position
294:             * @param noWordSep Characters that are non-alphanumeric, but
295:             * should be treated as word characters anyway
296:             * @param joinNonWordChars Treat consecutive non-alphanumeric
297:             * characters as one word
298:             * @since jEdit 4.2pre5
299:             */
300:            public static int findWordStart(String line, int pos,
301:                    String noWordSep, boolean joinNonWordChars) {
302:                return findWordStart(line, pos, noWordSep, joinNonWordChars,
303:                        false);
304:            } //}}}
305:
306:            //{{{ findWordStart() method
307:            /**
308:             * Locates the start of the word at the specified position.
309:             * @param line The text
310:             * @param pos The position
311:             * @param noWordSep Characters that are non-alphanumeric, but
312:             * should be treated as word characters anyway
313:             * @param joinNonWordChars Treat consecutive non-alphanumeric
314:             * characters as one word
315:             * @param eatWhitespace Include whitespace at start of word
316:             * @since jEdit 4.1pre2
317:             */
318:            public static int findWordStart(String line, int pos,
319:                    String noWordSep, boolean joinNonWordChars,
320:                    boolean eatWhitespace) {
321:                return findWordStart(line, pos, noWordSep, joinNonWordChars,
322:                        false, eatWhitespace);
323:            } //}}}
324:
325:            //{{{ findWordStart() method
326:            /**
327:             * Locates the start of the word at the specified position.
328:             * @param line The text
329:             * @param pos The position
330:             * @param noWordSep Characters that are non-alphanumeric, but
331:             * should be treated as word characters anyway
332:             * @param joinNonWordChars Treat consecutive non-alphanumeric
333:             * characters as one word
334:             * @param camelCasedWords Treat "camelCased" parts as words
335:             * @param eatWhitespace Include whitespace at start of word
336:             * @since jEdit 4.3pre10
337:             */
338:            public static int findWordStart(String line, int pos,
339:                    String noWordSep, boolean joinNonWordChars,
340:                    boolean camelCasedWords, boolean eatWhitespace) {
341:                char ch = line.charAt(pos);
342:
343:                if (noWordSep == null)
344:                    noWordSep = "";
345:
346:                //{{{ the character under the cursor changes how we behave.
347:                int type = getCharType(ch, noWordSep);
348:                //}}}
349:
350:                loop: for (int i = pos; i >= 0; i--) {
351:                    char lastCh = ch;
352:                    ch = line.charAt(i);
353:                    switch (type) {
354:                    //{{{ Whitespace...
355:                    case WHITESPACE:
356:                        // only select other whitespace in this case
357:                        if (Character.isWhitespace(ch))
358:                            break;
359:                        // word char or symbol; stop
360:                        else
361:                            return i + 1; //}}}
362:                        //{{{ Word character...
363:                    case WORD_CHAR:
364:                        // stop at next last (in writing direction) upper case char if camel cased
365:                        // (don't stop at every upper case char, don't treat noWordSep as word chars)
366:                        if (camelCasedWords && Character.isUpperCase(ch)
367:                                && !Character.isUpperCase(lastCh)
368:                                && Character.isLetterOrDigit(lastCh)) {
369:                            return i;
370:                        }
371:                        // stop at next first (in writing direction) upper case char if camel cased
372:                        // (don't stop at every upper case char)
373:                        else if (camelCasedWords && !Character.isUpperCase(ch)
374:                                && Character.isUpperCase(lastCh)) {
375:                            return i + 1;
376:                        }
377:                        // word char; keep going
378:                        else if (Character.isLetterOrDigit(ch)
379:                                || noWordSep.indexOf(ch) != -1) {
380:                            break;
381:                        }
382:                        // whitespace; include in word if eating
383:                        else if (Character.isWhitespace(ch) && eatWhitespace) {
384:                            type = WHITESPACE;
385:                            break;
386:                        } else
387:                            return i + 1; //}}}
388:                        //{{{ Symbol...
389:                    case SYMBOL:
390:                        if (!joinNonWordChars && pos != i)
391:                            return i + 1;
392:
393:                        // whitespace; include in word if eating
394:                        if (Character.isWhitespace(ch)) {
395:                            if (eatWhitespace) {
396:                                type = WHITESPACE;
397:                                break;
398:                            } else
399:                                return i + 1;
400:                        } else if (Character.isLetterOrDigit(ch)
401:                                || noWordSep.indexOf(ch) != -1) {
402:                            return i + 1;
403:                        } else {
404:                            break;
405:                        } //}}}
406:                    }
407:                }
408:
409:                return 0;
410:            } //}}}
411:
412:            //{{{ findWordEnd() method
413:            /**
414:             * Locates the end of the word at the specified position.
415:             * @param line The text
416:             * @param pos The position
417:             * @param noWordSep Characters that are non-alphanumeric, but
418:             * should be treated as word characters anyway
419:             */
420:            public static int findWordEnd(String line, int pos, String noWordSep) {
421:                return findWordEnd(line, pos, noWordSep, true);
422:            } //}}}
423:
424:            //{{{ findWordEnd() method
425:            /**
426:             * Locates the end of the word at the specified position.
427:             * @param line The text
428:             * @param pos The position
429:             * @param noWordSep Characters that are non-alphanumeric, but
430:             * should be treated as word characters anyway
431:             * @param joinNonWordChars Treat consecutive non-alphanumeric
432:             * characters as one word
433:             * @since jEdit 4.1pre2
434:             */
435:            public static int findWordEnd(String line, int pos,
436:                    String noWordSep, boolean joinNonWordChars) {
437:                return findWordEnd(line, pos, noWordSep, joinNonWordChars,
438:                        false);
439:            } //}}}
440:
441:            //{{{ findWordEnd() method
442:            /**
443:             * Locates the end of the word at the specified position.
444:             * @param line The text
445:             * @param pos The position
446:             * @param noWordSep Characters that are non-alphanumeric, but
447:             * should be treated as word characters anyway
448:             * @param joinNonWordChars Treat consecutive non-alphanumeric
449:             * characters as one word
450:             * @param eatWhitespace Include whitespace at end of word
451:             * @since jEdit 4.2pre5
452:             */
453:            public static int findWordEnd(String line, int pos,
454:                    String noWordSep, boolean joinNonWordChars,
455:                    boolean eatWhitespace) {
456:                return findWordEnd(line, pos, noWordSep, joinNonWordChars,
457:                        false, eatWhitespace);
458:            } //}}}
459:
460:            //{{{ findWordEnd() method
461:            /**
462:             * Locates the end of the word at the specified position.
463:             * @param line The text
464:             * @param pos The position
465:             * @param noWordSep Characters that are non-alphanumeric, but
466:             * should be treated as word characters anyway
467:             * @param joinNonWordChars Treat consecutive non-alphanumeric
468:             * characters as one word
469:             * @param camelCasedWords Treat "camelCased" parts as words
470:             * @param eatWhitespace Include whitespace at end of word
471:             * @since jEdit 4.3pre10
472:             */
473:            public static int findWordEnd(String line, int pos,
474:                    String noWordSep, boolean joinNonWordChars,
475:                    boolean camelCasedWords, boolean eatWhitespace) {
476:                if (pos != 0)
477:                    pos--;
478:
479:                char ch = line.charAt(pos);
480:
481:                if (noWordSep == null)
482:                    noWordSep = "";
483:
484:                //{{{ the character under the cursor changes how we behave.
485:                int type = getCharType(ch, noWordSep);
486:                //}}}
487:
488:                loop: for (int i = pos; i < line.length(); i++) {
489:                    char lastCh = ch;
490:                    ch = line.charAt(i);
491:                    switch (type) {
492:                    //{{{ Whitespace...
493:                    case WHITESPACE:
494:                        // only select other whitespace in this case
495:                        if (Character.isWhitespace(ch))
496:                            break;
497:                        else
498:                            return i; //}}}
499:                        //{{{ Word character...
500:                    case WORD_CHAR:
501:                        // stop at next last upper case char if camel cased
502:                        // (don't stop at every upper case char, don't treat noWordSep as word chars)
503:                        if (camelCasedWords && i > pos + 1
504:                                && !Character.isUpperCase(ch)
505:                                && Character.isLetterOrDigit(ch)
506:                                && Character.isUpperCase(lastCh)) {
507:                            return i - 1;
508:                        }
509:                        // stop at next first upper case char if camel caseg (don't stop at every upper case char)
510:                        else if (camelCasedWords && Character.isUpperCase(ch)
511:                                && !Character.isUpperCase(lastCh)) {
512:                            return i;
513:                        } else if (Character.isLetterOrDigit(ch)
514:                                || noWordSep.indexOf(ch) != -1) {
515:                            break;
516:                        }
517:                        // whitespace; include in word if eating
518:                        else if (Character.isWhitespace(ch) && eatWhitespace) {
519:                            type = WHITESPACE;
520:                            break;
521:                        } else
522:                            return i; //}}}
523:                        //{{{ Symbol...
524:                    case SYMBOL:
525:                        if (!joinNonWordChars && i != pos)
526:                            return i;
527:
528:                        // if we see whitespace, set flag.
529:                        if (Character.isWhitespace(ch)) {
530:                            if (eatWhitespace) {
531:                                type = WHITESPACE;
532:                                break;
533:                            } else
534:                                return i;
535:                        } else if (Character.isLetterOrDigit(ch)
536:                                || noWordSep.indexOf(ch) != -1) {
537:                            return i;
538:                        } else {
539:                            break;
540:                        } //}}}
541:                    }
542:                }
543:
544:                return line.length();
545:            } //}}}
546:
547:            /**
548:             * Returns the type of the char.
549:             *
550:             * @param ch the character
551:             * @param noWordSep Characters that are non-alphanumeric, but
552:             * should be treated as word characters anyway
553:             * @return the type of the char : {@link #WHITESPACE}, {@link #WORD_CHAR}, {@link #SYMBOL}
554:             */
555:            private static int getCharType(char ch, String noWordSep) {
556:                int type;
557:                if (Character.isWhitespace(ch))
558:                    type = WHITESPACE;
559:                else if (Character.isLetterOrDigit(ch)
560:                        || noWordSep.indexOf(ch) != -1)
561:                    type = WORD_CHAR;
562:                else
563:                    type = SYMBOL;
564:                return type;
565:            }
566:
567:            //{{{ spacesToTabs() method
568:            /**
569:             * Converts consecutive spaces to tabs in the specified string.
570:             * @param in The string
571:             * @param tabSize The tab size
572:             */
573:            public static String spacesToTabs(String in, int tabSize) {
574:                StringBuilder buf = new StringBuilder();
575:                int width = 0;
576:                int whitespace = 0;
577:                for (int i = 0; i < in.length(); i++) {
578:                    switch (in.charAt(i)) {
579:                    case ' ':
580:                        whitespace++;
581:                        width++;
582:                        break;
583:                    case '\t':
584:                        int tab = tabSize - (width % tabSize);
585:                        width += tab;
586:                        whitespace += tab;
587:                        break;
588:                    case '\n':
589:                        if (whitespace != 0) {
590:                            buf.append(StandardUtilities.createWhiteSpace(
591:                                    whitespace, tabSize, width - whitespace));
592:                        }
593:                        whitespace = 0;
594:                        width = 0;
595:                        buf.append('\n');
596:                        break;
597:                    default:
598:                        if (whitespace != 0) {
599:                            buf.append(StandardUtilities.createWhiteSpace(
600:                                    whitespace, tabSize, width - whitespace));
601:                            whitespace = 0;
602:                        }
603:                        buf.append(in.charAt(i));
604:                        width++;
605:                        break;
606:                    }
607:                }
608:
609:                if (whitespace != 0) {
610:                    buf.append(StandardUtilities.createWhiteSpace(whitespace,
611:                            tabSize, width - whitespace));
612:                }
613:
614:                return buf.toString();
615:            } //}}}
616:
617:            //{{{ tabsToSpaces() method
618:            /**
619:             * Converts tabs to consecutive spaces in the specified string.
620:             * @param in The string
621:             * @param tabSize The tab size
622:             */
623:            public static String tabsToSpaces(String in, int tabSize) {
624:                StringBuilder buf = new StringBuilder();
625:                int width = 0;
626:                for (int i = 0; i < in.length(); i++) {
627:                    switch (in.charAt(i)) {
628:                    case '\t':
629:                        int count = tabSize - (width % tabSize);
630:                        width += count;
631:                        while (--count >= 0)
632:                            buf.append(' ');
633:                        break;
634:                    case '\n':
635:                        width = 0;
636:                        buf.append(in.charAt(i));
637:                        break;
638:                    default:
639:                        width++;
640:                        buf.append(in.charAt(i));
641:                        break;
642:                    }
643:                }
644:                return buf.toString();
645:            } //}}}
646:
647:            //{{{ format() method
648:            /**
649:             * Formats the specified text by merging and breaking lines to the
650:             * specified width.
651:             * @param text The text
652:             * @param maxLineLength The maximum line length
653:             * @param tabSize The tab size
654:             */
655:            public static String format(String text, int maxLineLength,
656:                    int tabSize) {
657:                StringBuilder buf = new StringBuilder();
658:
659:                int index = 0;
660:
661:                for (;;) {
662:                    int newIndex = text.indexOf("\n\n", index);
663:                    if (newIndex == -1)
664:                        break;
665:
666:                    formatParagraph(text.substring(index, newIndex),
667:                            maxLineLength, tabSize, buf);
668:                    buf.append("\n\n");
669:                    index = newIndex + 2;
670:                }
671:
672:                if (index != text.length()) {
673:                    formatParagraph(text.substring(index), maxLineLength,
674:                            tabSize, buf);
675:                }
676:
677:                return buf.toString();
678:            } //}}}
679:
680:            //{{{ indexIgnoringWhitespace() method
681:            /**
682:             * Inverse of <code>ignoringWhitespaceIndex()</code>.
683:             * @param str a string (not an empty string)
684:             * @param index The index
685:             * @return The number of non-whitespace characters that precede the index.
686:             * @since jEdit 4.3pre2
687:             */
688:            public static int indexIgnoringWhitespace(String str, int index) {
689:                int j = 0;
690:                for (int i = 0; i < index; i++)
691:                    if (!Character.isWhitespace(str.charAt(i)))
692:                        j++;
693:                return j;
694:            } //}}}
695:
696:            //{{{ ignoringWhitespaceIndex() method
697:            /**
698:             * Inverse of <code>indexIgnoringWhitespace()</code>.
699:             * @param str a string (not an empty string)
700:             * @param index The index
701:             * @return The index into the string where the number of non-whitespace
702:             * characters that precede the index is count.
703:             * @since jEdit 4.3pre2
704:             */
705:            public static int ignoringWhitespaceIndex(String str, int index) {
706:                int j = 0;
707:                for (int i = 0;; i++) {
708:                    if (!Character.isWhitespace(str.charAt(i)))
709:                        j++;
710:
711:                    if (j > index)
712:                        return i;
713:                    if (i == str.length() - 1)
714:                        return i + 1;
715:                }
716:            } //}}}
717:
718:            //{{{ getStringCase() method
719:            public static final int MIXED = 0;
720:            public static final int LOWER_CASE = 1;
721:            public static final int UPPER_CASE = 2;
722:            public static final int TITLE_CASE = 3;
723:
724:            /**
725:             * Returns if the specified string is all upper case, all lower case,
726:             * or title case (first letter upper case, rest lower case).
727:             * @param str The string
728:             * @since jEdit 4.0pre1
729:             */
730:            public static int getStringCase(String str) {
731:                if (str.length() == 0)
732:                    return MIXED;
733:
734:                int state = -1;
735:
736:                char ch = str.charAt(0);
737:                if (Character.isLetter(ch)) {
738:                    if (Character.isUpperCase(ch))
739:                        state = UPPER_CASE;
740:                    else
741:                        state = LOWER_CASE;
742:                }
743:
744:                for (int i = 1; i < str.length(); i++) {
745:                    ch = str.charAt(i);
746:                    if (!Character.isLetter(ch))
747:                        continue;
748:
749:                    switch (state) {
750:                    case UPPER_CASE:
751:                        if (Character.isLowerCase(ch)) {
752:                            if (i == 1)
753:                                state = TITLE_CASE;
754:                            else
755:                                return MIXED;
756:                        }
757:                        break;
758:                    case LOWER_CASE:
759:                    case TITLE_CASE:
760:                        if (Character.isUpperCase(ch))
761:                            return MIXED;
762:                        break;
763:                    }
764:                }
765:
766:                return state;
767:            } //}}}
768:
769:            //{{{ toTitleCase() method
770:            /**
771:             * Converts the specified string to title case, by capitalizing the
772:             * first letter.
773:             * @param str The string
774:             * @since jEdit 4.0pre1
775:             */
776:            public static String toTitleCase(String str) {
777:                if (str.length() == 0)
778:                    return str;
779:                else {
780:                    return Character.toUpperCase(str.charAt(0))
781:                            + str.substring(1).toLowerCase();
782:                }
783:            } //}}}
784:
785:            //{{{ Private members
786:            private static final int WHITESPACE = 0;
787:            private static final int WORD_CHAR = 1;
788:            private static final int SYMBOL = 2;
789:
790:            //{{{ formatParagraph() method
791:            private static void formatParagraph(String text, int maxLineLength,
792:                    int tabSize, StringBuilder buf) {
793:                // align everything to paragraph's leading indent
794:                int leadingWhitespaceCount = StandardUtilities
795:                        .getLeadingWhiteSpace(text);
796:                String leadingWhitespace = text.substring(0,
797:                        leadingWhitespaceCount);
798:                int leadingWhitespaceWidth = StandardUtilities
799:                        .getLeadingWhiteSpaceWidth(text, tabSize);
800:
801:                buf.append(leadingWhitespace);
802:
803:                int lineLength = leadingWhitespaceWidth;
804:                StringTokenizer st = new StringTokenizer(text);
805:                while (st.hasMoreTokens()) {
806:                    String word = st.nextToken();
807:                    if (lineLength == leadingWhitespaceWidth) {
808:                        // do nothing
809:                    } else if (lineLength + word.length() + 1 > maxLineLength) {
810:                        buf.append('\n');
811:                        buf.append(leadingWhitespace);
812:                        lineLength = leadingWhitespaceWidth;
813:                    } else {
814:                        buf.append(' ');
815:                        lineLength++;
816:                    }
817:                    buf.append(word);
818:                    lineLength += word.length();
819:                }
820:            } //}}}
821:
822:            //{{{ indexIgnoringWhitespace() method
823:            public static void indexIgnoringWhitespace(String text,
824:                    int maxLineLength, int tabSize, StringBuffer buf) {
825:                // align everything to paragraph's leading indent
826:                int leadingWhitespaceCount = StandardUtilities
827:                        .getLeadingWhiteSpace(text);
828:                String leadingWhitespace = text.substring(0,
829:                        leadingWhitespaceCount);
830:                int leadingWhitespaceWidth = StandardUtilities
831:                        .getLeadingWhiteSpaceWidth(text, tabSize);
832:
833:                buf.append(leadingWhitespace);
834:
835:                int lineLength = leadingWhitespaceWidth;
836:                StringTokenizer st = new StringTokenizer(text);
837:                while (st.hasMoreTokens()) {
838:                    String word = st.nextToken();
839:                    if (lineLength == leadingWhitespaceWidth) {
840:                        // do nothing
841:                    } else if (lineLength + word.length() + 1 > maxLineLength) {
842:                        buf.append('\n');
843:                        buf.append(leadingWhitespace);
844:                        lineLength = leadingWhitespaceWidth;
845:                    } else {
846:                        buf.append(' ');
847:                        lineLength++;
848:                    }
849:                    buf.append(word);
850:                    lineLength += word.length();
851:                }
852:            } //}}}
853:
854:            //}}}
855:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.