From c46b3b8287522da9f5779303220e27057dacca91 Mon Sep 17 00:00:00 2001 From: Mark Davis Date: Sat, 25 May 2002 15:20:10 +0000 Subject: [PATCH] first cut at any-x X-SVN-Rev: 8709 --- .../dev/demo/translit/AnyTransliterator.java | 235 ++++++++++++++++++ .../com/ibm/icu/dev/demo/translit/Demo.java | 106 ++++++-- .../ibm/icu/dev/demo/translit/InfoDialog.java | 46 ++++ 3 files changed, 365 insertions(+), 22 deletions(-) create mode 100644 icu4j/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java create mode 100644 icu4j/src/com/ibm/icu/dev/demo/translit/InfoDialog.java diff --git a/icu4j/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java b/icu4j/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java new file mode 100644 index 00000000000..a5de06a558b --- /dev/null +++ b/icu4j/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java @@ -0,0 +1,235 @@ +package com.ibm.icu.dev.demo.translit; +import com.ibm.icu.dev.demo.impl.*; +import com.ibm.icu.lang.*; +import com.ibm.icu.text.*; + +public class AnyTransliterator extends Transliterator { + + static final boolean DEBUG = true; + private String targetName; + private RunIterator it; + private Position run; + + + public AnyTransliterator(String targetName, UnicodeFilter filter, RunIterator it){ + super("Any-" + targetName, filter); + this.targetName = targetName; + this.it = it; + run = new Position(); + } + + public AnyTransliterator(String targetName, UnicodeFilter filter){ + this(targetName, filter, new ScriptRunIterator()); + } + + static private Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex"); + + protected void handleTransliterate(Replaceable text, + Position offsets, boolean isIncremental) { + if (DEBUG) { + System.out.println("- handleTransliterate " + hex.transliterate(text.toString()) + + ", " + toString(offsets)); + } + it.reset(text, offsets); + + while (it.next(run)) { + if (targetName.equalsIgnoreCase(it.getName())) { + if (DEBUG) System.out.println("Skipping identical: " + targetName); + run.start = run.limit; // show we processed + continue; // skip if same + } + + Transliterator t; + String id = it.getName() + '-' + targetName; + try { + t = Transliterator.getInstance(id); + } catch (IllegalArgumentException ex) { + if (DEBUG) System.out.println("Couldn't find: " + id + ", Trying Latin as Pivot"); + id = it.getName() + "-Latin; Latin-" + targetName; + try { + t = Transliterator.getInstance(id); + } catch (IllegalArgumentException ex2) { + if (DEBUG) System.out.println("Couldn't find: " + id); + continue; + } + } + // TODO catch error later!! + + if (DEBUG) { + System.out.println(t.getID()); + System.out.println("input: " + hex.transliterate(text.toString()) + + ", " + toString(run)); + } + + if (isIncremental && it.atEnd()) { + t.transliterate(text, run); + } else { + t.finishTransliteration(text, run); + } + // adjust the offsets in line with the changes + it.adjust(run.limit); + + if (DEBUG) { + System.out.println("output: " + hex.transliterate(text.toString()) + + ", " + toString(run)); + } + } + + // show how far we got! + it.getExpanse(offsets); + if (run.start == run.limit) offsets.start = offsets.limit; + else offsets.start = run.start; + if (DEBUG) { + System.out.println("+ handleTransliterate: " + ", " + toString(offsets)); + System.out.println(); + } + } + + // should be method on Position + public static String toString(Position offsets) { + return "[cs: " + offsets.contextStart + + ", s: " + offsets.start + + ", l: " + offsets.limit + + ", cl: " + offsets.contextLimit + + "]"; + } + + public interface RunIterator { + public void reset(Replaceable text, Position expanse); + public void getExpanse(Position run); + public void reset(); + public boolean next(Position run); + public void getCurrent(Position run); + public String getName(); + public void adjust(int newCurrentLimit); + public boolean atEnd(); + } + + public static class ScriptRunIterator implements RunIterator { + Replaceable text; + Position expanse = new Position(); + Position current = new Position(); + int script; + boolean done = true; + + public void reset(Replaceable text, Position expanse) { + set(this.expanse, expanse); + this.text = text; + reset(); + } + + public void reset() { + done = false; + this.expanse = expanse; + script = UScript.INVALID_CODE; + // set up first range to be empty, at beginning + current.contextStart = expanse.contextStart; + current.start = current.limit = expanse.start; + + // find the COMMON stuff at the start of the expanse + int i, cp; + int limit = expanse.limit; + for (i = current.limit; i < limit; i += UTF16.getCharCount(cp)) { + cp = text.char32At(i); + int script = UScript.getScript(cp); + if (script != UScript.COMMON && script != UScript.INHERITED) break; + } + if (i == limit) done = true; + else current.contextLimit = i; + + } + + public boolean next(Position run) { + if (done) return false; + if (DEBUG) { + System.out.println("+cs: " + current.contextStart + + ", s: " + current.start + + ", l: " + current.limit + + ", cl: " + current.contextLimit); + } + // reset start context run to the last end + current.contextStart = current.limit; + current.start = current.contextLimit; + + // set up variables and loop + int limit = expanse.limit; + int lastScript = UScript.COMMON; + int veryLastScript = UScript.COMMON; + int i, cp; + for (i = current.start; i < limit; i += UTF16.getCharCount(cp)) { + cp = text.char32At(i); + int script = UScript.getScript(cp); + if (script == UScript.INHERITED) script = UScript.COMMON; + if (script != UScript.COMMON) { + // if we find a real script: + // if we already had a script, bail + // otherwise set our script + if (lastScript == UScript.COMMON) lastScript = script; + else if (lastScript != script) break; + } else if (veryLastScript != UScript.COMMON) { + // if we found COMMON -- and -- the last character was not, reset + current.limit = i; + } + veryLastScript = script; + } + // fix end + if (veryLastScript != UScript.COMMON) { + // if we found COMMON -- and -- the last character was not, reset + current.limit = i; + } + // if we are at the very end of the expanse, then expand it. + if (i == limit) { + current.contextLimit = expanse.contextLimit; + done = true; + } else { + current.contextLimit = i; + } + script = lastScript; + if (DEBUG) { + System.out.println("-cs: " + current.contextStart + + ", s: " + current.start + + ", l: " + current.limit + + ", cl: " + current.contextLimit); + } + + set(run, current); + return true; + } + + // SHOULD BE METHOD ON POSITION + public static void set(Position run, Position current) { + run.contextStart = current.contextStart; + run.start = current.start; + run.limit = current.limit; + run.contextLimit = current.contextLimit; + } + + public boolean atEnd() { + return current.limit == expanse.limit; + } + + public void getCurrent(Position run) { + set(run, current); + } + + public void getExpanse(Position run) { + set(run, expanse); + } + + public String getName() { + return UScript.getName(script); + } + + public void adjust(int newCurrentLimit) { + if (expanse == null) { + throw new IllegalArgumentException("Must reset() before calling"); + } + int delta = newCurrentLimit - current.limit; + current.limit += delta; + current.contextLimit += delta; + expanse.limit += delta; + expanse.contextLimit += delta; + } + + } +} \ No newline at end of file diff --git a/icu4j/src/com/ibm/icu/dev/demo/translit/Demo.java b/icu4j/src/com/ibm/icu/dev/demo/translit/Demo.java index 5e429a4b7b8..b2f2fcd3d58 100755 --- a/icu4j/src/com/ibm/icu/dev/demo/translit/Demo.java +++ b/icu4j/src/com/ibm/icu/dev/demo/translit/Demo.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/translit/Demo.java,v $ - * $Date: 2002/03/19 00:17:01 $ - * $Revision: 1.14 $ + * $Date: 2002/05/25 15:20:10 $ + * $Revision: 1.15 $ * ***************************************************************************************** */ @@ -28,11 +28,12 @@ import com.ibm.icu.text.*; *

Copyright (c) IBM Corporation 1999. All rights reserved. * * @author Alan Liu - * @version $RCSfile: Demo.java,v $ $Revision: 1.14 $ $Date: 2002/03/19 00:17:01 $ + * @version $RCSfile: Demo.java,v $ $Revision: 1.15 $ $Date: 2002/05/25 15:20:10 $ */ public class Demo extends Frame { static final boolean DEBUG = false; + static final String START_TEXT = "(cut,\u03BA\u03C5\u03C4,\u05D0,\u3042,\u4E80,\u091A\u0941\u0924\u094D)"; Transliterator translit = null; String fontName = "Arial Unicode MS"; @@ -84,11 +85,11 @@ public class Demo extends Frame { text.setFont(font); text.setSize(width, height); text.setVisible(true); - text.setText("\u03B1\u05D0\u3042\u4E80"); + text.setText(START_TEXT); add(text); setSize(width, height); - setTransliterator("Latin-Greek", false); + setTransliterator("Latin-Greek", null); } private void initMenus() { @@ -207,8 +208,13 @@ public class Demo extends Frame { new MenuShortcut(KeyEvent.VK_S))); swapSelectionItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Transliterator inv = translit.getInverse(); - setTransliterator(inv.getID(), false); + Transliterator inv; + try { + inv = translit.getInverse(); + } catch (Exception x) { + inv = new NullTransliterator(); + } + setTransliterator(inv.getID(), null); } }); @@ -248,7 +254,7 @@ public class Demo extends Frame { }); hexDialog = new InfoDialog(this, "Hex Entry", "Use U+..., \\u..., \\x{...}, or &#x...;", - "\u00E1" + "\\u00E1" ); Button button = new Button("Insert"); button.addActionListener(new ActionListener() { @@ -278,7 +284,7 @@ public class Demo extends Frame { String compound = ""; try { compound = compoundDialog.getArea().getText(); - setTransliterator(compound, false); + setTransliterator(compound, null); } catch (RuntimeException ex) { compoundDialog.getArea().setText(compound + "\n" + ex.getMessage()); } @@ -307,13 +313,19 @@ public class Demo extends Frame { String compound = ""; try { compound = rulesDialog.getArea().getText(); - setTransliterator(compound, true); + 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))); @@ -363,6 +375,7 @@ public class Demo extends Frame { InfoDialog hexDialog; InfoDialog compoundDialog; InfoDialog rulesDialog; + TextField ruleId; MenuItem convertSelectionItem = null; MenuItem swapSelectionItem = null; MenuItem convertTypingItem = null; @@ -384,7 +397,7 @@ public class Demo extends Frame { // 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)); + System.out.println("Registering: " + ID + ", " + t.toRules(true)); Transliterator.registerFactory(ID, singleton); } public Transliterator getInstance(String ID) { @@ -392,21 +405,63 @@ public class Demo extends Frame { } } + static { + 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); + + if (false) { + 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, boolean rules) { + + void setTransliterator(String name, String id) { if (DEBUG) System.out.println("Got: " + name); - if (!rules) { + if (id == null) { translit = Transliterator.getInstance(name); } else { - translit = Transliterator.createFromRules("Any-Test", name, Transliterator.FORWARD); + int pos = id.indexOf('-'); + String reverseId = ""; + if (pos < 0) { + reverseId = id + "-Any"; + id = "Any-" + id; + } else { + reverseId = id.substring(pos+1) + "-" + id.substring(0,pos); + } + + + translit = Transliterator.createFromRules(id, name, Transliterator.FORWARD); if (DEBUG) System.out.println("***Forward Rules"); if (DEBUG) System.out.println(((RuleBasedTransliterator)translit).toRules(true)); - DummyFactory.add("Any-Test", translit); - - Transliterator translit2 = Transliterator.createFromRules("Test-Any", name, Transliterator.REVERSE); + DummyFactory.add(id, translit); + + Transliterator translit2 = Transliterator.createFromRules(reverseId, name, Transliterator.REVERSE); if (DEBUG) System.out.println("***Backward Rules"); if (DEBUG) System.out.println(((RuleBasedTransliterator)translit2).toRules(true)); - DummyFactory.add("Test-Any", translit2); + DummyFactory.add(reverseId, translit2); Transliterator rev = translit.getInverse(); if (DEBUG) System.out.println("***Inverse Rules"); @@ -419,7 +474,12 @@ public class Demo extends Frame { addHistory(translit); - Transliterator inv = translit.getInverse(); + Transliterator inv; + try { + inv = translit.getInverse(); + } catch (Exception ex) { + inv = null; + } if (inv != null) { addHistory(inv); swapSelectionItem.setEnabled(true); @@ -450,13 +510,13 @@ public class Demo extends Frame { this.name = name; } public void actionPerformed(ActionEvent e) { - setTransliterator(name, false); + setTransliterator(name, null); } public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == e.SELECTED) { - setTransliterator(name, false); + setTransliterator(name, null); } else { - setTransliterator("Any-Null", false); + setTransliterator("Any-Null", null); } } } @@ -595,6 +655,7 @@ public class Demo extends Frame { dispose(); } + /* class InfoDialog extends Dialog { protected Button button; protected TextArea area; @@ -638,4 +699,5 @@ public class Demo extends Frame { }); } } + */ } diff --git a/icu4j/src/com/ibm/icu/dev/demo/translit/InfoDialog.java b/icu4j/src/com/ibm/icu/dev/demo/translit/InfoDialog.java new file mode 100644 index 00000000000..0a0516dafc5 --- /dev/null +++ b/icu4j/src/com/ibm/icu/dev/demo/translit/InfoDialog.java @@ -0,0 +1,46 @@ +package com.ibm.icu.dev.demo.translit; +import java.awt.event.*; +import java.awt.*; +public 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(); + } + }); + } +}