Thân chào
Hiện tại theo tôi biết thì Ipad có 2 cách để gõ tiếng Việt:
1 là sử dụng các phần mềm gõ TV mua trên itunes như .VN: nhược điểm là phải mất phí, phải mua tài khoản ...
2 là bật một trang web có hỗ trợ gõ tiếng việt lên và type sau đó copy, paste. Nhược điểm là phải có mạng wifi thì mới làm được.
Tôi rất trông đợi một bộ gõ tiếng việt tích hợp trực tiếp trên keyboard để anh em có thể type ngay tại từng ứng dụng, cái này thì phải chờ vietnamese developer thôi.
Trong thời gian chờ đợi tôi đã tìm ra 1 phương pháp khắc phục được nhược điểm của 2 cách hiện tại. Đó là sử dụng js (javascript).
Hiện tại theo tôi biết thì Ipad có 2 cách để gõ tiếng Việt:
1 là sử dụng các phần mềm gõ TV mua trên itunes như .VN: nhược điểm là phải mất phí, phải mua tài khoản ...
2 là bật một trang web có hỗ trợ gõ tiếng việt lên và type sau đó copy, paste. Nhược điểm là phải có mạng wifi thì mới làm được.
Tôi rất trông đợi một bộ gõ tiếng việt tích hợp trực tiếp trên keyboard để anh em có thể type ngay tại từng ứng dụng, cái này thì phải chờ vietnamese developer thôi.
Trong thời gian chờ đợi tôi đã tìm ra 1 phương pháp khắc phục được nhược điểm của 2 cách hiện tại. Đó là sử dụng js (javascript).
Cách thức thực hiện như sau:
1. Copy toàn bộ đoạn code dưới đây vào Notepad, save lại thành file Unikey.htm (lưu ý khi save phần Save as type chọn All Type)
2. Sync file này vào Ipad qua các phần mềm hỗ trợ đọc htm. Tôi đã test ok trên ReaddleDocs và GoodReader.
3. Mở file này ra và gõ tiếng việt rất chuẩn. Gõ xong thì copy và paste thôi.
Tôi đã thử làm 1 button Select All và Copy All để copy nhanh nội dung bằng javascript nhưng chạy trên IE ở win7 thì OK, FF cũng ok nhưng đưa vào ipad thì ko hoạt động được. Bro nào thạo js thử nghiên cứu cùng tôi để phát triển ứng dụng này.
Ngoài ra tôi cũng đang tìm cách mở ứng dụng này bằng safari nhưng cũng chưa thành công. Nếu mở được thì sử dụng kèm với 1 app browser hỗ trợ 2 cửa sổ web là có thể type và paste khá dễ dàng. Hy vọng bro nào đó tiếp tục nghiên cứu theo hướng này và share cho ae
Bắt đầu copy từ đây:
Lưu ý: đã có bản cập nhật cho phép gõ tiếng việt telex, vni và viqr, xin xem bài của tôi ở trang 3
Code:
<html> <head> <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> <meta name="ProgId" content="FrontPage.Editor.Document"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Unikey</title> </head> <body onload="setTypingMode(1);" bgcolor="#FFFFCC"> <form name="myform" id="myform"> <textarea name="holdtext" id="holdtext" rows="38" cols="66" style="font-family:Arial; font-size:25px;" onKeyUp="initTyper(this);"></textarea> </form> <script language="JavaScript1.2" type="text/javascript"> var supported = (document.all || document.getElementById); var disabled = false; var charmapid = 1; var keymodeid = 0; var linebreak = 0; var theTyper = null; reset = function(){} initTyper = telexingVietUC; function setTypingMode(mode) { keymodeid = mode; if (theTyper) theTyper.keymode= initKeys(); if (!supported && !disabled) { alert("Xin loi, trinh duyet web cua ban khong cho phep dung VietTyping.\n"); disabled = true; } } initCharMap = function() { return new CVietUniCodeMap(); } initKeys = function() { switch (keymodeid) { case 1: return new CTelexKeys(); case 2: return new CVniKeys(); case 3: return new CViqrKeys(); case 4: return new CAllKeys(); default: return new CVKOff(); } } function telexingVietUC (txtarea) { txtarea.vietarea= true; txtarea.onkeyup= null; if (!supported) return; txtarea.onkeypress= vietTyping; txtarea.getCurrentWord= getCurrentWord; txtarea.replaceWord= replaceWord; txtarea.onkeydown= onKeyDown; txtarea.onmousedown= onMouseDown; if(!theTyper) theTyper = new CVietString(""); } function getEvt(evt) { if (typeof(evt)=='string') return evt.charCodeAt(0); return document.all? event.keyCode: (evt && evt.which)? evt.which: 0; } function onKeyDown(evt) { var c= getEvt(evt); if ((c==10) || (c==13)) { reset(1); linebreak= 1; } else if ((c<49) && (c!=16) && (c!=20)) { linebreak= 0; reset(c==32); } return true; } function onMouseDown(evt) { reset(0); linebreak= 0; return true; } function vietTyping(evt) { var c= getEvt(evt); theTyper.value= this.getCurrentWord(); var changed= ((c>32) && theTyper.typing(c)); if (changed) this.replaceWord(theTyper.value); return !changed; } function getCurrentWord() { if(!document.all) return this.value; var caret = this.document.selection.createRange(); if (caret.text) return null; var backward = -10; do { var caret2 = caret.duplicate(); caret2.moveStart("character", backward++); } while (caret2.parentElement() != this && backward <0); this.curword = caret2.duplicate(); return caret2.text; } function replaceWord(newword) { if(!document.all) { this.value= newword; return; } this.curword.text = newword; this.curword.collapse(false); } // end interface // "class": CVietString // function CVietString(str) { this.value= str; this.keymode= initKeys(); this.charmap= initCharMap(); this.ctrlchar= '-'; this.changed= 0; this.typing= typing; this.Compose= Compose; this.Correct= Correct; this.findCharToChange= findCharToChange; return this; } function typing(ctrl) { this.changed = 0; this.ctrlchar = String.fromCharCode(ctrl); if (linebreak) linebreak= 0; else this.keymode.getAction(this); this.Correct(); return this.changed; } function Compose(type) { if(!this.value) return; var info = this.findCharToChange(type); if (!info || !info[0]) return; var telex; if (info[0]=='\\') telex= [1,this.ctrlchar,1]; else if (type>6) telex= this.charmap.getAEOWD(info[0], type, info[3]); else telex= this.charmap.getDau(info[0], type); if (!(this.changed = telex[0])) return; this.value = this.value.replaceAt(info[1],telex[1],info[2]); if (!telex[2]) { spellerror= 1; this.value+= this.ctrlchar; } } function Correct() { if (this.charmap.maxchrlen || !document.all) return 0; var tmp= this.value; if ('nNcC'.indexOf(this.ctrlchar)>=0) tmp+= this.ctrlchar; var er= /[^\x01-\x7f](hn|hc|gn)$/i.exec(tmp); if (er) { this.value= tmp.substring(0,tmp.length-2)+er[1].charAt(1)+er[1].charAt(0); this.changed= 1; } else if(!this.changed) return 0; er= /\w([^\x01-\x7f])(\w*)([^\x01-\x7f])\S*$/.exec(this.value); if (!er) return 0; var i= this.charmap.isVowel(er[1]); var ri= (i-1)%24 + 1, ci= (i-ri)/24; var i2= this.charmap.isVowel(er[3]); if (!ci || !i2) return 0; var ri2= (i2-1)%24 + 1, ci2= (i2-ri2)/24; var nc= this.charmap.charAt(ri)+ er[2]+ this.charmap.charAt(ci*24+ri2); this.value= this.value.replace(new RegExp(er[1]+er[2]+er[3],'g'), nc); } function findCharToChange(type) { var lastchars= this.charmap.lastCharsOf(this.value, 5); var i= 0, c=lastchars[0][0], chr=0; if (c=='\\') return [c,this.value.length-1,1]; if (type==15) while (!(chr=this.charmap.isVD(c))) { if ((c < 'A') || (i>=4) || !(c=lastchars[++i][0])) return null; } else while( "cghmnptCGHMNPT".indexOf(c)>=0) { if ((c < 'A') || (i>=2) || !(c=lastchars[++i][0])) return null; } c = lastchars[0][0].toLowerCase(); var pc = lastchars[1][0].toLowerCase(); var ppc = lastchars[2][0].toLowerCase(); if (i==0 && type!=15) { if ( (chr=this.charmap.isVowel(lastchars[1][0])) && ("uyoia".indexOf(c)>=0) && !this.charmap.isUO(pc,c) && !((pc=='o' && c=='a') || (pc=='u' && c=='y')) && !((ppc=='q' && pc=='u') || (ppc=='g' && pc=='i')) ) ++i; if (c=='a' && (type==9 || type==7)) i= 0; } c= lastchars[i][0]; if ((i==0 || chr==0) && type!=15) chr= this.charmap.isVowel(c); if (!chr) return null; var clen= lastchars[i][1], isuo=0; if ((i>0) && (type==7 || type==8 || type==11)) { isuo=this.charmap.isUO(lastchars[i+1][0],c); if (isuo) { chr=isuo; clen+=lastchars[++i][1]; isuo=1; } } var pos= this.value.length; for (var j=0; j<= i; j++) pos -= lastchars[j][1]; return [chr, pos, clen, isuo]; } // end CVietString // character-map template // function CVietCharMap(){ this.vietchars = null; this.length = 149; this.chr_cache = new Array(20); this.ind_cache = new Array(20); this.cptr = 0; this.caching= function(chr, ind) { this.chr_cache[this.cptr] = chr; this.ind_cache[this.cptr++] = ind; this.cptr %= 20; } return this; } CVietCharMap.prototype.charAt= function(ind){ var chrcode = this.vietchars[ind]; return chrcode ? String.fromCharCode(chrcode) : null; } CVietCharMap.prototype.isVowel= function(chr){ var i = 0; while ((i<20) && (chr != this.chr_cache[i])) ++i; if (i<20) return this.ind_cache[i]; i = this.length-5; while ((chr != this.charAt(i)) && i) --i; this.caching(chr, i); return i; } CVietCharMap.prototype.isVD= function (chr){ var ind = this.length-5; while ((chr != this.charAt(ind)) && (ind < this.length)) ++ind; return (ind<this.length)? ind: 0; } CVietCharMap.prototype.isUO= function (c1, c2){ if (!c1 || !c2) return 0; var ind1 = this.isVowel(c1); var ci = (ind1-1)%12; if ((ci!=9) && (ci!=10)) return 0; var ind2 = this.isVowel(c2); ci = (ind2-1)%12; if ((ci!=6) && (ci!=7) && (ci!=8)) return 0; return [ind1,ind2]; } CVietCharMap.prototype.getDau= function (ind, type){ var accented= (ind < 25)? 0: 1; var ind_i= (ind-1) % 24 +1; var charset= (type == 6)? 0 : type; if ((type== 6) && !accented) return [0]; var newind= charset*24 + ind_i; if (newind == ind) newind= ind_i; var chr= this.charAt(newind); if (!chr) chr= this.lowerCaseOf(0,newind); return [1, chr, newind>24 || type==6]; } var map=[ [7,7,7,8,8, 8,9,10,11,15], [0,3,6,0,6, 9,0, 3, 6, 0], [1,4,7,2,8,10,1, 4, 7, 1] ]; CVietCharMap.prototype.getAEOWD= function(ind, type, isuo) { var c=0, i1=isuo? ind[0]: ind; var vc1= (type==15)? (i1-1)%2 : (i1-1)%12; if (isuo) { var base= ind[1]-(ind[1]-1)%12; if (type==7 || type==11) c= this.charAt(i1-vc1+9)+this.charAt(base+7); else if (type==8) c= this.charAt(i1-vc1+10)+this.charAt(base+8); return [c!=0, c, 1]; } var i= -1, shift= 0, del= 0; while (shift==0 && ++i<map[0].length) { if (map[0][i]==type) { if(map[1][i]==vc1) shift= map[2][i]-vc1; else if(map[2][i]==vc1) shift= map[1][i]-vc1; } } if (shift==0) { if (type==7 && (vc1==2 || vc1==8)) shift=-1; else if ((type==9 && vc1==2) || (type==11 && vc1==8)) shift=-1; else if (type==8 && (vc1==1 || vc1==7)) shift=1; del= 1; } else del=(shift>0); i1 += shift; var chr= this.charAt(i1); if (i1<145) this.caching(chr, i1); if (!chr) chr= this.lowerCaseOf(0, i1); return [shift!=0, chr, del]; } CVietCharMap.prototype.lastCharsOf= function(str, num){ if (!num) return [str.charAt(str.length-1),1]; var vchars = new Array(num); for (var i=0; i< num; i++) { vchars[i]= [str.charAt(str.length-i-1),1]; } return vchars; } // end CVietCharMap prototype String.prototype.replaceAt= function(i,newchr,clen){ return this.substring(0,i)+ newchr + this.substring(i+clen); } // output map: class CVietUniCodeMap // function CVietUniCodeMap(){ var map= new CVietCharMap(); map.vietchars = new Array( "UNICODE", 97, 226, 259, 101, 234, 105, 111, 244, 417, 117, 432, 121, 65, 194, 258, 69, 202, 73, 79, 212, 416, 85, 431, 89, 225, 7845, 7855, 233, 7871, 237, 243, 7889, 7899, 250, 7913, 253, 193, 7844, 7854, 201, 7870, 205, 211, 7888, 7898, 218, 7912, 221, 224, 7847, 7857, 232, 7873, 236, 242, 7891, 7901, 249, 7915, 7923, 192, 7846, 7856, 200, 7872, 204, 210, 7890, 7900, 217, 7914, 7922, 7841, 7853, 7863, 7865, 7879, 7883, 7885, 7897, 7907, 7909, 7921, 7925, 7840, 7852, 7862, 7864, 7878, 7882, 7884, 7896, 7906, 7908, 7920, 7924, 7843, 7849, 7859, 7867, 7875, 7881, 7887, 7893, 7903, 7911, 7917, 7927, 7842, 7848, 7858, 7866, 7874, 7880, 7886, 7892, 7902, 7910, 7916, 7926, 227, 7851, 7861, 7869, 7877, 297, 245, 7895, 7905, 361, 7919, 7929, 195, 7850, 7860, 7868, 7876, 296, 213, 7894, 7904, 360, 7918, 7928, 100, 273, 68, 272); return map; } // input methods: class C...Keys function CVietKeys() { this.getAction= function(typer){ var i= this.keys.indexOf(typer.ctrlchar.toLowerCase()); if(i>=0) typer.Compose(this.actions[i]); } return this; } function CVKOff() { this.off = true; this.getAction= function(){}; return this; } function CTelexKeys() { var k= new CVietKeys(); k.keys= "sfjrxzaeowd"; k.actions= [1,2,3,4,5,6,9,10,11,8,15]; k.istelex= true; return k; } function CVniKeys() { var k= new CVietKeys(); k.keys= "0123456789"; k.actions= [6,1,2,4,5,3,7,8,8,15]; return k; } function CViqrKeys() { var k= new CVietKeys(); k.keys= "\xB4/'\u2019`.?~-^(*+d"; k.actions= [1,1,1,1,2,3,4,5,6,7,8,8,8,15]; return k; } function CAllKeys() { var k= new CVietKeys(); k.keys= "sfjrxzaeowd0123456789\xB4/'`.?~-^(*+d"; k.actions= [1,2,3,4,5,6,9,10,11,8,15,6,1,2,4,5,3,7,8,8,15,1,1,1,2,3,4,5,6,7,8,8,8,15]; k.istelex= true; return k; } // end vietuni.js </script> </body> </html>
Quảng cáo