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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +40 -4
  3. data/README +22 -51
  4. data/Rakefile +3 -17
  5. data/config/lingo.cfg +24 -15
  6. data/config/lir.cfg +25 -16
  7. data/dict/de/test_muh.txt +6 -0
  8. data/dict/en/lingo-dic.txt +2 -3
  9. data/lang/de.lang +10 -9
  10. data/lang/en.lang +1 -1
  11. data/lib/lingo.rb +4 -4
  12. data/lib/lingo/attendee.rb +27 -7
  13. data/lib/lingo/attendee/analysis_filter.rb +81 -0
  14. data/lib/lingo/attendee/debug_filter.rb +42 -0
  15. data/lib/lingo/attendee/debugger.rb +2 -11
  16. data/lib/lingo/attendee/decomposer.rb +6 -3
  17. data/lib/lingo/attendee/formatter.rb +6 -6
  18. data/lib/lingo/attendee/hal_filter.rb +94 -0
  19. data/lib/lingo/attendee/lsi_filter.rb +99 -0
  20. data/lib/lingo/attendee/multi_worder.rb +69 -43
  21. data/lib/lingo/attendee/sequencer.rb +32 -19
  22. data/lib/lingo/attendee/synonymer.rb +2 -2
  23. data/lib/lingo/attendee/text_reader.rb +63 -92
  24. data/lib/lingo/attendee/text_writer.rb +12 -21
  25. data/lib/lingo/attendee/tokenizer.rb +32 -21
  26. data/lib/lingo/attendee/variator.rb +3 -3
  27. data/lib/lingo/attendee/vector_filter.rb +7 -9
  28. data/lib/lingo/attendee/word_searcher.rb +3 -3
  29. data/lib/lingo/buffered_attendee.rb +3 -36
  30. data/lib/lingo/config.rb +1 -1
  31. data/lib/lingo/ctl.rb +7 -155
  32. data/lib/lingo/ctl/analysis.rb +136 -0
  33. data/lib/lingo/ctl/files.rb +86 -0
  34. data/lib/lingo/ctl/other.rb +140 -0
  35. data/lib/lingo/database.rb +64 -60
  36. data/lib/lingo/database/crypter.rb +7 -5
  37. data/lib/lingo/error.rb +5 -4
  38. data/lib/lingo/language.rb +13 -5
  39. data/lib/lingo/language/grammar.rb +13 -7
  40. data/lib/lingo/language/token.rb +6 -0
  41. data/lib/lingo/language/word.rb +23 -36
  42. data/lib/lingo/language/word_form.rb +5 -1
  43. data/lib/lingo/srv.rb +2 -2
  44. data/lib/lingo/text_utils.rb +96 -0
  45. data/lib/lingo/version.rb +1 -1
  46. data/lib/lingo/web/views/index.erb +1 -1
  47. data/test/attendee/ts_decomposer.rb +23 -5
  48. data/test/attendee/ts_multi_worder.rb +66 -0
  49. data/test/attendee/ts_sequencer.rb +28 -4
  50. data/test/attendee/ts_text_reader.rb +20 -0
  51. data/test/attendee/ts_tokenizer.rb +20 -0
  52. data/test/attendee/ts_variator.rb +1 -1
  53. data/test/attendee/ts_word_searcher.rb +39 -3
  54. data/test/lir3.txt +12 -0
  55. data/test/ref/artikel.non +1 -12
  56. data/test/ref/artikel.seq +3 -1
  57. data/test/ref/artikel.vec +1 -0
  58. data/test/ref/artikel.vef +35 -34
  59. data/test/ref/artikel.ven +8 -7
  60. data/test/ref/artikel.ver +34 -33
  61. data/test/ref/artikel.vet +2573 -2563
  62. data/test/ref/lir.non +77 -78
  63. data/test/ref/lir.seq +9 -7
  64. data/test/ref/lir.syn +1 -1
  65. data/test/ref/lir.vec +41 -41
  66. data/test/ref/lir.vef +210 -210
  67. data/test/ref/lir.ven +46 -46
  68. data/test/ref/lir.ver +72 -72
  69. data/test/ref/lir.vet +329 -329
  70. data/test/ts_database.rb +166 -62
  71. data/test/ts_language.rb +23 -23
  72. metadata +53 -34
  73. data/lib/lingo/attendee/dehyphenizer.rb +0 -120
  74. data/lib/lingo/attendee/noneword_filter.rb +0 -115
  75. 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-2014 John Vorhauer, Jens Wille #
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
- if stdout?(@ext)
101
- @filename, @file = @ext, lingo.config.stdout
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 : @file.print(@sep)
134
- @file.print(obj)
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
- @file.print(*buf)
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-2014 John Vorhauer, Jens Wille #
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
- ['SPAC', /^\s+/],
91
- ['WIKI', /^=+.+=+|^__[A-Z]+__/],
92
- ['NUMS', /^[+-]?(?:\d{4,}|\d{1,3}(?:\.\d{3,3})*)(?:\.|(?:,\d+)?%?)/],
93
- ['URLS', /^(?:www\.|mailto:|#{PROTO}|\S+?[._]\S+?@\S+?\.)[^\s<>]+/],
94
- ['ABRV', /^(?:(?:(?:#{CHAR})+\.)+)(?:#{CHAR})+/],
95
- ['WORD', /^(?:#{CHAR}|#{DIGIT}|-)+/],
96
- ['PUNC', /^[!,.:;?¡¿]+/]
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
- ['OTHR', /^["$#%&'()*+\/<=>@\[\\\]^_{|}~¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾×÷„“–]/],
101
- ['HELP', /^\S+/]
109
+ [TA_OTHER,
110
+ /^[-"$#%&'()*+\/<=>@\[\\\]^_{|}~¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾×÷„“–]/],
111
+ [TA_HELP,
112
+ /^\S+/]
102
113
  ]
103
114
 
104
115
  NESTS = {
105
- 'HTML' => ['<', '>'],
106
- 'WIKI:VARIABLE' => ['{{{', '}}}'],
107
- 'WIKI:TEMPLATE' => ['{{', '}}'],
108
- 'WIKI:LINK_INT' => ['[[', ']]'],
109
- 'WIKI:LINK_EXT' => [/^\[\s*#{PROTO}/, ']']
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 = get_array('skip-tags', '', :downcase)
176
+ @skip_tags = get_ary('skip-tags', '', :downcase)
166
177
  @tags = true unless @skip_tags.empty?
167
178
 
168
179
  skip = []
169
- skip << 'HTML' unless @tags
170
- skip << 'WIKI' unless @wiki
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 != 'SPAC' || @space
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 : 'SKIP',
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 == 'HTML' && !@skip_tags.empty?
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, Noneword_filter oder Vector_filter
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 = get_key('max-var', max = 10000).to_i
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
- get_array('check', WA_UNKNOWN).each { |s| @check[s.upcase] = true }
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-2014 John Vorhauer, Jens Wille #
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 = get_array('skip', DEFAULT_SKIP, :upcase)
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.nest(1) { [] }, Hash.new(0)
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 = get_array('tokens', '', :upcase)
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.get_class(@lex).each { |lex| forward_vector(lex, pos, lex.src) }
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.get_class(@lex).map { |lex|
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.lexicals.first.form : obj.form
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, Noneword_filter, Vector_filter
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.is_a?(Token) && obj.word? ?
81
- @dic.find_word(obj.form, obj) : obj)
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-2012 John Vorhauer, Jens Wille #
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
- !instance_variable_defined?(:@expected_tokens_in_buffer) ||
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
@@ -61,7 +61,7 @@ class Lingo
61
61
  attr_reader :language_file, :config_file
62
62
 
63
63
  def to_h
64
- @opts
64
+ { 'version' => VERSION }.merge(@opts)
65
65
  end
66
66
 
67
67
  def [](key)
@@ -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-2014 John Vorhauer, Jens Wille #
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.2', 18
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'