lingo 1.8.6 → 1.8.7

Sign up to get free protection for your applications and to get access to all the features.
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'