diff --git a/src/www/translator/about.html b/src/www/translator/about.html
index b5d17f11e..7fb8ee0e9 100644
--- a/src/www/translator/about.html
+++ b/src/www/translator/about.html
@@ -23,14 +23,20 @@ target language. Imported text can be segmented based on punctuation.
Optionally, one can also use line breaks or blank lines to indicate segmentation
in imported text. Text can be edited after it has been imported.
+
+Through menu options, the user sets the source and target language
+for the document and chooses which translation method to use by default.
+The tool supports two machine translation services:
+
+ - The GF web service.
+ The user picks which GF grammar to use from a menu of available grammars.
+
- The Apertium web service.
+
+
If an unsatisfactory automatic translation is
obtained, the user can click on it and replace it with a manual translation.
If multiple translations are obtained, one of them is shown by default and
the other ones are available in a popup menu.
-
-The GF web service is used for automatic translation. The user picks which
-grammar to use from a menu of available grammars. Through menu options,
-the user also sets the source and target language for the document.
The tool handles a set of documents. Documents can be named, saved,
@@ -46,8 +52,8 @@ closed and reopened later. Documents can be saved locally or in the cloud.
Document sharing in the cloud.
Interface to other translation services.
Interface to the grammar editor for grammar extension.
- More browser compatibility testing (Chrome, Firefox & Safari tested
- so far).
+ More browser compatibility testing (Chrome, Firefox, Safari &
+ Opera Mobile tested so far).
...
...
@@ -55,7 +61,7 @@ closed and reopened later. Documents can be saved locally or in the cloud.
- Last modified: Tue Jun 12 17:32:46 CEST 2012
+ Last modified: Wed Jun 13 23:28:06 CEST 2012
TH
diff --git a/src/www/translator/index.html b/src/www/translator/index.html
index 03264ebd5..b6771f3c8 100644
--- a/src/www/translator/index.html
+++ b/src/www/translator/index.html
@@ -71,7 +71,7 @@
HMTL
- Last modified: Tue Jun 12 16:08:01 CEST 2012
+ Last modified: Wed Jun 13 20:21:22 CEST 2012
About
@@ -80,6 +80,7 @@
+
diff --git a/src/www/translator/translator.css b/src/www/translator/translator.css
index 57902ebc3..0f4e328ca 100644
--- a/src/www/translator/translator.css
+++ b/src/www/translator/translator.css
@@ -27,6 +27,8 @@ table.menubar td:hover, table.menubar dt:hover, dl.popupmenu > dt:hover {
}
table table dl { left: 6em; }
table.menubar dt { white-space: nowrap; }
+dt.unsupported { color: #999; }
+
div.document {
/*margin-top: 7ex;*/
clear: both;
diff --git a/src/www/translator/translator.js b/src/www/translator/translator.js
index 04c5b19f3..800db6611 100644
--- a/src/www/translator/translator.js
+++ b/src/www/translator/translator.js
@@ -15,6 +15,7 @@ function Translator() {
this.server.get_grammarlist(bind(this.extend_methods,this))
update_language_menu(this,"source")
update_language_menu(this,"target")
+ if(apertium) this.add_apertium()
this.redraw();
}
@@ -23,7 +24,7 @@ function update_language_menu(t,id) {
clear(dl);
for(var i in languages) {
var l=languages[i]
- dl.appendChild(wrap("dt",radiobutton(id,l.code,l.name,bind(t.change,t))))
+ dl.appendChild(dt(radiobutton(id,l.code,l.name,bind(t.change,t))))
}
}
@@ -40,19 +41,68 @@ Translator.prototype.redraw=function() {
update_radiobutton("target",o.to)
update_radiobutton("view",o.view || "segmentbysegment")
update_checkbox("cloud",o.cloud || false)
- if(o.method!="Manual") {
+ switch(o.method) {
+ case "Manual":
+ case "Apertium":
+ t.update_language_menus()
+ t.update_translations()
+ break;
+ default: // GF
function cont2(gr_info) {
t.grammar_info=gr_info
+ t.update_language_menus() // needs grammar_info
t.update_translations()
}
function cont1() { t.server.grammar_info(cont2)}
t.server.switch_grammar(o.method,cont1)
}
- else
- t.update_translations()
}
}
+Translator.prototype.update_language_menus=function() {
+ var t=this
+ var o=t.document.options
+ var method=o.method+(o.method=="Apertium"?"/"+o.from:"")
+ if(t.menus_for==method) return;
+ t.menus_for=method
+ function mark_menu(name,supported) {
+ var menu=document.forms.options[name]
+ for(var i=0;i1) segment.choices=txts
else delete segment.choices
- replace()
+ replace(i)
+ }
+ function upd1(res) {
+ //console.log(translate_output)
+ if(res.translation) upd3([res.translation])
+ else upd3(["["+res.error.message+"]"])
+ }
+ function upd0(source) { apertium.translate(source,afrom,ato,upd1) }
+ if(apertium.isTranslatablePair(afrom,ato)) {
+ if(segment.options.method!="Manual"
+ && !eq_options(segment.options,o))
+ upd0(segment.source)
+ }
+ else
+ upd3(["[Apertium does not support "+show_translation(o)+"]"])
+ }
+
+ function update_gf_translation(i,gfrom,gto) {
+ var segment=ss[i]
+ function upd3(txts) {
+ segment.target=txts[0];
+ segment.options={method:o.method,from:o.from,to:o.to} // no sharing!
+ if(txts.length>1) segment.choices=txts
+ else delete segment.choices
+ replace(i)
}
function upd2(ts) {
function unlex(txt,cont) { gfshell('ps -unlextext "'+txt+'"',cont) }
@@ -103,8 +172,8 @@ Translator.prototype.update_translations=function() {
function upd0(source) {
t.server.translate({from:gfrom,to:gto,input:source},upd1)
}
- var fls=supported(gfrom)
- var tls=supported(gto)
+ var fls=t.gf_supported(o.from)
+ var tls=t.gf_supported(o.to)
if(fls && tls) {
if(segment.options.method!="Manual"
&& !eq_options(segment.options,o))
@@ -121,21 +190,36 @@ Translator.prototype.update_translations=function() {
}
}
- if(doc.options.method!="Manual") {
+ switch(doc.options.method) {
+ case "Manual":
+ break;
+ case "Apertium":
+ var afrom=alangcode(o.from)
+ var ato=alangcode(o.to)
+ for(var i in ss) update_apertium_translation(i,afrom,ato)
+ break;
+ default: // GF
var gname=t.grammar_info.name
var gfrom=gname+o.from
var gto=gname+o.to
- for(var i in ss) update_translation(i)
+ for(var i in ss) update_gf_translation(i,gfrom,gto)
}
}
+Translator.prototype.add_apertium=function() {
+ var dl=element("methods")
+ if(dl)
+ dl.appendChild(dt(radiobutton("method","Apertium","Apertium",
+ bind(this.change,this))))
+}
+
Translator.prototype.extend_methods=function(grammars) {
this.grammars=grammars
var dl=element("methods")
if(dl) for(var i in grammars) {
- dl.appendChild(wrap("dt",radiobutton("method",grammars[i],
- "GF: "+grammars[i],
- bind(this.change,this))))
+ dl.appendChild(dt(radiobutton("method",grammars[i],
+ "GF: "+grammars[i],
+ bind(this.change,this))))
}
update_radiobutton("method",this.document.options.method)
}
@@ -444,9 +528,9 @@ type Segment = { source:String, target:String, options:Options }
type DocOptions = Options & { view:View }
type Options = {from: Lang, to: Lang, method:Method}
type Lang = String // Eng, Swe, Ita, etc
-type Method = "Manual" | GrammarName
+type Method = "Manual" | "Apertium" | GFGrammarName
type View = "segmentbysegment" | "paralleltexts"
-type GrammarName = String // e.g. "Foods.pgf"
+type GFGrammarName = String // e.g. "Foods.pgf"
*/
function eq_options(o1,o2) {
@@ -522,9 +606,9 @@ Translator.prototype.draw_segment_given_target=function(s,target,i) {
var autoB=radiobutton("method","Auto","Auto",change,!manual)
var manualB=radiobutton("method","Manual","Manual",change,manual)
return wrap("form",
- [wrap("dt",autoB),
- wrap("dt",manualB),
- wrap("dt",draw_translation(o))])
+ [dt(autoB),
+ dt(manualB),
+ dt(draw_translation(o))])
}
function draw_options(o) {
@@ -548,26 +632,35 @@ function new_segment(source) {
return { source:source, target:"", options:{} } // leave options empty
}
-function draw_translation(o) {
- return text("("+concname(o.from||"?")+" → "+concname(o.to||"?")+")")
+function draw_translation(o) { return text(show_translation(o)) }
+
+function show_translation(o) {
+ return "("+concname(o.from||"?")+" → "+concname(o.to||"?")+")"
}
/* --- Auxiliary functions -------------------------------------------------- */
-function lang(code,name) { return { code:code, name:name} }
-function lang1(name) {
+function lang(code,name,code2) { return {code:code, name:name, code2:code2} }
+function lang1(namecode2) {
+ var nc=namecode2.split(":");
+ var name=nc[0]
var ws=name.split("/");
- return ws.length==1 ? lang(name.substr(0,3),name) : lang(ws[0],ws[1]);
+ var code2=nc.length>1 ? nc[1] : ""
+ return ws.length==1 ? lang(name.substr(0,3),name,code2)
+ : lang(ws[0],ws[1],code2);
}
-var languages =
- map(lang1,"Amharic Arabic Bulgarian Catalan Danish Dutch English Finnish French German Hindi Ina/Interlingua Italian Jpn/Japanese Latin Norwegian Polish Ron/Romanian Russian Spanish Swedish Thai Turkish Urdu".split(" "));
+
+var languages = // [ISO-639-2 code "/"] language name ":" ISO 639-1 code
+ map(lang1,"Amharic:am Arabic:ar Bulgarian:bg Catalan:ca Danish:da Dutch:nl English:en Finnish:fi French:fr German:de Hindi:hi Ina/Interlingua:ia Italian:it Jpn/Japanese:ja Latin:la Norwegian:nb Polish:pl Ron/Romanian:ro Russian:ru Spanish:es Swedish:sv Thai:th Turkish:tr Urdu:ur".split(" "));
var langname={};
-for(var i in languages)
+var langcode2={}
+for(var i in languages) {
langname[languages[i].code]=languages[i].name
-
+ langcode2[languages[i].code]=languages[i].code2
+}
function concname(code) { return langname[code] || code; }
-
+function alangcode(code) { return langcode2[code] || code; }
function tr_local() {
/*