• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 import java.util.Vector;
2 import java.util.List;
3 import java.util.Iterator;
4 import java.util.Arrays;
5 import java.io.File;
6 import java.io.FileWriter;
7 import java.io.BufferedWriter;
8 import java.io.PrintWriter;
9 import java.io.IOException;
10 // JDOM classes used for document representation
11 import org.jdom.Document;
12 import org.jdom.Element;
13 import org.jdom.Attribute;
14 import org.jdom.JDOMException;
15 import org.jdom.input.SAXBuilder;
16 
17 /**
18  * Converts the matrix.xml file to a matrix.texi file, suitable for
19  * being included from gettext's nls.texi.
20  *
21  * @author Bruno Haible
22  */
23 public class Matrix {
24 
25   public static class PoFile {
26     String domain;
27     String team;
28     int percentage;
PoFile(String domain, String team, int percentage)29     public PoFile (String domain, String team, int percentage) {
30       this.domain = domain;
31       this.team = team;
32       this.percentage = percentage;
33     }
34   }
35 
36   public static class Data {
37     List /* of String */ domains = new Vector();
38     List /* of String */ teams = new Vector();
39     List /* of PoFile */ po_files = new Vector();
40   }
41 
42   public static final int FALSE = 0;
43   public static final int TRUE = 1;
44   public static final int EXTERNAL = 2;
45 
spaces(PrintWriter stream, int n)46   public static void spaces (PrintWriter stream, int n) {
47     for (int i = n; i > 0; i--)
48       stream.print(' ');
49   }
50 
main(String[] args)51   public static void main (String[] args) {
52     Data data = new Data();
53 
54     SAXBuilder builder = new SAXBuilder(/*true*/); // "true" turns on validation
55     Document doc;
56     try {
57       doc = builder.build(new File("matrix.xml"));
58     } catch (IOException e) {
59       e.printStackTrace();
60       doc = null;
61       System.exit(1);
62     } catch (JDOMException e) {
63       e.printStackTrace();
64       doc = null;
65       System.exit(1);
66     }
67     Element po_inventory = doc.getRootElement();
68     {
69       Element domains = po_inventory.getChild("domains");
70       Iterator i = domains.getChildren("domain").iterator();
71       while (i.hasNext()) {
72         Element domain = (Element)i.next();
73         data.domains.add(domain.getAttribute("name").getValue());
74       }
75     }
76     {
77       Element teams = po_inventory.getChild("teams");
78       Iterator i = teams.getChildren("team").iterator();
79       while (i.hasNext()) {
80         Element team = (Element)i.next();
81         data.teams.add(team.getAttribute("name").getValue());
82       }
83     }
84     {
85       Element po_files = po_inventory.getChild("PoFiles");
86       Iterator i = po_files.getChildren("po").iterator();
87       while (i.hasNext()) {
88         Element po = (Element)i.next();
89         String value = po.getText();
90         data.po_files.add(
91             new PoFile(
92                 po.getAttribute("domain").getValue(),
93                 po.getAttribute("team").getValue(),
94                 value.equals("") ? -1 : Integer.parseInt(value)));
95       }
96     }
97 
98     // Special treatment of clisp. The percentages are incorrect.
99     if (!data.teams.contains("en"))
100       data.teams.add("en");
101     data.po_files.add(new PoFile("clisp","en",100));
102     data.po_files.add(new PoFile("clisp","de",83));
103     data.po_files.add(new PoFile("clisp","fr",58));
104     data.po_files.add(new PoFile("clisp","es",54));
105     data.po_files.add(new PoFile("clisp","nl",57));
106     data.po_files.add(new PoFile("clisp","ru",74));
107 
108     // Obsolete domains.
109     data.domains.remove("gettext");
110     for (Iterator i = data.po_files.iterator(); i.hasNext(); ) {
111       PoFile po = (PoFile)i.next();
112       if (po.domain.equals("gettext"))
113         i.remove();
114     }
115 
116     try {
117       FileWriter f = new FileWriter("matrix.texi");
118       BufferedWriter bf = new BufferedWriter(f);
119       PrintWriter stream = new PrintWriter(bf);
120 
121       String[] domains = (String[])data.domains.toArray(new String[0]);
122       Arrays.sort(domains);
123       String[] teams = (String[])data.teams.toArray(new String[0]);
124       Arrays.sort(teams);
125       int ndomains = domains.length;
126       int nteams = teams.length;
127 
128       int[][] matrix = new int[ndomains][];
129       for (int d = 0; d < ndomains; d++)
130         matrix[d] = new int[nteams];
131       int[] total_per_domain = new int[ndomains];
132       int[] total_per_team = new int[nteams];
133       int total = 0;
134       {
135         Iterator i = data.po_files.iterator();
136         while (i.hasNext()) {
137           PoFile po = (PoFile)i.next();
138           if (po.percentage >= 50) {
139             int d = Arrays.binarySearch(domains,po.domain);
140             if (d < 0)
141               throw new Error("didn't find domain \""+po.domain+"\"");
142             int t = Arrays.binarySearch(teams,po.team);
143             if (t < 0)
144               throw new Error("didn't find team \""+po.team+"\"");
145             matrix[d][t] = TRUE;
146             total_per_domain[d]++;
147             total_per_team[t]++;
148             total++;
149           } else if (po.percentage < 0) {
150             int d = Arrays.binarySearch(domains,po.domain);
151             if (d < 0)
152               throw new Error("didn't find domain \""+po.domain+"\"");
153             int t = Arrays.binarySearch(teams,po.team);
154             if (t < 0) {
155               System.err.println(po.domain+": didn't find team \""+po.team+"\"");
156               continue;
157             }
158             matrix[d][t] = EXTERNAL;
159           }
160         }
161       }
162 
163       int[] columnwidth = new int[nteams];
164       for (int t = 0; t < nteams; t++)
165         columnwidth[t] =
166           Math.max(teams[t].length(),
167                    Integer.toString(total_per_team[t]).length());
168 
169       // Split into separate tables, to keep 80 column width.
170       int maxwidth = 80 - 21 - 5 - Integer.toString(total).length();
171 
172       // First determine how many groups are needed.
173       int ngroups = 0;
174       {
175         int width = 0, last_team = 0;
176         for (int t = 0; t < nteams; t++) {
177           int newwidth = width + columnwidth[t] + 1;
178           if (newwidth > maxwidth) {
179             last_team = t;
180             ngroups++;
181             width = 0;
182           }
183           width += columnwidth[t] + 1;
184         }
185         if (last_team < nteams)
186           ngroups++;
187       }
188 
189       // Then initialize the size of each group.
190       int[][] groups = new int[ngroups][];
191       {
192         int width = 0, last_team = 0, index = 0;
193         for (int t = 0; t < nteams; t++) {
194           int newwidth = width + columnwidth[t] + 1;
195           if (newwidth > maxwidth) {
196             groups[index++] = new int[] { last_team, t };
197             last_team = t;
198             width = 0;
199           }
200           width += columnwidth[t] + 1;
201         }
202         if (last_team < nteams)
203           groups[index] = new int[] { last_team, nteams };
204       }
205 
206       stream.println("@example");
207       for (int group = 0; group < ngroups; group++) {
208         if (group > 0)
209           stream.println();
210 
211         stream.println("@group");
212 
213         if (group == 0)
214           stream.print("Ready PO files      ");
215         else
216           stream.print("                    ");
217         for (int t = groups[group][0]; t < groups[group][1]; t++) {
218           int i = columnwidth[t]-teams[t].length();
219           spaces(stream,1+i/2);
220           stream.print(teams[t].replace("@","@@"));
221           spaces(stream,(i+1)/2);
222         }
223         stream.println();
224 
225         stream.print("                   +");
226         for (int t = groups[group][0]; t < groups[group][1]; t++)
227           for (int i = columnwidth[t] + 1; i > 0; i--)
228             stream.print('-');
229         stream.println("-+");
230 
231         for (int d = 0; d < ndomains; d++) {
232           String domain = domains[d];
233           if (domain.length() > 18)
234             domain = domain.substring(0, 18-3) + "...";
235           stream.print(domain);
236           spaces(stream,18 - domain.length() + 1);
237           stream.print('|');
238           for (int t = groups[group][0]; t < groups[group][1]; t++) {
239             stream.print(' ');
240             if (matrix[d][t] == TRUE) {
241               int i = columnwidth[t]-2;
242               spaces(stream,i/2);
243               stream.print("[]");
244               spaces(stream,(i+1)/2);
245             } else if (matrix[d][t] == EXTERNAL) {
246               int i = columnwidth[t]-2;
247               spaces(stream,i/2);
248               stream.print("()");
249               spaces(stream,(i+1)/2);
250             } else {
251               spaces(stream,columnwidth[t]);
252             }
253           }
254           stream.print(' ');
255           stream.print('|');
256           if (group == ngroups-1) {
257             stream.print(' ');
258             String s = Integer.toString(total_per_domain[d]);
259             spaces(stream,2-s.length());
260             stream.print(s);
261           }
262           stream.println();
263         }
264 
265         stream.print("                   +");
266         for (int t = groups[group][0]; t < groups[group][1]; t++)
267           for (int i = columnwidth[t] + 1; i > 0; i--)
268             stream.print('-');
269         stream.println("-+");
270 
271         if (group == ngroups-1) {
272           String s = Integer.toString(nteams);
273           spaces(stream,4-s.length());
274           stream.print(s);
275           stream.print(" teams          ");
276         } else {
277           stream.print("                    ");
278         }
279         for (int t = groups[group][0]; t < groups[group][1]; t++) {
280           int i = columnwidth[t]-teams[t].length();
281           spaces(stream,1+i/2);
282           stream.print(teams[t].replace("@","@@"));
283           spaces(stream,(i+1)/2);
284         }
285         stream.println();
286 
287         if (group == ngroups-1) {
288           String s = Integer.toString(ndomains);
289           spaces(stream,4-s.length());
290           stream.print(s);
291           stream.print(" domains        ");
292         } else {
293           stream.print("                    ");
294         }
295         for (int t = groups[group][0]; t < groups[group][1]; t++) {
296           stream.print(' ');
297           String s = Integer.toString(total_per_team[t]);
298           int i = columnwidth[t]-s.length();
299           int j = (s.length() < 2 ? 1 : 0);
300           spaces(stream,(i+j)/2);
301           stream.print(s);
302           spaces(stream,(i+1-j)/2);
303         }
304         if (group == ngroups-1) {
305           stream.print(' ');
306           stream.print(' ');
307           String s = Integer.toString(total);
308           spaces(stream,3-s.length());
309           stream.print(s);
310         }
311         stream.println();
312 
313         stream.println("@end group");
314       }
315       stream.println("@end example");
316 
317       stream.close();
318       bf.close();
319       f.close();
320     } catch (IOException e) {
321       e.printStackTrace();
322       System.exit(1);
323     }
324   }
325 
326 }
327