• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  *******************************************************************************
4  * Copyright (C) 2002-2012, International Business Machines Corporation and    *
5  * others. All Rights Reserved.                                                *
6  *******************************************************************************
7  */
8 package org.unicode.cldr.util;
9 
10 import java.util.ArrayList;
11 import java.util.List;
12 
13 import com.ibm.icu.lang.CharSequences;
14 import com.ibm.icu.text.UnicodeSet;
15 
16 public abstract class Tabber {
17     public static final byte LEFT = 0, CENTER = 1, RIGHT = 2;
18     private static final String[] ALIGNMENT_NAMES = { "Left", "Center", "Right" };
19 
20     /**
21      * Repeats a string n times
22      * @param source
23      * @param times
24      */
25     // TODO - optimize repeats using doubling?
repeat(String source, int times)26     public static String repeat(String source, int times) {
27         if (times <= 0) return "";
28         if (times == 1) return source;
29         StringBuffer result = new StringBuffer();
30         for (; times > 0; --times) {
31             result.append(source);
32         }
33         return result.toString();
34     }
35 
process(String source)36     public String process(String source) {
37         StringBuffer result = new StringBuffer();
38         int lastPos = 0;
39         for (int count = 0; lastPos < source.length(); ++count) {
40             int pos = source.indexOf('\t', lastPos);
41             if (pos < 0) pos = source.length();
42             process_field(count, source, lastPos, pos, result);
43             lastPos = pos + 1;
44         }
45         return prefix + result.toString() + postfix;
46     }
47 
48     private String prefix = "";
49     private String postfix = "";
50 
process_field(int count, String source, int start, int limit, StringBuffer output)51     public abstract void process_field(int count, String source, int start, int limit, StringBuffer output);
52 
clear()53     public Tabber clear() {
54         return this;
55     }
56 
57     public static class MonoTabber extends Tabber {
58         int minGap = 0;
59 
60         private List stops = new ArrayList();
61         private List types = new ArrayList();
62 
clear()63         public Tabber clear() {
64             stops.clear();
65             types.clear();
66             minGap = 0;
67             return this;
68         }
69 
toString()70         public String toString() {
71             StringBuffer buffer = new StringBuffer();
72             for (int i = 0; i < stops.size(); ++i) {
73                 if (i != 0) buffer.append("; ");
74                 buffer
75                     .append(ALIGNMENT_NAMES[((Integer) types.get(i)).intValue()])
76                     .append(",")
77                     .append(stops.get(i));
78             }
79             return buffer.toString();
80         }
81 
82         /**
83          * Adds tab stop and how to align the text UP TO that stop
84          * @param tabPos
85          * @param type
86          */
addAbsolute(int tabPos, int type)87         public MonoTabber addAbsolute(int tabPos, int type) {
88             stops.add(new Integer(tabPos));
89             types.add(new Integer(type));
90             return this;
91         }
92 
93         /**
94          * Adds relative tab stop and how to align the text UP TO that stop
95          */
add(int fieldWidth, byte type)96         public Tabber add(int fieldWidth, byte type) {
97             int last = getStop(stops.size() - 1);
98             stops.add(new Integer(last + fieldWidth));
99             types.add(new Integer(type));
100             return this;
101         }
102 
getStop(int fieldNumber)103         public int getStop(int fieldNumber) {
104             if (fieldNumber < 0) return 0;
105             if (fieldNumber >= stops.size()) fieldNumber = stops.size() - 1;
106             return ((Integer) stops.get(fieldNumber)).intValue();
107         }
108 
getType(int fieldNumber)109         public int getType(int fieldNumber) {
110             if (fieldNumber < 0) return LEFT;
111             if (fieldNumber >= stops.size()) return LEFT;
112             return ((Integer) types.get(fieldNumber)).intValue();
113         }
114 
process_field(int count, String source, int start, int limit, StringBuffer output)115         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
116             String piece = source.substring(start, limit);
117             int startPos = getStop(count - 1);
118             int endPos = getStop(count) - minGap;
119             int type = getType(count);
120             final int pieceLength = getMonospaceWidth(piece);
121             switch (type) {
122             case LEFT:
123                 break;
124             case RIGHT:
125                 startPos = endPos - pieceLength;
126                 break;
127             case CENTER:
128                 startPos = (startPos + endPos - pieceLength + 1) / 2;
129                 break;
130             }
131 
132             int gap = startPos - getMonospaceWidth(output);
133             if (count != 0 && gap < minGap) gap = minGap;
134             if (gap > 0) output.append(repeat(" ", gap));
135             output.append(piece);
136         }
137 
138         static final UnicodeSet IGNOREABLE = new UnicodeSet("[:di:]");
139 
getMonospaceWidth(CharSequence piece)140         private int getMonospaceWidth(CharSequence piece) {
141             int len = 0;
142             for (int cp : CharSequences.codePoints(piece)) {
143                 if (!IGNOREABLE.contains(cp)) {
144                     ++len;
145                 }
146             }
147             return len;
148         }
149     }
150 
151     public static Tabber NULL_TABBER = new Tabber() {
152         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
153             if (count > 0) output.append("\t");
154             output.append(source.substring(start, limit));
155         }
156     };
157 
158     public static class HTMLTabber extends Tabber {
159         private List<String> parameters = new ArrayList();
160         private String element = "td";
161         {
162             setPrefix("<tr>");
163             setPostfix("</tr>");
164         }
165 
setParameters(int count, String params)166         public HTMLTabber setParameters(int count, String params) {
167             // fill in
168             while (parameters.size() <= count) {
169                 parameters.add(null);
170             }
171             parameters.set(count, params);
172             return this;
173         }
174 
getElement()175         public String getElement() {
176             return element;
177         }
178 
setElement(String element)179         public HTMLTabber setElement(String element) {
180             this.element = element;
181             return this;
182         }
183 
process_field(int count, String source, int start, int limit, StringBuffer output)184         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
185             output.append("<" + element);
186             String params = null;
187             if (count < parameters.size()) {
188                 params = parameters.get(count);
189             }
190             if (params != null) {
191                 output.append(' ');
192                 output.append(params);
193             }
194             output.append(">");
195             output.append(source.substring(start, limit));
196             // TODO Quote string
197             output.append("</" + element + ">");
198         }
199     }
200 
201     /**
202      */
getPostfix()203     public String getPostfix() {
204         return postfix;
205     }
206 
207     /**
208      */
getPrefix()209     public String getPrefix() {
210         return prefix;
211     }
212 
213     /**
214      * @param string
215      */
setPostfix(String string)216     public Tabber setPostfix(String string) {
217         postfix = string;
218         return this;
219     }
220 
221     /**
222      * @param string
223      */
setPrefix(String string)224     public Tabber setPrefix(String string) {
225         prefix = string;
226         return this;
227     }
228 
add(int i, byte left2)229     public Tabber add(int i, byte left2) {
230         // does nothing unless overridden
231         return this;
232     }
233 
234 }
235