Skip to content

Commit b3861ed

Browse files
committed
init
0 parents  commit b3861ed

File tree

5 files changed

+362
-0
lines changed

5 files changed

+362
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode/

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# opencc-rust-lib
2+
3+
[polyproline/opencc-rust](https://github.com/polyproline/opencc-rust) 封裝為 ES6 模組,使 OpenCC 可以直接被瀏覽器引用。

index.html

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<html>
2+
<head>
3+
<title>OpenCC Rust Demo</title>
4+
<style>
5+
body {
6+
display: flex;
7+
flex-direction: column;
8+
align-items: center;
9+
margin: 0;
10+
padding: 20px;
11+
font-family: Arial, sans-serif;
12+
}
13+
14+
.container {
15+
display: flex;
16+
align-items: flex-start;
17+
margin-bottom: 20px;
18+
}
19+
20+
.container > * {
21+
margin-right: 10px;
22+
}
23+
24+
.textarea-container {
25+
display: flex;
26+
flex-direction: column;
27+
align-items: center;
28+
margin: 10px;
29+
}
30+
31+
textarea {
32+
width: 300px;
33+
height: 150px;
34+
resize: both;
35+
}
36+
37+
label {
38+
margin-top: 5px;
39+
font-weight: bold;
40+
}
41+
42+
#convert {
43+
margin-top: 90px;
44+
margin-right: 0px;
45+
}
46+
47+
</style>
48+
<script type="module">
49+
import { converter } from "./js/opencc-rust.mjs"
50+
51+
window.convert = async function() {
52+
const text = document.getElementById("text").value
53+
const converted = await converter.convert(text);
54+
55+
document.getElementById("result").value = converted;
56+
}
57+
</script>
58+
</head>
59+
<body>
60+
<div class="container">
61+
<div class="textarea-container">
62+
<label for="text">Origin</label>
63+
<textarea id="text"></textarea>
64+
</div>
65+
<button onclick="convert()" id="convert">Convert</button>
66+
<div class="textarea-container">
67+
<label for="result">Translated</label>
68+
<textarea id="result" readonly></textarea>
69+
</div>
70+
</div>
71+
</body>
72+
</html>

js/opencc-rust-lib.mjs

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
let wasm;
2+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
3+
4+
cachedTextDecoder.decode();
5+
6+
let cachegetUint8Memory0 = null;
7+
function getUint8Memory0() {
8+
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
9+
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
10+
}
11+
return cachegetUint8Memory0;
12+
}
13+
14+
function getStringFromWasm0(ptr, len) {
15+
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
16+
}
17+
18+
let WASM_VECTOR_LEN = 0;
19+
20+
let cachedTextEncoder = new TextEncoder('utf-8');
21+
22+
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
23+
? function (arg, view) {
24+
return cachedTextEncoder.encodeInto(arg, view);
25+
}
26+
: function (arg, view) {
27+
const buf = cachedTextEncoder.encode(arg);
28+
view.set(buf);
29+
return {
30+
read: arg.length,
31+
written: buf.length
32+
};
33+
});
34+
35+
function passStringToWasm0(arg, malloc, realloc) {
36+
37+
if (realloc === undefined) {
38+
const buf = cachedTextEncoder.encode(arg);
39+
const ptr = malloc(buf.length);
40+
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
41+
WASM_VECTOR_LEN = buf.length;
42+
return ptr;
43+
}
44+
45+
let len = arg.length;
46+
let ptr = malloc(len);
47+
48+
const mem = getUint8Memory0();
49+
50+
let offset = 0;
51+
52+
for (; offset < len; offset++) {
53+
const code = arg.charCodeAt(offset);
54+
if (code > 0x7F) break;
55+
mem[ptr + offset] = code;
56+
}
57+
58+
if (offset !== len) {
59+
if (offset !== 0) {
60+
arg = arg.slice(offset);
61+
}
62+
ptr = realloc(ptr, len, len = offset + arg.length * 3);
63+
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
64+
const ret = encodeString(arg, view);
65+
66+
offset += ret.written;
67+
}
68+
69+
WASM_VECTOR_LEN = offset;
70+
return ptr;
71+
}
72+
73+
let cachegetInt32Memory0 = null;
74+
function getInt32Memory0() {
75+
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
76+
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
77+
}
78+
return cachegetInt32Memory0;
79+
}
80+
/**
81+
*/
82+
class Converter {
83+
84+
static __wrap(ptr) {
85+
const obj = Object.create(Converter.prototype);
86+
obj.ptr = ptr;
87+
88+
return obj;
89+
}
90+
91+
free() {
92+
const ptr = this.ptr;
93+
this.ptr = 0;
94+
95+
wasm.__wbg_converter_free(ptr);
96+
}
97+
/**
98+
* @param {string} data
99+
* @returns {string}
100+
*/
101+
async convert(data) {
102+
try {
103+
const retptr = wasm.__wbindgen_export_2.value - 16;
104+
wasm.__wbindgen_export_2.value = retptr;
105+
var ptr0 = passStringToWasm0(data, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
106+
var len0 = WASM_VECTOR_LEN;
107+
wasm.converter_convert(retptr, this.ptr, ptr0, len0);
108+
var r0 = getInt32Memory0()[retptr / 4 + 0];
109+
var r1 = getInt32Memory0()[retptr / 4 + 1];
110+
return getStringFromWasm0(r0, r1);
111+
} finally {
112+
wasm.__wbindgen_export_2.value += 16;
113+
wasm.__wbindgen_free(r0, r1);
114+
}
115+
}
116+
/**
117+
*/
118+
delete() {
119+
wasm.converter_delete(this.ptr);
120+
}
121+
}
122+
/**
123+
*/
124+
class ConverterBuild {
125+
126+
static __wrap(ptr) {
127+
const obj = Object.create(ConverterBuild.prototype);
128+
obj.ptr = ptr;
129+
130+
return obj;
131+
}
132+
133+
free() {
134+
const ptr = this.ptr;
135+
this.ptr = 0;
136+
137+
wasm.__wbg_converterbuild_free(ptr);
138+
}
139+
/**
140+
* @returns {ConverterBuild}
141+
*/
142+
static new() {
143+
var ret = wasm.converterbuild_new();
144+
return ConverterBuild.__wrap(ret);
145+
}
146+
/**
147+
* @param {string} data
148+
*/
149+
adddict(data) {
150+
var ptr0 = passStringToWasm0(data, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
151+
var len0 = WASM_VECTOR_LEN;
152+
wasm.converterbuild_adddict(this.ptr, ptr0, len0);
153+
}
154+
/**
155+
*/
156+
group() {
157+
wasm.converterbuild_group(this.ptr);
158+
}
159+
/**
160+
* @returns {Converter}
161+
*/
162+
build() {
163+
var ret = wasm.converterbuild_build(this.ptr);
164+
return Converter.__wrap(ret);
165+
}
166+
}
167+
168+
async function load(module, imports) {
169+
if (typeof Response === 'function' && module instanceof Response) {
170+
171+
if (typeof WebAssembly.instantiateStreaming === 'function') {
172+
try {
173+
return await WebAssembly.instantiateStreaming(module, imports);
174+
175+
} catch (e) {
176+
if (module.headers.get('Content-Type') != 'application/wasm') {
177+
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
178+
179+
} else {
180+
throw e;
181+
}
182+
}
183+
}
184+
185+
const bytes = await module.arrayBuffer();
186+
return await WebAssembly.instantiate(bytes, imports);
187+
188+
} else {
189+
190+
const instance = await WebAssembly.instantiate(module, imports);
191+
192+
if (instance instanceof WebAssembly.Instance) {
193+
return { instance, module };
194+
195+
} else {
196+
return instance;
197+
}
198+
}
199+
}
200+
201+
async function init(input) {
202+
const imports = {};
203+
imports.wbg = {};
204+
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
205+
throw new Error(getStringFromWasm0(arg0, arg1));
206+
};
207+
const { instance, module } = await load(await input, imports);
208+
209+
wasm = instance.exports;
210+
init.__wbindgen_wasm_module = module;
211+
212+
return wasm;
213+
}
214+
215+
export {
216+
Converter,
217+
ConverterBuild,
218+
init
219+
};

js/opencc-rust.mjs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Converter, ConverterBuild, init } from "./opencc-rust-lib.mjs"
2+
3+
const RESOURCES = {
4+
opencc_wasm: "https://cdn.jsdelivr.net/gh/polyproline/opencc-wasm@main/opencc_gc.wasm",
5+
HKVariants: "https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariants.txt",
6+
HKVariantsRev: "https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRev.txt",
7+
HKVariantsRevPhrases: "https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRevPhrases.txt",
8+
JPShinjitaiCharacters: "https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiCharacters.txt",
9+
JPShinjitaiPhrases: "https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiPhrases.txt",
10+
JPVariants: "https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariants.txt",
11+
JPVariantsRev: "https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariantsRev.txt",
12+
STCharacters: "https://cdn.jsdelivr.net/npm/opencc-data/data/STCharacters.txt",
13+
STPhrases: "https://cdn.jsdelivr.net/npm/opencc-data/data/STPhrases.txt",
14+
TSCharacters: "https://cdn.jsdelivr.net/npm/opencc-data/data/TSCharacters.txt",
15+
TSPhrases: "https://cdn.jsdelivr.net/npm/opencc-data/data/TSPhrases.txt",
16+
TWPhrasesIT: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesIT.txt",
17+
TWPhrasesName: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesName.txt",
18+
TWPhrasesOther: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesOther.txt",
19+
TWPhrasesRev: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesRev.txt",
20+
TWVariants: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariants.txt",
21+
TWVariantsRev: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRev.txt",
22+
TWVariantsRevPhrases: "https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRevPhrases.txt"
23+
};
24+
25+
const CONVERTION_MAP = {
26+
ToSimple: [
27+
["HKVariantsRevPhrases", "HKVariantsRev"],
28+
["TWPhrasesRev", "TWVariantsRevPhrases", "TWVariantsRev"],
29+
["TSPhrases", "TSCharacters"]
30+
],
31+
ToTraditional: [
32+
["TWVariantsRevPhrases", "TWVariantsRev"],
33+
["HKVariantsRevPhrases", "HKVariantsRev"],
34+
["JPShinjitaiPhrases", "JPShinjitaiCharacters", "JPVariantsRev"],
35+
["STPhrases", "STCharacters"]
36+
],
37+
ToTaiwan: [
38+
["STPhrases", "STCharacters"],
39+
"TWVariants",
40+
["TWPhrasesIT", "TWPhrasesName", "TWPhrasesOther"]
41+
],
42+
ToHongKong: [
43+
["STPhrases", "STCharacters"],
44+
"HKVariants"
45+
]
46+
};
47+
48+
const SELECTED_DICT = CONVERTION_MAP.ToTaiwan;
49+
50+
const wasm = await fetch(RESOURCES.opencc_wasm);
51+
await init(wasm);
52+
53+
const build = ConverterBuild.new();
54+
for (let dict of SELECTED_DICT) {
55+
if (Array.isArray(dict)) {
56+
for(let d of dict) {
57+
build.adddict(await fetch(RESOURCES[d]).then(response => response.text()));
58+
}
59+
} else {
60+
build.adddict(await fetch(RESOURCES[dict]).then(response => response.text()));
61+
}
62+
build.group();
63+
}
64+
65+
const converter = build.build();
66+
67+
export { converter };

0 commit comments

Comments
 (0)