/* ******************************************************************************* * Copyright (C) 1996-2010, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.dev.demo.translit; import java.awt.Button; import java.awt.CheckboxMenuItem; import java.awt.FileDialog; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.Label; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.MenuShortcut; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.text.CharacterIterator; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeSet; import com.ibm.icu.impl.Differ; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.text.BreakIterator; import com.ibm.icu.text.CanonicalIterator; import com.ibm.icu.text.Normalizer; import com.ibm.icu.text.ReplaceableString; import com.ibm.icu.text.Transliterator; import com.ibm.icu.text.UTF16; import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.text.UnicodeSetIterator; /** * A frame that allows the user to experiment with keyboard * transliteration. This class has a main() method so it can be run * as an application. The frame contains an editable text component * and uses keyboard transliteration to process keyboard events. * *

Copyright (c) IBM Corporation 1999. All rights reserved. * * @author Alan Liu */ public class Demo extends Frame { /** * For serialization */ private static final long serialVersionUID = 1L; static final boolean DEBUG = false; static final String START_TEXT = "(cut,\u03BA\u03C5\u03C4,\u05D0,\u30AF\u30C8,\u4E80,\u091A\u0941\u0924\u094D)"; Transliterator translit = null; String fontName = "Arial Unicode MS"; int fontSize = 18; /* boolean compound = false; Transliterator[] compoundTranslit = new Transliterator[MAX_COMPOUND]; static final int MAX_COMPOUND = 128; int compoundCount = 0; */ TransliteratingTextComponent text = null; Menu translitMenu; CheckboxMenuItem translitItem; CheckboxMenuItem noTranslitItem; static final String NO_TRANSLITERATOR = "None"; //private static final String COPYRIGHT = // "\u00A9 IBM Corporation 1999. All rights reserved."; public static void main(String[] args) { Frame f = new Demo(600, 200); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameClosed(); // System.exit(0); } }); f.setVisible(true); com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameOpened(); } public Demo(int width, int height) { super("Transliteration Demo"); initMenus(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { handleClose(); } }); text = new TransliteratingTextComponent(); Font font = new Font(fontName, Font.PLAIN, fontSize); text.setFont(font); text.setSize(width, height); text.setVisible(true); text.setText(START_TEXT); add(text); setSize(width, height); setTransliterator("Latin-Greek", null); } private void initMenus() { MenuBar mbar; Menu menu; MenuItem mitem; //CheckboxMenuItem citem; setMenuBar(mbar = new MenuBar()); mbar.add(menu = new Menu("File")); menu.add(mitem = new MenuItem("Quit")); mitem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { handleClose(); } }); /* final ItemListener setTransliteratorListener = new ItemListener() { public void itemStateChanged(ItemEvent e) { CheckboxMenuItem item = (CheckboxMenuItem) e.getSource(); if (e.getStateChange() == ItemEvent.DESELECTED) { // Don't let the current transliterator be deselected. // Just reselect it. item.setState(true); } else if (compound) { // Adding an item to a compound transliterator handleAddToCompound(item.getLabel()); } else if (item != translitItem) { // Deselect previous choice. Don't need to call // setState(true) on new choice. translitItem.setState(false); translitItem = item; handleSetTransliterator(item.getLabel()); } } }; */ /* translitMenu.add(translitItem = noTranslitItem = new CheckboxMenuItem(NO_TRANSLITERATOR, true)); noTranslitItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { // Can't uncheck None -- any action here sets None to true setNoTransliterator(); } }); translitMenu.addSeparator(); */ /* translitMenu.add(citem = new CheckboxMenuItem("Compound")); citem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { CheckboxMenuItem item = (CheckboxMenuItem) e.getSource(); if (e.getStateChange() == ItemEvent.DESELECTED) { // If compound gets deselected, then select NONE setNoTransliterator(); } else if (!compound) { // Switching from non-compound to compound translitItem.setState(false); translitItem = item; translit = null; compound = true; compoundCount = 0; for (int i=0; i &Hex($1) &Name($1);\r\n" + "&Hex-Any($1) < ('\\' [uU] [a-fA-F0-9]*);\r\n" + "&Name-Any($1) < ('{' [^\\}]* '}');" ); button = new Button("Set"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String compound = ""; try { compound = rulesDialog.getArea().getText(); String id = ruleId.getText(); setTransliterator(compound, id); } catch (RuntimeException ex) { rulesDialog.getArea().setText(compound + "\n#" + ex.getMessage()); } } }); rulesDialog.getBottom().add(button); ruleId = new TextField("test1", 20); Label temp = new Label(" Name:"); rulesDialog.getBottom().add(temp); rulesDialog.getBottom().add(ruleId); translitMenu.add(mitem = new MenuItem("From Rules...", new MenuShortcut(KeyEvent.VK_R))); mitem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { rulesDialog.show(); } }); translitMenu.add(mitem = new MenuItem("From File...", new MenuShortcut(KeyEvent.VK_F))); mitem.addActionListener(new FileListener(this, RULE_FILE)); translitMenu.add(mitem = new MenuItem("Test File...")); mitem.addActionListener(new FileListener(this, TEST_FILE)); // Flesh out the menu with the installed transliterators translitMenu.addSeparator(); Iterator sources = add(new TreeSet(), Transliterator.getAvailableSources()).iterator(); while(sources.hasNext()) { String source = (String) sources.next(); Iterator targets = add(new TreeSet(), Transliterator.getAvailableTargets(source)).iterator(); Menu targetMenu = new Menu(source); while(targets.hasNext()) { String target = (String) targets.next(); Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target)); if (variantSet.size() < 2) { mitem = new MenuItem(target); mitem.addActionListener(new TransliterationListener(source + "-" + target)); targetMenu.add(mitem); } else { Iterator variants = variantSet.iterator(); Menu variantMenu = new Menu(target); while(variants.hasNext()) { String variant = (String) variants.next(); String menuName = variant.length() == 0 ? "" : variant; //System.out.println("<" + source + "-" + target + "/" + variant + ">, <" + menuName + ">"); mitem = new MenuItem(menuName); mitem.addActionListener(new TransliterationListener(source + "-" + target + "/" + variant)); variantMenu.add(mitem); } targetMenu.add(variantMenu); } } translitMenu.add(targetMenu); } } static final int RULE_FILE = 0, TEST_FILE = 1; // static class FileListener implements ActionListener { Demo frame; int choice; FileListener(Demo frame, int choice) { this.frame = frame; this.choice = choice; } public void actionPerformed(ActionEvent e) { String id = frame.translit.getID(); int slashPos = id.indexOf('/'); String variant = ""; if (slashPos >= 0) { variant = "_" + id.substring(slashPos+1); id = id.substring(0, slashPos); } FileDialog fileDialog = new FileDialog(frame, "Input File"); fileDialog.setFile("Test_" + id + ".txt"); fileDialog.show(); String fileName = fileDialog.getFile(); String fileDirectory = fileDialog.getDirectory(); if (fileName != null) { try { File f = new File(fileDirectory, fileName); if (choice == RULE_FILE) { // read stuff into buffer StringBuffer buffer = new StringBuffer(); FileInputStream fis = new FileInputStream(f); InputStreamReader isr = new InputStreamReader(fis, "UTF8"); BufferedReader br = new BufferedReader(isr, 32*1024); while (true) { String line = br.readLine(); if (line == null) break; if (line.length() > 0 && line.charAt(0) == '\uFEFF') line = line.substring(1); // strip BOM buffer.append('\n'); buffer.append(line); } br.close(); // Transform file name into id if (fileName.startsWith("Transliterator_")) { fileName = fileName.substring("Transliterator_".length()); } int pos = fileName.indexOf('_'); if (pos < 0) { id = fileName; } else { id = fileName.substring(0, pos) + "-"; int pos2 = fileName.indexOf('_', pos+1); if (pos2 < 0) { id += fileName.substring(pos+1); } else { id += fileName.substring(pos+1, pos2) + "/" + fileName.substring(pos2 + 1); } } pos = id.lastIndexOf('.'); if (pos >= 0) id = id.substring(0, pos); // Now set frame.setTransliterator(buffer.toString(), id); } else if (choice == TEST_FILE) { genTestFile(f, frame.translit, variant); } } catch (Exception e2) { e2.printStackTrace(); System.out.println("Problem opening/reading: " + fileDirectory + ", " + fileName); } } fileDialog.dispose(); } } boolean transliterateTyping = true; Transliterator fromHex = Transliterator.getInstance("Hex-Any"); InfoDialog helpDialog; InfoDialog hexDialog; InfoDialog compoundDialog; InfoDialog rulesDialog; TextField ruleId; MenuItem convertSelectionItem = null; MenuItem swapSelectionItem = null; MenuItem convertTypingItem = null; Menu historyMenu; Map historyMap = new HashMap(); Set historySet = new TreeSet(new Comparator() { public int compare(Object a, Object b) { MenuItem aa = (MenuItem)a; MenuItem bb = (MenuItem)b; return aa.getLabel().compareTo(bb.getLabel()); } }); // ADD Factory since otherwise getInverse blows out static class DummyFactory implements Transliterator.Factory { static DummyFactory singleton = new DummyFactory(); static HashMap m = new HashMap(); // Since Transliterators are immutable, we don't have to clone on set & get static void add(String ID, Transliterator t) { m.put(ID, t); System.out.println("Registering: " + ID + ", " + t.toRules(true)); Transliterator.registerFactory(ID, singleton); } public Transliterator getInstance(String ID) { return (Transliterator) m.get(ID); } } static void printBreaks(int num, String testSource, BreakIterator brkItr) { String result = ""; int lastPos = 0; while (true) { int pos = brkItr.next(); if (pos == BreakIterator.DONE) break; result += testSource.substring(lastPos, pos) + "&"; lastPos = pos; System.out.println(pos); } System.out.println("Test" + num + ": " + result); } static void printIteration(int num, String testSource, CharacterIterator ci) { String result = ""; while (true) { char ch = ci.next(); if (ch == CharacterIterator.DONE) break; result += ch + "(" + ci.getIndex() + ")"; } System.out.println("Test" + num + ": " + result); } static void printSources() { String[] list = {"Latin-ThaiLogical", "ThaiLogical-Latin", "Thai-ThaiLogical", "ThaiLogical-Thai"}; UnicodeSet all = new UnicodeSet(); for (int i = 0; i < list.length; ++i) { Transliterator tr = Transliterator.getInstance(list[i]); UnicodeSet src = tr.getSourceSet(); System.out.println(list[i] + ": " + src.toPattern(true)); all.addAll(src); } System.out.println("All: " + all.toPattern(true)); UnicodeSet rem = new UnicodeSet("[[:latin:][:thai:]]"); System.out.println("missing from [:latin:][:thai:]: " + all.removeAll(rem).toPattern(true)); } // 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; static Transliterator title = Transliterator.getInstance("title"); static String hexAndNameRules = " ([:c:]) > \\u200E &hex/unicode($1) ' ( ) ' &name($1) \\u200E ' ';" + "([:mark:]) > \\u200E &hex/unicode($1) ' ( ' \\u200E \u25CC $1 \\u200E ' ) ' &name($1) \\u200E ' ';" + "(.) > \\u200E &hex/unicode($1) ' ( ' \\u200E $1 \\u200E ' ) ' &name($1) ' ' \\u200E;"; static Transliterator hexAndName = Transliterator.createFromRules("any-hexAndName", hexAndNameRules, Transliterator.FORWARD); //static Transliterator upper = Transliterator.getInstance("upper"); static final byte NONE = 0, TITLEWORD = 1, TITLELINE = 2; static void genTestFile(File sourceFile, Transliterator translit, String variant) { try { System.out.println("Reading: " + sourceFile.getCanonicalPath()); BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream(sourceFile), "UTF-8")); String targetFile = sourceFile.getCanonicalPath(); int dotPos = targetFile.lastIndexOf('.'); if (dotPos >= 0) targetFile = targetFile.substring(0,dotPos); targetFile += variant; File outFile = new File(targetFile + ".html"); System.out.println("Writing: " + outFile.getCanonicalPath()); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( new FileOutputStream(outFile), "UTF-8"))); String direction = ""; String id = translit.getID(); if (id.indexOf("Arabic") >= 0 || id.indexOf("Hebrew") >= 0) { direction = " direction: rtl;"; } boolean testRoundTrip = true; boolean generateSets = true; if (id.startsWith("Han-") || id.startsWith("ja-")) { testRoundTrip = false; generateSets = false; } out.println(""); out.println(""); out.println("" + id + " Transliteration Check"); out.println("

See Test_Instructions.html for details.

"); out.println(""); //out.println(""); Transliterator tl = translit; Transliterator lt = tl.getInverse(); Transliterator ltFilter = tl.getInverse(); ltFilter.setFilter(new UnicodeSet("[:^Lu:]")); Transliterator tlFilter = lt.getInverse(); tlFilter.setFilter(new UnicodeSet("[:^Lu:]")); //Transliterator.getInstance("[:^Lu:]" + lt.getID()); BreakIterator sentenceBreak = BreakIterator.getSentenceInstance(); byte titleSetting = TITLELINE; //boolean upperfilter = false; boolean first = true; while (true) { String line = in.readLine(); if (line == null) break; line = line.trim(); if (line.length() == 0) continue; if (line.charAt(0) == '\uFEFF') line = line.substring(1); // remove BOM if (line.charAt(0) == '#') continue; // comments if (line.equals("@TITLECASE@")) { titleSetting = TITLEWORD; out.println(""); continue; } else if (line.equals("@UPPERFILTER@")) { //upperfilter = true; continue; } else if (line.startsWith("@SET")) { UnicodeSet s = new UnicodeSet(line.substring(4).trim()); out.println(""); UnicodeSetIterator it = new UnicodeSetIterator(s); while (it.next()) { addSentenceToTable(out, it.codepoint != UnicodeSetIterator.IS_STRING ? UTF16.valueOf(it.codepoint) : it.string, NONE, true, testRoundTrip, first, tl, lt); } continue; } sentenceBreak.setText(line); int start = 0; while (true) { int end = sentenceBreak.next(); if (end == BreakIterator.DONE) break; String coreSentence = line.substring(start, end); //System.out.println("Core: " + hex.transliterate(coreSentence)); end = start; int oldPos = 0; while (oldPos < coreSentence.length()) { // hack, because sentence doesn't seem to be working right int pos = coreSentence.indexOf(". ", oldPos); if (pos < 0) pos = coreSentence.length(); else pos = pos+2; int pos2 = coreSentence.indexOf('\u3002', oldPos); if (pos2 < 0) pos2 = coreSentence.length(); else pos2 = pos2 + 1; if (pos > pos2) pos = pos2; String sentence = coreSentence.substring(oldPos, pos).trim(); //System.out.println("Sentence: " + hex.transliterate(coreSentence)); oldPos = pos; addSentenceToTable(out, sentence, titleSetting, false, testRoundTrip, first, tl, lt); first = false; } } } out.println("
ThaiLatinThai
Names
Characters
"); out.close(); // Now write the source/target sets if (generateSets) { outFile = new File(targetFile + "_Sets.html"); System.out.println("Writing: " + outFile.getCanonicalPath()); out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( new FileOutputStream(outFile), "UTF-8"))); out.println(""); out.println(""); out.println("" + id + " Transliteration Sets"); out.println(""); int dashPos = id.indexOf('-'); int slashPos = id.indexOf('/'); if (slashPos < 0) slashPos = id.length(); UnicodeSet sourceSuper = null; try { String temp = id.substring(0,dashPos); if (temp.equals("ja")) sourceSuper = new UnicodeSet("[[:Han:][:hiragana:][:katakana:]]"); else sourceSuper = new UnicodeSet("[[:" + temp + ":][:Mn:][:Me:]]"); } catch (Exception e) {} UnicodeSet targetSuper = null; try { targetSuper = new UnicodeSet("[[:" + id.substring(dashPos+1, slashPos) + ":][:Mn:][:Me:]]"); } catch (Exception e) {} int nfdStyle = CLOSE_CASE | CLOSE_FLATTEN | CLOSE_CANONICAL; int nfkdStyle = nfdStyle | CLOSE_COMPATIBILITY; out.println(""); out.close(); } System.out.println("Done Writing"); } catch (Exception e) { e.printStackTrace(); } } static void addSentenceToTable(PrintWriter out, String sentence, byte titleSetting, boolean addName, boolean testRoundTrip, boolean first, Transliterator tl, Transliterator lt) { if (sentence.length() == 0) return; // skip empty lines String originalShow = sentence; String latin; latin = tl.transliterate(saveAscii.transliterate(sentence)); String latinShow = latin; if (titleSetting == TITLEWORD) { latinShow = title.transliterate(latin); } else if (titleSetting == TITLELINE) { latinShow = titlecaseFirstWord(latinShow); } latinShow = restoreAscii.transliterate(latinShow); String reverse; reverse = restoreAscii.transliterate(lt.transliterate(latin)); String NFKDSentence = Normalizer.normalize(sentence, Normalizer.NFKD); String NFKDLatin = Normalizer.normalize(latin, Normalizer.NFKD); String NFKDReverse = Normalizer.normalize(reverse, Normalizer.NFKD); if (latinShow.length() == 0) { latinShow = "empty"; } else if (NFKDSentence.equals(NFKDLatin)) { latinShow = "" + latinShow + ""; } String reverseShow = reverse; if (testRoundTrip && !NFKDReverse.equals(NFKDSentence)) { int minLen = reverse.length(); if (minLen > sentence.length()) minLen = sentence.length(); int i; for (i = 0; i < minLen; ++i) { if (reverse.charAt(i) != sentence.charAt(i)) break; } //originalShow = sentence.substring(0,i) + "" + sentence.substring(i) + ""; reverseShow = reverseShow.length() == 0 ? "empty" //: reverse.substring(0,i) + "" + reverse.substring(i) + ""; : showDifference(sentence, reverse); out.println("" : ">") + originalShow + "" + latinShow + "" + reverseShow + ""); } else { out.println("" : ">") + originalShow + "" + latinShow + ""); } if (addName) { latinShow = hexAndName.transliterate(latin); if (latinShow.length() == 0) latinShow = "empty"; originalShow = hexAndName.transliterate(sentence); if (originalShow.length() == 0) originalShow = "empty"; out.println("" + originalShow + "" + latinShow + ""); } out.println(""); } static String showDifference(String as, String bs) { Differ differ = new Differ(300, 3); StringBuffer out = new StringBuffer(); int max = as.length(); if (max < bs.length()) max = bs.length(); for (int j = 0; j <= max; ++j) { if (j < as.length()) differ.addA(as.substring(j, j+1)); if (j < bs.length()) differ.addB(bs.substring(j, j+1)); differ.checkMatch(j == max); if (differ.getACount() != 0 || differ.getBCount() != 0) { out.append("..."); if (differ.getACount() != 0) { out.append(""); for (int i = 0; i < differ.getACount(); ++i) { out.append(differ.getA(i)); } out.append(""); } if (differ.getBCount() != 0) { out.append(""); for (int i = 0; i < differ.getBCount(); ++i) { out.append(differ.getB(i)); } out.append(""); } out.append("..."); } } return out.toString(); } static void showSets(PrintWriter out, Transliterator translit, Transliterator inverse, UnicodeSet sourceSuper, UnicodeSet targetSuper, int options) { out.println("
  • Source Set:
  • "); out.println("
  • Reverse Target Set:
  • "); out.println("
  • Target Set:
  • "); out.println("
  • Reverse Source Set:
  • "); } static final int CLOSE_CASE = 1, CLOSE_FLATTEN = 2, CLOSE_CANONICAL = 4, CLOSE_COMPATIBILITY = 8; static UnicodeSet closeUnicodeSet(UnicodeSet source, int options) { if (options == 0) return source; UnicodeSetIterator it = new UnicodeSetIterator(source); UnicodeSet additions = new UnicodeSet(); // to avoid messing up iterator UnicodeSet removals = new UnicodeSet(); // to avoid messing up iterator String base; int cp; // Add all case equivalents if ((options & CLOSE_CASE) != 0) { while (it.next()) { cp = it.codepoint; if (cp == UnicodeSetIterator.IS_STRING) continue; int type = UCharacter.getType(cp); if (type == Character.UPPERCASE_LETTER || type == Character.LOWERCASE_LETTER || type == Character.TITLECASE_LETTER) { additions.add(UCharacter.toLowerCase(UTF16.valueOf(cp))); additions.add(UCharacter.toUpperCase(UTF16.valueOf(cp))); } } source.addAll(additions); } // Add the canonical closure of all strings and characters in source if ((options & CLOSE_CANONICAL) != 0) { it.reset(); additions.clear(); CanonicalIterator ci = new CanonicalIterator("."); while (it.next()) { if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string; else base = UTF16.valueOf(it.codepoint); ci.setSource(base); while (true) { String trial = ci.next(); if (trial == null) break; if (trial.equals(base)) continue; additions.add(trial); } } source.addAll(additions); } // flatten strings if ((options & CLOSE_FLATTEN) != 0) { it.reset(); additions.clear(); while (it.next()) { if (it.codepoint != UnicodeSetIterator.IS_STRING) continue; additions.addAll(it.string); removals.add(it.string); //System.out.println("flattening '" + hex.transliterate(it.string) + "'"); } source.addAll(additions); source.removeAll(removals); } // Now add decompositions of characters in source if ((options & CLOSE_COMPATIBILITY) != 0) { it.reset(source); additions.clear(); while (it.next()) { if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string; else base = UTF16.valueOf(it.codepoint); if (Normalizer.isNormalized(base, Normalizer.NFKD,0)) continue; String decomp = Normalizer.normalize(base, Normalizer.NFKD); additions.add(decomp); } source.addAll(additions); // Now add any other character that decomposes to a character in source for (cp = 0; cp < 0x10FFFF; ++cp) { if (!UCharacter.isDefined(cp)) continue; if (Normalizer.isNormalized(cp, Normalizer.NFKD,0)) continue; if (source.contains(cp)) continue; String decomp = Normalizer.normalize(cp, Normalizer.NFKD); if (source.containsAll(decomp)) { // System.out.println("Adding: " + Integer.toString(cp,16) + " " + UCharacter.getName(cp)); source.add(cp); } } } return source; } static String toPattern(UnicodeSet source, UnicodeSet superset) { if (superset != null) { source.removeAll(superset); return "[" + superset.toPattern(true) + " " + source.toPattern(true) + "]"; } return source.toPattern(true); } static BreakIterator bi = BreakIterator.getWordInstance(); static String titlecaseFirstWord(String line) { // search for first word with letters. If the first letter is lower, then titlecase it. bi.setText(line); int start = 0; while (true) { int end = bi.next(); if (end == BreakIterator.DONE) break; int firstLetterType = getFirstLetterType(line, start, end); if (firstLetterType != Character.UNASSIGNED) { if (firstLetterType != Character.LOWERCASE_LETTER) break; line = line.substring(0, start) + UCharacter.toTitleCase(line.substring(start, end), bi) + line.substring(end); break; } end = start; } return line; } static final int LETTER_MASK = (1< XXX # " + UCharacter.getName(it.codepoint)); main.add(it.codepoint); } if (others.size() != 0) { out.println("Decomposed characters found above: "); others.removeAll(main); it.reset(others); while (it.next()) { out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint)); } } out.close(); System.out.println("Done Writing"); } catch (Exception e) { e.printStackTrace(); } } static Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex"); static final String saveRules = "A <> \uEA41; B <> \uEA42; C <> \uEA43; D <> \uEA44; E <> \uEA45; F <> \uEA46; G <> \uEA47; H <> \uEA48; I <> \uEA49; " + "J <> \uEA4A; K <> \uEA4B; L <> \uEA4C; M <> \uEA4D; N <> \uEA4E; O <> \uEA4F; P <> \uEA50; Q <> \uEA51; R <> \uEA52; " + "S <> \uEA53; T <> \uEA54; U <> \uEA55; V <> \uEA56; W <> \uEA57; X <> \uEA58; Y <> \uEA59; Z <> \uEA5A; " + "a <> \uEA61; b <> \uEA62; c <> \uEA63; d <> \uEA64; e <> \uEA65; f <> \uEA66; g <> \uEA67; h <> \uEA68; i <> \uEA69; " + "j <> \uEA6A; k <> \uEA6B; l <> \uEA6C; m <> \uEA6D; n <> \uEA6E; o <> \uEA6F; p <> \uEA70; q <> \uEA71; r <> \uEA72; " + "s <> \uEA73; t <> \uEA74; u <> \uEA75; v <> \uEA76; w <> \uEA77; x <> \uEA78; y <> \uEA79; z <> \uEA7A;"; static Transliterator saveAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.FORWARD); static Transliterator restoreAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.REVERSE); static { if (false) { for (char i = 'A'; i <= 'z'; ++i) { System.out.print(i + " <> " + hex.transliterate(String.valueOf((char)(0xEA00 + i))) + "; "); } UnicodeSet x = new UnicodeSet("[[:^ccc=0:]&[:^ccc=230:]]"); x = x.complement(); x = x.complement(); System.out.println("Test: " + x.toPattern(true)); Transliterator y = Transliterator.createFromRules("xxx", "$notAbove = [[:^ccc=0:]&[:^ccc=230:]]; u ($notAbove*) \u0308 > XXX | $1; ", Transliterator.FORWARD); String[] testList = {"u\u0308", "u\u0316\u0308", "u\u0308\u0316", "u\u0301\u0308", "u\u0308\u0301"}; for (int i = 0; i < testList.length; ++i) { String yy = y.transliterate(testList[i]); System.out.println(hex.transliterate(testList[i]) + " => " + hex.transliterate(yy)); } //printNames(new UnicodeSet("[\u0600-\u06FF]"), "Arabic-Latin.txt"); /* BreakTransliterator.register(); BreakTransliterator testTrans = new BreakTransliterator("Any-XXX", null, null, "$"); String testSource = "The Quick: Brown fox--jumped."; BreakIterator bi = testTrans.getBreakIterator(); bi.setText(new StringCharacterIterator(testSource)); printBreaks(0, testSource, bi); //bi.setText(UCharacterIterator.getInstance(testSource)); //printBreaks(1, testSource, bi); printIteration(2, testSource, new StringCharacterIterator(testSource)); //printIteration(3, testSource, UCharacterIterator.getInstance(testSource)); String test = testTrans.transliterate(testSource); System.out.println("Test3: " + test); DummyFactory.add(testTrans.getID(), testTrans); */ // AnyTransliterator.ScriptRunIterator.registerAnyToScript(); AnyTransliterator at = new AnyTransliterator("Greek", null); at.transliterate("(cat,\u03b1,\u0915)"); DummyFactory.add(at.getID(), at); at = new AnyTransliterator("Devanagari", null); at.transliterate("(cat,\u03b1,\u0915)"); DummyFactory.add(at.getID(), at); at = new AnyTransliterator("Latin", null); at.transliterate("(cat,\u03b1,\u0915)"); DummyFactory.add(at.getID(), at); DummyFactory.add("Any-gif", Transliterator.createFromRules("gif", "'\\'u(..)(..) > '';", Transliterator.FORWARD)); DummyFactory.add("gif-Any", Transliterator.getInstance("Any-Null")); DummyFactory.add("Any-RemoveCurly", Transliterator.createFromRules("RemoveCurly", "[\\{\\}] > ;", Transliterator.FORWARD)); DummyFactory.add("RemoveCurly-Any", Transliterator.getInstance("Any-Null")); System.out.println("Trying &hex"); Transliterator t = Transliterator.createFromRules("hex2", "(.) > &hex($1);", Transliterator.FORWARD); System.out.println("Registering"); DummyFactory.add("Any-hex2", t); System.out.println("Trying &gif"); t = Transliterator.createFromRules("gif2", "(.) > &any-gif($1);", Transliterator.FORWARD); System.out.println("Registering"); DummyFactory.add("Any-gif2", t); } } void setTransliterator(String name, String id) { if (DEBUG) System.out.println("Got: " + name); if (id == null) { translit = Transliterator.getInstance(name); } else { String reverseId = ""; int pos = id.indexOf('-'); if (pos < 0) { reverseId = id + "-Any"; id = "Any-" + id; } else { int pos2 = id.indexOf("/", pos); if (pos2 < 0) { reverseId = id.substring(pos+1) + "-" + id.substring(0,pos); } else { reverseId = id.substring(pos+1, pos2) + "-" + id.substring(0,pos) + id.substring(pos2); } } translit = Transliterator.createFromRules(id, name, Transliterator.FORWARD); if (DEBUG) { System.out.println("***Forward Rules"); System.out.println(translit.toRules(true)); System.out.println("***Source Set"); System.out.println(translit.getSourceSet().toPattern(true)); } System.out.println("***Target Set"); UnicodeSet target = translit.getTargetSet(); System.out.println(target.toPattern(true)); UnicodeSet rest = new UnicodeSet("[a-z]").removeAll(target); System.out.println("***ASCII - Target Set"); System.out.println(rest.toPattern(true)); DummyFactory.add(id, translit); Transliterator translit2 = Transliterator.createFromRules(reverseId, name, Transliterator.REVERSE); if (DEBUG) { System.out.println("***Backward Rules"); System.out.println(translit2.toRules(true)); } DummyFactory.add(reverseId, translit2); Transliterator rev = translit.getInverse(); if (DEBUG) System.out.println("***Inverse Rules"); if (DEBUG) System.out.println(rev.toRules(true)); } text.flush(); text.setTransliterator(translit); convertSelectionItem.setLabel(Transliterator.getDisplayName(translit.getID())); addHistory(translit); Transliterator inv; try { inv = translit.getInverse(); } catch (Exception ex) { inv = null; } if (inv != null) { addHistory(inv); swapSelectionItem.setEnabled(true); } else { swapSelectionItem.setEnabled(false); } System.out.println("Set transliterator: " + translit.getID() + (inv != null ? " and " + inv.getID() : "")); } void addHistory(Transliterator trans) { String name = trans.getID(); MenuItem cmi = (MenuItem) historyMap.get(name); if (cmi == null) { cmi = new MenuItem(Transliterator.getDisplayName(name)); cmi.addActionListener(new TransliterationListener(name)); historyMap.put(name, cmi); historySet.add(cmi); historyMenu.removeAll(); Iterator it = historySet.iterator(); while (it.hasNext()) { historyMenu.add((MenuItem)it.next()); } } } class TransliterationListener implements ActionListener, ItemListener { String name; public TransliterationListener(String name) { this.name = name; } public void actionPerformed(ActionEvent e) { setTransliterator(name, null); } public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { setTransliterator(name, null); } else { setTransliterator("Any-Null", null); } } } class FontActionListener implements ActionListener { String name; public FontActionListener(String name) { this.name = name; } public void actionPerformed(ActionEvent e) { if (DEBUG) System.out.println("Font: " + name); fontName = name; text.setFont(new Font(fontName, Font.PLAIN, fontSize)); } } class SizeActionListener implements ActionListener { int size; public SizeActionListener(int size) { this.size = size; } public void actionPerformed(ActionEvent e) { if (DEBUG) System.out.println("Size: " + size); fontSize = size; text.setFont(new Font(fontName, Font.PLAIN, fontSize)); } } Set add(Set s, Enumeration enumeration) { while(enumeration.hasMoreElements()) { s.add(enumeration.nextElement()); } return s; } /** * Get a sorted list of the system transliterators. */ /* private static Vector getSystemTransliteratorNames() { Vector v = new Vector(); for (Enumeration e=Transliterator.getAvailableIDs(); e.hasMoreElements(); ) { v.addElement(e.nextElement()); } // Insertion sort, O(n^2) acceptable for small n for (int i=0; i<(v.size()-1); ++i) { String a = (String) v.elementAt(i); for (int j=i+1; j 0) { v.setElementAt(b, i); v.setElementAt(a, j); a = b; } } } return v; } */ /* private void setNoTransliterator() { translitItem = noTranslitItem; noTranslitItem.setState(true); handleSetTransliterator(noTranslitItem.getLabel()); compound = false; for (int i=0; i. */ /* private static Transliterator decodeTranslitItem(String name) { return (name.equals(NO_TRANSLITERATOR)) ? null : Transliterator.getInstance(name); } */ private void handleBatchTransliterate(Transliterator trans) { if (trans == null) { return; } int start = text.getSelectionStart(); int end = text.getSelectionEnd(); ReplaceableString s = new ReplaceableString(text.getText().substring(start, end)); StringBuffer log = null; if (DEBUG) { log = new StringBuffer(); log.append('"' + s.toString() + "\" (start " + start + ", end " + end + ") -> \""); } trans.transliterate(s); String str = s.toString(); if (DEBUG) { log.append(str + "\""); System.out.println("Batch " + trans.getID() + ": " + log.toString()); } text.replaceRange(str, start, end); text.select(start, start + str.length()); } private void handleClose() { helpDialog.dispose(); dispose(); } /* class InfoDialog extends Dialog { protected Button button; protected TextArea area; protected Dialog me; protected Panel bottom; public TextArea getArea() { return area; } public Panel getBottom() { return bottom; } InfoDialog(Frame parent, String title, String label, String message) { super(parent, title, false); me = this; this.setLayout(new BorderLayout()); if (label.length() != 0) { this.add("North", new Label(label)); } area = new TextArea(message, 8, 80, TextArea.SCROLLBARS_VERTICAL_ONLY); this.add("Center", area); button = new Button("Hide"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { me.hide(); } }); bottom = new Panel(); bottom.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); bottom.add(button); this.add("South", bottom); this.pack(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { me.hide(); } }); } } */ }