ajax-cat 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "ajax-cat"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ondrej Odchazel"]
12
+ s.date = "2012-04-26"
13
+ s.description = "computer-aided translation backed by machine translation"
14
+ s.email = "odchazel@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "ajax-cat.gemspec",
28
+ "lib/.DS_Store",
29
+ "lib/ajax-cat.rb",
30
+ "lib/public/AjaxCatList.coffee",
31
+ "lib/public/AjaxCatTranslation.coffee",
32
+ "lib/public/Suggestions.coffee",
33
+ "lib/public/TranslationTable.coffee",
34
+ "lib/public/Utils.coffee",
35
+ "lib/public/ajax-cat.coffee",
36
+ "lib/public/ajax-cat.js",
37
+ "lib/public/bootstrap.css",
38
+ "lib/public/bootstrap.js",
39
+ "lib/public/index.html",
40
+ "lib/public/index.js",
41
+ "lib/public/jquery.js",
42
+ "lib/public/style.css",
43
+ "lib/public/translation.html",
44
+ "lib/public/translation.js",
45
+ "test/helper.rb",
46
+ "test/test_ajax-cat.rb"
47
+ ]
48
+ s.homepage = "http://github.com/hypertornado/ajax-cat"
49
+ s.licenses = ["MIT"]
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = "1.8.17"
52
+ s.summary = "computer-aided translation backed by machine translation"
53
+
54
+ if s.respond_to? :specification_version then
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
59
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
61
+ else
62
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
63
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
64
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
68
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
69
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
70
+ end
71
+ end
72
+
Binary file
@@ -0,0 +1,5 @@
1
+ require 'sinatra.rb'
2
+
3
+ get '/' do
4
+ redirect '/index.html'
5
+ end
@@ -0,0 +1,63 @@
1
+ class AjaxCatList
2
+
3
+ constructor: ->
4
+ $('#new-translation-modal').hide()
5
+ $('#new-translation').on('click',@new_translation)
6
+ $('#create-new-translation').on('click',@create_new_translation)
7
+ @show_translations()
8
+ $(".example").click(
9
+ (event) =>
10
+ text = $(event.currentTarget).data("text")
11
+ $('#new-translation-text').val(text)
12
+ return false
13
+ )
14
+
15
+ new_translation: =>
16
+ $('#new-translation-name').val('Name')
17
+ $('#new-translation-text').val('')
18
+ $('#new-translation-modal').modal('show')
19
+ $('#new-translation-text').focus()
20
+
21
+ show_translations: =>
22
+ $("#translation-list").html('')
23
+ return unless localStorage['ac-data']
24
+ ids = JSON.parse(localStorage['ac-data'])
25
+ for i in ids
26
+ doc = JSON.parse(localStorage[i])
27
+ $("#translation-list").append("<tr><td width='100%'><a href='/translation.html##{doc.id}'>#{doc.name}</a></td><td><button data-id='#{doc.id}' class='btn btn-danger btn-mini delete-button'>delete</button></td></tr>")
28
+ $(".delete-button").click(
29
+ (event) =>
30
+ id = $(event.currentTarget).data("id")
31
+ if confirm("Delete this translation?")
32
+ @delete_document(id)
33
+ @show_translations()
34
+ )
35
+
36
+ delete_document: (id) =>
37
+ return unless localStorage['ac-data']
38
+ ids = JSON.parse(localStorage['ac-data'])
39
+ new_ids = []
40
+ for i in ids
41
+ new_ids.push(i) unless i == id
42
+ localStorage.removeItem(id)
43
+ localStorage.setItem('ac-data', JSON.stringify(new_ids))
44
+
45
+
46
+ create_new_translation: =>
47
+ text = $('#new-translation-text').val()
48
+ if localStorage['ac-data']
49
+ docs = JSON.parse(localStorage['ac-data'])
50
+ else
51
+ docs = []
52
+ doc = {}
53
+ doc.id = Utils.random_string()
54
+ doc['name'] = $('#new-translation-name').val()
55
+ doc['pair'] = $('#new-translation-pair').val()
56
+ doc.source = Utils.split_source(text)
57
+ doc.target = new Array(doc.source.length)
58
+ docs.push(doc.id)
59
+ localStorage.setItem('ac-data', JSON.stringify(docs))
60
+ localStorage.setItem(doc.id, JSON.stringify(doc))
61
+ $('#new-translation-modal').modal('hide')
62
+ @show_translations()
63
+
@@ -0,0 +1,147 @@
1
+ class AjaxCatTranslation
2
+
3
+ cur_position: false
4
+ pair: "en-cs"
5
+ #host: "10.10.24.118"
6
+ host: "localhost"
7
+
8
+ constructor: ->
9
+ @host = window.location.hostname
10
+ @suggestions = new Suggestions(@)
11
+ $('#translation-preview-modal').hide()
12
+ $('#myTab').tab('show')
13
+ hash = window.location.hash.substr(1)
14
+ data = localStorage.getItem(hash)
15
+ unless data
16
+ alert "No such document."
17
+ return
18
+ @doc = JSON.parse(data)
19
+ @pair = @doc.pair
20
+ $('h1').html("#{@doc.name} <small>#{@pair}</small>")
21
+ $("title").html("#{@doc.name} - AJAX-CAT")
22
+ i = 0
23
+ for s in @doc.source
24
+ $("#source-top").append("<span class='ac-element ac-source' data-position='#{i}'>#{s}</span>")
25
+ $("#source-bottom").append("<span class='ac-element ac-source' data-position='#{i}'>#{s}</span>")
26
+ i += 1
27
+ i = 0
28
+ for t in @doc.target
29
+ t = "" unless t
30
+ $("#target-top").append("<span class='ac-element ac-target' data-position='#{i}'>#{t}</span>")
31
+ $("#target-bottom").append("<span class='ac-element ac-target' data-position='#{i}'>#{t}</span>")
32
+ i += 1
33
+ $('.ac-element').click(
34
+ (event) =>
35
+ position = $(event.target).data('position')
36
+ @change_position(position)
37
+ )
38
+ @length = $("#source-top").children().length
39
+ @change_position(0)
40
+ @bind_events()
41
+ @resize()
42
+
43
+ resize: =>
44
+ width = $(window).width()
45
+ $("#translation-table-container").width(width - 60)
46
+
47
+ bind_events: =>
48
+ $("#target-sentence").on('keydown'
49
+ (event) =>
50
+ switch event.which
51
+ when 13 #enter
52
+ @suggestions.take_suggestion()
53
+ when 32 #space
54
+ text = $("#target-sentence").val()
55
+ text = Utils.trim text
56
+ if text.length > 0
57
+ ar = text.split(/[ ]+/)
58
+ word = ar[(ar.length - 1)]
59
+ @table.mark_words(word)
60
+ when 33 #pgup
61
+ @change_position(@cur_position - 1) if @cur_position > 0
62
+ return false
63
+ when 34 #pgdown
64
+ @change_position(@cur_position + 1) if (@cur_position + 1) < @length
65
+ return false
66
+ when 38 #up
67
+ @suggestions.up()
68
+ when 40 #down
69
+ @suggestions.down()
70
+ else
71
+ $(window).trigger('loadSuggestions')
72
+
73
+ )
74
+
75
+ $("#preview").click(
76
+ =>
77
+ @save_target()
78
+ @show_preview()
79
+ return false
80
+ )
81
+
82
+ $("#save").click(
83
+ =>
84
+ @save_target()
85
+ alert "Translation was saved into your browser."
86
+ )
87
+
88
+ show_preview: =>
89
+ $("#source").text(@doc.source.join(''))
90
+ $("#target").text(@doc.target.join(''))
91
+ $('#translation-preview-modal').modal('show')
92
+
93
+ save_target: =>
94
+ $("#target-top .ac-target[data-position=#{@cur_position}]").text($("#target-sentence").val())
95
+ $("#target-bottom .ac-target[data-position=#{@cur_position}]").text($("#target-sentence").val())
96
+
97
+ tar = []
98
+ for el in $("#target-top .ac-target")
99
+ tar.push($(el).text())
100
+ @doc.target = tar
101
+ localStorage.setItem(@doc.id, JSON.stringify(@doc))
102
+
103
+
104
+ load_translation_table: (sentence) =>
105
+ sentence = Utils.tokenize(sentence)
106
+ if sentence.match(/^[\ \t]*$/)
107
+ $("#translation-table-container").html("")
108
+ @suggestions.clear()
109
+ return
110
+ $("#translation-table-container").text("")
111
+ $.ajax "http://"+@host+":8888/table"
112
+ data:
113
+ pair: @pair
114
+ q: sentence
115
+ success: (data) =>
116
+ @table = new TranslationTable(@, data)
117
+ $("#translation-table-container").html(@table.get_table())
118
+ $(window).trigger('loadSuggestions')
119
+ error: =>
120
+ #alert "failed to load translation table"
121
+
122
+ change_position: (position) =>
123
+ @save_target() if @cur_position != false
124
+ $("#source-top").children().slice(0,position).show()
125
+ $("#source-top").children().slice(position,@length).hide()
126
+ $("#source-bottom").children().slice(0,position + 1).hide()
127
+ $("#source-bottom").children().slice(position + 1,@length).show()
128
+
129
+ $("#target-top").children().slice(0,position).show()
130
+ $("#target-top").children().slice(position,@length).hide()
131
+ $("#target-bottom").children().slice(0,position + 1).hide()
132
+ $("#target-bottom").children().slice(position + 1,@length).show()
133
+
134
+ $("#source-sentence").text($("#source-top .ac-source[data-position=#{position}]").text())
135
+ $("#target-sentence").val($("#target-top .ac-target[data-position=#{position}]").text())
136
+ @cur_position = position
137
+ $("#target-sentence").focus()
138
+ @load_translation_table($("#source-top .ac-source[data-position=#{position}]").text())
139
+
140
+ add_words: (words, change_covered = false) =>
141
+ text = $("#target-sentence").val()
142
+ text = Utils.trim(text)
143
+ words = Utils.trim(words)
144
+ text = Utils.trim(text)
145
+ text += " #{words} "
146
+ $("#target-sentence").val(text)
147
+ $("#target-sentence").click()
@@ -0,0 +1,87 @@
1
+ class Suggestions
2
+
3
+ constructor: (@translation, limit = 5) ->
4
+ i = 0
5
+ while i < limit
6
+ sug = $("<div>"
7
+ class: 'ac-suggestion'
8
+ 'data-suggestion-position': i
9
+ click: =>
10
+ @take_suggestion()
11
+ mouseover: (event) =>
12
+ target = $(event.currentTarget)
13
+ if target.hasClass('suggestion-enabled')
14
+ @set_position(target.data('suggestion-position'))
15
+ )
16
+ $("#suggestions-container").append(sug)
17
+ i += 1
18
+
19
+ $(window).bind('loadSuggestions'
20
+ =>
21
+ @load_suggestions()
22
+ $("#target-sentence").focus()
23
+ )
24
+
25
+ clear: =>
26
+ $(".ac-suggestion").text("")
27
+ $(".ac-suggestion").removeClass('suggestion-enabled')
28
+ $(".ac-suggestion").removeClass('suggestion-active')
29
+
30
+ load_suggestions: =>
31
+ @clear()
32
+ sentence = $("#source-sentence").text()
33
+ sentence = Utils.tokenize(sentence)
34
+ translated = Utils.tokenize($("#source-target").text())
35
+ covered = @translation.table.covered_vector()
36
+ $.ajax "http://"+@translation.host+":8888/suggestion"
37
+ data:
38
+ pair: @translation.pair
39
+ q: Utils.tokenize(sentence)
40
+ covered: covered
41
+ translated: translated
42
+ success: (data) =>
43
+ data = JSON.parse(data)
44
+ @process_suggestions(data)
45
+ error: =>
46
+ #alert "failed to load suggestions"
47
+
48
+ take_suggestion: =>
49
+ return if (@get_position() == false)
50
+ text = $(".suggestion-active span").text()
51
+ @translation.add_words(text)
52
+ @translation.table.mark_words(text)
53
+
54
+
55
+ process_suggestions: (data) =>
56
+ i = 0
57
+ for suggestion in data.suggestions
58
+ translation = $("#target-sentence").val()
59
+ el = $(".ac-suggestion").slice(i, (i + 1))
60
+ el.html("#{translation} <span>#{suggestion}</span>")
61
+ el.addClass('suggestion-enabled')
62
+ i += 1
63
+
64
+ positions: =>
65
+ return $(".suggestion-enabled").length
66
+
67
+ get_position: =>
68
+ el = $(".suggestion-active")
69
+ return false unless el.length
70
+ return el.data('suggestion-position')
71
+
72
+ set_position: (position) =>
73
+ $(".suggestion-active").removeClass('suggestion-active')
74
+ $(".suggestion-enabled[data-suggestion-position=#{position}]").addClass('suggestion-active')
75
+
76
+ up: =>
77
+ position = @get_position()
78
+ return if position == false
79
+ @set_position(position - 1)
80
+
81
+ down: =>
82
+ position = @get_position()
83
+ if position == false
84
+ @set_position(0)
85
+ return
86
+ if (position + 1) < @positions()
87
+ @set_position(position + 1)
@@ -0,0 +1,98 @@
1
+ class TranslationTable
2
+
3
+ constructor: (@translation, data) ->
4
+ @data = JSON.parse(data)
5
+
6
+ get_table: =>
7
+ ret = $("<table>"
8
+ class: 'translation-table'
9
+ )
10
+ ret.append(@get_header())
11
+ for row in @data.target
12
+ ret.append(@get_row(row))
13
+ return ret
14
+
15
+ get_header: =>
16
+ ret = $("<tr>")
17
+ i = 0
18
+ for word in @data.source
19
+ src = $("<th>"
20
+ class: 'ac-source'
21
+ html: word
22
+ "data-position": i
23
+ click: (event) =>
24
+ position = parseInt($(event.currentTarget).data('position'))
25
+ if @position_marked(position)
26
+ @unmark_position(position)
27
+ else
28
+ @mark_position(position)
29
+ $(window).trigger('loadSuggestions')
30
+ )
31
+ ret.append(src)
32
+ i += 1
33
+ return ret
34
+
35
+ get_row: (row) =>
36
+ ret = $("<tr>")
37
+ i = 0
38
+ for word in row
39
+ len = parseInt(word.s)
40
+ if word.empty
41
+ ret.append("<td colspan='#{word.s}' class='ac-empty'></td>")
42
+ else
43
+ cell = $("<td colspan='#{word.s}' class='ac-word'></td>")
44
+ content = $("<div>"
45
+ 'data-position-from': i
46
+ 'data-position-to': (i + len - 1)
47
+ html: word.t
48
+ click: (event) =>
49
+ i = parseInt($(event.currentTarget).data('position-from'))
50
+ while i <= parseInt($(event.currentTarget).data('position-to'))
51
+ @mark_position(i)
52
+ i += 1
53
+ @translation.add_words($(event.currentTarget).text())
54
+ $(window).trigger('loadSuggestions')
55
+ )
56
+ cell.append(content)
57
+ ret.append(cell)
58
+ i += len
59
+ return ret
60
+
61
+ position_marked: (position) =>
62
+ return true if $("th.ac-source").slice(position, (position + 1)).hasClass('ac-selected')
63
+ return false
64
+
65
+ mark_words: (words) =>
66
+ words = "#{words} "
67
+ for el in $(".ac-word div")
68
+ el_text = Utils.trim $(el).text()
69
+ el_text = "#{el_text} "
70
+ if ((words.indexOf(el_text) == 0) and (words.length >= el_text.length))
71
+ #console.log "#{words}, #{el_text}, #{words.length} , #{el_text.length}"
72
+ @mark_interval($(el).data('position-from'), $(el).data('position-to'))
73
+ $(window).trigger('loadSuggestions')
74
+ words = words.substr(el_text.length)
75
+ words = Utils.trim(words)
76
+ words = "#{words} "
77
+ return unless words.length > 0
78
+
79
+ mark_interval: (from, to) =>
80
+ i = from
81
+ while i <= to
82
+ @mark_position(i)
83
+ i += 1
84
+
85
+ mark_position: (position) =>
86
+ $("th.ac-source").slice(position, (position + 1)).addClass('ac-selected')
87
+
88
+ unmark_position: (position) =>
89
+ $("th.ac-source").slice(position, (position + 1)).removeClass('ac-selected')
90
+
91
+ covered_vector: =>
92
+ ret = ""
93
+ for el in $("th.ac-source")
94
+ if $(el).hasClass('ac-selected')
95
+ ret += "1"
96
+ else
97
+ ret += "0"
98
+ return ret