]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/demo/translit/Demo.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / demo / translit / Demo.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2008, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.dev.demo.translit;\r
8 \r
9 import java.awt.*;\r
10 import java.awt.event.*;\r
11 import java.util.*;\r
12 import java.text.CharacterIterator;\r
13 \r
14 import com.ibm.icu.dev.test.util.Differ;\r
15 import com.ibm.icu.lang.*;\r
16 import com.ibm.icu.text.*;\r
17 \r
18 import java.io.*;\r
19 \r
20 /**\r
21  * A frame that allows the user to experiment with keyboard\r
22  * transliteration.  This class has a main() method so it can be run\r
23  * as an application.  The frame contains an editable text component\r
24  * and uses keyboard transliteration to process keyboard events.\r
25  *\r
26  * <p>Copyright (c) IBM Corporation 1999.  All rights reserved.\r
27  *\r
28  * @author Alan Liu\r
29  */\r
30 public class Demo extends Frame {\r
31 \r
32     /**\r
33      * For serialization\r
34      */\r
35     private static final long serialVersionUID = 1L;\r
36     static final boolean DEBUG = false;\r
37     static final String START_TEXT = "(cut,\u03BA\u03C5\u03C4,\u05D0,\u30AF\u30C8,\u4E80,\u091A\u0941\u0924\u094D)";\r
38 \r
39     Transliterator translit = null;\r
40     String fontName = "Arial Unicode MS";\r
41     int fontSize = 18;\r
42     \r
43     \r
44 \r
45     /*\r
46     boolean compound = false;\r
47     Transliterator[] compoundTranslit = new Transliterator[MAX_COMPOUND];\r
48     static final int MAX_COMPOUND = 128;\r
49     int compoundCount = 0;\r
50     */\r
51 \r
52     TransliteratingTextComponent text = null;\r
53 \r
54     Menu translitMenu;\r
55     CheckboxMenuItem translitItem;\r
56     CheckboxMenuItem noTranslitItem;\r
57 \r
58     static final String NO_TRANSLITERATOR = "None";\r
59 \r
60     //private static final String COPYRIGHT =\r
61     //    "\u00A9 IBM Corporation 1999. All rights reserved.";\r
62 \r
63     public static void main(String[] args) {\r
64         Frame f = new Demo(600, 200);\r
65         f.addWindowListener(new WindowAdapter() {\r
66             public void windowClosing(WindowEvent e) {\r
67                 com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameClosed();\r
68 //                System.exit(0);\r
69             }\r
70         });\r
71         f.setVisible(true);\r
72         com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameOpened();\r
73     }\r
74 \r
75     public Demo(int width, int height) {\r
76         super("Transliteration Demo");\r
77 \r
78         initMenus();\r
79 \r
80         addWindowListener(new WindowAdapter() {\r
81             public void windowClosing(WindowEvent e) {\r
82                 handleClose();\r
83             }\r
84         });\r
85         \r
86         text = new TransliteratingTextComponent();\r
87         Font font = new Font(fontName, Font.PLAIN, fontSize);\r
88         text.setFont(font);\r
89         text.setSize(width, height);\r
90         text.setVisible(true);\r
91         text.setText(START_TEXT);\r
92         add(text);\r
93 \r
94         setSize(width, height);\r
95         setTransliterator("Latin-Greek", null);\r
96     }\r
97 \r
98     private void initMenus() {\r
99         MenuBar mbar;\r
100         Menu menu;\r
101         MenuItem mitem;\r
102         //CheckboxMenuItem citem;\r
103         \r
104         setMenuBar(mbar = new MenuBar());\r
105         mbar.add(menu = new Menu("File"));\r
106         menu.add(mitem = new MenuItem("Quit"));\r
107         mitem.addActionListener(new ActionListener() {\r
108             public void actionPerformed(ActionEvent e) {\r
109                 handleClose();\r
110             }\r
111         });\r
112 /*\r
113         final ItemListener setTransliteratorListener = new ItemListener() {\r
114             public void itemStateChanged(ItemEvent e) {\r
115                 CheckboxMenuItem item = (CheckboxMenuItem) e.getSource();\r
116                 if (e.getStateChange() == ItemEvent.DESELECTED) {\r
117                     // Don't let the current transliterator be deselected.\r
118                     // Just reselect it.\r
119                     item.setState(true);\r
120                 } else if (compound) {\r
121                     // Adding an item to a compound transliterator\r
122                     handleAddToCompound(item.getLabel());\r
123                 } else if (item != translitItem) {\r
124                     // Deselect previous choice.  Don't need to call\r
125                     // setState(true) on new choice.\r
126                     translitItem.setState(false);\r
127                     translitItem = item;\r
128                     handleSetTransliterator(item.getLabel());\r
129                 }\r
130             }\r
131         };\r
132 */\r
133         /*\r
134         translitMenu.add(translitItem = noTranslitItem =\r
135                          new CheckboxMenuItem(NO_TRANSLITERATOR, true));\r
136         noTranslitItem.addItemListener(new ItemListener() {\r
137             public void itemStateChanged(ItemEvent e) {\r
138                 // Can't uncheck None -- any action here sets None to true\r
139                 setNoTransliterator();\r
140             }\r
141         });\r
142 \r
143         translitMenu.addSeparator();\r
144         */\r
145 \r
146 /*\r
147         translitMenu.add(citem = new CheckboxMenuItem("Compound"));\r
148         citem.addItemListener(new ItemListener() {\r
149             public void itemStateChanged(ItemEvent e) {\r
150                 CheckboxMenuItem item = (CheckboxMenuItem) e.getSource();\r
151                 if (e.getStateChange() == ItemEvent.DESELECTED) {\r
152                     // If compound gets deselected, then select NONE\r
153                     setNoTransliterator();\r
154                 } else if (!compound) {\r
155                     // Switching from non-compound to compound\r
156                     translitItem.setState(false);\r
157                     translitItem = item;\r
158                     translit = null;\r
159                     compound = true;\r
160                     compoundCount = 0;\r
161                     for (int i=0; i<MAX_COMPOUND; ++i) {\r
162                         compoundTranslit[i] = null;\r
163                     }\r
164                 }\r
165             }\r
166         });\r
167       \r
168         translitMenu.addSeparator();\r
169        */\r
170 \r
171         /*\r
172         for (Enumeration e=getSystemTransliteratorNames().elements();\r
173              e.hasMoreElements(); ) {\r
174             String s = (String) e.nextElement();\r
175             translitMenu.add(citem = new CheckboxMenuItem(s));\r
176             citem.addItemListener(setTransliteratorListener);\r
177         }\r
178         */\r
179         \r
180         Menu fontMenu = new Menu("Font");\r
181         String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();\r
182         for (int i = 0; i < fonts.length; ++i) {\r
183             MenuItem mItem = new MenuItem(fonts[i]);\r
184             mItem.addActionListener(new FontActionListener(fonts[i]));\r
185             fontMenu.add(mItem);\r
186         }\r
187         mbar.add(fontMenu);\r
188         \r
189         Menu sizeMenu = new Menu("Size");\r
190         int[] sizes = {9, 10, 12, 14, 18, 24, 36, 48, 72};\r
191         for (int i = 0; i < sizes.length; ++i) {\r
192             MenuItem mItem = new MenuItem("" + sizes[i]);\r
193             mItem.addActionListener(new SizeActionListener(sizes[i]));\r
194             sizeMenu.add(mItem);\r
195         }\r
196         mbar.add(sizeMenu);\r
197         \r
198         translit = null;\r
199         \r
200         mbar.add(translitMenu = new Menu("Transliterator"));\r
201         \r
202         translitMenu.add(convertSelectionItem = new MenuItem("Transliterate", \r
203             new MenuShortcut(KeyEvent.VK_K)));\r
204         convertSelectionItem.addActionListener(new ActionListener() {\r
205             public void actionPerformed(ActionEvent e) {\r
206                 handleBatchTransliterate(translit);\r
207             }\r
208         });\r
209         \r
210         translitMenu.add(swapSelectionItem = new MenuItem("Reverse", \r
211             new MenuShortcut(KeyEvent.VK_S)));\r
212         swapSelectionItem.addActionListener(new ActionListener() {\r
213             public void actionPerformed(ActionEvent e) {\r
214                 Transliterator inv;\r
215                 try {\r
216                     inv = translit.getInverse();\r
217                 } catch (Exception x) {\r
218                     inv = Transliterator.getInstance("null");\r
219                 }\r
220                 setTransliterator(inv.getID(), null);\r
221             }\r
222         });\r
223         \r
224         translitMenu.add(convertTypingItem = new MenuItem("No Typing Conversion",\r
225             new MenuShortcut(KeyEvent.VK_T)));\r
226         convertTypingItem.addActionListener(new ActionListener() {\r
227             public void actionPerformed(ActionEvent e) {\r
228                 if (!transliterateTyping) {\r
229                     text.setTransliterator(translit);\r
230                     convertTypingItem.setLabel("No Typing Conversion");\r
231                 } else {\r
232                     text.flush();\r
233                     text.setTransliterator(null);\r
234                     convertTypingItem.setLabel("Convert Typing");\r
235                 }\r
236                 transliterateTyping = !transliterateTyping;\r
237             }\r
238         });\r
239         \r
240         translitMenu.add(historyMenu = new Menu("Recent"));\r
241         \r
242         helpDialog = new InfoDialog(this, "Simple Demo", "Instructions",\r
243            "CTL A, X, C, V have customary meanings.\n"\r
244          + "Arrow keys, delete and backspace work.\n"\r
245          + "To get a character from its control point, type the hex, then hit CTL Q"\r
246         );\r
247         helpDialog.getArea().setEditable(false);\r
248         \r
249        \r
250         Menu helpMenu;\r
251         mbar.add(helpMenu = new Menu("Extras"));\r
252         helpMenu.add(mitem = new MenuItem("Help"));\r
253         mitem.addActionListener(new ActionListener() {\r
254             public void actionPerformed(ActionEvent e) {\r
255                 helpDialog.show();\r
256             }\r
257         });   \r
258         \r
259         hexDialog = new InfoDialog(this, "Hex Entry", "Use U+..., \\u..., \\x{...}, or &#x...;",\r
260            "\\u00E1"\r
261         );\r
262         Button button = new Button("Insert");\r
263         button.addActionListener(new ActionListener() {\r
264             public void actionPerformed(ActionEvent e) {\r
265                 String hexValue = hexDialog.getArea().getText();\r
266                 text.insertText(fromHex.transliterate(hexValue));\r
267             }\r
268         });\r
269         hexDialog.getBottom().add(button);\r
270         \r
271         helpMenu.add(mitem = new MenuItem("Hex...", \r
272             new MenuShortcut(KeyEvent.VK_H)));\r
273         mitem.addActionListener(new ActionListener() {\r
274             public void actionPerformed(ActionEvent e) {\r
275                 hexDialog.show();\r
276             }\r
277         });\r
278         \r
279         // Compound Transliterator\r
280         \r
281         compoundDialog = new InfoDialog(this, "Compound Transliterator", "",\r
282            "[^\\u0000-\\u00FF] hex"\r
283         );\r
284         button = new Button("Set");\r
285         button.addActionListener(new ActionListener() {\r
286             public void actionPerformed(ActionEvent e) {\r
287                 String compound = "";\r
288                 try {\r
289                     compound = compoundDialog.getArea().getText();\r
290                     setTransliterator(compound, null);\r
291                 } catch (RuntimeException ex) {\r
292                     compoundDialog.getArea().setText(compound + "\n" + ex.getMessage());\r
293                 }\r
294             }\r
295         });\r
296         compoundDialog.getBottom().add(button);\r
297         \r
298         translitMenu.add(mitem = new MenuItem("Multiple...", \r
299             new MenuShortcut(KeyEvent.VK_M)));\r
300         mitem.addActionListener(new ActionListener() {\r
301             public void actionPerformed(ActionEvent e) {\r
302                 compoundDialog.show();\r
303             }\r
304         });\r
305         \r
306         // RuleBased Transliterator\r
307         \r
308         rulesDialog = new InfoDialog(this, "Rule-Based Transliterator", "",\r
309            "([A-Z]) > &Hex($1) &Name($1);\r\n" \r
310             + "&Hex-Any($1) < ('\\' [uU] [a-fA-F0-9]*);\r\n" \r
311             + "&Name-Any($1) < ('{' [^\\}]* '}');"\r
312         );\r
313         button = new Button("Set");\r
314         button.addActionListener(new ActionListener() {\r
315             public void actionPerformed(ActionEvent e) {\r
316                 String compound = "";\r
317                 try {\r
318                     compound = rulesDialog.getArea().getText();\r
319                     String id = ruleId.getText();\r
320                     setTransliterator(compound, id);\r
321                 } catch (RuntimeException ex) {\r
322                     rulesDialog.getArea().setText(compound + "\n#" + ex.getMessage());\r
323                 }\r
324             }\r
325         });\r
326         rulesDialog.getBottom().add(button);\r
327         ruleId = new TextField("test1", 20);\r
328         Label temp = new Label(" Name:");\r
329         rulesDialog.getBottom().add(temp);\r
330         rulesDialog.getBottom().add(ruleId);\r
331         \r
332         \r
333         translitMenu.add(mitem = new MenuItem("From Rules...", \r
334             new MenuShortcut(KeyEvent.VK_R)));\r
335         mitem.addActionListener(new ActionListener() {\r
336             public void actionPerformed(ActionEvent e) {\r
337                 rulesDialog.show();\r
338             }\r
339         });\r
340         \r
341         \r
342         translitMenu.add(mitem = new MenuItem("From File...", \r
343             new MenuShortcut(KeyEvent.VK_F)));\r
344         mitem.addActionListener(new FileListener(this, RULE_FILE));\r
345         \r
346         translitMenu.add(mitem = new MenuItem("Test File..."));\r
347         mitem.addActionListener(new FileListener(this, TEST_FILE));\r
348         \r
349         // Flesh out the menu with the installed transliterators\r
350         \r
351         translitMenu.addSeparator();\r
352         \r
353         Iterator sources = add(new TreeSet(), Transliterator.getAvailableSources()).iterator();\r
354         while(sources.hasNext()) {\r
355             String source = (String) sources.next();\r
356             Iterator targets = add(new TreeSet(), Transliterator.getAvailableTargets(source)).iterator();\r
357             Menu targetMenu = new Menu(source);\r
358             while(targets.hasNext()) {\r
359                 String target = (String) targets.next();\r
360                 Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target));\r
361                 if (variantSet.size() < 2) {\r
362                     mitem = new MenuItem(target);\r
363                     mitem.addActionListener(new TransliterationListener(source + "-" + target));\r
364                     targetMenu.add(mitem);\r
365                 } else {\r
366                     Iterator variants = variantSet.iterator();\r
367                     Menu variantMenu = new Menu(target);\r
368                     while(variants.hasNext()) {\r
369                         String variant = (String) variants.next();\r
370                         String menuName = variant.length() == 0 ? "<default>" : variant;\r
371                         //System.out.println("<" + source + "-" + target + "/" + variant + ">, <" + menuName + ">");\r
372                         mitem = new MenuItem(menuName);\r
373                         mitem.addActionListener(new TransliterationListener(source + "-" + target + "/" + variant));\r
374                         variantMenu.add(mitem);\r
375                     }\r
376                     targetMenu.add(variantMenu);\r
377                 }\r
378             }\r
379             translitMenu.add(targetMenu);\r
380         }\r
381         \r
382         \r
383     }\r
384     \r
385     static final int RULE_FILE = 0, TEST_FILE = 1;\r
386     //\r
387     static class FileListener implements ActionListener {\r
388         Demo frame;\r
389         int choice;\r
390         \r
391         FileListener(Demo frame, int choice) {\r
392             this.frame = frame;\r
393             this.choice = choice;\r
394         }\r
395         \r
396         public void actionPerformed(ActionEvent e) {\r
397             String id = frame.translit.getID();\r
398             int slashPos = id.indexOf('/');\r
399             String variant = "";\r
400             if (slashPos >= 0) {\r
401                 variant = "_" + id.substring(slashPos+1);\r
402                 id = id.substring(0, slashPos);\r
403             }\r
404             \r
405             FileDialog fileDialog = new FileDialog(frame, "Input File");\r
406             fileDialog.setFile("Test_" + id + ".txt");\r
407             fileDialog.show();\r
408             String fileName = fileDialog.getFile();\r
409             String fileDirectory = fileDialog.getDirectory();\r
410             if (fileName != null) {\r
411                 try {\r
412                     File f = new File(fileDirectory, fileName);\r
413                     if (choice == RULE_FILE) {\r
414                         \r
415                         // read stuff into buffer\r
416                         \r
417                         StringBuffer buffer = new StringBuffer();\r
418                         FileInputStream fis = new FileInputStream(f);\r
419                         InputStreamReader isr = new InputStreamReader(fis, "UTF8");\r
420                         BufferedReader br = new BufferedReader(isr, 32*1024);\r
421                         while (true) {\r
422                             String line = br.readLine();\r
423                             if (line == null) break;\r
424                             if (line.length() > 0 && line.charAt(0) == '\uFEFF') line = line.substring(1); // strip BOM\r
425                             buffer.append('\n');\r
426                             buffer.append(line);\r
427                         }\r
428                         br.close();\r
429                         \r
430                         // Transform file name into id\r
431                         if (fileName.startsWith("Transliterator_")) {\r
432                             fileName = fileName.substring("Transliterator_".length());\r
433                         }\r
434                         int pos = fileName.indexOf('_');\r
435                         if (pos < 0) {\r
436                             id = fileName;\r
437                         } else {\r
438                             id = fileName.substring(0, pos) + "-";\r
439                             int pos2 = fileName.indexOf('_', pos+1);\r
440                             if (pos2 < 0) {\r
441                                 id += fileName.substring(pos+1);\r
442                             } else {\r
443                                 id += fileName.substring(pos+1, pos2) + "/" + fileName.substring(pos2 + 1);\r
444                             }\r
445                         }                        \r
446                         pos = id.lastIndexOf('.');\r
447                         if (pos >= 0) id = id.substring(0, pos);\r
448                         \r
449                         // Now set\r
450                         \r
451                         frame.setTransliterator(buffer.toString(), id);\r
452                     } else if (choice == TEST_FILE) {\r
453                         genTestFile(f, frame.translit, variant);\r
454                     }\r
455                 } catch (Exception e2) {\r
456                     e2.printStackTrace();\r
457                     System.out.println("Problem opening/reading: " + fileDirectory + ", " + fileName);\r
458                 }\r
459             }\r
460             fileDialog.dispose();\r
461         }\r
462     }\r
463     \r
464 \r
465     boolean transliterateTyping = true;\r
466     Transliterator fromHex = Transliterator.getInstance("Hex-Any");\r
467     InfoDialog helpDialog;\r
468     InfoDialog hexDialog;\r
469     InfoDialog compoundDialog;\r
470     InfoDialog rulesDialog;\r
471     TextField ruleId;\r
472     MenuItem convertSelectionItem = null;\r
473     MenuItem swapSelectionItem = null;\r
474     MenuItem convertTypingItem = null;\r
475     Menu historyMenu;\r
476     Map historyMap = new HashMap();\r
477     Set historySet = new TreeSet(new Comparator() {\r
478             public int compare(Object a, Object b) {\r
479                 MenuItem aa = (MenuItem)a;\r
480                 MenuItem bb = (MenuItem)b;\r
481                 return aa.getLabel().compareTo(bb.getLabel());\r
482             }\r
483         });\r
484         \r
485     // ADD Factory since otherwise getInverse blows out\r
486     static class DummyFactory implements Transliterator.Factory {\r
487         static DummyFactory singleton = new DummyFactory();\r
488         static HashMap m = new HashMap();\r
489 \r
490         // Since Transliterators are immutable, we don't have to clone on set & get\r
491         static void add(String ID, Transliterator t) {\r
492             m.put(ID, t);\r
493             System.out.println("Registering: " + ID + ", " + t.toRules(true));\r
494             Transliterator.registerFactory(ID, singleton);\r
495         }\r
496         public Transliterator getInstance(String ID) {\r
497             return (Transliterator) m.get(ID);\r
498         }\r
499     }\r
500     \r
501     static void printBreaks(int num, String testSource, BreakIterator brkItr) {\r
502         String result = "";\r
503         int lastPos = 0;\r
504         while (true) {\r
505             int pos = brkItr.next();\r
506             if (pos == BreakIterator.DONE) break;\r
507             result += testSource.substring(lastPos, pos) + "&";\r
508             lastPos = pos;\r
509             System.out.println(pos);\r
510         }\r
511         System.out.println("Test" + num + ": " + result);\r
512     }\r
513     \r
514     static void printIteration(int num, String testSource, CharacterIterator ci) {\r
515         String result = "";\r
516         while (true) {\r
517             char ch = ci.next();\r
518             if (ch == CharacterIterator.DONE) break;\r
519             result += ch + "(" + ci.getIndex() + ")";\r
520         }\r
521         System.out.println("Test" + num + ": " + result);\r
522     }\r
523     \r
524     static void printSources() {\r
525         String[] list = {"Latin-ThaiLogical", "ThaiLogical-Latin", "Thai-ThaiLogical", "ThaiLogical-Thai"};\r
526         UnicodeSet all = new UnicodeSet();\r
527         for (int i = 0; i < list.length; ++i) {\r
528             Transliterator tr = Transliterator.getInstance(list[i]);\r
529             UnicodeSet src = tr.getSourceSet();\r
530             System.out.println(list[i] + ": " + src.toPattern(true));\r
531             all.addAll(src);\r
532         }\r
533         System.out.println("All: " + all.toPattern(true));\r
534         UnicodeSet rem = new UnicodeSet("[[:latin:][:thai:]]");\r
535         System.out.println("missing from [:latin:][:thai:]: " + all.removeAll(rem).toPattern(true));\r
536     }\r
537     \r
538     // 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;\r
539 \r
540     static Transliterator title = Transliterator.getInstance("title");\r
541     static String hexAndNameRules = "    ([:c:]) > \\u200E &hex/unicode($1) ' ( ) ' &name($1) \\u200E ' ';"\r
542         + "([:mark:]) > \\u200E &hex/unicode($1) ' ( ' \\u200E \u25CC $1 \\u200E ' ) ' &name($1) \\u200E ' ';"\r
543         + "(.) > \\u200E &hex/unicode($1) ' ( ' \\u200E $1 \\u200E ' ) ' &name($1) ' ' \\u200E;";\r
544 \r
545     static Transliterator hexAndName = Transliterator.createFromRules("any-hexAndName", \r
546         hexAndNameRules, Transliterator.FORWARD);\r
547     \r
548 \r
549 \r
550     //static Transliterator upper = Transliterator.getInstance("upper");\r
551      \r
552     static final byte NONE = 0, TITLEWORD = 1, TITLELINE = 2;\r
553     \r
554     static void genTestFile(File sourceFile, Transliterator translit, String variant) {\r
555         try {\r
556             \r
557             System.out.println("Reading: " + sourceFile.getCanonicalPath());\r
558             BufferedReader in = new BufferedReader(\r
559                 new InputStreamReader(\r
560                     new FileInputStream(sourceFile), "UTF-8"));\r
561             String targetFile = sourceFile.getCanonicalPath();\r
562             int dotPos = targetFile.lastIndexOf('.');\r
563             if (dotPos >= 0) targetFile = targetFile.substring(0,dotPos);\r
564             targetFile += variant;\r
565             \r
566             File outFile = new File(targetFile + ".html");\r
567             System.out.println("Writing: " + outFile.getCanonicalPath());\r
568             \r
569             PrintWriter out = new PrintWriter(\r
570                 new BufferedWriter(\r
571                     new OutputStreamWriter(\r
572                         new FileOutputStream(outFile), "UTF-8")));\r
573                         \r
574             String direction = "";\r
575             String id = translit.getID();\r
576             if (id.indexOf("Arabic") >= 0 || id.indexOf("Hebrew") >= 0) {\r
577                 direction = " direction: rtl;";\r
578             }\r
579             boolean testRoundTrip = true;\r
580             boolean generateSets = true;\r
581             if (id.startsWith("Han-") || id.startsWith("ja-")) {\r
582                 testRoundTrip = false;\r
583                 generateSets = false;\r
584             }\r
585             out.println("<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");\r
586             out.println("<style><!--");\r
587             out.println("td, th       { vertical-align: top; border: 1px solid black }");\r
588             out.println("td.s       { background-color: #EEEEEE;" + direction + " }");\r
589             out.println("td.r       { background-color: #CCCCCC;" + direction + " }");\r
590             out.println("td.n       { background-color: #FFFFCC; }");\r
591             out.println("td.title       { border: 0px solid black}");\r
592             out.println("span.d       { background-color: #FF6666 }");\r
593             out.println("span.r       { background-color: #66FF66 }");\r
594 \r
595             out.println("body         { font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', Arial, sans-serif; margin: 5 }");\r
596             out.println("--></style>");\r
597             out.println("<title>" + id + " Transliteration Check</title></head>");\r
598             out.println("<body bgcolor='#FFFFFF'><p>See <a href='Test_Instructions.html'>Test_Instructions.html</a> for details.</p>");\r
599             out.println("<table>");\r
600             \r
601             //out.println("<tr><th width='33%'>Thai</th><th width='33%'>Latin</th><th width='33%'>Thai</th></tr>");\r
602   \r
603             Transliterator tl = translit;\r
604             Transliterator lt = tl.getInverse();\r
605             \r
606             Transliterator ltFilter = tl.getInverse();\r
607             ltFilter.setFilter(new UnicodeSet("[:^Lu:]"));\r
608             Transliterator tlFilter = lt.getInverse();\r
609             tlFilter.setFilter(new UnicodeSet("[:^Lu:]"));\r
610             \r
611             //Transliterator.getInstance("[:^Lu:]" +  lt.getID());\r
612             \r
613             BreakIterator sentenceBreak = BreakIterator.getSentenceInstance();\r
614             \r
615             byte titleSetting = TITLELINE;\r
616             //boolean upperfilter = false;\r
617             boolean first = true;\r
618             while (true) {\r
619                 String line = in.readLine();\r
620                 if (line == null) break;\r
621                 line = line.trim();\r
622                 if (line.length() == 0) continue;\r
623                 if (line.charAt(0) == '\uFEFF') line = line.substring(1); // remove BOM\r
624                 \r
625                 if (line.charAt(0) == '#') continue; // comments\r
626                 \r
627                 if (line.equals("@TITLECASE@")) {\r
628                     titleSetting = TITLEWORD;\r
629                     out.println("<tr><td colspan='2' class='title'><b>Names</b></td></tr>");\r
630                     continue;\r
631                 } else if (line.equals("@UPPERFILTER@")) {\r
632                     //upperfilter = true;\r
633                     continue;\r
634                 } else if (line.startsWith("@SET")) {\r
635                     UnicodeSet s = new UnicodeSet(line.substring(4).trim());\r
636                     out.println("<tr><td colspan='2' class='title'><b>Characters</b></td></tr>");\r
637                     UnicodeSetIterator it = new UnicodeSetIterator(s);\r
638                     while (it.next()) {\r
639                         addSentenceToTable(out, it.codepoint != UnicodeSetIterator.IS_STRING \r
640                             ? UTF16.valueOf(it.codepoint)\r
641                             : it.string,\r
642                             NONE, true, testRoundTrip, first, tl, lt);\r
643                     }\r
644                     continue;\r
645                 }\r
646                         \r
647                 sentenceBreak.setText(line);\r
648                 int start = 0;\r
649                 while (true) {\r
650                     int end = sentenceBreak.next();\r
651                     if (end == BreakIterator.DONE) break;\r
652                     String coreSentence = line.substring(start, end);\r
653                     //System.out.println("Core: " + hex.transliterate(coreSentence));\r
654                     end = start;\r
655                     \r
656                     int oldPos = 0;\r
657                     while (oldPos < coreSentence.length()) {\r
658                         // hack, because sentence doesn't seem to be working right\r
659                         int pos = coreSentence.indexOf(". ", oldPos);\r
660                         if (pos < 0) pos = coreSentence.length(); else pos = pos+2;\r
661                         int pos2 = coreSentence.indexOf('\u3002', oldPos);\r
662                         if (pos2 < 0) pos2 = coreSentence.length(); else pos2 = pos2 + 1;\r
663                         if (pos > pos2) pos = pos2;\r
664                         String sentence = coreSentence.substring(oldPos, pos).trim();\r
665                         //System.out.println("Sentence: " + hex.transliterate(coreSentence));\r
666                         oldPos = pos;\r
667                         \r
668                         addSentenceToTable(out, sentence,\r
669                             titleSetting, false, testRoundTrip, first, tl, lt);\r
670                         \r
671                         first = false;\r
672                     }\r
673                 }\r
674             }\r
675             out.println("</table></body>");\r
676             out.close();\r
677             \r
678             // Now write the source/target sets\r
679             if (generateSets) {\r
680                 outFile = new File(targetFile + "_Sets.html");\r
681                 System.out.println("Writing: " + outFile.getCanonicalPath());\r
682                 \r
683                 out = new PrintWriter(\r
684                     new BufferedWriter(\r
685                         new OutputStreamWriter(\r
686                             new FileOutputStream(outFile), "UTF-8")));\r
687                 out.println("<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");\r
688                 out.println("<style><!--");\r
689                 out.println("body         { font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', Arial, sans-serif; margin: 5 }");\r
690                 out.println("--></style>");\r
691                 out.println("<title>" + id + " Transliteration Sets</title></head>");\r
692                 out.println("<body bgcolor='#FFFFFF'>");\r
693                 \r
694                 int dashPos = id.indexOf('-');\r
695                 int slashPos = id.indexOf('/');\r
696                 if (slashPos < 0) slashPos = id.length();\r
697                 UnicodeSet sourceSuper = null;\r
698                 try {\r
699                     String temp = id.substring(0,dashPos);\r
700                     if (temp.equals("ja")) sourceSuper = new UnicodeSet("[[:Han:][:hiragana:][:katakana:]]");\r
701                     else sourceSuper = new UnicodeSet("[[:" + temp + ":][:Mn:][:Me:]]");\r
702                 } catch (Exception e) {}\r
703                 \r
704                 UnicodeSet targetSuper = null;\r
705                 try {\r
706                     targetSuper = new UnicodeSet("[[:" + id.substring(dashPos+1, slashPos) + ":][:Mn:][:Me:]]");\r
707                 } catch (Exception e) {}\r
708                 \r
709                 int nfdStyle = CLOSE_CASE | CLOSE_FLATTEN | CLOSE_CANONICAL;\r
710                 int nfkdStyle = nfdStyle | CLOSE_COMPATIBILITY;\r
711                 out.println("<ul>");\r
712                 out.println("<p><b>None</b></p>");\r
713                 showSets(out, translit, lt, null, null, 0);\r
714                 out.println("<p><b>NFD</b></p>");\r
715                 showSets(out, translit, lt, sourceSuper, targetSuper, nfdStyle);\r
716                 out.println("<p><b>NFKD</b></p>");\r
717                 showSets(out, translit, lt, sourceSuper, targetSuper, nfkdStyle);\r
718                 out.println("</ul></body>");\r
719                 out.close();\r
720             }\r
721             System.out.println("Done Writing");\r
722         } catch (Exception e) {\r
723             e.printStackTrace();\r
724         }\r
725     }\r
726     \r
727     static void addSentenceToTable(PrintWriter out, String sentence, \r
728             byte titleSetting, boolean addName, boolean testRoundTrip, boolean first,\r
729             Transliterator tl, Transliterator lt) {\r
730         if (sentence.length() == 0) return; // skip empty lines\r
731         \r
732         String originalShow = sentence;\r
733         String latin;\r
734         latin = tl.transliterate(saveAscii.transliterate(sentence));\r
735 \r
736         String latinShow = latin;\r
737         if (titleSetting == TITLEWORD) {\r
738             latinShow = title.transliterate(latin);\r
739         } else if (titleSetting == TITLELINE) {\r
740             latinShow = titlecaseFirstWord(latinShow);\r
741         }\r
742         latinShow = restoreAscii.transliterate(latinShow);\r
743                         \r
744         String reverse;\r
745         reverse = restoreAscii.transliterate(lt.transliterate(latin));\r
746                         \r
747         String NFKDSentence = Normalizer.normalize(sentence, Normalizer.NFKD);\r
748         String NFKDLatin = Normalizer.normalize(latin, Normalizer.NFKD);\r
749         String NFKDReverse = Normalizer.normalize(reverse, Normalizer.NFKD);\r
750         \r
751         if (latinShow.length() == 0) {\r
752             latinShow = "<i>empty</i>";\r
753         } else if (NFKDSentence.equals(NFKDLatin)) {\r
754             latinShow = "<span class='r'>" + latinShow + "</span>";\r
755         }\r
756         String reverseShow = reverse;\r
757         \r
758         if (testRoundTrip && !NFKDReverse.equals(NFKDSentence)) {\r
759             int minLen = reverse.length();\r
760             if (minLen > sentence.length()) minLen = sentence.length();\r
761             int i;\r
762             for (i = 0; i < minLen; ++i) {\r
763                 if (reverse.charAt(i) != sentence.charAt(i)) break;\r
764             }\r
765             //originalShow = sentence.substring(0,i) + "<span class='d'>" + sentence.substring(i) + "</span>";\r
766             reverseShow = reverseShow.length() == 0 \r
767                 ? "<i>empty</i>" \r
768                 //: reverse.substring(0,i) + "<span class='d'>" + reverse.substring(i) + "</span>";\r
769                 : showDifference(sentence, reverse);\r
770             out.println("<tr><td class='s'" + (first ? " width='50%'>" : ">") + originalShow \r
771                 + "</td><td rowSpan='2'>" + latinShow\r
772                 + "</td></tr><tr><td class='r'>" + reverseShow\r
773                 + "</td></tr>");\r
774         } else {\r
775             out.println("<tr><td class='s'" + (first ? " width='50%'>" : ">") + originalShow \r
776                 + "</td><td>" + latinShow\r
777                 + "</td></tr>");\r
778         }\r
779         if (addName) {\r
780             latinShow = hexAndName.transliterate(latin);\r
781             if (latinShow.length() == 0) latinShow = "<i>empty</i>";\r
782             originalShow = hexAndName.transliterate(sentence);\r
783             if (originalShow.length() == 0) originalShow = "<i>empty</i>";\r
784 \r
785             out.println("<tr><td class='n'>" + originalShow\r
786                 + "</td><td class='n'>" + latinShow\r
787                 + "</td></tr>");\r
788         }\r
789         out.println("<tr><td></td></tr>");\r
790         \r
791     }\r
792     \r
793     static String showDifference(String as, String bs) {\r
794         Differ differ = new Differ(300, 3);\r
795         StringBuffer out = new StringBuffer();\r
796         int max = as.length();\r
797         if (max < bs.length()) max = bs.length();\r
798         for (int j = 0; j <= max; ++j) {\r
799             if (j < as.length()) differ.addA(as.substring(j, j+1));\r
800             if (j < bs.length()) differ.addB(bs.substring(j, j+1));\r
801             differ.checkMatch(j == max);\r
802 \r
803             if (differ.getACount() != 0 || differ.getBCount() != 0) {\r
804                 out.append("...");\r
805                 if (differ.getACount() != 0) {\r
806                     out.append("<span class='r'>");\r
807                     for (int i = 0; i < differ.getACount(); ++i) {\r
808                         out.append(differ.getA(i));\r
809                     }\r
810                     out.append("</span>");\r
811                 }\r
812                 if (differ.getBCount() != 0) {\r
813                     out.append("<span class='d'>");\r
814                     for (int i = 0; i < differ.getBCount(); ++i) {\r
815                         out.append(differ.getB(i));\r
816                     }\r
817                     out.append("</span>");\r
818                 }\r
819                 out.append("...");\r
820             }\r
821         }\r
822         return out.toString();\r
823     }\r
824     \r
825     static void showSets(PrintWriter out, Transliterator translit, Transliterator inverse,\r
826       UnicodeSet sourceSuper, UnicodeSet targetSuper, int options) {\r
827         out.println("<li>Source Set:<ul><li>" +         toPattern(closeUnicodeSet(translit.getSourceSet(), options), sourceSuper) + "</li></ul></li>");\r
828         out.println("<li>Reverse Target Set:<ul><li>" + toPattern(closeUnicodeSet(inverse.getTargetSet(),  options), sourceSuper) + "</li></ul></li>");\r
829         out.println("<li>Target Set:<ul><li>" +         toPattern(closeUnicodeSet(translit.getTargetSet(), options), targetSuper) + "</li></ul></li>");\r
830         out.println("<li>Reverse Source Set:<ul><li>" + toPattern(closeUnicodeSet(inverse.getSourceSet(),  options), targetSuper) + "</li></ul></li>");\r
831     }\r
832         \r
833     static final int CLOSE_CASE = 1, CLOSE_FLATTEN = 2, CLOSE_CANONICAL = 4, CLOSE_COMPATIBILITY = 8;\r
834     \r
835     static UnicodeSet closeUnicodeSet(UnicodeSet source, int options) {\r
836         if (options == 0) return source;\r
837         \r
838         UnicodeSetIterator it = new UnicodeSetIterator(source);\r
839         UnicodeSet additions = new UnicodeSet(); // to avoid messing up iterator\r
840         UnicodeSet removals = new UnicodeSet(); // to avoid messing up iterator\r
841         String base;\r
842         int cp;\r
843         \r
844         // Add all case equivalents\r
845         if ((options & CLOSE_CASE) != 0) {\r
846             while (it.next()) {\r
847                 cp = it.codepoint;\r
848                 if (cp == UnicodeSetIterator.IS_STRING) continue;\r
849                 int type = UCharacter.getType(cp);\r
850                 if (type == Character.UPPERCASE_LETTER || type == Character.LOWERCASE_LETTER || type == Character.TITLECASE_LETTER) {\r
851                     additions.add(UCharacter.toLowerCase(UTF16.valueOf(cp)));\r
852                     additions.add(UCharacter.toUpperCase(UTF16.valueOf(cp)));\r
853                 }\r
854             }\r
855             source.addAll(additions);\r
856         }\r
857        \r
858         // Add the canonical closure of all strings and characters in source\r
859         if ((options & CLOSE_CANONICAL) != 0) {\r
860             it.reset();\r
861             additions.clear();\r
862             CanonicalIterator ci = new CanonicalIterator(".");\r
863             while (it.next()) {\r
864                 if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string;\r
865                 else base = UTF16.valueOf(it.codepoint);\r
866                 ci.setSource(base);\r
867                 while (true) {\r
868                     String trial = ci.next();\r
869                     if (trial == null) break;\r
870                     if (trial.equals(base)) continue;\r
871                     additions.add(trial);\r
872                 }\r
873             }\r
874             source.addAll(additions);\r
875         }\r
876 \r
877         // flatten strings\r
878         if ((options & CLOSE_FLATTEN) != 0) {\r
879             it.reset();\r
880             additions.clear();\r
881             while (it.next()) {\r
882                 if (it.codepoint != UnicodeSetIterator.IS_STRING) continue;\r
883                 additions.addAll(it.string);\r
884                 removals.add(it.string);\r
885                 //System.out.println("flattening '" + hex.transliterate(it.string) + "'");\r
886             }\r
887             source.addAll(additions);\r
888             source.removeAll(removals);\r
889         }\r
890        \r
891         // Now add decompositions of characters in source\r
892         if ((options & CLOSE_COMPATIBILITY) != 0) {\r
893             it.reset(source);\r
894             additions.clear();\r
895             while (it.next()) {\r
896                 if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string;\r
897                 else base = UTF16.valueOf(it.codepoint);\r
898                 if (Normalizer.isNormalized(base, Normalizer.NFKD,0)) continue;\r
899                 String decomp = Normalizer.normalize(base, Normalizer.NFKD);\r
900                 additions.add(decomp);\r
901             }\r
902             source.addAll(additions);\r
903             \r
904             // Now add any other character that decomposes to a character in source\r
905             for (cp = 0; cp < 0x10FFFF; ++cp) {\r
906                 if (!UCharacter.isDefined(cp)) continue;\r
907                 if (Normalizer.isNormalized(cp, Normalizer.NFKD,0)) continue;\r
908                 if (source.contains(cp)) continue;\r
909                 \r
910                 String decomp = Normalizer.normalize(cp, Normalizer.NFKD);\r
911                 if (source.containsAll(decomp)) {\r
912                     // System.out.println("Adding: " + Integer.toString(cp,16) + " " + UCharacter.getName(cp));\r
913                     source.add(cp);\r
914                 }\r
915             }\r
916         }\r
917         \r
918         return source;\r
919     }\r
920     \r
921     static String toPattern(UnicodeSet source, UnicodeSet superset) {\r
922         if (superset != null) {\r
923             source.removeAll(superset);\r
924             return "[" + superset.toPattern(true) + " " + source.toPattern(true) + "]";\r
925         }\r
926         return source.toPattern(true);\r
927     }\r
928     \r
929     static BreakIterator bi = BreakIterator.getWordInstance();\r
930     \r
931     static String titlecaseFirstWord(String line) {\r
932         // search for first word with letters. If the first letter is lower, then titlecase it.\r
933         bi.setText(line);\r
934         int start = 0;\r
935         while (true) {\r
936             int end = bi.next();\r
937             if (end == BreakIterator.DONE) break;\r
938             int firstLetterType = getFirstLetterType(line, start, end);\r
939             if (firstLetterType != Character.UNASSIGNED) {\r
940                 if (firstLetterType != Character.LOWERCASE_LETTER) break;\r
941                 line = line.substring(0, start) \r
942                     + UCharacter.toTitleCase(line.substring(start, end), bi)\r
943                     + line.substring(end);\r
944                 break;\r
945             }\r
946             end = start;\r
947         }\r
948         return line;\r
949     }\r
950     \r
951     static final int LETTER_MASK = \r
952           (1<<Character.UPPERCASE_LETTER)\r
953         | (1<<Character.LOWERCASE_LETTER)\r
954         | (1<<Character.TITLECASE_LETTER)\r
955         | (1<<Character.MODIFIER_LETTER)\r
956         | (1<<Character.OTHER_LETTER)\r
957         ;\r
958     \r
959     static int getFirstLetterType(String line, int start, int end) {\r
960         int cp;\r
961         for (int i = start; i < end; i += UTF16.getCharCount(cp)) {\r
962             cp = UTF16.charAt(line, i);\r
963             int type = UCharacter.getType(cp);\r
964             if (((1<<type) & LETTER_MASK) != 0) return type;\r
965         }\r
966         return Character.UNASSIGNED;\r
967     }\r
968     \r
969     static void printNames(UnicodeSet s, String targetFile) {\r
970         try {\r
971             File outFile = new File(targetFile);\r
972             System.out.println("Writing: " + outFile.getCanonicalPath());\r
973                 \r
974             PrintWriter out = new PrintWriter(\r
975                 new BufferedWriter(\r
976                     new OutputStreamWriter(\r
977                         new FileOutputStream(outFile), "UTF-8")));\r
978             UnicodeSet main = new UnicodeSet();\r
979             \r
980             UnicodeSet others = new UnicodeSet();\r
981             UnicodeSetIterator it = new UnicodeSetIterator(s);\r
982             while (it.next()) {\r
983                 if (!UCharacter.isDefined(it.codepoint)) continue;\r
984                 if (!Normalizer.isNormalized(it.codepoint, Normalizer.NFD,0)) {\r
985                     String decomp = Normalizer.normalize(it.codepoint, Normalizer.NFD);\r
986                     others.addAll(decomp);\r
987                     continue;\r
988                 }\r
989                 out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));\r
990                 main.add(it.codepoint);\r
991             }\r
992             \r
993             if (others.size() != 0) {\r
994                 out.println("Decomposed characters found above: ");\r
995                 others.removeAll(main);\r
996                 it.reset(others);\r
997                 while (it.next()) {\r
998                     out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));\r
999                 }\r
1000             }\r
1001             \r
1002             out.close();\r
1003             System.out.println("Done Writing");\r
1004         } catch (Exception e) {\r
1005             e.printStackTrace();\r
1006         }\r
1007     }\r
1008     \r
1009     static Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex");\r
1010     static final String saveRules = \r
1011           "A <> \uEA41; B <> \uEA42; C <> \uEA43; D <> \uEA44; E <> \uEA45; F <> \uEA46; G <> \uEA47; H <> \uEA48; I <> \uEA49; "\r
1012         + "J <> \uEA4A; K <> \uEA4B; L <> \uEA4C; M <> \uEA4D; N <> \uEA4E; O <> \uEA4F; P <> \uEA50; Q <> \uEA51; R <> \uEA52; "\r
1013         + "S <> \uEA53; T <> \uEA54; U <> \uEA55; V <> \uEA56; W <> \uEA57; X <> \uEA58; Y <> \uEA59; Z <> \uEA5A; "\r
1014         + "a <> \uEA61; b <> \uEA62; c <> \uEA63; d <> \uEA64; e <> \uEA65; f <> \uEA66; g <> \uEA67; h <> \uEA68; i <> \uEA69; "\r
1015         + "j <> \uEA6A; k <> \uEA6B; l <> \uEA6C; m <> \uEA6D; n <> \uEA6E; o <> \uEA6F; p <> \uEA70; q <> \uEA71; r <> \uEA72; "\r
1016         + "s <> \uEA73; t <> \uEA74; u <> \uEA75; v <> \uEA76; w <> \uEA77; x <> \uEA78; y <> \uEA79; z <> \uEA7A;";\r
1017         \r
1018     static Transliterator saveAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.FORWARD);\r
1019     static Transliterator restoreAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.REVERSE);\r
1020     \r
1021     static {\r
1022         \r
1023         if (false) {\r
1024         \r
1025         for (char i = 'A'; i <= 'z'; ++i) {\r
1026             System.out.print(i + " <> " + hex.transliterate(String.valueOf((char)(0xEA00 + i))) + "; ");\r
1027         }\r
1028 \r
1029         UnicodeSet x = new UnicodeSet("[[:^ccc=0:]&[:^ccc=230:]]");\r
1030         x = x.complement();\r
1031         x = x.complement();\r
1032         System.out.println("Test: " + x.toPattern(true));\r
1033         \r
1034         Transliterator y = Transliterator.createFromRules("xxx", "$notAbove = [[:^ccc=0:]&[:^ccc=230:]]; u ($notAbove*) \u0308 > XXX | $1; ", Transliterator.FORWARD);\r
1035         \r
1036         String[] testList = {"u\u0308", "u\u0316\u0308", "u\u0308\u0316", "u\u0301\u0308", "u\u0308\u0301"};\r
1037         for (int i = 0; i < testList.length; ++i) {\r
1038             String yy = y.transliterate(testList[i]);\r
1039             System.out.println(hex.transliterate(testList[i]) + " => " + hex.transliterate(yy));\r
1040         }\r
1041         \r
1042         //printNames(new UnicodeSet("[\u0600-\u06FF]"), "Arabic-Latin.txt");\r
1043         \r
1044         \r
1045         /*  \r
1046         BreakTransliterator.register();\r
1047         \r
1048         BreakTransliterator testTrans = new BreakTransliterator("Any-XXX", null, null, "$");\r
1049         String testSource = "The Quick:   Brown fox--jumped.";\r
1050         BreakIterator bi = testTrans.getBreakIterator();\r
1051         bi.setText(new StringCharacterIterator(testSource));\r
1052         printBreaks(0, testSource, bi);\r
1053         //bi.setText(UCharacterIterator.getInstance(testSource));\r
1054         //printBreaks(1, testSource, bi);\r
1055         \r
1056         printIteration(2, testSource, new StringCharacterIterator(testSource));\r
1057         //printIteration(3, testSource, UCharacterIterator.getInstance(testSource));\r
1058         \r
1059         \r
1060         \r
1061         String test = testTrans.transliterate(testSource);\r
1062         System.out.println("Test3: " + test);\r
1063         DummyFactory.add(testTrans.getID(), testTrans);\r
1064         */\r
1065         \r
1066         // AnyTransliterator.ScriptRunIterator.registerAnyToScript();\r
1067         \r
1068         AnyTransliterator at = new AnyTransliterator("Greek", null);\r
1069         at.transliterate("(cat,\u03b1,\u0915)");\r
1070         DummyFactory.add(at.getID(), at);\r
1071         \r
1072         at = new AnyTransliterator("Devanagari", null);\r
1073         at.transliterate("(cat,\u03b1,\u0915)");\r
1074         DummyFactory.add(at.getID(), at);\r
1075         \r
1076         at = new AnyTransliterator("Latin", null);\r
1077         at.transliterate("(cat,\u03b1,\u0915)");\r
1078         DummyFactory.add(at.getID(), at);\r
1079         \r
1080         DummyFactory.add("Any-gif", Transliterator.createFromRules("gif", "'\\'u(..)(..) > '<img src=\"http://www.unicode.org/gifs/24/' $1 '/U' $1$2 '.gif\">';", Transliterator.FORWARD));        \r
1081         DummyFactory.add("gif-Any", Transliterator.getInstance("Any-Null"));        \r
1082 \r
1083         DummyFactory.add("Any-RemoveCurly", Transliterator.createFromRules("RemoveCurly", "[\\{\\}] > ;", Transliterator.FORWARD));        \r
1084         DummyFactory.add("RemoveCurly-Any", Transliterator.getInstance("Any-Null"));\r
1085         \r
1086         System.out.println("Trying &hex");\r
1087         Transliterator t = Transliterator.createFromRules("hex2", "(.) > &hex($1);", Transliterator.FORWARD);\r
1088         System.out.println("Registering");\r
1089         DummyFactory.add("Any-hex2", t);        \r
1090         \r
1091         System.out.println("Trying &gif");\r
1092         t = Transliterator.createFromRules("gif2", "(.) > &any-gif($1);", Transliterator.FORWARD);\r
1093         System.out.println("Registering");\r
1094         DummyFactory.add("Any-gif2", t);    \r
1095         }\r
1096     }\r
1097     \r
1098     \r
1099     void setTransliterator(String name, String id) {\r
1100         if (DEBUG) System.out.println("Got: " + name);\r
1101         if (id == null) {\r
1102             translit = Transliterator.getInstance(name);\r
1103         } else {\r
1104             String reverseId = "";\r
1105             int pos = id.indexOf('-');\r
1106             if (pos < 0) {\r
1107                 reverseId = id + "-Any";\r
1108                 id = "Any-" + id;\r
1109             } else {\r
1110                 int pos2 = id.indexOf("/", pos);\r
1111                 if (pos2 < 0) {\r
1112                     reverseId = id.substring(pos+1) + "-" + id.substring(0,pos);\r
1113                 } else {\r
1114                     reverseId = id.substring(pos+1, pos2) + "-" + id.substring(0,pos) + id.substring(pos2);\r
1115                 }\r
1116             }\r
1117             \r
1118             \r
1119             translit = Transliterator.createFromRules(id, name, Transliterator.FORWARD);\r
1120             if (DEBUG) {\r
1121                 System.out.println("***Forward Rules");\r
1122                 System.out.println(translit.toRules(true));\r
1123                 System.out.println("***Source Set");\r
1124                 System.out.println(translit.getSourceSet().toPattern(true));\r
1125             }\r
1126                 System.out.println("***Target Set");\r
1127                 UnicodeSet target = translit.getTargetSet();\r
1128                 System.out.println(target.toPattern(true));\r
1129                 UnicodeSet rest = new UnicodeSet("[a-z]").removeAll(target);\r
1130                 System.out.println("***ASCII - Target Set");\r
1131                 System.out.println(rest.toPattern(true));\r
1132                 \r
1133             DummyFactory.add(id, translit);\r
1134             \r
1135             Transliterator translit2 = Transliterator.createFromRules(reverseId, name, Transliterator.REVERSE);\r
1136             if (DEBUG) {\r
1137                 System.out.println("***Backward Rules");\r
1138                 System.out.println(translit2.toRules(true));\r
1139             }\r
1140             DummyFactory.add(reverseId, translit2);\r
1141             \r
1142             Transliterator rev = translit.getInverse();\r
1143             if (DEBUG) System.out.println("***Inverse Rules");\r
1144             if (DEBUG) System.out.println(rev.toRules(true));\r
1145             \r
1146         }\r
1147         text.flush();\r
1148         text.setTransliterator(translit);\r
1149         convertSelectionItem.setLabel(Transliterator.getDisplayName(translit.getID()));\r
1150         \r
1151         addHistory(translit);\r
1152         \r
1153         Transliterator inv;\r
1154         try {\r
1155             inv = translit.getInverse();\r
1156         } catch (Exception ex) {\r
1157             inv = null;\r
1158         }\r
1159         if (inv != null) {\r
1160             addHistory(inv);\r
1161             swapSelectionItem.setEnabled(true);\r
1162         } else {\r
1163             swapSelectionItem.setEnabled(false);\r
1164         }\r
1165         System.out.println("Set transliterator: " + translit.getID()\r
1166             + (inv != null ? " and " + inv.getID() : ""));\r
1167     }\r
1168     \r
1169     void addHistory(Transliterator trans) {\r
1170         String name = trans.getID();\r
1171         MenuItem cmi = (MenuItem) historyMap.get(name);\r
1172         if (cmi == null) {\r
1173             cmi = new MenuItem(Transliterator.getDisplayName(name));\r
1174             cmi.addActionListener(new TransliterationListener(name));\r
1175             historyMap.put(name, cmi);\r
1176             historySet.add(cmi);\r
1177             historyMenu.removeAll();\r
1178             Iterator it = historySet.iterator();\r
1179             while (it.hasNext()) {\r
1180                 historyMenu.add((MenuItem)it.next());\r
1181             }\r
1182         }\r
1183     }\r
1184     \r
1185     class TransliterationListener implements ActionListener, ItemListener {\r
1186         String name;\r
1187         public TransliterationListener(String name) {\r
1188             this.name = name;\r
1189         }\r
1190         public void actionPerformed(ActionEvent e) {\r
1191             setTransliterator(name, null);\r
1192         }\r
1193         public void itemStateChanged(ItemEvent e) {\r
1194             if (e.getStateChange() == ItemEvent.SELECTED) {\r
1195                 setTransliterator(name, null);\r
1196             } else {\r
1197                 setTransliterator("Any-Null", null);\r
1198             }\r
1199         }\r
1200     }\r
1201     \r
1202     class FontActionListener implements ActionListener {\r
1203         String name;\r
1204         public FontActionListener(String name) {\r
1205             this.name = name;\r
1206         }\r
1207         public void actionPerformed(ActionEvent e) {\r
1208             if (DEBUG) System.out.println("Font: " + name);\r
1209             fontName = name;\r
1210             text.setFont(new Font(fontName, Font.PLAIN, fontSize));\r
1211         }\r
1212     }\r
1213     \r
1214     class SizeActionListener implements ActionListener {\r
1215         int size;\r
1216         public SizeActionListener(int size) {\r
1217             this.size = size;\r
1218         }\r
1219         public void actionPerformed(ActionEvent e) {\r
1220             if (DEBUG) System.out.println("Size: " + size);\r
1221             fontSize = size;\r
1222             text.setFont(new Font(fontName, Font.PLAIN, fontSize));\r
1223         }\r
1224     }\r
1225     \r
1226     Set add(Set s, Enumeration enumeration) {\r
1227         while(enumeration.hasMoreElements()) {\r
1228             s.add(enumeration.nextElement());\r
1229         }\r
1230         return s;\r
1231     }\r
1232 \r
1233     /**\r
1234      * Get a sorted list of the system transliterators.\r
1235      */\r
1236      /*\r
1237     private static Vector getSystemTransliteratorNames() {\r
1238         Vector v = new Vector();\r
1239         for (Enumeration e=Transliterator.getAvailableIDs();\r
1240              e.hasMoreElements(); ) {\r
1241             v.addElement(e.nextElement());\r
1242         }\r
1243         // Insertion sort, O(n^2) acceptable for small n\r
1244         for (int i=0; i<(v.size()-1); ++i) {\r
1245             String a = (String) v.elementAt(i);\r
1246             for (int j=i+1; j<v.size(); ++j) {\r
1247                 String b = (String) v.elementAt(j);\r
1248                 if (a.compareTo(b) > 0) {\r
1249                     v.setElementAt(b, i);\r
1250                     v.setElementAt(a, j);\r
1251                     a = b;\r
1252                 }\r
1253             }\r
1254         }\r
1255         return v;\r
1256     }\r
1257     */\r
1258 \r
1259 /*\r
1260     private void setNoTransliterator() {\r
1261         translitItem = noTranslitItem;\r
1262         noTranslitItem.setState(true);\r
1263         handleSetTransliterator(noTranslitItem.getLabel());\r
1264         compound = false;\r
1265         for (int i=0; i<translitMenu.getItemCount(); ++i) {\r
1266             MenuItem it = translitMenu.getItem(i);\r
1267             if (it != noTranslitItem && it instanceof CheckboxMenuItem) {\r
1268                 ((CheckboxMenuItem) it).setState(false);\r
1269             }\r
1270         }\r
1271     }\r
1272 */\r
1273 /*\r
1274     private void handleAddToCompound(String name) {\r
1275         if (compoundCount < MAX_COMPOUND) {\r
1276             compoundTranslit[compoundCount] = decodeTranslitItem(name);\r
1277             ++compoundCount;\r
1278             Transliterator t[] = new Transliterator[compoundCount];\r
1279             System.arraycopy(compoundTranslit, 0, t, 0, compoundCount);\r
1280             translit = new CompoundTransliterator(t);\r
1281             text.setTransliterator(translit);\r
1282         }\r
1283     }\r
1284 */\r
1285 /*\r
1286     private void handleSetTransliterator(String name) {\r
1287         translit = decodeTranslitItem(name);\r
1288         text.setTransliterator(translit);\r
1289     }\r
1290     */\r
1291 \r
1292     /**\r
1293      * Decode a menu item that looks like <translit name>.\r
1294      */\r
1295      /*\r
1296     private static Transliterator decodeTranslitItem(String name) {\r
1297         return (name.equals(NO_TRANSLITERATOR))\r
1298             ? null : Transliterator.getInstance(name);\r
1299     }\r
1300     */\r
1301 \r
1302     private void handleBatchTransliterate(Transliterator trans) {\r
1303         if (trans == null) {\r
1304             return;\r
1305         }\r
1306 \r
1307         int start = text.getSelectionStart();\r
1308         int end = text.getSelectionEnd();\r
1309         ReplaceableString s =\r
1310             new ReplaceableString(text.getText().substring(start, end));\r
1311 \r
1312         StringBuffer log = null;\r
1313         if (DEBUG) {\r
1314             log = new StringBuffer();\r
1315             log.append('"' + s.toString() + "\" (start " + start +\r
1316                        ", end " + end + ") -> \"");\r
1317         }\r
1318 \r
1319         trans.transliterate(s);\r
1320         String str = s.toString();\r
1321 \r
1322         if (DEBUG) {\r
1323             log.append(str + "\"");\r
1324             System.out.println("Batch " + trans.getID() + ": " + log.toString());\r
1325         }\r
1326 \r
1327         text.replaceRange(str, start, end);\r
1328         text.select(start, start + str.length());\r
1329     }\r
1330 \r
1331     private void handleClose() {\r
1332         helpDialog.dispose();\r
1333         dispose();\r
1334     }\r
1335     \r
1336     /*\r
1337     class InfoDialog extends Dialog {\r
1338         protected Button button;\r
1339         protected TextArea area;\r
1340         protected Dialog me;\r
1341         protected Panel bottom;\r
1342         \r
1343         public TextArea getArea() {\r
1344             return area;\r
1345         }\r
1346         \r
1347         public Panel getBottom() {\r
1348             return bottom;\r
1349         }\r
1350         \r
1351         InfoDialog(Frame parent, String title, String label, String message) {\r
1352             super(parent, title, false);\r
1353             me = this;\r
1354             this.setLayout(new BorderLayout());\r
1355             if (label.length() != 0) {\r
1356                 this.add("North", new Label(label));\r
1357             }\r
1358             \r
1359             area = new TextArea(message, 8, 80, TextArea.SCROLLBARS_VERTICAL_ONLY);\r
1360             this.add("Center", area);\r
1361             \r
1362             button = new Button("Hide");\r
1363             button.addActionListener(new ActionListener() {\r
1364                 public void actionPerformed(ActionEvent e) {\r
1365                     me.hide();\r
1366                 }\r
1367             });\r
1368             bottom = new Panel();\r
1369             bottom.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));\r
1370             bottom.add(button);\r
1371             this.add("South", bottom);\r
1372             this.pack();\r
1373             addWindowListener(new WindowAdapter() {\r
1374                 public void windowClosing(WindowEvent e) {\r
1375                     me.hide();\r
1376                 }\r
1377             });\r
1378         }\r
1379     }\r
1380     */\r
1381 }\r