mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
translator: per segment translation method selection
This commit is contained in:
@@ -50,10 +50,11 @@ td.options { padding: 1ex 1em; }
|
|||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
td.options > div, td.actions > div { position: relative; margin: 0; }
|
td.options > div, td.actions > div { position: relative; margin: 0; }
|
||||||
td.options:hover > div > dl,td.actions:hover > div > dl { display: block; }
|
td.options:hover > div > form > dl,td.actions:hover > div > dl {
|
||||||
td.options > div > dl, td.actions > div > dl {
|
display: block;
|
||||||
left: 0.8em;
|
}
|
||||||
padding: 0.6ex;
|
td.options > div > form > dl, td.actions > div > dl {
|
||||||
|
left: 1em;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -77,6 +78,8 @@ table.paralleltexts td.target { padding-left: 0.7em; }
|
|||||||
|
|
||||||
label { font-family: sans-serif; }
|
label { font-family: sans-serif; }
|
||||||
|
|
||||||
|
form { margin: 0; }
|
||||||
|
|
||||||
form.import {
|
form.import {
|
||||||
min-width: 90%; /* extend to availiable width for Safari */
|
min-width: 90%; /* extend to availiable width for Safari */
|
||||||
/*background: #eee;*/
|
/*background: #eee;*/
|
||||||
|
|||||||
@@ -3,21 +3,23 @@
|
|||||||
/* --- Translator object ---------------------------------------------------- */
|
/* --- Translator object ---------------------------------------------------- */
|
||||||
|
|
||||||
function Translator() {
|
function Translator() {
|
||||||
this.local=tr_local();
|
var t=this
|
||||||
this.view=element("document")
|
t.local=tr_local();
|
||||||
|
t.view=element("document")
|
||||||
if(!supports_html5_storage()) {
|
if(!supports_html5_storage()) {
|
||||||
var warning=span_class("error",text("It appears that localStorage is unsupported or disabled in this browser. Documents will not be preserved after you leave or reload this page!"))
|
var warning=span_class("error",text("It appears that localStorage is unsupported or disabled in this browser. Documents will not be preserved after you leave or reload this page!"))
|
||||||
insertAfter(warning,this.view)
|
insertAfter(warning,t.view)
|
||||||
}
|
}
|
||||||
this.current=this.local.get("current")
|
t.current=t.local.get("current")
|
||||||
this.document=this.current && this.current!="/" && this.local.get("/"+this.current) || empty_document()
|
t.document=t.current && t.current!="/" && t.local.get("/"+t.current) || empty_document()
|
||||||
this.server=pgf_online({})
|
t.servers={}; //The API is stateful, use one pgf_online object per grammar
|
||||||
this.server.get_grammarlist(bind(this.extend_methods,this))
|
t.grammar_info={};
|
||||||
update_language_menu(this,"source")
|
pgf_online({}).get_grammarlist(bind(t.extend_methods,t))
|
||||||
update_language_menu(this,"target")
|
update_language_menu(t,"source")
|
||||||
if(apertium) this.add_apertium()
|
update_language_menu(t,"target")
|
||||||
|
if(apertium) t.add_apertium()
|
||||||
//initialize_sorting(["TR"],["segment"])
|
//initialize_sorting(["TR"],["segment"])
|
||||||
this.redraw();
|
t.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_language_menu(t,id) {
|
function update_language_menu(t,id) {
|
||||||
@@ -37,25 +39,34 @@ Translator.prototype.redraw=function() {
|
|||||||
clear(t.view)
|
clear(t.view)
|
||||||
appendChildren(t.view,t.drawing.doc)
|
appendChildren(t.view,t.drawing.doc)
|
||||||
var o=t.document.options
|
var o=t.document.options
|
||||||
update_radiobutton("method",o.method)
|
var form=document.forms.options
|
||||||
update_radiobutton("source",o.from)
|
update_radiobutton(form,"method",o.method)
|
||||||
update_radiobutton("target",o.to)
|
update_radiobutton(form,"source",o.from)
|
||||||
update_radiobutton("view",o.view || "segmentbysegment")
|
update_radiobutton(form,"target",o.to)
|
||||||
|
update_radiobutton(form,"view",o.view || "segmentbysegment")
|
||||||
update_checkbox("cloud",o.cloud || false)
|
update_checkbox("cloud",o.cloud || false)
|
||||||
switch(o.method) {
|
t.update_language_menus()
|
||||||
case "Manual":
|
t.update_translations()
|
||||||
case "Apertium":
|
}
|
||||||
t.update_language_menus()
|
}
|
||||||
t.update_translations()
|
|
||||||
break;
|
Translator.prototype.switch_grammar=function(grammar,cont) {
|
||||||
default: // GF
|
var t=this
|
||||||
|
var gi=t.grammar_info[grammar]
|
||||||
|
if(gi) cont(gi)
|
||||||
|
else {
|
||||||
|
var pgf=t.servers[grammar]
|
||||||
|
if(pgf) pgf.waiting.push(cont)
|
||||||
|
else {
|
||||||
|
pgf=t.servers[grammar]=pgf_online({})
|
||||||
|
pgf.waiting=[cont]
|
||||||
function cont2(gr_info) {
|
function cont2(gr_info) {
|
||||||
t.grammar_info=gr_info
|
t.grammar_info[grammar]=gr_info
|
||||||
t.update_language_menus() // needs grammar_info
|
console.log("Passing grammar info for "+grammar+" to "+pgf.waiting.length+" clients")
|
||||||
t.update_translations()
|
while(pgf.waiting.length>0) pgf.waiting.pop()(gr_info)
|
||||||
}
|
}
|
||||||
function cont1() { t.server.grammar_info(cont2)}
|
function cont1() { pgf.grammar_info(cont2)}
|
||||||
t.server.switch_grammar(o.method,cont1)
|
pgf.switch_grammar(grammar,cont1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,15 +102,18 @@ Translator.prototype.update_language_menus=function() {
|
|||||||
mark_menus(ssupport,tsupport)
|
mark_menus(ssupport,tsupport)
|
||||||
break;
|
break;
|
||||||
default: // GF
|
default: // GF
|
||||||
var supported=bind(t.gf_supported,t)
|
function cont() {
|
||||||
mark_menus(supported,supported)
|
function gfsupport(code) { return t.gf_supported(o.method,code) }
|
||||||
|
mark_menus(gfsupport,gfsupport)
|
||||||
|
}
|
||||||
|
t.switch_grammar(o.method,cont)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator.prototype.gf_supported=function(langcode) {
|
Translator.prototype.gf_supported=function(grammar,langcode) {
|
||||||
var t=this;
|
var t=this;
|
||||||
var concname=t.grammar_info.name+langcode
|
var concname=t.grammar_info[grammar].name+langcode
|
||||||
var l=t.grammar_info.languages
|
var l=t.grammar_info[grammar].languages
|
||||||
for(var i in l) if(l[i].name==concname) return true
|
for(var i in l) if(l[i].name==concname) return true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -125,17 +139,17 @@ Translator.prototype.update_translations=function() {
|
|||||||
ts[i].appendChild(text(segment.target+" "))
|
ts[i].appendChild(text(segment.target+" "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function update_segment(i,txts) {
|
function update_segment(m,i,txts) {
|
||||||
var segment=ss[i]
|
var segment=ss[i]
|
||||||
segment.target=txts[0];
|
segment.target=txts[0];
|
||||||
segment.options={method:o.method,from:o.from,to:o.to} // no sharing!
|
segment.options={method:m,from:o.from,to:o.to} // no sharing!
|
||||||
if(txts.length>1) segment.choices=txts
|
if(txts.length>1) segment.choices=txts
|
||||||
else delete segment.choices
|
else delete segment.choices
|
||||||
replace(i)
|
replace(i)
|
||||||
}
|
}
|
||||||
function update_apertium_translation(i,afrom,ato) {
|
function update_apertium_translation(i,afrom,ato) {
|
||||||
var segment=ss[i]
|
var segment=ss[i]
|
||||||
function upd3(txts) { update_segment(i,txts) }
|
function upd3(txts) { update_segment("Apertium",i,txts) }
|
||||||
function upd1(res) {
|
function upd1(res) {
|
||||||
//console.log(translate_output)
|
//console.log(translate_output)
|
||||||
if(res.translation) upd3([res.translation])
|
if(res.translation) upd3([res.translation])
|
||||||
@@ -143,17 +157,16 @@ Translator.prototype.update_translations=function() {
|
|||||||
}
|
}
|
||||||
function upd0(source) { apertium.translate(source,afrom,ato,upd1) }
|
function upd0(source) { apertium.translate(source,afrom,ato,upd1) }
|
||||||
if(apertium.isTranslatablePair(afrom,ato)) {
|
if(apertium.isTranslatablePair(afrom,ato)) {
|
||||||
if(segment.options.method!="Manual"
|
if(!eq_options(segment.options,o)) upd0(segment.source)
|
||||||
&& !eq_options(segment.options,o))
|
|
||||||
upd0(segment.source)
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
upd3(["[Apertium does not support "+show_translation(o)+"]"])
|
upd3(["[Apertium does not support "+show_translation(o)+"]"])
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_gf_translation(i,gfrom,gto) {
|
function update_gf_translation(i,grammar,gfrom,gto) {
|
||||||
var segment=ss[i]
|
var segment=ss[i]
|
||||||
function upd3(txts) { update_segment(i,txts) }
|
var server=t.servers[grammar]
|
||||||
|
function upd3(txts) { update_segment(grammar,i,txts) }
|
||||||
function upd2(ts) {
|
function upd2(ts) {
|
||||||
function unlex(txt,cont) { gfshell('ps -unlextext "'+txt+'"',cont) }
|
function unlex(txt,cont) { gfshell('ps -unlextext "'+txt+'"',cont) }
|
||||||
|
|
||||||
@@ -167,14 +180,17 @@ Translator.prototype.update_translations=function() {
|
|||||||
upd2(collect_texts(translate_output[0].translations))
|
upd2(collect_texts(translate_output[0].translations))
|
||||||
}
|
}
|
||||||
function upd0(source) {
|
function upd0(source) {
|
||||||
t.server.translate({from:gfrom,to:gto,input:source},upd1)
|
server.translate({from:gfrom,to:gto,input:source},upd1)
|
||||||
}
|
}
|
||||||
var fls=t.gf_supported(o.from)
|
var fls=t.gf_supported(grammar,o.from)
|
||||||
var tls=t.gf_supported(o.to)
|
var tls=t.gf_supported(grammar,o.to)
|
||||||
if(fls && tls) {
|
if(fls && tls) {
|
||||||
if(segment.options.method!="Manual"
|
var want={from:o.from, to:o.to, method:grammar}
|
||||||
&& !eq_options(segment.options,o))
|
if(!eq_options(segment.options,want)) {
|
||||||
|
console.log("Updating "+i)
|
||||||
gfshell('ps -lextext "'+segment.source+'"',upd0)
|
gfshell('ps -lextext "'+segment.source+'"',upd0)
|
||||||
|
}
|
||||||
|
else if(i==0) console.log("No update ",want,segment.options)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var fn=concname(o.from)
|
var fn=concname(o.from)
|
||||||
@@ -182,43 +198,64 @@ Translator.prototype.update_translations=function() {
|
|||||||
var unsup=" is not supported by the grammar"
|
var unsup=" is not supported by the grammar"
|
||||||
var sup=" is supported by the grammar"
|
var sup=" is supported by the grammar"
|
||||||
var msg= fls ? tn+unsup : tls ? fn+unsup :
|
var msg= fls ? tn+unsup : tls ? fn+unsup :
|
||||||
"Neither "+fn+" nor "+tn+sup
|
"Neither "+fn+" nor "+tn+sup
|
||||||
upd3(["["+msg+"]"])
|
upd3(["["+msg+"]"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(doc.options.method) {
|
for(var i in ss) {
|
||||||
case "Manual":
|
var m= ss[i].options.method || doc.options.method
|
||||||
break;
|
var d=ss[i].use_default
|
||||||
case "Apertium":
|
if(d || d==null) m=doc.options.method
|
||||||
var afrom=alangcode(o.from)
|
switch(m) {
|
||||||
var ato=alangcode(o.to)
|
case "Manual":
|
||||||
for(var i in ss) update_apertium_translation(i,afrom,ato)
|
console.log("Manual "+i)
|
||||||
break;
|
break;
|
||||||
default: // GF
|
case "Apertium":
|
||||||
var gname=t.grammar_info.name
|
var afrom=alangcode(o.from)
|
||||||
var gfrom=gname+o.from
|
var ato=alangcode(o.to)
|
||||||
var gto=gname+o.to
|
update_apertium_translation(i,afrom,ato)
|
||||||
for(var i in ss) update_gf_translation(i,gfrom,gto)
|
break;
|
||||||
|
default: // GF
|
||||||
|
function capture(i,m) { // Capture current values of loop variables
|
||||||
|
function upd00(grammar_info) {
|
||||||
|
var gname=grammar_info.name
|
||||||
|
console.log("Got grammar info "+gname+" for "+i)
|
||||||
|
var gfrom=gname+o.from
|
||||||
|
var gto=gname+o.to
|
||||||
|
update_gf_translation(i,m,gfrom,gto)
|
||||||
|
}
|
||||||
|
t.switch_grammar(m,upd00)
|
||||||
|
}
|
||||||
|
capture(i,m)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator.prototype.add_apertium=function() {
|
Translator.prototype.add_apertium=function() {
|
||||||
var dl=element("methods")
|
var dl=element("methods")
|
||||||
if(dl)
|
if(dl) add_apertium_to_menu(dl,bind(this.change,this))
|
||||||
dl.appendChild(dt(radiobutton("method","Apertium","Apertium",
|
}
|
||||||
bind(this.change,this))))
|
|
||||||
|
function add_apertium_to_menu(dl,action) {
|
||||||
|
dl.appendChild(dt(radiobutton("method","Apertium","Apertium",action)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator.prototype.extend_methods=function(grammars) {
|
Translator.prototype.extend_methods=function(grammars) {
|
||||||
this.grammars=grammars
|
this.grammars=grammars
|
||||||
var dl=element("methods")
|
var dl=element("methods")
|
||||||
|
if(dl) this.extend_methods_menu(dl,bind(this.change,this))
|
||||||
|
update_radiobutton(document.forms.options,"method",this.document.options.method)
|
||||||
|
this.redraw()
|
||||||
|
}
|
||||||
|
|
||||||
|
Translator.prototype.extend_methods_menu=function(dl,action) {
|
||||||
|
var grammars=this.grammars
|
||||||
if(dl) for(var i in grammars) {
|
if(dl) for(var i in grammars) {
|
||||||
dl.appendChild(dt(radiobutton("method",grammars[i],
|
dl.appendChild(dt(radiobutton("method",grammars[i],
|
||||||
"GF: "+grammars[i],
|
"GF: "+grammars[i],
|
||||||
bind(this.change,this))))
|
action)))
|
||||||
}
|
}
|
||||||
update_radiobutton("method",this.document.options.method)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Translator.prototype.change=function(el) {
|
Translator.prototype.change=function(el) {
|
||||||
@@ -642,22 +679,33 @@ function draw_choices(txts,onclick) {
|
|||||||
Translator.prototype.draw_segment_given_target=function(s,target,i) {
|
Translator.prototype.draw_segment_given_target=function(s,target,i) {
|
||||||
var t=this
|
var t=this
|
||||||
|
|
||||||
function draw_options2(o) {
|
function draw_options2() {
|
||||||
|
var o=s.options
|
||||||
function change(el) {
|
function change(el) {
|
||||||
o.method=el.value // side effect, updating the document in-place
|
s.use_default = el.value=="Default"
|
||||||
t.update_translations()
|
var m = s.use_default ? t.document.options.method : el.value
|
||||||
|
if(m!=o.method) {
|
||||||
|
o.method=m // side effect, updating the document in-place
|
||||||
|
o.to="" // hack to force an update
|
||||||
|
console.log("Method changed to "+m)
|
||||||
|
t.update_translations()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var manual=o.method=="Manual"
|
var autoB=radiobutton("method","Default","Default",change)
|
||||||
var autoB=radiobutton("method","Auto","Auto",change,!manual)
|
var manualB=radiobutton("method","Manual","Manual",change)
|
||||||
var manualB=radiobutton("method","Manual","Manual",change,manual)
|
var dl=wrap_class("dl","popupmenu",
|
||||||
return wrap("form",
|
[dt(autoB),
|
||||||
[dt(autoB),
|
dt([manualB,text(" "),draw_translation(o)])])
|
||||||
dt(manualB),
|
if(apertium) add_apertium_to_menu(dl,change)
|
||||||
dt(draw_translation(o))])
|
t.extend_methods_menu(dl,change)
|
||||||
|
var form=wrap("form",dl)
|
||||||
|
var d = s.use_default
|
||||||
|
var m = d || d==null ? "Default" : o.method || "Default"
|
||||||
|
update_radiobutton(form,"method",m)
|
||||||
|
return form
|
||||||
}
|
}
|
||||||
function draw_options(o) {
|
function draw_options() {
|
||||||
return wrap("div",[span_class("arrow",text(" ⇒ ")),
|
return wrap("div",[span_class("arrow",text(" ⇒ ")),draw_options2()])
|
||||||
wrap("dl",draw_options2(o))])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var insertB=dt(text("Insert a new segment"))
|
var insertB=dt(text("Insert a new segment"))
|
||||||
@@ -670,7 +718,7 @@ Translator.prototype.draw_segment_given_target=function(s,target,i) {
|
|||||||
[insertB,removeB])]))
|
[insertB,removeB])]))
|
||||||
var source=wrap_class("td","source",text(s.source))
|
var source=wrap_class("td","source",text(s.source))
|
||||||
source.onclick=function() { t.edit_source(source,i); }
|
source.onclick=function() { t.edit_source(source,i); }
|
||||||
var options=wrap_class("td","options",draw_options(s.options))
|
var options=wrap_class("td","options",draw_options())
|
||||||
|
|
||||||
return node("tr",{"class":"segment",id:i},[actions,source,options,target])
|
return node("tr",{"class":"segment",id:i},[actions,source,options,target])
|
||||||
}
|
}
|
||||||
@@ -825,8 +873,8 @@ function radiobutton(name,value,label,change,checked) {
|
|||||||
return wrap("label",[b,text(label)])
|
return wrap("label",[b,text(label)])
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_radiobutton(name,value) {
|
function update_radiobutton(form,name,value) {
|
||||||
var bs=document.forms.options[name]
|
var bs=form[name]
|
||||||
if(bs.length)
|
if(bs.length)
|
||||||
for(var i in bs) if(bs[i].value==value) bs[i].checked=true
|
for(var i in bs) if(bs[i].value==value) bs[i].checked=true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user