オーストラリア人の作った日英辞書であるedictは24万語、10MB程度ある。
データは直列で記述されている。
http://www.edrdg.org/jmdict/edict.html
建久 [けんきゅう] /(n) Kenkyu era (1190.4.11-1199.4.27)/
正治 [しょうじ] /(n) Shoji era (1199.4.27-1201.2.13)/
文治 [ぶんじ] /(n) (1) civil administration/(2) Bunji era (1185.8.14-1190.4.11)/
オリジナルはEUC。そのままfetchをすると文字化けする。UTF8に変換する。
検索条件はindexOfのあいまい検索。大文字小文字も区別せず。
let _word =word.toLowerCase(),ret=o.data.filter(d=>~d.toLowerCase().indexOf(_word))
表示側、セレクトを通知する。セレクトした文字を取得する。
element.onselect =function(ev){
let text=window.getSelection().toString()
}
全部
/*
license: http://www.edrdg.org/jmdict/edict.html
edict.set({url:'https://gnjo.github.io/edictutf8',caller:a,max:20}).load()
edict.one(word).then(d=>console.log(d)); //one is a string
edict.lex(word).then(d=>console.log(d)); //lex is data array
*/
;(function(root){
let o={};
o.data=null;
o.url='https://gnjo.github.io/edictutf8'
o.max=50;
o.caller=(obj=>obj)
o.set=(obj=>{Object.assign(o,obj);return o})
o.load=(word)=>{return new Promise(sol=>{
if(o.data) return sol(word);
return fetch(o.url).then(d=>d.text())
.then(d=>{
o.data=d.split('\n');
o.caller({type:'load',ret:o.data.length,word:word})
return sol(word)
})
;
})}
o._calc=(word,type)=>{return new Promise(sol=>{
let _word =word.toLowerCase(),ret=o.data.filter(d=>~d.toLowerCase().indexOf(_word))
ret=(type==='one')?ret.slice(0,1).toString():ret.slice(0,o.max)
o.caller({type:type,ret:ret,word:word})
return sol(ret);
})}
o.one=(word=>(!o.data)?o.load(word).then(o.one):o._calc(word,'one'))
o.lex=(word=>(!o.data)?o.load(word).then(o.lex):o._calc(word,'lex'))
;
root.edict =o;
})(this);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<div class="f"><textarea class="l"></textarea><textarea class="r"></textarea></div>
<style>
.f{width:100%;height:90vh;display:flex;flex-direction:row}
.f>*{width:50%;height:100%;outline:none;resize:none}
</style>
var fn={},_=window._,edict=window.edict;
fn.q=(d=>document.querySelector(d))
;
let sel=fn.q('.l'),ret=fn.q('.r')
,select=function(ev){
Promise.resolve(window.getSelection().toString())
.then(edict.lex)
.then(d=>{ ret.value=d.join('\n');return d})
//.then(edict.one)
//.then(d=>{ ret.value=d;return d})
;
}
,caller=(ev)=>{ console.log(ev) }
;
sel.onselect=_.debounce(select,200)
edict.set({url:'https://gnjo.github.io/edictutf8',caller:caller,max:20}).load()
//edict.set({caller:caller}).load()
;
追記。24万語の検索は時間がかかるので、webWorker版に。
<div class="f"><textarea class="l"></textarea><textarea class="r"></textarea></div>
<style>
.f{width:100%;height:90vh;display:flex;flex-direction:row}
.f>*{width:50%;height:100%;outline:none;resize:none}
</style>
<script type="text/plain" id="edict">
;(function(root){
let o={};
...
root.edict =o;
})(this)
;
onmessage=function(e){edict[e.data.key].apply(this,e.data.args).then(postMessage)}
</script>
var fn={}
fn.q=(d=>document.querySelector(d))
fn.gsl=(()=>window.getSelection().toString())
fn.worker=(src)=>{
//inner.js or text or element
let is={},f=(d=>URL.createObjectURL(new Blob( [d], {type:"text\/javascript"} )));
is.element=function(o){return !!(o && o.nodeType === 1)};
is.url=(d=>!/\n|;/.test(d));
return new Worker( is.element(src)?f(src.textContent):is.url(src)?src:f(src) );
}
;
let sel=fn.q('.l'),ret=fn.q('.r'),w=fn.worker(fn.q('#edict'))
;
sel.onselect=function(ev){ w.postMessage({key:'lex',args:[fn.gsl()]}) }
w.onmessage=function(ev){ ret.textContent = ev.data.join('\n') }