Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.sdklib.util;
     18 
     19 
     20 public abstract class LineUtil {
     21 
     22     /**
     23      * Reformats a line so that it fits in 78 characters max.
     24      * <p/>
     25      * When wrapping the second line and following, prefix the string with a number of
     26      * spaces. This will use the first colon (:) to determine the prefix size
     27      * or use 4 as a minimum if there are no colons in the string.
     28      *
     29      * @param line The line to reflow. Must be non-null.
     30      * @return A new line to print as-is, that contains \n as needed.
     31      */
     32     public static String reflowLine(String line) {
     33         final int maxLen = 78;
     34 
     35         // Most of time the line will fit in the given length and this will be a no-op
     36         int n = line.length();
     37         int cr = line.indexOf('\n');
     38         if (n <= maxLen && (cr == -1 || cr == n - 1)) {
     39             return line;
     40         }
     41 
     42         int prefixSize = line.indexOf(':') + 1;
     43         // If there' some spacing after the colon, use the same when wrapping
     44         if (prefixSize > 0 && prefixSize < maxLen) {
     45             while(prefixSize < n && line.charAt(prefixSize) == ' ') {
     46                 prefixSize++;
     47             }
     48         } else {
     49             prefixSize = 4;
     50         }
     51         String prefix = String.format(
     52                 "%-" + Integer.toString(prefixSize) + "s",      //$NON-NLS-1$ //$NON-NLS-2$
     53                 " ");                                           //$NON-NLS-1$
     54 
     55         StringBuilder output = new StringBuilder(n + prefixSize);
     56 
     57         while (n > 0) {
     58             cr = line.indexOf('\n');
     59             if (n <= maxLen && (cr == -1 || cr == n - 1)) {
     60                 output.append(line);
     61                 break;
     62             }
     63 
     64             // Line is longer than the max length, find the first character before and after
     65             // the whitespace where we want to break the line.
     66             int posNext = maxLen;
     67             if (cr != -1 && cr != n - 1 && cr <= posNext) {
     68                 posNext = cr + 1;
     69                 while (posNext < n && line.charAt(posNext) == '\n') {
     70                     posNext++;
     71                 }
     72             }
     73             while (posNext < n && line.charAt(posNext) == ' ') {
     74                 posNext++;
     75             }
     76             while (posNext > 0) {
     77                 char c = line.charAt(posNext - 1);
     78                 if (c != ' ' && c != '\n') {
     79                     posNext--;
     80                 } else {
     81                     break;
     82                 }
     83             }
     84 
     85             if (posNext == 0 || (posNext >= n && maxLen < n)) {
     86                 // We found no whitespace separator. This should generally not occur.
     87                 posNext = maxLen;
     88             }
     89             int posPrev = posNext;
     90             while (posPrev > 0) {
     91                 char c = line.charAt(posPrev - 1);
     92                 if (c == ' ' || c == '\n') {
     93                     posPrev--;
     94                 } else {
     95                     break;
     96                 }
     97             }
     98 
     99             output.append(line.substring(0, posPrev)).append('\n');
    100             line = prefix + line.substring(posNext);
    101             n = line.length();
    102         }
    103 
    104         return output.toString();
    105     }
    106 
    107     /**
    108      * Formats the string using {@link String#format(String, Object...)}
    109      * and then returns the result of {@link #reflowLine(String)}.
    110      *
    111      * @param format The string format.
    112      * @param params The parameters for the string format.
    113      * @return The result of {@link #reflowLine(String)} on the formatted string.
    114      */
    115     public static String reformatLine(String format, Object...params) {
    116         return reflowLine(String.format(format, params));
    117     }
    118 }
    119