logaling-command 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2011 Miho SUZUKI
3
+ # Copyright (C) 2012 Miho SUZUKI
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU General Public License as published by
@@ -14,159 +14,95 @@
14
14
  #
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
-
18
- begin
19
- require 'psych'
20
- rescue LoadError => e
21
- raise LoadError unless e.message =~ /psych/
22
- puts "please install psych first."
23
- end
24
- require "yaml"
25
- require "csv"
26
- require "fileutils"
27
-
28
17
  module Logaling
29
18
  class Glossary
30
- class << self
31
- def load(file)
32
- load_glossary(file)
33
- end
34
-
35
- def load_glossary(file)
36
- case File.extname(file)
37
- when ".csv"
38
- load_glossary_csv(file)
39
- when ".tsv"
40
- load_glossary_tsv(file)
41
- when ".yml"
42
- load_glossary_yml(file)
43
- end
44
- end
19
+ SUPPORTED_FILE_TYPE = %w(yml tsv csv)
45
20
 
46
- def load_glossary_yml(path)
47
- YAML::load_file(path) || []
48
- end
21
+ attr_reader :name, :source_language, :target_language
49
22
 
50
- def load_glossary_tsv(path)
51
- load_glossary_csv(path, "\t")
52
- end
23
+ def initialize(name, source_language, target_language, project=nil)
24
+ @name = name
25
+ @source_language = source_language
26
+ @target_language = target_language
27
+ @project = project
28
+ end
53
29
 
54
- def load_glossary_csv(path, sep=",")
55
- glossary = []
56
- CSV.open(path, "r:utf-8", {:col_sep => sep}) do |csv|
57
- csv.each do |row|
58
- glossary << {"source_term" => row[0], "target_term" => row[1], "note" => ""} if row.size >= 2
59
- end
60
- end
61
- glossary
30
+ def terms
31
+ raise Logaling::GlossaryDBNotFound unless File.exist?(@project.glossary_db_path)
32
+ index
33
+ terms = []
34
+ Logaling::GlossaryDB.open(@project.glossary_db_path, "utf8") do |db|
35
+ terms = db.translation_list(self)
62
36
  end
37
+ terms
63
38
  end
64
- attr_reader :glossary, :source_language, :target_language
65
39
 
66
- def initialize(glossary, source_language, target_language, logaling_home)
67
- @logaling_home = logaling_home
68
- @glossary = glossary
69
- @source_language = source_language
70
- @target_language = target_language
40
+ def bilingual_pair_exists?(source_term, target_term, note=nil)
41
+ raise Logaling::GlossaryDBNotFound unless File.exist?(@project.glossary_db_path)
42
+ index
43
+ terms = []
44
+ Logaling::GlossaryDB.open(@project.glossary_db_path, "utf8") do |db|
45
+ terms = db.get_bilingual_pair(source_term, target_term, @name, note)
46
+ end
47
+ !terms.empty?
71
48
  end
72
49
 
73
50
  def add(source_term, target_term, note)
74
- FileUtils.touch(source_path) unless File.exist?(source_path)
75
-
76
- glossary = Glossary.load_glossary(source_path)
77
- glossary << build_term(source_term, target_term, note)
78
- dump_glossary(glossary)
79
- rescue
80
- raise GlossaryNotFound
51
+ glossary_source.add(source_term, target_term, note)
81
52
  end
82
53
 
83
54
  def update(source_term, target_term, new_target_term, note)
84
- raise GlossaryNotFound unless File.exist?(source_path)
85
-
86
- glossary = Glossary.load_glossary(source_path)
87
-
88
- target_index = find_term_index(glossary, source_term, target_term)
89
- if target_index
90
- glossary[target_index] = rebuild_term(glossary[target_index], source_term, new_target_term, note)
91
- dump_glossary(glossary)
92
- else
93
- raise TermError, "Can't found term '#{source_term}: #{target_term}' in '#{@glossary}'"
94
- end
55
+ glossary_source.update(source_term, target_term, new_target_term, note)
95
56
  end
96
57
 
97
58
  def delete(source_term, target_term)
98
- raise GlossaryNotFound unless File.exist?(source_path)
99
-
100
- glossary = Glossary.load_glossary(source_path)
101
- target_index = find_term_index(glossary, source_term, target_term)
102
- unless target_index
103
- raise TermError, "Can't found term '#{source_term} #{target_term}' in '#{@glossary}'" unless target_index
104
- end
105
-
106
- glossary.delete_at(target_index)
107
- dump_glossary(glossary)
59
+ glossary_source.delete(source_term, target_term)
108
60
  end
109
61
 
110
62
  def delete_all(source_term, force=false)
111
- raise GlossaryNotFound unless File.exist?(source_path)
112
-
113
- glossary = Glossary.load_glossary(source_path)
114
- delete_candidates = target_terms(glossary, source_term)
115
- if delete_candidates.empty?
116
- raise TermError, "Can't found term '#{source_term} in '#{@glossary}'"
117
- end
118
-
119
- if delete_candidates.size == 1 || force
120
- glossary.delete_if{|term| term['source_term'] == source_term }
121
- dump_glossary(glossary)
122
- else
123
- raise TermError, "There are duplicate terms in glossary.\n" +
124
- "If you really want to delete, please put `loga delete [SOURCE_TERM] --force`\n" +
125
- " or `loga delete [SOURCE_TERM] [TARGET_TERM]`"
126
- end
63
+ glossary_source.delete_all(source_term, force)
127
64
  end
128
65
 
129
- def source_path
130
- if @source_path
131
- @source_path
66
+ def glossary_source
67
+ if @glossary_source
68
+ @glossary_source
132
69
  else
133
- fname = [@glossary, @source_language, @target_language].join(".")
134
- @source_path = File.join(@logaling_home, "projects", @glossary, "glossary", "#{fname}.yml")
70
+ file_name = [@name, @source_language, @target_language, 'yml'].join('.')
71
+ source_dir = @project.glossary_source_path
72
+ FileUtils.mkdir_p(source_dir)
73
+ source_path = File.join(source_dir, file_name)
74
+ @glossary_source = Logaling::GlossarySource.create(source_path, self)
135
75
  end
136
76
  end
137
77
 
138
- private
139
- def build_term(source_term, target_term, note)
140
- note ||= ''
141
- {'source_term' => source_term, 'target_term' => target_term, 'note' => note}
78
+ def to_s
79
+ [@name, @source_language, @target_language].join('.')
142
80
  end
143
81
 
144
- def rebuild_term(current, source_term, target_term, note)
145
- if current['target_term'] != target_term && (note.nil? || note == "")
146
- note = current['note']
147
- end
148
- target_term = current['target_term'] if target_term == ""
149
- build_term(source_term, target_term, note)
150
- end
151
-
152
- def find_term_index(glossary, source_term, target_term='')
153
- glossary.find_index do |term|
154
- if target_term.empty?
155
- term['source_term'] == source_term
156
- else
157
- term['source_term'] == source_term && term['target_term'] == target_term
82
+ private
83
+ def index
84
+ Logaling::GlossaryDB.open(@project.glossary_db_path, "utf8") do |db|
85
+ db.recreate_table
86
+ glossary_sources.each do |glossary_source|
87
+ unless db.glossary_source_exist?(glossary_source)
88
+ puts "now index #{@name}..."
89
+ db.index_glossary_source(glossary_source)
90
+ end
91
+ end
92
+ indexed_glossary_sources = db.glossary_sources_related_on_glossary(self)
93
+ (indexed_glossary_sources - glossary_sources).each do |removed_glossary_source|
94
+ puts "now deindex #{@name}..."
95
+ db.deindex_glossary_source(removed_glossary_source)
158
96
  end
159
97
  end
160
98
  end
161
99
 
162
- def target_terms(glossary, source_term)
163
- glossary.select {|term| term['source_term'] == source_term }
164
- end
165
-
166
- def dump_glossary(glossary)
167
- File.open(source_path, "w") do |f|
168
- f.puts(glossary.to_yaml)
100
+ def glossary_sources
101
+ glob_condition = SUPPORTED_FILE_TYPE.map do |type|
102
+ file_name = [self.to_s, type].join('.')
103
+ File.join(@project.glossary_source_path, file_name)
169
104
  end
105
+ Dir.glob(glob_condition).map {|source_path| GlossarySource.create(source_path, self)}
170
106
  end
171
107
  end
172
108
  end
@@ -49,11 +49,10 @@ module Logaling
49
49
  end
50
50
 
51
51
  def recreate_table
52
- version = Groonga["configurations"] ? get_config("version") : 0
53
- if version.to_i != VERSION
52
+ unless latest_version?
54
53
  remove_schema
55
54
  populate_schema
56
- add_config("version", VERSION.to_s)
55
+ update_version_to_latest
57
56
  end
58
57
  end
59
58
 
@@ -62,41 +61,63 @@ module Logaling
62
61
  @database = nil
63
62
  end
64
63
 
65
- def deindex_glossary(glossary_name, glossary_source)
66
- delete_translations_by_glossary_source(glossary_source)
67
- delete_glossary(glossary_name)
68
- delete_glossary_source(glossary_source)
64
+ def deindex_glossary(glossary, glossary_source)
65
+ delete_translations_by_glossary_source(glossary_source.source_path)
66
+ delete_glossary(glossary.name)
67
+ delete_glossary_source(glossary_source.source_path)
69
68
  end
70
69
 
71
- def index_glossary(glossary, glossary_name, glossary_source, source_language, target_language, indexed_at)
70
+ def deindex_glossary_source(glossary_source)
71
+ delete_translations_by_glossary_source(glossary_source.source_path)
72
+ delete_glossary_source(glossary_source.source_path)
73
+ end
74
+
75
+ def index_glossary_source(glossary_source)
76
+ delete_terms if offline_index?
77
+ glossary = glossary_source.glossary
78
+
79
+ deindex_glossary_source(glossary_source)
80
+
81
+ add_glossary_source(glossary_source)
82
+ glossary_source.load.each do |term|
83
+ source_term = term['source_term']
84
+ target_term = term['target_term']
85
+ note = term['note']
86
+ add_translation(glossary.name, glossary_source.source_path, glossary.source_language, glossary.target_language, source_term, target_term, note)
87
+ end
88
+
89
+ create_terms if offline_index?
90
+ end
91
+
92
+ def index_glossary(glossary, glossary_source)
72
93
  delete_terms if offline_index?
73
94
 
74
- deindex_glossary(glossary_name, glossary_source)
95
+ deindex_glossary(glossary, glossary_source)
75
96
 
76
- add_glossary_source(glossary_source, indexed_at)
77
- add_glossary(glossary_name)
78
- glossary.each do |term|
97
+ add_glossary_source(glossary_source)
98
+ add_glossary(glossary)
99
+ glossary_source.load.each do |term|
79
100
  source_term = term['source_term']
80
101
  target_term = term['target_term']
81
102
  note = term['note']
82
- add_translation(glossary_name, glossary_source, source_language, target_language, source_term, target_term, note)
103
+ add_translation(glossary.name, glossary_source.source_path, glossary.source_language, glossary.target_language, source_term, target_term, note)
83
104
  end
84
105
 
85
106
  create_terms if offline_index?
86
107
  end
87
108
 
88
- def lookup(source_term, glossary_source=nil)
109
+ def lookup(source_term, glossary=nil)
89
110
  records_selected = Groonga["translations"].select do |record|
90
111
  conditions = [record.source_term =~ source_term]
91
- if glossary_source
92
- conditions << (record.source_language =~ glossary_source.source_language) if glossary_source.source_language
93
- conditions << (record.target_language =~ glossary_source.target_language) if glossary_source.target_language
112
+ if glossary
113
+ conditions << (record.source_language =~ glossary.source_language) if glossary.source_language
114
+ conditions << (record.target_language =~ glossary.target_language) if glossary.target_language
94
115
  end
95
116
  conditions
96
117
  end
97
- if glossary_source
118
+ if glossary
98
119
  specified_glossary = records_selected.select do |record|
99
- record.glossary == glossary_source.glossary
120
+ record.glossary == glossary.name
100
121
  end
101
122
  specified_glossary.each do |record|
102
123
  record.key._score += 10
@@ -113,13 +134,8 @@ module Logaling
113
134
  :normalize => true}
114
135
  snippet = records_selected.expression.snippet(["<snippet>", "</snippet>"], options)
115
136
  struct_result(records, snippet)
116
- ensure
117
- snippet.close if snippet
118
- records_selected.expression.close if records_selected
119
- specified_glossary.expression.close if specified_glossary
120
137
  end
121
138
 
122
-
123
139
  def lookup_dictionary(search_word)
124
140
  records_selected_source = Groonga["translations"].select do |record|
125
141
  target = record.match_target do |match_record|
@@ -150,74 +166,71 @@ module Logaling
150
166
  snippet = records_selected.expression.snippet(["<snippet>", "</snippet>"], options)
151
167
 
152
168
  struct_result(records, snippet)
153
- ensure
154
- snippet.close if snippet
155
- records_selected.expression.close if records_selected
156
169
  end
157
170
 
158
- def translation_list(glossary_source)
171
+ def translation_list(glossary, order='ascending')
159
172
  records_raw = Groonga["translations"].select do |record|
160
173
  [
161
- record.glossary == glossary_source.glossary,
162
- record.source_language == glossary_source.source_language,
163
- record.target_language == glossary_source.target_language
174
+ record.glossary == glossary.name,
175
+ record.source_language == glossary.source_language,
176
+ record.target_language == glossary.target_language
164
177
  ]
165
178
  end
166
179
 
167
180
  records = records_raw.sort([
168
- {:key=>"source_term", :order=>'ascending'},
169
- {:key=>"target_term", :order=>'ascending'}])
181
+ {:key => "source_term", :order => order},
182
+ {:key => "target_term", :order => order}
183
+ ])
170
184
 
171
185
  struct_result(records)
172
- ensure
173
- records_raw.expression.close
174
186
  end
175
187
 
176
- def get_bilingual_pair(source_term, target_term, glossary)
188
+ def get_bilingual_pair(source_term, target_term, glossary, note=nil)
177
189
  records = Groonga["translations"].select do |record|
178
- [
179
- record.glossary == glossary,
180
- record.source_term == source_term,
181
- record.target_term == target_term
182
- ]
183
- end
184
-
185
- struct_result(records)
186
- ensure
187
- records.expression.close
188
- end
189
-
190
- def get_bilingual_pair_with_note(source_term, target_term, note, glossary)
191
- records = Groonga["translations"].select do |record|
192
- [
193
- record.glossary == glossary,
194
- record.source_term == source_term,
195
- record.target_term == target_term,
196
- record.note == note
197
- ]
190
+ if note
191
+ [
192
+ record.glossary == glossary,
193
+ record.source_term == source_term,
194
+ record.target_term == target_term,
195
+ record.note == note
196
+ ]
197
+ else
198
+ [
199
+ record.glossary == glossary,
200
+ record.source_term == source_term,
201
+ record.target_term == target_term
202
+ ]
203
+ end
198
204
  end
199
-
200
205
  struct_result(records)
201
- ensure
202
- records.expression.close
203
206
  end
204
207
 
205
- def glossary_source_exist?(glossary_source, indexed_at)
208
+ def glossary_source_exist?(glossary_source)
206
209
  glossary = Groonga["glossary_sources"].select do |record|
207
210
  [
208
- record.key == glossary_source,
209
- record.indexed_at == indexed_at
211
+ record.key == glossary_source.source_path,
212
+ record.indexed_at == glossary_source.mtime
210
213
  ]
211
214
  end
212
215
  !glossary.size.zero?
213
- ensure
214
- glossary.expression.close
215
216
  end
216
217
 
217
- def get_all_glossary_source
218
- Groonga["glossary_sources"].sort([
218
+ def get_all_glossary_sources
219
+ source_paths = Groonga["glossary_sources"].sort([
219
220
  {:key=>"_key", :order=>'ascending'}
220
221
  ]).map{|record| record.key}
222
+ source_paths.map do |source_path|
223
+ glossary_name, source_language, target_language = File.basename(source_path).split(/\./)
224
+ glossary = Glossary.new(glossary_name, source_language, target_language)
225
+ GlossarySource.create(source_path, glossary)
226
+ end
227
+ end
228
+
229
+ def glossary_sources_related_on_glossary(glossary)
230
+ records = Groonga["glossary_sources"].select do |record|
231
+ [record.key =~ glossary.to_s]
232
+ end
233
+ records.map{|record| GlossarySource.create(record.key.key, glossary) }
221
234
  end
222
235
 
223
236
  def get_all_glossary
@@ -235,12 +248,10 @@ module Logaling
235
248
  records.each do |record|
236
249
  record.key.delete
237
250
  end
238
- ensure
239
- records.expression.close
240
251
  end
241
252
 
242
- def add_glossary_source(glossary_source, indexed_at)
243
- Groonga["glossary_sources"].add(glossary_source, :indexed_at => indexed_at)
253
+ def add_glossary_source(glossary_source)
254
+ Groonga["glossary_sources"].add(glossary_source.source_path, :indexed_at => glossary_source.mtime)
244
255
  end
245
256
 
246
257
  def delete_glossary(glossary_name)
@@ -251,12 +262,10 @@ module Logaling
251
262
  records.each do |record|
252
263
  record.key.delete
253
264
  end
254
- ensure
255
- records.expression.close
256
265
  end
257
266
 
258
- def add_glossary(glossary_name)
259
- Groonga["glossaries"].add(glossary_name)
267
+ def add_glossary(glossary)
268
+ Groonga["glossaries"].add(glossary.name)
260
269
  end
261
270
 
262
271
  def delete_translations_by_glossary_source(glossary_source)
@@ -267,8 +276,6 @@ module Logaling
267
276
  records.each do |record|
268
277
  record.key.delete
269
278
  end
270
- ensure
271
- records.expression.close
272
279
  end
273
280
 
274
281
  def delete_terms
@@ -345,11 +352,9 @@ module Logaling
345
352
 
346
353
  def remove_schema
347
354
  Groonga::Schema.define do |schema|
348
- schema.remove_table("configurations") if Groonga["configurations"]
349
- schema.remove_table("translations") if Groonga["translations"]
350
- schema.remove_table("glossaries") if Groonga["glossaries"]
351
- schema.remove_table("glossary_sources") if Groonga["glossary_sources"]
352
- schema.remove_table("terms") if Groonga["terms"]
355
+ %w(configurations translations glossaries glossary_sources terms).each do |table|
356
+ schema.remove_table(table) if Groonga[table]
357
+ end
353
358
  end
354
359
  end
355
360
 
@@ -360,8 +365,8 @@ module Logaling
360
365
  def struct_result(records, snippet=nil)
361
366
  records.map do |record|
362
367
  term = record.key
363
- snipped_source_term = snippet ? snip_source_term(term, snippet) : []
364
- snipped_target_term = snippet ? snip_target_term(term, snippet) : []
368
+ snipped_source_term = snippet ? struct_snipped_term(term.source_term, snippet) : []
369
+ snipped_target_term = snippet ? struct_snipped_term(term.target_term, snippet) : []
365
370
  {:glossary_name => term.glossary.key,
366
371
  :source_language => term.source_language,
367
372
  :target_language => term.target_language,
@@ -387,14 +392,21 @@ module Logaling
387
392
  structed_source_term
388
393
  end
389
394
 
390
- def snip_source_term(term, snippet)
391
- snipped_text = snippet.execute(term.source_term).join
392
- struct_snipped_text(snipped_text)
395
+ def struct_snipped_term(term, snippet)
396
+ snipped_text = snippet.execute(term).join
397
+ snipped_text.empty? ? [term] : struct_snipped_text(snipped_text)
398
+ end
399
+
400
+ def latest_version?
401
+ current_version == VERSION
402
+ end
403
+
404
+ def current_version
405
+ Groonga["configurations"] ? get_config("version").to_i : 0
393
406
  end
394
407
 
395
- def snip_target_term(term, snippet)
396
- snipped_text = snippet.execute(term.target_term).join
397
- struct_snipped_text(snipped_text)
408
+ def update_version_to_latest
409
+ add_config("version", VERSION.to_s)
398
410
  end
399
411
 
400
412
  def get_config(conf_key)
@@ -406,8 +418,6 @@ module Logaling
406
418
  config.conf_value
407
419
  end
408
420
  value.size > 0 ? value[0] : ""
409
- ensure
410
- records.expression.close
411
421
  end
412
422
 
413
423
  def add_config(conf_key, conf_value)
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2011 Miho SUZUKI
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "logaling/glossary_sources/glossary_yaml_source"
19
+ require "logaling/glossary_sources/glossary_csv_source"
20
+ require "logaling/glossary_sources/glossary_tsv_source"
21
+
22
+ module Logaling
23
+ class GlossarySource
24
+ def self.create(source_path, glossary)
25
+ case File.extname(source_path)
26
+ when ".csv"
27
+ GlossarySources::GlossaryCsvSource.new(source_path, glossary)
28
+ when ".tsv"
29
+ GlossarySources::GlossaryTsvSource.new(source_path, glossary)
30
+ when ".yml"
31
+ GlossarySources::GlossaryYamlSource.new(source_path, glossary)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Koji SHIMADA <koji.shimada@enishi-tech.com>
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module Logaling
19
+ module GlossarySources
20
+ class Base
21
+ attr_reader :source_path, :glossary
22
+
23
+ def initialize(source_path, glossary)
24
+ @source_path = source_path
25
+ @glossary = glossary
26
+ end
27
+
28
+ def eql?(other)
29
+ return false unless self.class == other.class
30
+ @source_path == other.source_path
31
+ end
32
+
33
+ def hash
34
+ @source_path.hash
35
+ end
36
+
37
+ def mtime
38
+ File.mtime(@source_path)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Koji SHIMADA <koji.shimada@enishi-tech.com>
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "logaling/glossary_sources/base"
19
+ require "csv"
20
+
21
+ module Logaling::GlossarySources
22
+ class GlossaryCsvSource < Base
23
+ def load
24
+ glossary_source = []
25
+ CSV.open(source_path, "r:utf-8", {:col_sep => ','}) do |csv|
26
+ csv.each do |row|
27
+ glossary_source << {"source_term" => row[0], "target_term" => row[1], "note" => ""} if row.size >= 2
28
+ end
29
+ end
30
+ glossary_source
31
+ end
32
+ end
33
+ end