first cut at any-x

X-SVN-Rev: 8709
This commit is contained in:
Mark Davis 2002-05-25 15:20:10 +00:00
parent c76aaff480
commit c46b3b8287
3 changed files with 365 additions and 22 deletions

View file

@ -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;
}
}
}

View file

@ -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.*;
* <p>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(..)(..) > '<img src=\"http://www.unicode.org/gifs/24/' $1 '/U' $1$2 '.gif\">';", 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 {
});
}
}
*/
}

View file

@ -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();
}
});
}
}