blob: 841d009dc8c844ebb98caa0e2af315d2565d1b65 [file] [log] [blame]
Stuart McCullochf3173222012-06-07 21:57:32 +00001package aQute.lib.justif;
2
3import java.util.*;
4
Stuart McCullochf3173222012-06-07 21:57:32 +00005public class Justif {
Stuart McCulloch4482c702012-06-15 13:27:53 +00006 int[] tabs;
7
8 public Justif(int width, int... tabs) {
Stuart McCullochf3173222012-06-07 21:57:32 +00009 this.tabs = tabs;
10 }
11
12 /**
13 * Routine to wrap a stringbuffer. Basically adds line endings but has the
14 * following control characters:
15 * <ul>
16 * <li>Space at the beginnng of a line is repeated when wrapped for indent.</li>
17 * <li>A tab will mark the current position and wrapping will return to that
18 * position</li>
19 * <li>A form feed in a tabbed colum will break but stay in the column</li>
20 * </ul>
21 *
22 * @param sb
23 */
24 public void wrap(StringBuilder sb) {
25 List<Integer> indents = new ArrayList<Integer>();
Stuart McCulloch4482c702012-06-15 13:27:53 +000026
Stuart McCullochf3173222012-06-07 21:57:32 +000027 int indent = 0;
28 int linelength = 0;
29 int lastSpace = 0;
30 int r = 0;
31 boolean begin = true;
32
33 while (r < sb.length()) {
34 switch (sb.charAt(r++)) {
Stuart McCulloch4482c702012-06-15 13:27:53 +000035 case '\n' :
Stuart McCullochf3173222012-06-07 21:57:32 +000036 linelength = 0;
37
Stuart McCulloch4482c702012-06-15 13:27:53 +000038 indent = indents.isEmpty() ? 0 : indents.remove(0);
39 begin = true;
Stuart McCullochf3173222012-06-07 21:57:32 +000040 lastSpace = 0;
Stuart McCulloch4482c702012-06-15 13:27:53 +000041 break;
42
43 case ' ' :
44 if (begin)
45 indent++;
46 lastSpace = r - 1;
47 linelength++;
48 break;
49
50 case '\t' :
51 indents.add(indent);
52 indent = linelength;
53 sb.deleteCharAt(--r);
54
55 if (r < sb.length()) {
56 char digit = sb.charAt(r);
57 if (Character.isDigit(digit)) {
58 sb.deleteCharAt(r);
59
60 int column = (digit - '0');
61 if (column < tabs.length)
62 indent = tabs[column];
63 else
64 indent = column * 8;
65
66 int diff = indent - linelength;
67 if (diff > 0) {
68 for (int i = 0; i < diff; i++) {
69 sb.insert(r, ' ');
70 }
71 r += diff;
72 linelength += diff;
73 }
74 }
75 }
76 break;
77
78 case '\f' :
79 linelength = 100000; // force a break
80 lastSpace = r - 1;
81
82 //$FALL-THROUGH$
83
84 default :
85 linelength++;
86 begin = false;
87 if (lastSpace != 0 && linelength > 60) {
88 sb.setCharAt(lastSpace, '\n');
89 linelength = 0;
90
91 for (int i = 0; i < indent; i++) {
92 sb.insert(lastSpace + 1, ' ');
93 linelength++;
94 }
95 r += indent;
96 lastSpace = 0;
97 }
Stuart McCullochf3173222012-06-07 21:57:32 +000098 }
99 }
100 }
101
Stuart McCullochf3173222012-06-07 21:57:32 +0000102}