lingo 1.8.0 → 1.8.1
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.
- data/ChangeLog +13 -0
- data/README +49 -29
- data/Rakefile +28 -4
- data/TODO +2 -9
- data/bin/lingo +24 -0
- data/bin/lingoctl +24 -0
- data/de/lingo-dic.txt +559 -74
- data/info/gpl-hdr.txt +21 -24
- data/lib/lingo.rb +83 -112
- data/lib/lingo/agenda_item.rb +53 -0
- data/lib/lingo/attendee.rb +261 -0
- data/lib/lingo/attendee/abbreviator.rb +95 -97
- data/lib/lingo/attendee/debugger.rb +94 -93
- data/lib/lingo/attendee/decomposer.rb +76 -83
- data/lib/lingo/attendee/dehyphenizer.rb +141 -144
- data/lib/lingo/attendee/formatter.rb +65 -0
- data/lib/lingo/attendee/multi_worder.rb +302 -0
- data/lib/lingo/attendee/noneword_filter.rb +89 -84
- data/lib/lingo/attendee/object_filter.rb +91 -0
- data/lib/lingo/attendee/sequencer.rb +159 -158
- data/lib/lingo/attendee/synonymer.rb +81 -84
- data/lib/lingo/attendee/text_reader.rb +242 -0
- data/lib/lingo/attendee/text_writer.rb +169 -0
- data/lib/lingo/attendee/tokenizer.rb +192 -191
- data/lib/lingo/attendee/variator.rb +152 -156
- data/lib/lingo/attendee/vector_filter.rb +140 -135
- data/lib/lingo/attendee/word_searcher.rb +98 -0
- data/lib/lingo/buffered_attendee.rb +69 -0
- data/lib/lingo/cachable.rb +58 -0
- data/lib/lingo/call.rb +72 -0
- data/lib/lingo/cli.rb +26 -0
- data/lib/lingo/config.rb +23 -26
- data/lib/lingo/core_ext.rb +42 -0
- data/lib/lingo/ctl.rb +239 -173
- data/lib/lingo/database.rb +148 -496
- data/lib/lingo/database/crypter.rb +85 -0
- data/lib/lingo/database/gdbm_store.rb +49 -0
- data/lib/lingo/database/hash_store.rb +67 -0
- data/lib/lingo/database/libcdb_store.rb +58 -0
- data/lib/lingo/database/sdbm_store.rb +64 -0
- data/lib/lingo/database/show_progress.rb +81 -0
- data/lib/lingo/database/source.rb +134 -0
- data/lib/lingo/database/source/key_value.rb +62 -0
- data/lib/lingo/database/source/multi_key.rb +65 -0
- data/lib/lingo/database/source/multi_value.rb +65 -0
- data/lib/lingo/database/source/single_word.rb +60 -0
- data/lib/lingo/database/source/word_class.rb +64 -0
- data/lib/lingo/error.rb +122 -0
- data/lib/lingo/language.rb +78 -518
- data/lib/lingo/language/dictionary.rb +173 -0
- data/lib/lingo/language/grammar.rb +211 -0
- data/lib/lingo/language/lexical.rb +66 -0
- data/lib/lingo/language/lexical_hash.rb +88 -0
- data/lib/lingo/language/token.rb +48 -0
- data/lib/lingo/language/word.rb +130 -0
- data/lib/lingo/language/word_form.rb +83 -0
- data/lib/lingo/reportable.rb +59 -0
- data/lib/lingo/version.rb +1 -1
- data/lingo-all.cfg +14 -10
- data/lingo-call.cfg +5 -5
- data/lingo.cfg +14 -12
- data/lingo.rb +26 -0
- data/lir.cfg +13 -9
- data/spec/spec_helper.rb +1 -0
- data/test.cfg +11 -11
- data/test/attendee/ts_abbreviator.rb +0 -6
- data/test/attendee/ts_decomposer.rb +0 -6
- data/test/attendee/{ts_multiworder.rb → ts_multi_worder.rb} +1 -7
- data/test/attendee/ts_noneword_filter.rb +1 -7
- data/test/attendee/{ts_objectfilter.rb → ts_object_filter.rb} +1 -7
- data/test/attendee/ts_sequencer.rb +0 -6
- data/test/attendee/ts_synonymer.rb +0 -6
- data/test/attendee/{ts_textreader.rb → ts_text_reader.rb} +1 -7
- data/test/attendee/{ts_textwriter.rb → ts_text_writer.rb} +1 -7
- data/test/attendee/ts_tokenizer.rb +0 -6
- data/test/attendee/ts_variator.rb +0 -6
- data/test/attendee/ts_vector_filter.rb +1 -7
- data/test/attendee/{ts_wordsearcher.rb → ts_word_searcher.rb} +1 -7
- data/test/ref/artikel.non +2 -29
- data/test/ref/artikel.seq +13 -8
- data/test/ref/artikel.vec +30 -15
- data/test/ref/artikel.ven +29 -14
- data/test/ref/artikel.ver +58 -43
- data/test/ref/lir.csv +146 -145
- data/test/ref/lir.non +186 -210
- data/test/ref/lir.seq +54 -50
- data/test/test_helper.rb +41 -36
- data/test/ts_database.rb +12 -11
- data/test/ts_language.rb +118 -68
- metadata +67 -29
- data/lib/lingo/attendee/multiworder.rb +0 -301
- data/lib/lingo/attendee/objectfilter.rb +0 -86
- data/lib/lingo/attendee/textreader.rb +0 -237
- data/lib/lingo/attendee/textwriter.rb +0 -196
- data/lib/lingo/attendee/wordsearcher.rb +0 -96
- data/lib/lingo/attendees.rb +0 -289
- data/lib/lingo/const.rb +0 -131
- data/lib/lingo/modules.rb +0 -98
- data/lib/lingo/types.rb +0 -285
- data/lib/lingo/utilities.rb +0 -40
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
25
|
+
#++
|
|
26
|
+
|
|
27
|
+
class Lingo
|
|
28
|
+
|
|
29
|
+
# Provides a simple caching mechanism.
|
|
30
|
+
|
|
31
|
+
module Cachable
|
|
32
|
+
|
|
33
|
+
def init_cachable
|
|
34
|
+
@cache = Hash.new(false)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def hit?(key)
|
|
38
|
+
@cache.has_key?(key)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def store(key, value)
|
|
42
|
+
@cache[key] = cache_value(value)
|
|
43
|
+
value
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def retrieve(key)
|
|
47
|
+
cache_value(@cache[key])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def cache_value(value)
|
|
53
|
+
value.nil? ? nil : value.dup
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
data/lib/lingo/call.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
25
|
+
#++
|
|
26
|
+
|
|
27
|
+
class Lingo
|
|
28
|
+
|
|
29
|
+
class Call < self
|
|
30
|
+
|
|
31
|
+
def initialize(args = [])
|
|
32
|
+
super(args, StringIO.new, StringIO.new, StringIO.new)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def call
|
|
36
|
+
invite
|
|
37
|
+
|
|
38
|
+
if block_given?
|
|
39
|
+
begin
|
|
40
|
+
yield self
|
|
41
|
+
ensure
|
|
42
|
+
reset
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
self
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def talk(str)
|
|
50
|
+
config.stdin.reopen(str)
|
|
51
|
+
|
|
52
|
+
start
|
|
53
|
+
|
|
54
|
+
%w[stdout stderr].flat_map { |key|
|
|
55
|
+
io = config.send(key).tap(&:rewind)
|
|
56
|
+
io.readlines.each(&:chomp!).tap {
|
|
57
|
+
io.truncate(0)
|
|
58
|
+
io.rewind
|
|
59
|
+
}
|
|
60
|
+
}.tap { |res|
|
|
61
|
+
if block_given?
|
|
62
|
+
res.map!(&Proc.new)
|
|
63
|
+
else
|
|
64
|
+
res.sort!
|
|
65
|
+
res.uniq!
|
|
66
|
+
end
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
data/lib/lingo/cli.rb
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
25
|
+
#++
|
|
26
|
+
|
|
1
27
|
require 'nuggets/util/cli'
|
|
2
28
|
|
|
3
29
|
class Lingo
|
data/lib/lingo/config.rb
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# Copyright (C) 2007
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
# welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
|
|
26
|
-
#
|
|
27
|
-
# Lex Lingo rules from here on
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
28
25
|
#++
|
|
29
26
|
|
|
30
27
|
require 'yaml'
|
|
@@ -44,13 +41,13 @@ class Lingo
|
|
|
44
41
|
load_config('config')
|
|
45
42
|
|
|
46
43
|
Array(self['meeting/attendees']).each { |a|
|
|
47
|
-
r = a['textreader'] or next
|
|
44
|
+
r = a['text_reader'] || a['textreader'] or next
|
|
48
45
|
|
|
49
46
|
f = @cli.files
|
|
50
47
|
|
|
51
48
|
if i = r['files']
|
|
52
49
|
r['files'] = i.strip == '$(files)' ?
|
|
53
|
-
f : i.split(
|
|
50
|
+
f : i.split(STRING_SEPARATOR_RE)
|
|
54
51
|
elsif !f.empty?
|
|
55
52
|
r['files'] = f
|
|
56
53
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
25
|
+
#++
|
|
26
|
+
|
|
27
|
+
require 'unicode'
|
|
28
|
+
|
|
29
|
+
class String
|
|
30
|
+
|
|
31
|
+
alias_method :_lingo_original_downcase, :downcase
|
|
32
|
+
alias_method :_lingo_original_downcase!, :downcase!
|
|
33
|
+
|
|
34
|
+
def downcase
|
|
35
|
+
Unicode.downcase(self)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def downcase!
|
|
39
|
+
replace(downcase)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
data/lib/lingo/ctl.rb
CHANGED
|
@@ -1,173 +1,239 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
###############################################################################
|
|
5
|
+
# #
|
|
6
|
+
# Lingo -- A full-featured automatic indexing system #
|
|
7
|
+
# #
|
|
8
|
+
# Copyright (C) 2005-2007 John Vorhauer #
|
|
9
|
+
# Copyright (C) 2007-2012 John Vorhauer, Jens Wille #
|
|
10
|
+
# #
|
|
11
|
+
# Lingo is free software; you can redistribute it and/or modify it under the #
|
|
12
|
+
# terms of the GNU Affero General Public License as published by the Free #
|
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
|
14
|
+
# any later version. #
|
|
15
|
+
# #
|
|
16
|
+
# Lingo is distributed in the hope that it will be useful, but WITHOUT ANY #
|
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
|
19
|
+
# more details. #
|
|
20
|
+
# #
|
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
|
22
|
+
# along with Lingo. If not, see <http://www.gnu.org/licenses/>. #
|
|
23
|
+
# #
|
|
24
|
+
###############################################################################
|
|
25
|
+
#++
|
|
26
|
+
|
|
27
|
+
require 'optparse'
|
|
28
|
+
require 'fileutils'
|
|
29
|
+
|
|
30
|
+
class Lingo
|
|
31
|
+
|
|
32
|
+
module Ctl
|
|
33
|
+
|
|
34
|
+
extend self
|
|
35
|
+
|
|
36
|
+
PROG, VERSION, OPTWIDTH = $0, '0.0.2', 18
|
|
37
|
+
PROGNAME, OPTIONS = File.basename(PROG), {}
|
|
38
|
+
|
|
39
|
+
COMMANDS, ALIASES = {}, Hash.new { |h, k|
|
|
40
|
+
h[k] = COMMANDS.has_key?(k) ? k : 'usage'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ALIASES['ls'] # OCCUPY
|
|
44
|
+
|
|
45
|
+
{ config: %w[configuration],
|
|
46
|
+
lang: %w[language],
|
|
47
|
+
dict: %w[dictionary dictionaries],
|
|
48
|
+
store: %w[store],
|
|
49
|
+
sample: %w[sample\ text\ file] }.each { |what, (sing, plur)|
|
|
50
|
+
COMMANDS["list#{what}"] = [
|
|
51
|
+
"List available #{plur || "#{sing}s"}", 'Arguments: [name...]'
|
|
52
|
+
] if what != :store
|
|
53
|
+
COMMANDS["find#{what}"] = [
|
|
54
|
+
"Find #{sing} in Lingo search path", 'Arguments: name'
|
|
55
|
+
]
|
|
56
|
+
COMMANDS["copy#{what}"] = [
|
|
57
|
+
"Copy #{sing} to local Lingo directory", 'Arguments: name'
|
|
58
|
+
] if what != :store
|
|
59
|
+
|
|
60
|
+
%w[list find copy].each { |method|
|
|
61
|
+
next unless COMMANDS.has_key?(name = "#{method}#{what}")
|
|
62
|
+
class_eval %Q{def do_#{name}; #{method}(:#{what}); end}
|
|
63
|
+
|
|
64
|
+
[0, -1].repeated_permutation(2) { |i, j|
|
|
65
|
+
key = "#{method[i]}#{what[j]}"
|
|
66
|
+
break ALIASES[key] = name unless ALIASES.has_key?(key)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if what == :store
|
|
71
|
+
COMMANDS['clearstore'] = [
|
|
72
|
+
'Remove store files to force rebuild', 'Arguments: name'
|
|
73
|
+
]
|
|
74
|
+
ALIASES['cs'] = 'clearstore'
|
|
75
|
+
end
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
{ demo: ['Initialize demo directory (Default: current directory)',
|
|
79
|
+
'Arguments: [path]'],
|
|
80
|
+
path: 'Print search path for dictionaries and configurations',
|
|
81
|
+
help: 'Print help for available commands',
|
|
82
|
+
version: 'Print Lingo version number' }.each { |what, description|
|
|
83
|
+
COMMANDS[name = what.to_s] = description; ALIASES[name[0]] = name
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
USAGE = <<EOT
|
|
87
|
+
Usage: #{PROG} <command> [arguments] [options]
|
|
88
|
+
#{PROG} [-h|--help] [--version]
|
|
89
|
+
EOT
|
|
90
|
+
|
|
91
|
+
def do
|
|
92
|
+
parse_options
|
|
93
|
+
send("do_#{ALIASES[ARGV.shift]}")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def list(what, doit = true)
|
|
99
|
+
names = Regexp.union(*ARGV.empty? ? '' : ARGV)
|
|
100
|
+
|
|
101
|
+
Lingo.list(what, path: path_for_scope).select { |file|
|
|
102
|
+
File.basename(file) =~ names ? doit ? puts(file) : true : false
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def find(what, doit = true)
|
|
107
|
+
name = ARGV.shift or do_usage('Required argument `name\' missing.')
|
|
108
|
+
no_args
|
|
109
|
+
|
|
110
|
+
file = Lingo.find(what, name, path: path_for_scope, &method(:do_usage))
|
|
111
|
+
doit ? puts(file) : file
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def copy(what)
|
|
115
|
+
do_usage('Source and target are the same.') if OPTIONS[:scope] == :local
|
|
116
|
+
|
|
117
|
+
source = find(what, false)
|
|
118
|
+
target = File.join(path_for_scope(:local), Lingo.basepath(what, source))
|
|
119
|
+
|
|
120
|
+
do_usage('Source and target are the same.') if source == target
|
|
121
|
+
|
|
122
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
123
|
+
FileUtils.cp(source, target, verbose: true)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def do_clearstore
|
|
127
|
+
store = Dir["#{find(:store, false)}.*"]
|
|
128
|
+
FileUtils.rm(store, verbose: true) unless store.empty?
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def do_demo
|
|
132
|
+
OPTIONS.update(path: ARGV.shift, scope: :system)
|
|
133
|
+
no_args
|
|
134
|
+
|
|
135
|
+
copy_list(:config) { |i| !File.basename(i).start_with?('test') }
|
|
136
|
+
copy_list(:lang)
|
|
137
|
+
copy_list(:dict) { |i| File.basename(i).start_with?('user') }
|
|
138
|
+
copy_list(:sample)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def do_path
|
|
142
|
+
no_args
|
|
143
|
+
puts path_for_scope || PATH
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def do_help(opts = nil)
|
|
147
|
+
no_args
|
|
148
|
+
|
|
149
|
+
msg = opts ? [opts, 'Commands:'] : []
|
|
150
|
+
|
|
151
|
+
aliases = Hash.new { |h, k| h[k] = [] }
|
|
152
|
+
ALIASES.each { |k, v| aliases[v] << k }
|
|
153
|
+
|
|
154
|
+
COMMANDS.each { |c, (d, *e)|
|
|
155
|
+
a = aliases[c]
|
|
156
|
+
c = "#{c} (#{a.join(', ')})" unless a.empty?
|
|
157
|
+
|
|
158
|
+
if opts
|
|
159
|
+
msg << " %-#{OPTWIDTH}s %s" % [c, d]
|
|
160
|
+
else
|
|
161
|
+
msg << "#{c}" << " - #{d}"
|
|
162
|
+
e.each { |i| msg << " + #{i}" }
|
|
163
|
+
end
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
abort msg.join("\n")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def do_version(doit = true)
|
|
170
|
+
no_args
|
|
171
|
+
|
|
172
|
+
msg = "Lingo v#{Lingo::VERSION}"
|
|
173
|
+
doit ? puts(msg) : msg
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def do_usage(msg = nil)
|
|
177
|
+
abort "#{"#{PROGNAME}: #{msg}\n\n" if msg}#{USAGE}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def parse_options
|
|
181
|
+
OptionParser.new(USAGE, OPTWIDTH) { |opts|
|
|
182
|
+
opts.separator ''
|
|
183
|
+
opts.separator 'Scope options:'
|
|
184
|
+
|
|
185
|
+
opts.on('--system', 'Restrict command to the system-wide Lingo directory') {
|
|
186
|
+
OPTIONS[:scope] = :system
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
opts.on('--global', 'Restrict command to the user\'s personal Lingo directory') {
|
|
190
|
+
OPTIONS[:scope] = :global
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
opts.on('--local', 'Restrict command to the local Lingo directory') {
|
|
194
|
+
OPTIONS[:scope] = :local
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
opts.separator ''
|
|
198
|
+
opts.separator 'Generic options:'
|
|
199
|
+
|
|
200
|
+
opts.on('-h', '--help', 'Print this help message and exit') {
|
|
201
|
+
do_help(opts)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
opts.on('--version', 'Print program version and exit') {
|
|
205
|
+
abort "#{PROGNAME} v#{VERSION} (#{do_version(false)})"
|
|
206
|
+
}
|
|
207
|
+
}.parse!
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def path_for_scope(scope = OPTIONS[:scope])
|
|
211
|
+
case scope
|
|
212
|
+
when :system then [BASE]
|
|
213
|
+
when :global then [HOME]
|
|
214
|
+
when :local then [OPTIONS[:path] || CURR]
|
|
215
|
+
when nil
|
|
216
|
+
else do_usage("Invalid scope `#{scope.inspect}'.")
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def no_args
|
|
221
|
+
do_usage('Too many arguments.') unless ARGV.empty?
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def copy_list(what)
|
|
225
|
+
files = list(what, false)
|
|
226
|
+
files.select!(&Proc.new) if block_given?
|
|
227
|
+
files.each { |file| ARGV.replace([file]); copy(what) }
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def self.ctl
|
|
233
|
+
Ctl.do
|
|
234
|
+
rescue => err
|
|
235
|
+
raise if $VERBOSE
|
|
236
|
+
abort "#{err.backtrace.first}: #{err} (#{err.class})"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end
|