lingo 1.8.6 → 1.8.7
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.
- checksums.yaml +4 -4
- data/ChangeLog +40 -4
- data/README +22 -51
- data/Rakefile +3 -17
- data/config/lingo.cfg +24 -15
- data/config/lir.cfg +25 -16
- data/dict/de/test_muh.txt +6 -0
- data/dict/en/lingo-dic.txt +2 -3
- data/lang/de.lang +10 -9
- data/lang/en.lang +1 -1
- data/lib/lingo.rb +4 -4
- data/lib/lingo/attendee.rb +27 -7
- data/lib/lingo/attendee/analysis_filter.rb +81 -0
- data/lib/lingo/attendee/debug_filter.rb +42 -0
- data/lib/lingo/attendee/debugger.rb +2 -11
- data/lib/lingo/attendee/decomposer.rb +6 -3
- data/lib/lingo/attendee/formatter.rb +6 -6
- data/lib/lingo/attendee/hal_filter.rb +94 -0
- data/lib/lingo/attendee/lsi_filter.rb +99 -0
- data/lib/lingo/attendee/multi_worder.rb +69 -43
- data/lib/lingo/attendee/sequencer.rb +32 -19
- data/lib/lingo/attendee/synonymer.rb +2 -2
- data/lib/lingo/attendee/text_reader.rb +63 -92
- data/lib/lingo/attendee/text_writer.rb +12 -21
- data/lib/lingo/attendee/tokenizer.rb +32 -21
- data/lib/lingo/attendee/variator.rb +3 -3
- data/lib/lingo/attendee/vector_filter.rb +7 -9
- data/lib/lingo/attendee/word_searcher.rb +3 -3
- data/lib/lingo/buffered_attendee.rb +3 -36
- data/lib/lingo/config.rb +1 -1
- data/lib/lingo/ctl.rb +7 -155
- data/lib/lingo/ctl/analysis.rb +136 -0
- data/lib/lingo/ctl/files.rb +86 -0
- data/lib/lingo/ctl/other.rb +140 -0
- data/lib/lingo/database.rb +64 -60
- data/lib/lingo/database/crypter.rb +7 -5
- data/lib/lingo/error.rb +5 -4
- data/lib/lingo/language.rb +13 -5
- data/lib/lingo/language/grammar.rb +13 -7
- data/lib/lingo/language/token.rb +6 -0
- data/lib/lingo/language/word.rb +23 -36
- data/lib/lingo/language/word_form.rb +5 -1
- data/lib/lingo/srv.rb +2 -2
- data/lib/lingo/text_utils.rb +96 -0
- data/lib/lingo/version.rb +1 -1
- data/lib/lingo/web/views/index.erb +1 -1
- data/test/attendee/ts_decomposer.rb +23 -5
- data/test/attendee/ts_multi_worder.rb +66 -0
- data/test/attendee/ts_sequencer.rb +28 -4
- data/test/attendee/ts_text_reader.rb +20 -0
- data/test/attendee/ts_tokenizer.rb +20 -0
- data/test/attendee/ts_variator.rb +1 -1
- data/test/attendee/ts_word_searcher.rb +39 -3
- data/test/lir3.txt +12 -0
- data/test/ref/artikel.non +1 -12
- data/test/ref/artikel.seq +3 -1
- data/test/ref/artikel.vec +1 -0
- data/test/ref/artikel.vef +35 -34
- data/test/ref/artikel.ven +8 -7
- data/test/ref/artikel.ver +34 -33
- data/test/ref/artikel.vet +2573 -2563
- data/test/ref/lir.non +77 -78
- data/test/ref/lir.seq +9 -7
- data/test/ref/lir.syn +1 -1
- data/test/ref/lir.vec +41 -41
- data/test/ref/lir.vef +210 -210
- data/test/ref/lir.ven +46 -46
- data/test/ref/lir.ver +72 -72
- data/test/ref/lir.vet +329 -329
- data/test/ts_database.rb +166 -62
- data/test/ts_language.rb +23 -23
- metadata +53 -34
- data/lib/lingo/attendee/dehyphenizer.rb +0 -120
- data/lib/lingo/attendee/noneword_filter.rb +0 -115
- data/test/attendee/ts_noneword_filter.rb +0 -15
@@ -6,7 +6,7 @@
|
|
6
6
|
# Lingo -- A full-featured automatic indexing system #
|
7
7
|
# #
|
8
8
|
# Copyright (C) 2005-2007 John Vorhauer #
|
9
|
-
# Copyright (C) 2007-
|
9
|
+
# Copyright (C) 2007-2015 John Vorhauer, Jens Wille #
|
10
10
|
# #
|
11
11
|
# Lingo is free software; you can redistribute it and/or modify it under the #
|
12
12
|
# terms of the GNU Affero General Public License as published by the Free #
|
@@ -79,7 +79,11 @@ class Lingo
|
|
79
79
|
|
80
80
|
class TextWriter < self
|
81
81
|
|
82
|
+
include TextUtils
|
83
|
+
|
82
84
|
def init
|
85
|
+
@encoding = get_enc
|
86
|
+
|
83
87
|
@ext = get_key('ext', 'txt2')
|
84
88
|
@lir = get_key('lir-format', false)
|
85
89
|
|
@@ -97,11 +101,8 @@ class Lingo
|
|
97
101
|
when :FILE
|
98
102
|
@no_sep = true
|
99
103
|
|
100
|
-
|
101
|
-
@
|
102
|
-
else
|
103
|
-
@file = File.open(@filename = File.set_ext(param, ".#{@ext}"), 'w')
|
104
|
-
end
|
104
|
+
@io = stdout?(@ext) ? (@path = @ext; open_stdout) :
|
105
|
+
open_path(@path = set_ext(param, @ext), 'w')
|
105
106
|
|
106
107
|
@lir_rec_no, @lir_rec_buf = '', []
|
107
108
|
when :RECORD
|
@@ -113,16 +114,10 @@ class Lingo
|
|
113
114
|
end
|
114
115
|
when :EOL
|
115
116
|
@no_sep = true
|
116
|
-
|
117
|
-
unless @lir
|
118
|
-
@file.puts unless @no_puts
|
119
|
-
end
|
117
|
+
@io.puts unless @lir || @no_puts
|
120
118
|
when :EOF
|
121
119
|
flush_lir_buffer if @lir
|
122
|
-
|
123
|
-
unless stdout?(@filename)
|
124
|
-
@file.close
|
125
|
-
end
|
120
|
+
@io.close unless stdout?(@path)
|
126
121
|
end
|
127
122
|
end
|
128
123
|
|
@@ -130,8 +125,8 @@ class Lingo
|
|
130
125
|
obj = obj.form if obj.is_a?(WordForm)
|
131
126
|
|
132
127
|
@lir ? @lir_rec_buf << obj : begin
|
133
|
-
@no_sep ? @no_sep = false : @
|
134
|
-
@
|
128
|
+
@no_sep ? @no_sep = false : @io.print(@sep)
|
129
|
+
@io.print(obj)
|
135
130
|
end
|
136
131
|
end
|
137
132
|
|
@@ -141,17 +136,13 @@ class Lingo
|
|
141
136
|
unless @lir_rec_no.empty? || @lir_rec_buf.empty?
|
142
137
|
buf = [@lir_rec_no, @lir_rec_buf.join(@sep), "\n"]
|
143
138
|
@sep =~ /\n/ ? buf.insert(1, "\n").unshift('*') : buf.insert(1, '*')
|
144
|
-
@
|
139
|
+
@io.print(*buf)
|
145
140
|
end
|
146
141
|
|
147
142
|
@lir_rec_no = ''
|
148
143
|
@lir_rec_buf.clear
|
149
144
|
end
|
150
145
|
|
151
|
-
def stdout?(filename)
|
152
|
-
%w[STDOUT -].include?(filename)
|
153
|
-
end
|
154
|
-
|
155
146
|
end
|
156
147
|
|
157
148
|
# For backwards compatibility.
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# Lingo -- A full-featured automatic indexing system #
|
7
7
|
# #
|
8
8
|
# Copyright (C) 2005-2007 John Vorhauer #
|
9
|
-
# Copyright (C) 2007-
|
9
|
+
# Copyright (C) 2007-2015 John Vorhauer, Jens Wille #
|
10
10
|
# #
|
11
11
|
# Lingo is free software; you can redistribute it and/or modify it under the #
|
12
12
|
# terms of the GNU Affero General Public License as published by the Free #
|
@@ -84,29 +84,40 @@ class Lingo
|
|
84
84
|
|
85
85
|
CHAR, DIGIT = Char::CHAR, Char::DIGIT
|
86
86
|
|
87
|
+
ALNUM = "(?:#{CHAR}|#{DIGIT})"
|
88
|
+
|
87
89
|
PROTO = '(?:news|https?|ftps?)://'
|
88
90
|
|
89
91
|
RULES = [
|
90
|
-
[
|
91
|
-
|
92
|
-
[
|
93
|
-
|
94
|
-
[
|
95
|
-
|
96
|
-
[
|
92
|
+
[TA_SPACE,
|
93
|
+
/^\s+/],
|
94
|
+
[TA_WIKI,
|
95
|
+
/^=+.+=+|^__[A-Z]+__/],
|
96
|
+
[TA_NUMBER,
|
97
|
+
/^[+-]?(?:\d{4,}|\d{1,3}(?:\.\d{3,3})*)(?:\.|(?:,\d+)?%?)/],
|
98
|
+
[TA_URL,
|
99
|
+
/^(?:www\.|mailto:|#{PROTO}|\S+?[._]\S+?@\S+?\.)[^\s<>]+/],
|
100
|
+
[TA_ABBREVIATION,
|
101
|
+
/^(?:(?:(?:#{CHAR})+\.)+)(?:#{CHAR})+/],
|
102
|
+
[TA_WORD,
|
103
|
+
/^#{ALNUM}(?:-*#{ALNUM})*/],
|
104
|
+
[TA_PUNCTUATION,
|
105
|
+
/^[!,.:;?¡¿]+/]
|
97
106
|
]
|
98
107
|
|
99
108
|
OTHER = [
|
100
|
-
[
|
101
|
-
|
109
|
+
[TA_OTHER,
|
110
|
+
/^[-"$#%&'()*+\/<=>@\[\\\]^_{|}~¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾×÷„“–]/],
|
111
|
+
[TA_HELP,
|
112
|
+
/^\S+/]
|
102
113
|
]
|
103
114
|
|
104
115
|
NESTS = {
|
105
|
-
|
106
|
-
'
|
107
|
-
'
|
108
|
-
'
|
109
|
-
'
|
116
|
+
TA_HTML => ['<', '>'],
|
117
|
+
TA_WIKI + ':VARIABLE' => ['{{{', '}}}'],
|
118
|
+
TA_WIKI + ':TEMPLATE' => ['{{', '}}'],
|
119
|
+
TA_WIKI + ':LINK_INT' => ['[[', ']]'],
|
120
|
+
TA_WIKI + ':LINK_EXT' => [/^\[\s*#{PROTO}/, ']']
|
110
121
|
}
|
111
122
|
|
112
123
|
class << self
|
@@ -162,12 +173,12 @@ class Lingo
|
|
162
173
|
@tags = get_key('tags', false)
|
163
174
|
@wiki = get_key('wiki', false)
|
164
175
|
|
165
|
-
@skip_tags =
|
176
|
+
@skip_tags = get_ary('skip-tags', '', :downcase)
|
166
177
|
@tags = true unless @skip_tags.empty?
|
167
178
|
|
168
179
|
skip = []
|
169
|
-
skip <<
|
170
|
-
skip <<
|
180
|
+
skip << TA_HTML unless @tags
|
181
|
+
skip << TA_WIKI unless @wiki
|
171
182
|
|
172
183
|
[@rules = RULES.dup, @nests = NESTS.dup].each { |hash|
|
173
184
|
hash.delete_if { |name, _| skip.include?(Token.clean(name)) }
|
@@ -230,7 +241,7 @@ class Lingo
|
|
230
241
|
next unless line =~ expr
|
231
242
|
|
232
243
|
rest = $'
|
233
|
-
forward_token($&, name, rest) if name !=
|
244
|
+
forward_token($&, name, rest) if name != TA_SPACE || @space
|
234
245
|
|
235
246
|
yield rest
|
236
247
|
}
|
@@ -289,12 +300,12 @@ class Lingo
|
|
289
300
|
end
|
290
301
|
|
291
302
|
def forward_token(form, attr, rest = '')
|
292
|
-
forward(Token.new(form, @override.empty? ? attr :
|
303
|
+
forward(Token.new(form, @override.empty? ? attr : TA_SKIP,
|
293
304
|
@position += 1, @offset - form.bytesize - rest.bytesize))
|
294
305
|
end
|
295
306
|
|
296
307
|
def overriding?(nest)
|
297
|
-
nest ==
|
308
|
+
nest == TA_HTML && !@skip_tags.empty?
|
298
309
|
end
|
299
310
|
|
300
311
|
end
|
@@ -39,7 +39,7 @@ class Lingo
|
|
39
39
|
#
|
40
40
|
# === Mögliche Verlinkung
|
41
41
|
# Erwartet:: Daten vom Typ *Word* (andere werden einfach durchgereicht) z.B. von Wordsearcher
|
42
|
-
# Erzeugt:: Daten vom Typ *Word* zur Weiterleitung z.B. an Synonymer, Decomposer, Multiworder, Sequencer
|
42
|
+
# Erzeugt:: Daten vom Typ *Word* zur Weiterleitung z.B. an Synonymer, Decomposer, Multiworder, Sequencer oder Vector_filter
|
43
43
|
#
|
44
44
|
# === Parameter
|
45
45
|
# Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
|
@@ -76,14 +76,14 @@ class Lingo
|
|
76
76
|
|
77
77
|
def init
|
78
78
|
@marker = get_key('marker', '*')
|
79
|
-
@max =
|
79
|
+
@max = get_int('max-var', max = 10000)
|
80
80
|
@max = max unless @max > 0
|
81
81
|
@var = get_key('variations')
|
82
82
|
|
83
83
|
raise MissingConfigError.new(:variations) if @var.empty?
|
84
84
|
|
85
85
|
@check = Hash.new(false)
|
86
|
-
|
86
|
+
get_ary('check', WA_UNKNOWN).each { |s| @check[s.upcase] = true }
|
87
87
|
|
88
88
|
set_dic
|
89
89
|
set_gra
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# Lingo -- A full-featured automatic indexing system #
|
7
7
|
# #
|
8
8
|
# Copyright (C) 2005-2007 John Vorhauer #
|
9
|
-
# Copyright (C) 2007-
|
9
|
+
# Copyright (C) 2007-2015 John Vorhauer, Jens Wille #
|
10
10
|
# #
|
11
11
|
# Lingo is free software; you can redistribute it and/or modify it under the #
|
12
12
|
# terms of the GNU Affero General Public License as published by the Free #
|
@@ -90,15 +90,13 @@ class Lingo
|
|
90
90
|
|
91
91
|
DEFAULT_GENDER_SEPARATOR = Database::Source::WordClass::GENDER_SEPARATOR
|
92
92
|
|
93
|
-
TERMINALS = [:FILE, :RECORD, :EOF]
|
94
|
-
|
95
93
|
def init
|
96
94
|
@lex = get_re('lexicals', '[sy]')
|
97
|
-
@skip =
|
95
|
+
@skip = get_ary('skip', DEFAULT_SKIP, :upcase)
|
98
96
|
|
99
97
|
@src = @pos = @sort_fmt = @sort_rel = @docnum = nil
|
100
98
|
|
101
|
-
@tokens, @vectors, @word_count = [], Hash.
|
99
|
+
@tokens, @vectors, @word_count = [], Hash.array(1), Hash.new(0)
|
102
100
|
|
103
101
|
if @dict = get_key('dict', false)
|
104
102
|
@norm = get_key('norm', false)
|
@@ -110,7 +108,7 @@ class Lingo
|
|
110
108
|
@pos = get_key('pos', false)
|
111
109
|
@pos = DEFAULT_POS_SEPARATOR if @pos == true
|
112
110
|
|
113
|
-
@tokens =
|
111
|
+
@tokens = get_ary('tokens', '', :upcase)
|
114
112
|
@tokens.concat(Tokenizer.rules) if @tokens.delete('ALL')
|
115
113
|
end
|
116
114
|
|
@@ -157,7 +155,7 @@ class Lingo
|
|
157
155
|
pos = obj.position_and_offset if @pos
|
158
156
|
|
159
157
|
obj.is_a?(Token) ? forward_vector(obj, pos) :
|
160
|
-
obj.
|
158
|
+
obj.each_lex(@lex) { |lex| forward_vector(lex, pos, lex.src) }
|
161
159
|
end
|
162
160
|
end
|
163
161
|
|
@@ -172,14 +170,14 @@ class Lingo
|
|
172
170
|
end
|
173
171
|
|
174
172
|
def forward_dict(obj, sep = DEFAULT_GENDER_SEPARATOR)
|
175
|
-
vectors = obj.
|
173
|
+
vectors = obj.each_lex(@lex).map { |lex|
|
176
174
|
"#{lex.form} ##{lex.attr}".tap { |str|
|
177
175
|
str << sep << lex.gender if lex.gender
|
178
176
|
}
|
179
177
|
}
|
180
178
|
|
181
179
|
unless vectors.empty?
|
182
|
-
vec = @norm ? obj.
|
180
|
+
vec = @norm ? obj.lex_form : obj.form
|
183
181
|
forward_vector("#{vec}#{@dict}#{vectors.join(' ')}")
|
184
182
|
end
|
185
183
|
end
|
@@ -36,7 +36,7 @@ class Lingo
|
|
36
36
|
#
|
37
37
|
# === Mögliche Verlinkung
|
38
38
|
# Erwartet:: Daten vom Typ *Token* (andere werden einfach durchgereicht) z.B. von Tokenizer, Abbreviator
|
39
|
-
# Erzeugt:: Daten vom Typ *Word* für erkannte Wörter z.B. für Synonymer, Decomposer, Ocr_variator, Multiworder, Sequencer,
|
39
|
+
# Erzeugt:: Daten vom Typ *Word* für erkannte Wörter z.B. für Synonymer, Decomposer, Ocr_variator, Multiworder, Sequencer, Vector_filter
|
40
40
|
#
|
41
41
|
# === Parameter
|
42
42
|
# Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
|
@@ -77,8 +77,8 @@ class Lingo
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def process(obj)
|
80
|
-
forward(obj
|
81
|
-
|
80
|
+
forward(obj)
|
81
|
+
forward(@dic.find_word(obj.form, obj)) if obj.word_token?
|
82
82
|
end
|
83
83
|
|
84
84
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# Lingo -- A full-featured automatic indexing system #
|
7
7
|
# #
|
8
8
|
# Copyright (C) 2005-2007 John Vorhauer #
|
9
|
-
# Copyright (C) 2007-
|
9
|
+
# Copyright (C) 2007-2015 John Vorhauer, Jens Wille #
|
10
10
|
# #
|
11
11
|
# Lingo is free software; you can redistribute it and/or modify it under the #
|
12
12
|
# terms of the GNU Affero General Public License as published by the Free #
|
@@ -34,53 +34,20 @@ class Lingo
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def process(obj)
|
37
|
-
@buffer << obj
|
37
|
+
obj.word_token? ? forward(obj) : @buffer << obj
|
38
38
|
process_buffer if process_buffer?
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
-
def form_at(index, klass = WordForm)
|
44
|
-
obj = @buffer[index]
|
45
|
-
obj.form if obj.is_a?(klass)
|
46
|
-
end
|
47
|
-
|
48
|
-
def forward_number_of_token(len = default = @buffer.size, punct = !default)
|
49
|
-
begin
|
50
|
-
unless @buffer.empty?
|
51
|
-
forward(item = @buffer.delete_at(0))
|
52
|
-
len -= 1 unless punct && item.form == CHAR_PUNCT
|
53
|
-
end
|
54
|
-
end while len > 0
|
55
|
-
end
|
56
|
-
|
57
|
-
def valid_tokens_in_buffer
|
58
|
-
@buffer.count { |item| item.form != CHAR_PUNCT }
|
59
|
-
end
|
60
|
-
|
61
43
|
def process_buffer?
|
62
|
-
|
63
|
-
valid_tokens_in_buffer >= @expected_tokens_in_buffer
|
44
|
+
raise NotImplementedError
|
64
45
|
end
|
65
46
|
|
66
47
|
def process_buffer
|
67
48
|
raise NotImplementedError
|
68
49
|
end
|
69
50
|
|
70
|
-
def control_multi(cmd)
|
71
|
-
if [:RECORD, :EOF].include?(cmd)
|
72
|
-
@eof_handling = true
|
73
|
-
|
74
|
-
while valid_tokens_in_buffer > 1
|
75
|
-
process_buffer
|
76
|
-
end
|
77
|
-
|
78
|
-
forward_number_of_token
|
79
|
-
|
80
|
-
@eof_handling = false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
51
|
end
|
85
52
|
|
86
53
|
end
|
data/lib/lingo/config.rb
CHANGED
data/lib/lingo/ctl.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# Lingo -- A full-featured automatic indexing system #
|
7
7
|
# #
|
8
8
|
# Copyright (C) 2005-2007 John Vorhauer #
|
9
|
-
# Copyright (C) 2007-
|
9
|
+
# Copyright (C) 2007-2015 John Vorhauer, Jens Wille #
|
10
10
|
# #
|
11
11
|
# Lingo is free software; you can redistribute it and/or modify it under the #
|
12
12
|
# terms of the GNU Affero General Public License as published by the Free #
|
@@ -25,9 +25,6 @@
|
|
25
25
|
#++
|
26
26
|
|
27
27
|
require 'optparse'
|
28
|
-
require 'zip'
|
29
|
-
|
30
|
-
Zip.unicode_names = true
|
31
28
|
|
32
29
|
class Lingo
|
33
30
|
|
@@ -35,7 +32,7 @@ class Lingo
|
|
35
32
|
|
36
33
|
extend self
|
37
34
|
|
38
|
-
PROG, VERSION, OPTWIDTH = $0, '0.0.
|
35
|
+
PROG, VERSION, OPTWIDTH = $0, '0.0.3', 21
|
39
36
|
PROGNAME, OPTIONS = File.basename(PROG), {}
|
40
37
|
|
41
38
|
COMMANDS, ALIASES = {}, Hash.nest { |k|
|
@@ -67,151 +64,8 @@ Usage: #{PROG} <command> [arguments] [options]
|
|
67
64
|
COMMANDS[name], ALIASES[short] = desc, name
|
68
65
|
end
|
69
66
|
|
70
|
-
{ config: %w[c configuration],
|
71
|
-
lang: %w[l language],
|
72
|
-
dict: %w[d dictionary dictionaries],
|
73
|
-
store: %w[s store],
|
74
|
-
sample: %w[e sample\ text\ file]
|
75
|
-
}.each { |n, (s, q, r)|
|
76
|
-
t = n == :store
|
77
|
-
|
78
|
-
cmd([:list, :l, n], s, "List available #{r || "#{q}s"}", '[name...]') if !t
|
79
|
-
cmd([:find, :f, n], s, "Find #{q} in Lingo search path", 'name')
|
80
|
-
cmd([:copy, :c, n], s, "Copy #{q} to local Lingo directory", 'name') if !t
|
81
|
-
cmd([:clear, :c, n], s, 'Remove store files to force rebuild', 'name') if t
|
82
|
-
}
|
83
|
-
|
84
|
-
{ demo: [:d, 'Initialize demo directory', '[path]', 'current directory'],
|
85
|
-
archive: [:a, 'Create archive of directory', '[path]', 'current directory'],
|
86
|
-
rackup: [:r, 'Print path to rackup file', 'name'],
|
87
|
-
path: [:p, 'Print search path for dictionaries and configurations'],
|
88
|
-
help: [:h, 'Print help for available commands'],
|
89
|
-
version: [:v, 'Print Lingo version number']
|
90
|
-
}.each { |n, (s, *a)| cmd(n.to_s, s.to_s, *a) }
|
91
|
-
|
92
67
|
private
|
93
68
|
|
94
|
-
def list(what, doit = true)
|
95
|
-
names = Regexp.union(*ARGV.empty? ? '' : ARGV)
|
96
|
-
|
97
|
-
Lingo.list(what, path: path_for_scope).select { |file|
|
98
|
-
File.basename(file) =~ names ? doit ? puts(file) : true : false
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
def find(what, doit = true)
|
103
|
-
name = ARGV.shift or missing_arg(:name)
|
104
|
-
no_args
|
105
|
-
|
106
|
-
file = Lingo.find(what, name, path: path_for_scope) { usage }
|
107
|
-
doit ? puts(file) : file
|
108
|
-
end
|
109
|
-
|
110
|
-
def copy(what)
|
111
|
-
usage('Source and target are the same.') if OPTIONS[:scope] == :local
|
112
|
-
|
113
|
-
source = find(what, false)
|
114
|
-
target = File.join(path_for_scope(:local), Lingo.basepath(what, source))
|
115
|
-
|
116
|
-
usage('Source and target are the same.') if source == target
|
117
|
-
|
118
|
-
return unless overwrite?(target)
|
119
|
-
|
120
|
-
FileUtils.mkdir_p(File.dirname(target))
|
121
|
-
FileUtils.cp(source, target, verbose: true)
|
122
|
-
end
|
123
|
-
|
124
|
-
def do_archive
|
125
|
-
OPTIONS.update(path: ARGV.shift, scope: :local)
|
126
|
-
no_args
|
127
|
-
|
128
|
-
source = File.expand_path(path_for_scope.first)
|
129
|
-
target = "#{source}.zip"
|
130
|
-
|
131
|
-
abort "No such directory: #{source}" unless Dir.exist?(source)
|
132
|
-
|
133
|
-
return unless overwrite?(target, true)
|
134
|
-
|
135
|
-
base, name = File.split(source)
|
136
|
-
|
137
|
-
Dir.chdir(base) {
|
138
|
-
Zip::File.open(target, Zip::File::CREATE) { |zipfile|
|
139
|
-
Dir[File.join(name, '**', '*')].each { |file|
|
140
|
-
zipfile.add(file, file)
|
141
|
-
}
|
142
|
-
}
|
143
|
-
}
|
144
|
-
|
145
|
-
puts "Directory successfully archived at `#{target}'."
|
146
|
-
end
|
147
|
-
|
148
|
-
def do_clearstore
|
149
|
-
store = Dir["#{find(:store, false)}.*"]
|
150
|
-
FileUtils.rm(store, verbose: true) unless store.empty?
|
151
|
-
end
|
152
|
-
|
153
|
-
def do_demo
|
154
|
-
OPTIONS.update(path: ARGV.shift, scope: :system)
|
155
|
-
no_args
|
156
|
-
|
157
|
-
path = path_for_scope(:local).first
|
158
|
-
|
159
|
-
copy_list(:config) { |i| !File.basename(i).start_with?('test') }
|
160
|
-
copy_list(:lang)
|
161
|
-
copy_list(:dict) { |i| File.basename(i).start_with?('user') }
|
162
|
-
copy_list(:sample)
|
163
|
-
|
164
|
-
puts "Demo directory successfully initialized at `#{path}'."
|
165
|
-
end
|
166
|
-
|
167
|
-
def do_rackup(doit = true)
|
168
|
-
name = ARGV.shift or missing_arg(:name)
|
169
|
-
no_args
|
170
|
-
|
171
|
-
require 'lingo/app'
|
172
|
-
|
173
|
-
if file = Lingo::App.rackup(name)
|
174
|
-
doit ? puts(file) : file
|
175
|
-
else
|
176
|
-
usage("Invalid app name `#{name.inspect}'.")
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def do_path
|
181
|
-
no_args
|
182
|
-
puts path_for_scope || PATH
|
183
|
-
end
|
184
|
-
|
185
|
-
def do_help(opts = nil)
|
186
|
-
no_args
|
187
|
-
|
188
|
-
msg = opts ? [opts, 'Commands:'] : []
|
189
|
-
|
190
|
-
aliases = Hash.nest { [] }
|
191
|
-
ALIASES.each { |k, v| aliases[v] << k }
|
192
|
-
|
193
|
-
COMMANDS.each { |c, (d, *e)|
|
194
|
-
a = aliases[c]
|
195
|
-
c = "#{c} (#{a.join(', ')})" unless a.empty?
|
196
|
-
|
197
|
-
if opts
|
198
|
-
msg << " %-#{OPTWIDTH}s %s" % [c, d]
|
199
|
-
else
|
200
|
-
msg << "#{c}" << " - #{d}"
|
201
|
-
e.each { |i| msg << " + #{i}" }
|
202
|
-
end
|
203
|
-
}
|
204
|
-
|
205
|
-
abort msg.join("\n")
|
206
|
-
end
|
207
|
-
|
208
|
-
def do_version(doit = true)
|
209
|
-
no_args
|
210
|
-
|
211
|
-
msg = "Lingo v#{Lingo::VERSION}"
|
212
|
-
doit ? puts(msg) : msg
|
213
|
-
end
|
214
|
-
|
215
69
|
def parse_options
|
216
70
|
OptionParser.new(USAGE, OPTWIDTH) { |opts|
|
217
71
|
opts.separator ''
|
@@ -266,12 +120,6 @@ Usage: #{PROG} <command> [arguments] [options]
|
|
266
120
|
usage('Too many arguments.') unless ARGV.empty?
|
267
121
|
end
|
268
122
|
|
269
|
-
def copy_list(what)
|
270
|
-
files = list(what, false)
|
271
|
-
files.select! { |i| yield i } if block_given?
|
272
|
-
files.each { |file| ARGV.replace([file]); copy(what) }
|
273
|
-
end
|
274
|
-
|
275
123
|
def overwrite?(target, unlink = false)
|
276
124
|
!File.exist?(target) || if agree?("#{target} already exists. Overwrite?")
|
277
125
|
File.unlink(target) if unlink
|
@@ -280,7 +128,7 @@ Usage: #{PROG} <command> [arguments] [options]
|
|
280
128
|
end
|
281
129
|
|
282
130
|
def agree?(msg)
|
283
|
-
print "#{msg} (y/n) [n] "
|
131
|
+
print "#{msg} (y/n) [n]: "
|
284
132
|
|
285
133
|
case answer = $stdin.gets.chomp
|
286
134
|
when /\Ano?\z/i, '' then nil
|
@@ -301,3 +149,7 @@ Usage: #{PROG} <command> [arguments] [options]
|
|
301
149
|
end
|
302
150
|
|
303
151
|
end
|
152
|
+
|
153
|
+
require_relative 'ctl/files'
|
154
|
+
require_relative 'ctl/analysis'
|
155
|
+
require_relative 'ctl/other'
|