2 *******************************************************************************
\r
3 * Copyright (C) 1996-2008, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.demo.translit;
\r
10 import java.awt.event.*;
\r
12 import java.text.CharacterIterator;
\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
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
26 * <p>Copyright (c) IBM Corporation 1999. All rights reserved.
\r
30 public class Demo extends Frame {
\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
39 Transliterator translit = null;
\r
40 String fontName = "Arial Unicode MS";
\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
52 TransliteratingTextComponent text = null;
\r
55 CheckboxMenuItem translitItem;
\r
56 CheckboxMenuItem noTranslitItem;
\r
58 static final String NO_TRANSLITERATOR = "None";
\r
60 //private static final String COPYRIGHT =
\r
61 // "\u00A9 IBM Corporation 1999. All rights reserved.";
\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
72 com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameOpened();
\r
75 public Demo(int width, int height) {
\r
76 super("Transliteration Demo");
\r
80 addWindowListener(new WindowAdapter() {
\r
81 public void windowClosing(WindowEvent e) {
\r
86 text = new TransliteratingTextComponent();
\r
87 Font font = new Font(fontName, Font.PLAIN, fontSize);
\r
89 text.setSize(width, height);
\r
90 text.setVisible(true);
\r
91 text.setText(START_TEXT);
\r
94 setSize(width, height);
\r
95 setTransliterator("Latin-Greek", null);
\r
98 private void initMenus() {
\r
102 //CheckboxMenuItem citem;
\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
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
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
143 translitMenu.addSeparator();
\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
161 for (int i=0; i<MAX_COMPOUND; ++i) {
\r
162 compoundTranslit[i] = null;
\r
168 translitMenu.addSeparator();
\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
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
187 mbar.add(fontMenu);
\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
196 mbar.add(sizeMenu);
\r
200 mbar.add(translitMenu = new Menu("Transliterator"));
\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
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
216 inv = translit.getInverse();
\r
217 } catch (Exception x) {
\r
218 inv = Transliterator.getInstance("null");
\r
220 setTransliterator(inv.getID(), null);
\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
233 text.setTransliterator(null);
\r
234 convertTypingItem.setLabel("Convert Typing");
\r
236 transliterateTyping = !transliterateTyping;
\r
240 translitMenu.add(historyMenu = new Menu("Recent"));
\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
247 helpDialog.getArea().setEditable(false);
\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
259 hexDialog = new InfoDialog(this, "Hex Entry", "Use U+..., \\u..., \\x{...}, or &#x...;",
\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
269 hexDialog.getBottom().add(button);
\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
279 // Compound Transliterator
\r
281 compoundDialog = new InfoDialog(this, "Compound Transliterator", "",
\r
282 "[^\\u0000-\\u00FF] hex"
\r
284 button = new Button("Set");
\r
285 button.addActionListener(new ActionListener() {
\r
286 public void actionPerformed(ActionEvent e) {
\r
287 String compound = "";
\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
296 compoundDialog.getBottom().add(button);
\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
306 // RuleBased Transliterator
\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
313 button = new Button("Set");
\r
314 button.addActionListener(new ActionListener() {
\r
315 public void actionPerformed(ActionEvent e) {
\r
316 String compound = "";
\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
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
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
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
346 translitMenu.add(mitem = new MenuItem("Test File..."));
\r
347 mitem.addActionListener(new FileListener(this, TEST_FILE));
\r
349 // Flesh out the menu with the installed transliterators
\r
351 translitMenu.addSeparator();
\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
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
376 targetMenu.add(variantMenu);
\r
379 translitMenu.add(targetMenu);
\r
385 static final int RULE_FILE = 0, TEST_FILE = 1;
\r
387 static class FileListener implements ActionListener {
\r
391 FileListener(Demo frame, int choice) {
\r
392 this.frame = frame;
\r
393 this.choice = choice;
\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
405 FileDialog fileDialog = new FileDialog(frame, "Input File");
\r
406 fileDialog.setFile("Test_" + id + ".txt");
\r
408 String fileName = fileDialog.getFile();
\r
409 String fileDirectory = fileDialog.getDirectory();
\r
410 if (fileName != null) {
\r
412 File f = new File(fileDirectory, fileName);
\r
413 if (choice == RULE_FILE) {
\r
415 // read stuff into buffer
\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
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
430 // Transform file name into id
\r
431 if (fileName.startsWith("Transliterator_")) {
\r
432 fileName = fileName.substring("Transliterator_".length());
\r
434 int pos = fileName.indexOf('_');
\r
438 id = fileName.substring(0, pos) + "-";
\r
439 int pos2 = fileName.indexOf('_', pos+1);
\r
441 id += fileName.substring(pos+1);
\r
443 id += fileName.substring(pos+1, pos2) + "/" + fileName.substring(pos2 + 1);
\r
446 pos = id.lastIndexOf('.');
\r
447 if (pos >= 0) id = id.substring(0, pos);
\r
451 frame.setTransliterator(buffer.toString(), id);
\r
452 } else if (choice == TEST_FILE) {
\r
453 genTestFile(f, frame.translit, variant);
\r
455 } catch (Exception e2) {
\r
456 e2.printStackTrace();
\r
457 System.out.println("Problem opening/reading: " + fileDirectory + ", " + fileName);
\r
460 fileDialog.dispose();
\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
472 MenuItem convertSelectionItem = null;
\r
473 MenuItem swapSelectionItem = null;
\r
474 MenuItem convertTypingItem = null;
\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
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
490 // Since Transliterators are immutable, we don't have to clone on set & get
\r
491 static void add(String ID, Transliterator t) {
\r
493 System.out.println("Registering: " + ID + ", " + t.toRules(true));
\r
494 Transliterator.registerFactory(ID, singleton);
\r
496 public Transliterator getInstance(String ID) {
\r
497 return (Transliterator) m.get(ID);
\r
501 static void printBreaks(int num, String testSource, BreakIterator brkItr) {
\r
502 String result = "";
\r
505 int pos = brkItr.next();
\r
506 if (pos == BreakIterator.DONE) break;
\r
507 result += testSource.substring(lastPos, pos) + "&";
\r
509 System.out.println(pos);
\r
511 System.out.println("Test" + num + ": " + result);
\r
514 static void printIteration(int num, String testSource, CharacterIterator ci) {
\r
515 String result = "";
\r
517 char ch = ci.next();
\r
518 if (ch == CharacterIterator.DONE) break;
\r
519 result += ch + "(" + ci.getIndex() + ")";
\r
521 System.out.println("Test" + num + ": " + result);
\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
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
538 // 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;
\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
545 static Transliterator hexAndName = Transliterator.createFromRules("any-hexAndName",
\r
546 hexAndNameRules, Transliterator.FORWARD);
\r
550 //static Transliterator upper = Transliterator.getInstance("upper");
\r
552 static final byte NONE = 0, TITLEWORD = 1, TITLELINE = 2;
\r
554 static void genTestFile(File sourceFile, Transliterator translit, String variant) {
\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
566 File outFile = new File(targetFile + ".html");
\r
567 System.out.println("Writing: " + outFile.getCanonicalPath());
\r
569 PrintWriter out = new PrintWriter(
\r
570 new BufferedWriter(
\r
571 new OutputStreamWriter(
\r
572 new FileOutputStream(outFile), "UTF-8")));
\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
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
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
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
601 //out.println("<tr><th width='33%'>Thai</th><th width='33%'>Latin</th><th width='33%'>Thai</th></tr>");
\r
603 Transliterator tl = translit;
\r
604 Transliterator lt = tl.getInverse();
\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
611 //Transliterator.getInstance("[:^Lu:]" + lt.getID());
\r
613 BreakIterator sentenceBreak = BreakIterator.getSentenceInstance();
\r
615 byte titleSetting = TITLELINE;
\r
616 //boolean upperfilter = false;
\r
617 boolean first = 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
625 if (line.charAt(0) == '#') continue; // comments
\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
631 } else if (line.equals("@UPPERFILTER@")) {
\r
632 //upperfilter = true;
\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
642 NONE, true, testRoundTrip, first, tl, lt);
\r
647 sentenceBreak.setText(line);
\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
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
668 addSentenceToTable(out, sentence,
\r
669 titleSetting, false, testRoundTrip, first, tl, lt);
\r
675 out.println("</table></body>");
\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
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
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
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
704 UnicodeSet targetSuper = null;
\r
706 targetSuper = new UnicodeSet("[[:" + id.substring(dashPos+1, slashPos) + ":][:Mn:][:Me:]]");
\r
707 } catch (Exception e) {}
\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
721 System.out.println("Done Writing");
\r
722 } catch (Exception e) {
\r
723 e.printStackTrace();
\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
732 String originalShow = sentence;
\r
734 latin = tl.transliterate(saveAscii.transliterate(sentence));
\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
742 latinShow = restoreAscii.transliterate(latinShow);
\r
745 reverse = restoreAscii.transliterate(lt.transliterate(latin));
\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
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
756 String reverseShow = reverse;
\r
758 if (testRoundTrip && !NFKDReverse.equals(NFKDSentence)) {
\r
759 int minLen = reverse.length();
\r
760 if (minLen > sentence.length()) minLen = sentence.length();
\r
762 for (i = 0; i < minLen; ++i) {
\r
763 if (reverse.charAt(i) != sentence.charAt(i)) break;
\r
765 //originalShow = sentence.substring(0,i) + "<span class='d'>" + sentence.substring(i) + "</span>";
\r
766 reverseShow = reverseShow.length() == 0
\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
775 out.println("<tr><td class='s'" + (first ? " width='50%'>" : ">") + originalShow
\r
776 + "</td><td>" + latinShow
\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
785 out.println("<tr><td class='n'>" + originalShow
\r
786 + "</td><td class='n'>" + latinShow
\r
789 out.println("<tr><td></td></tr>");
\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
803 if (differ.getACount() != 0 || differ.getBCount() != 0) {
\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
810 out.append("</span>");
\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
817 out.append("</span>");
\r
822 return out.toString();
\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
833 static final int CLOSE_CASE = 1, CLOSE_FLATTEN = 2, CLOSE_CANONICAL = 4, CLOSE_COMPATIBILITY = 8;
\r
835 static UnicodeSet closeUnicodeSet(UnicodeSet source, int options) {
\r
836 if (options == 0) return source;
\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
844 // Add all case equivalents
\r
845 if ((options & CLOSE_CASE) != 0) {
\r
846 while (it.next()) {
\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
855 source.addAll(additions);
\r
858 // Add the canonical closure of all strings and characters in source
\r
859 if ((options & CLOSE_CANONICAL) != 0) {
\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
868 String trial = ci.next();
\r
869 if (trial == null) break;
\r
870 if (trial.equals(base)) continue;
\r
871 additions.add(trial);
\r
874 source.addAll(additions);
\r
878 if ((options & CLOSE_FLATTEN) != 0) {
\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
887 source.addAll(additions);
\r
888 source.removeAll(removals);
\r
891 // Now add decompositions of characters in source
\r
892 if ((options & CLOSE_COMPATIBILITY) != 0) {
\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
902 source.addAll(additions);
\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
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
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
926 return source.toPattern(true);
\r
929 static BreakIterator bi = BreakIterator.getWordInstance();
\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
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
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
959 static int getFirstLetterType(String line, int start, int end) {
\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
966 return Character.UNASSIGNED;
\r
969 static void printNames(UnicodeSet s, String targetFile) {
\r
971 File outFile = new File(targetFile);
\r
972 System.out.println("Writing: " + outFile.getCanonicalPath());
\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
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
989 out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));
\r
990 main.add(it.codepoint);
\r
993 if (others.size() != 0) {
\r
994 out.println("Decomposed characters found above: ");
\r
995 others.removeAll(main);
\r
997 while (it.next()) {
\r
998 out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));
\r
1003 System.out.println("Done Writing");
\r
1004 } catch (Exception e) {
\r
1005 e.printStackTrace();
\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
1018 static Transliterator saveAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.FORWARD);
\r
1019 static Transliterator restoreAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.REVERSE);
\r
1025 for (char i = 'A'; i <= 'z'; ++i) {
\r
1026 System.out.print(i + " <> " + hex.transliterate(String.valueOf((char)(0xEA00 + i))) + "; ");
\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
1034 Transliterator y = Transliterator.createFromRules("xxx", "$notAbove = [[:^ccc=0:]&[:^ccc=230:]]; u ($notAbove*) \u0308 > XXX | $1; ", Transliterator.FORWARD);
\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
1042 //printNames(new UnicodeSet("[\u0600-\u06FF]"), "Arabic-Latin.txt");
\r
1046 BreakTransliterator.register();
\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
1056 printIteration(2, testSource, new StringCharacterIterator(testSource));
\r
1057 //printIteration(3, testSource, UCharacterIterator.getInstance(testSource));
\r
1061 String test = testTrans.transliterate(testSource);
\r
1062 System.out.println("Test3: " + test);
\r
1063 DummyFactory.add(testTrans.getID(), testTrans);
\r
1066 // AnyTransliterator.ScriptRunIterator.registerAnyToScript();
\r
1068 AnyTransliterator at = new AnyTransliterator("Greek", null);
\r
1069 at.transliterate("(cat,\u03b1,\u0915)");
\r
1070 DummyFactory.add(at.getID(), at);
\r
1072 at = new AnyTransliterator("Devanagari", null);
\r
1073 at.transliterate("(cat,\u03b1,\u0915)");
\r
1074 DummyFactory.add(at.getID(), at);
\r
1076 at = new AnyTransliterator("Latin", null);
\r
1077 at.transliterate("(cat,\u03b1,\u0915)");
\r
1078 DummyFactory.add(at.getID(), at);
\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
1083 DummyFactory.add("Any-RemoveCurly", Transliterator.createFromRules("RemoveCurly", "[\\{\\}] > ;", Transliterator.FORWARD));
\r
1084 DummyFactory.add("RemoveCurly-Any", Transliterator.getInstance("Any-Null"));
\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
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
1099 void setTransliterator(String name, String id) {
\r
1100 if (DEBUG) System.out.println("Got: " + name);
\r
1102 translit = Transliterator.getInstance(name);
\r
1104 String reverseId = "";
\r
1105 int pos = id.indexOf('-');
\r
1107 reverseId = id + "-Any";
\r
1110 int pos2 = id.indexOf("/", pos);
\r
1112 reverseId = id.substring(pos+1) + "-" + id.substring(0,pos);
\r
1114 reverseId = id.substring(pos+1, pos2) + "-" + id.substring(0,pos) + id.substring(pos2);
\r
1119 translit = Transliterator.createFromRules(id, name, Transliterator.FORWARD);
\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
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
1133 DummyFactory.add(id, translit);
\r
1135 Transliterator translit2 = Transliterator.createFromRules(reverseId, name, Transliterator.REVERSE);
\r
1137 System.out.println("***Backward Rules");
\r
1138 System.out.println(translit2.toRules(true));
\r
1140 DummyFactory.add(reverseId, translit2);
\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
1148 text.setTransliterator(translit);
\r
1149 convertSelectionItem.setLabel(Transliterator.getDisplayName(translit.getID()));
\r
1151 addHistory(translit);
\r
1153 Transliterator inv;
\r
1155 inv = translit.getInverse();
\r
1156 } catch (Exception ex) {
\r
1159 if (inv != null) {
\r
1161 swapSelectionItem.setEnabled(true);
\r
1163 swapSelectionItem.setEnabled(false);
\r
1165 System.out.println("Set transliterator: " + translit.getID()
\r
1166 + (inv != null ? " and " + inv.getID() : ""));
\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
1185 class TransliterationListener implements ActionListener, ItemListener {
\r
1187 public TransliterationListener(String name) {
\r
1190 public void actionPerformed(ActionEvent e) {
\r
1191 setTransliterator(name, null);
\r
1193 public void itemStateChanged(ItemEvent e) {
\r
1194 if (e.getStateChange() == ItemEvent.SELECTED) {
\r
1195 setTransliterator(name, null);
\r
1197 setTransliterator("Any-Null", null);
\r
1202 class FontActionListener implements ActionListener {
\r
1204 public FontActionListener(String name) {
\r
1207 public void actionPerformed(ActionEvent e) {
\r
1208 if (DEBUG) System.out.println("Font: " + name);
\r
1210 text.setFont(new Font(fontName, Font.PLAIN, fontSize));
\r
1214 class SizeActionListener implements ActionListener {
\r
1216 public SizeActionListener(int size) {
\r
1219 public void actionPerformed(ActionEvent e) {
\r
1220 if (DEBUG) System.out.println("Size: " + size);
\r
1222 text.setFont(new Font(fontName, Font.PLAIN, fontSize));
\r
1226 Set add(Set s, Enumeration enumeration) {
\r
1227 while(enumeration.hasMoreElements()) {
\r
1228 s.add(enumeration.nextElement());
\r
1234 * Get a sorted list of the system transliterators.
\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
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
1260 private void setNoTransliterator() {
\r
1261 translitItem = noTranslitItem;
\r
1262 noTranslitItem.setState(true);
\r
1263 handleSetTransliterator(noTranslitItem.getLabel());
\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
1274 private void handleAddToCompound(String name) {
\r
1275 if (compoundCount < MAX_COMPOUND) {
\r
1276 compoundTranslit[compoundCount] = decodeTranslitItem(name);
\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
1286 private void handleSetTransliterator(String name) {
\r
1287 translit = decodeTranslitItem(name);
\r
1288 text.setTransliterator(translit);
\r
1293 * Decode a menu item that looks like <translit name>.
\r
1296 private static Transliterator decodeTranslitItem(String name) {
\r
1297 return (name.equals(NO_TRANSLITERATOR))
\r
1298 ? null : Transliterator.getInstance(name);
\r
1302 private void handleBatchTransliterate(Transliterator trans) {
\r
1303 if (trans == null) {
\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
1312 StringBuffer log = null;
\r
1314 log = new StringBuffer();
\r
1315 log.append('"' + s.toString() + "\" (start " + start +
\r
1316 ", end " + end + ") -> \"");
\r
1319 trans.transliterate(s);
\r
1320 String str = s.toString();
\r
1323 log.append(str + "\"");
\r
1324 System.out.println("Batch " + trans.getID() + ": " + log.toString());
\r
1327 text.replaceRange(str, start, end);
\r
1328 text.select(start, start + str.length());
\r
1331 private void handleClose() {
\r
1332 helpDialog.dispose();
\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
1343 public TextArea getArea() {
\r
1347 public Panel getBottom() {
\r
1351 InfoDialog(Frame parent, String title, String label, String message) {
\r
1352 super(parent, title, false);
\r
1354 this.setLayout(new BorderLayout());
\r
1355 if (label.length() != 0) {
\r
1356 this.add("North", new Label(label));
\r
1359 area = new TextArea(message, 8, 80, TextArea.SCROLLBARS_VERTICAL_ONLY);
\r
1360 this.add("Center", area);
\r
1362 button = new Button("Hide");
\r
1363 button.addActionListener(new ActionListener() {
\r
1364 public void actionPerformed(ActionEvent e) {
\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
1373 addWindowListener(new WindowAdapter() {
\r
1374 public void windowClosing(WindowEvent e) {
\r