cr.rb 4.1.4 → 4.1.5
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/exe/cr +67 -0
- data/lib/cr/counter.rb +106 -0
- data/lib/cr/version.rb +3 -3
- data/lib/cr.rb +530 -117
- metadata +20 -5
- data/bin/cr +0 -597
data/lib/cr.rb
CHANGED
@@ -1,36 +1,546 @@
|
|
1
1
|
# ------------------------------------------------------
|
2
2
|
# File : cr.rb
|
3
|
-
# Authors :
|
3
|
+
# Authors : Aoran Zeng <ccmywish@qq.com>
|
4
4
|
# Created on : <2022-04-15>
|
5
|
-
# Last modified : <2023-
|
5
|
+
# Last modified : <2023-05-09>
|
6
6
|
#
|
7
7
|
# cr:
|
8
8
|
#
|
9
9
|
# This file is the lib of `cr.rb``
|
10
10
|
# ------------------------------------------------------
|
11
11
|
|
12
|
-
require '
|
13
|
-
|
12
|
+
require 'colorator'
|
13
|
+
require_relative 'cr/version'
|
14
14
|
|
15
|
-
|
15
|
+
class String
|
16
|
+
def underline = "\e[4m#{self}\e[0m"
|
17
|
+
end
|
18
|
+
|
19
|
+
class CrypticResolver::Resolver
|
20
|
+
|
21
|
+
require_relative 'cr/counter'
|
22
|
+
|
23
|
+
# Notice that we only update the Default library, not Extra library
|
24
|
+
def update_dicts
|
25
|
+
|
26
|
+
@counter.count_def_lib(display: false)
|
27
|
+
old_wc = @counter.word_count_of_def_lib
|
28
|
+
|
29
|
+
puts "cr: Updating all dicts in Default library..."
|
30
|
+
|
31
|
+
begin
|
32
|
+
Dir.chdir DEFAULT_LIB_PATH do
|
33
|
+
if Gem.win_platform?
|
34
|
+
# Windows doesn't have fork
|
35
|
+
Dir.children(DEFAULT_LIB_PATH).each do |dict|
|
36
|
+
next if File.file? dict
|
37
|
+
puts "cr: Wait to update #{dict}..."
|
38
|
+
`git -C ./#{dict} pull -q`
|
39
|
+
end
|
40
|
+
else
|
41
|
+
# *nix
|
42
|
+
Dir.children(DEFAULT_LIB_PATH).each do |dict|
|
43
|
+
next if File.file? dict
|
44
|
+
fork do
|
45
|
+
puts "cr: Wait to update #{dict}..."
|
46
|
+
`git -C ./#{dict} pull -q`
|
47
|
+
end
|
48
|
+
end
|
49
|
+
Process.waitall
|
50
|
+
end # end if/else
|
51
|
+
end
|
52
|
+
|
53
|
+
rescue Interrupt
|
54
|
+
abort "cr: Cancel update"
|
55
|
+
end
|
56
|
+
|
57
|
+
puts "cr: Update done"
|
58
|
+
|
59
|
+
# clear
|
60
|
+
@counter.word_count_of_def_lib = 0
|
61
|
+
# recount
|
62
|
+
@counter.count_def_lib(display: false)
|
63
|
+
|
64
|
+
new_wc = @counter.word_count_of_def_lib
|
65
|
+
puts ; puts "#{new_wc - old_wc} words added in Default library"
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def add_dict(repo)
|
70
|
+
if repo.nil?
|
71
|
+
abort "cr: Need an argument!".bold.red
|
72
|
+
end
|
73
|
+
|
74
|
+
# Simplify adding dictionary
|
75
|
+
if !repo.start_with?("https://") and !repo.start_with?("git@")
|
76
|
+
if repo.include?('/')
|
77
|
+
repo = "https://github.com/#{repo}.git"
|
78
|
+
else
|
79
|
+
repo = "https://github.com/cryptic-resolver/cryptic_#{repo}.git"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
begin
|
84
|
+
puts "cr: Adding new dictionary..."
|
85
|
+
`git -C #{DEFAULT_LIB_PATH} clone #{repo} -q`
|
86
|
+
rescue Interrupt
|
87
|
+
abort "cr: Cancel add dict"
|
88
|
+
end
|
89
|
+
|
90
|
+
puts "cr: Add new dictionary done"
|
91
|
+
|
92
|
+
# github/com/ccmywish/ruby_knowledge(.git)
|
93
|
+
dict = repo.split('/')[-1].delete_suffix('.git')
|
94
|
+
wc = @counter.count_dict_words(DEFAULT_LIB_PATH ,dict)
|
95
|
+
puts ; puts "#{wc} words added"
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def del_dict(repo)
|
100
|
+
if repo.nil?
|
101
|
+
abort "cr: Need an argument!".bold.red
|
102
|
+
end
|
103
|
+
Dir.chdir DEFAULT_LIB_PATH do
|
104
|
+
begin
|
105
|
+
# Dir.rmdir repo # Can't rm a filled dir
|
106
|
+
# FileUtils.rmdir repo # Can't rm a filled dir
|
107
|
+
FileUtils.rm_rf repo
|
108
|
+
puts "cr: Delete dictionary #{repo.bold.green} done"
|
109
|
+
rescue Exception => e
|
110
|
+
puts "cr: #{e}".bold.red
|
111
|
+
list_dicts
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def load_sheet(library, dict, sheet_name)
|
118
|
+
file = library + "/#{dict}/#{sheet_name}.toml"
|
119
|
+
if File.exist? file
|
120
|
+
return Tomlrb.load_file file # gem 'tomlrb'
|
121
|
+
# return TOML.load_file file # gem 'toml'
|
122
|
+
else nil end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
=begin
|
127
|
+
Pretty print the info of the given word
|
128
|
+
|
129
|
+
A info looks like this
|
130
|
+
emacs = {
|
131
|
+
name = "Emacs"
|
132
|
+
desc = "edit macros"
|
133
|
+
more = "a feature-rich editor"
|
134
|
+
see = ["Vim"]
|
135
|
+
}
|
136
|
+
|
137
|
+
@param info [Hash] the information of the given word (mapped to a keyword in TOML)
|
138
|
+
=end
|
139
|
+
def pp_info(info)
|
140
|
+
name = info['name'] || "No name!".red # keyword `or` is invalid here in Ruby
|
141
|
+
|
142
|
+
desc = info['desc']
|
143
|
+
more = info['more']
|
144
|
+
|
145
|
+
if desc
|
146
|
+
puts "\n #{name}: #{desc}"
|
147
|
+
print "\n ",more,"\n" if more
|
148
|
+
else
|
149
|
+
puts "\n #{name}"
|
150
|
+
print "\n ",more,"\n" if more
|
151
|
+
end
|
152
|
+
|
153
|
+
if see_also = info['see']
|
154
|
+
print "\n", "SEE ALSO ".magenta
|
155
|
+
if see_also.is_a?(Array)
|
156
|
+
last_ndx = see_also.size - 1
|
157
|
+
see_also.each_with_index do |x,i|
|
158
|
+
if last_ndx == i
|
159
|
+
print x.underline # Last word doesn't show space
|
160
|
+
else
|
161
|
+
print x.underline, ' '
|
162
|
+
end
|
163
|
+
end
|
164
|
+
else
|
165
|
+
print see_also.underline
|
166
|
+
end
|
167
|
+
puts
|
168
|
+
end
|
169
|
+
puts
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
# Print default cryptic_ dicts
|
174
|
+
def pp_dict(dict)
|
175
|
+
puts "From: #{dict}".green
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
=begin
|
180
|
+
Used for synonym jump
|
181
|
+
Because we absolutely jump to a must-have word
|
182
|
+
So we can directly lookup to it
|
183
|
+
|
184
|
+
Notice that, we must jump to a specific word definition
|
185
|
+
So in the toml file, you must specify the precise word.
|
186
|
+
If it has multiple meanings, for example
|
187
|
+
|
188
|
+
[blah]
|
189
|
+
same = "xdg" # this is wrong, because xdg has multiple
|
190
|
+
# definitions, and all of them specify a
|
191
|
+
# category
|
192
|
+
|
193
|
+
[blah]
|
194
|
+
same = "XDG downloader =>xdg.Download" # this is correct
|
195
|
+
|
196
|
+
[blah]
|
197
|
+
name = "BlaH" # You may want to display a better name first
|
198
|
+
same = "XDG downloader =>xdg.Download" # this is correct
|
199
|
+
=end
|
200
|
+
def pp_same_info(library, dict, word, cache_content, same_key, own_name)
|
201
|
+
|
202
|
+
# If it's a synonym for anther word,
|
203
|
+
# we should lookup into this dict again, but maybe with a different file
|
204
|
+
|
205
|
+
# file name
|
206
|
+
x = word.chr.downcase
|
207
|
+
|
208
|
+
=begin
|
209
|
+
dictionary maintainer must obey the rule for xxx.yyy word:
|
210
|
+
xxx should be lower case
|
211
|
+
yyy can be any case
|
212
|
+
|
213
|
+
Because yyy should clearly explain the category info, IBM is better than ibm
|
214
|
+
Implementation should not be too simple if we want to stress the function we
|
215
|
+
expect.
|
216
|
+
|
217
|
+
'jump to' will output to user, so this is important not only inside our sheet.
|
218
|
+
|
219
|
+
same = "XDM downloader=>xdm.Download"
|
220
|
+
|
221
|
+
We split 'same' key into two parts via spaceship symbol `=>`, first part will
|
222
|
+
output to user, the second part is for internal jump.
|
223
|
+
=end
|
224
|
+
jump_to, same = same_key.split("=>")
|
225
|
+
same = jump_to if same.nil?
|
226
|
+
|
227
|
+
unless own_name
|
228
|
+
own_name = word
|
229
|
+
end
|
230
|
+
puts own_name.bold.blue + ' redirects to ' + jump_to.bold.blue
|
231
|
+
|
232
|
+
=begin
|
233
|
+
As '.' is used to delimit a word and a category, what if
|
234
|
+
we jump to a dotted word?
|
235
|
+
|
236
|
+
[eg]
|
237
|
+
same = "e.g." # this must lead to a wrong resolution to
|
238
|
+
# word 'e', category 'g'
|
239
|
+
|
240
|
+
All you need is to be like this:
|
241
|
+
|
242
|
+
[eg]
|
243
|
+
same = "'e.g.'" # cr will notice the single quote
|
244
|
+
=end
|
245
|
+
if same =~ /^'(.*)'$/
|
246
|
+
same, category = $1, nil
|
247
|
+
else
|
248
|
+
same, category = same.split('.')
|
249
|
+
end
|
250
|
+
|
251
|
+
if same.chr == x
|
252
|
+
# No need to load another dictionary if match
|
253
|
+
sheet_content = cache_content
|
254
|
+
else
|
255
|
+
sheet_content = load_sheet(library, dict, same.chr.downcase)
|
256
|
+
end
|
257
|
+
|
258
|
+
if category.nil?
|
259
|
+
info = sheet_content[same]
|
260
|
+
else
|
261
|
+
info = sheet_content[same][category]
|
262
|
+
end
|
263
|
+
|
264
|
+
if info.nil?
|
265
|
+
puts "WARN: Synonym jumps to the wrong place `#{same}`,
|
266
|
+
Please consider fixing this in `#{x}.toml` of the dictionary `#{dict}`".red
|
267
|
+
# exit
|
268
|
+
return false
|
269
|
+
# double or more jumps
|
270
|
+
elsif same_key = info['same']
|
271
|
+
own_name = info['name']
|
272
|
+
return pp_same_info(library, dict, same, cache_content, same_key, own_name)
|
273
|
+
else
|
274
|
+
pp_info(info)
|
275
|
+
return true
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
#
|
282
|
+
# Lookup the given word in a sheet (a toml file) and also print.
|
283
|
+
# The core idea is that:
|
284
|
+
#
|
285
|
+
# 1. if the word is `same` with another synonym, it will directly jump to
|
286
|
+
# a word in this dictionary, but maybe a different sheet.
|
287
|
+
#
|
288
|
+
# 2. load the toml file and check the given word
|
289
|
+
# 2.1 with no category specifier
|
290
|
+
# [abcd]
|
291
|
+
# 2.2 with category specifier
|
292
|
+
# [abcd.tYPe]
|
293
|
+
#
|
294
|
+
def lookup(library, dict, file, word)
|
295
|
+
sheet_content = load_sheet(library, dict, file)
|
296
|
+
return false if sheet_content.nil?
|
297
|
+
|
298
|
+
info = sheet_content[word]
|
299
|
+
return false if info.nil?
|
300
|
+
|
301
|
+
# Warn if the info is empty. For example:
|
302
|
+
# emacs = { }
|
303
|
+
if info.size == 0
|
304
|
+
abort "WARN: Lack of everything of the given word
|
305
|
+
Please consider fixing this in the dict `#{dict}`".red
|
306
|
+
end
|
307
|
+
|
308
|
+
# Word with no category specifier
|
309
|
+
# We call this meaning as type 1
|
310
|
+
type_1_exist_flag = false
|
311
|
+
|
312
|
+
# if already jump, don't check the word itself
|
313
|
+
is_jump = false
|
314
|
+
|
315
|
+
# synonym info print
|
316
|
+
if same_key = info['same']
|
317
|
+
own_name = info['name']
|
318
|
+
pp_dict(dict)
|
319
|
+
pp_same_info(library, dict, word, sheet_content, same_key, own_name)
|
320
|
+
# It's also a type 1
|
321
|
+
type_1_exist_flag = true
|
322
|
+
is_jump = true
|
323
|
+
end
|
16
324
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
325
|
+
# normal info print
|
326
|
+
# To developer:
|
327
|
+
# The word should at least has one of `desc` and `more`
|
328
|
+
# But when none exists, this may not be considered wrong,
|
329
|
+
# Because the type2 make the case too.
|
330
|
+
#
|
331
|
+
# So, just ignore it, even if it's really a mistake(insignificant)
|
332
|
+
# by dictionary maintainers.
|
333
|
+
#
|
334
|
+
if !is_jump && (info.has_key?('desc') || info.has_key?('more'))
|
335
|
+
pp_dict(dict)
|
336
|
+
pp_info(info)
|
337
|
+
type_1_exist_flag = true
|
338
|
+
end
|
339
|
+
|
340
|
+
# Meanings with category specifier
|
341
|
+
# We call this meaning as type 2
|
342
|
+
categories = info.keys - ["name", "desc", "more", "same", "see"]
|
343
|
+
|
344
|
+
if !categories.empty?
|
345
|
+
|
346
|
+
if type_1_exist_flag
|
347
|
+
print "OR".bold.blue, "\n"
|
348
|
+
else
|
349
|
+
pp_dict(dict)
|
350
|
+
end
|
351
|
+
|
352
|
+
categories.each do |meaning|
|
353
|
+
info0 = sheet_content[word][meaning]
|
354
|
+
if same_key = info0['same']
|
355
|
+
own_name = info0['name']
|
356
|
+
pp_same_info(library, dict, word, sheet_content, same_key, own_name)
|
357
|
+
else
|
358
|
+
pp_info(info0)
|
359
|
+
end
|
360
|
+
|
361
|
+
# last meaning doesn't show this separate line
|
362
|
+
print "OR".bold.blue, "\n" unless categories.last == meaning
|
363
|
+
end
|
364
|
+
return true
|
365
|
+
elsif type_1_exist_flag then return true
|
366
|
+
else return false end
|
367
|
+
end
|
368
|
+
|
369
|
+
|
370
|
+
#
|
371
|
+
# The main procedure of `cr`
|
372
|
+
#
|
373
|
+
# 1. Search the default library first
|
374
|
+
# 2. Search the extra library if it does exist
|
375
|
+
#
|
376
|
+
# The `search` is done via the `lookup` function. It will print
|
377
|
+
# the info while finding. If `lookup` always return false then
|
378
|
+
# means lacking of this word in our dicts. So a welcomed
|
379
|
+
# contribution is printed on the screen.
|
380
|
+
#
|
381
|
+
def resolve_word(word)
|
382
|
+
|
383
|
+
word = word.downcase # downcase! would lead to frozen error in Ruby 2.7.2
|
384
|
+
# The index is the toml file we'll look into
|
385
|
+
index = word.chr
|
386
|
+
case index
|
387
|
+
when '0'..'9'
|
388
|
+
index = '0-9'
|
389
|
+
end
|
390
|
+
|
391
|
+
# cache lookup's results
|
392
|
+
results = []
|
393
|
+
|
394
|
+
# First consider the default library
|
395
|
+
default = Dir.children(DEFAULT_LIB_PATH)
|
396
|
+
default.each do |dict|
|
397
|
+
results << lookup(DEFAULT_LIB_PATH,dict,index,word)
|
398
|
+
end
|
399
|
+
|
400
|
+
# Then is the extra library
|
401
|
+
if @extra_lib_path
|
402
|
+
extra = Dir.children(@extra_lib_path)
|
403
|
+
extra.each do |dict|
|
404
|
+
results << lookup(@extra_lib_path,dict,index,word)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
unless results.include? true
|
409
|
+
puts <<~NotFound
|
410
|
+
cr: Not found anything about '#{word}'. You could try
|
411
|
+
|
412
|
+
#{"case 1: Update all dictionaries".blue}
|
413
|
+
#{"$ cr -u".yellow}
|
414
|
+
#{"case 2: List available official and feature dictionaries".blue}
|
415
|
+
#{"$ cr -l".yellow}
|
416
|
+
#{"$ cr -a repo".yellow} (Add a specific dict to default lib)
|
417
|
+
#{"case 3: Contribute to theses dictionaries".blue}
|
418
|
+
Visit: https://github.com/cryptic-resolver
|
419
|
+
|
420
|
+
NotFound
|
421
|
+
else return end
|
422
|
+
end
|
423
|
+
|
424
|
+
|
425
|
+
#
|
426
|
+
# Delegate to `search_word_internal`
|
427
|
+
#
|
428
|
+
def search_word(pattern)
|
429
|
+
found_or_not1 = false
|
430
|
+
found_or_not2 = false
|
431
|
+
|
432
|
+
found_or_not1 = search_word_internal(pattern, DEFAULT_LIB_PATH)
|
433
|
+
if @extra_lib_path
|
434
|
+
found_or_not2 = search_word_internal(pattern, @extra_lib_path)
|
435
|
+
end
|
436
|
+
|
437
|
+
if (found_or_not1 == false) && (found_or_not2 == false)
|
438
|
+
puts "cr: No words match with #{pattern.inspect}".red ; puts
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
#
|
443
|
+
# This `search_word_internal` routine is quite like `resolve_word`
|
444
|
+
# Notice:
|
445
|
+
# We handle two cases
|
446
|
+
#
|
447
|
+
# 1. the 'pattern' is the regexp itself
|
448
|
+
# 2. the 'pattern' is like '/blah/'
|
449
|
+
#
|
450
|
+
# The second is what Ruby and Perl users like to do, handle it!
|
451
|
+
#
|
452
|
+
def search_word_internal(pattern, library)
|
453
|
+
|
454
|
+
if pattern.nil?
|
455
|
+
abort "cr: Need an argument!".bold.red
|
456
|
+
end
|
457
|
+
|
458
|
+
if pattern =~ /^\/(.*)\/$/
|
459
|
+
regexp = %r[#$1]
|
460
|
+
else
|
461
|
+
regexp = %r[#{pattern}]
|
462
|
+
end
|
463
|
+
|
464
|
+
found_or_not = false
|
465
|
+
|
466
|
+
# Try to match every word in all dicts
|
467
|
+
Dir.children(library).each do |dict|
|
468
|
+
|
469
|
+
path = File.join(library, dict)
|
470
|
+
next if File.file? path
|
471
|
+
sheets = Dir.children(path).select do
|
472
|
+
_1.end_with?('.toml')
|
473
|
+
end
|
474
|
+
|
475
|
+
similar_words_in_a_dict = []
|
476
|
+
|
477
|
+
sheets.each do |sheet|
|
478
|
+
sheet_content = load_sheet(library, dict, File.basename(sheet,'.toml'))
|
479
|
+
|
480
|
+
sheet_content.keys.each do
|
481
|
+
if _1 =~ regexp
|
482
|
+
found_or_not = true
|
483
|
+
similar_words_in_a_dict << _1
|
484
|
+
end
|
485
|
+
end
|
486
|
+
# end of each sheet in a dict
|
487
|
+
end
|
488
|
+
|
489
|
+
unless similar_words_in_a_dict.empty?
|
490
|
+
pp_dict(dict)
|
491
|
+
require 'ls_table'
|
492
|
+
LsTable.ls(similar_words_in_a_dict) do |e|
|
493
|
+
puts e.blue
|
494
|
+
end
|
495
|
+
puts
|
496
|
+
end
|
497
|
+
end
|
498
|
+
return found_or_not
|
499
|
+
end
|
500
|
+
|
501
|
+
|
502
|
+
# 1. List Default library's dicts
|
503
|
+
# 2. List Extra library's dicts
|
504
|
+
# 3. List official dicts
|
505
|
+
def list_dicts
|
506
|
+
|
507
|
+
def _do_the_same_thing
|
508
|
+
count = 0
|
509
|
+
Dir.children(".").each do |dict|
|
510
|
+
next if File.file? dict
|
511
|
+
count += 1
|
512
|
+
prefix = (count.to_s + '.').ljust 4
|
513
|
+
puts " #{prefix}#{dict}"
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
Dir.chdir DEFAULT_LIB_PATH do
|
518
|
+
puts "Default library: #{DEFAULT_LIB_PATH}".bold.green
|
519
|
+
_do_the_same_thing
|
520
|
+
end
|
521
|
+
|
522
|
+
if @extra_lib_path
|
523
|
+
puts
|
524
|
+
Dir.chdir @extra_lib_path do
|
525
|
+
puts "Extra library: #{@extra_lib_path}".bold.green
|
526
|
+
_do_the_same_thing
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
puts ; puts "Official dictionaries: (Add it by 'cr -a xxx')".bold.green
|
531
|
+
puts RECOMMENDED_DICTS
|
532
|
+
end
|
533
|
+
|
534
|
+
|
535
|
+
def word_count
|
536
|
+
@counter.count!(display: true)
|
26
537
|
end
|
27
538
|
|
28
539
|
end
|
29
540
|
|
30
541
|
|
31
|
-
class CrypticResolver::Resolver
|
32
542
|
|
33
|
-
|
543
|
+
class CrypticResolver::Resolver
|
34
544
|
|
35
545
|
require 'tomlrb'
|
36
546
|
require 'fileutils'
|
@@ -47,21 +557,19 @@ class CrypticResolver::Resolver
|
|
47
557
|
"https://github.com/cryptic-resolver/cryptic_technology"
|
48
558
|
]
|
49
559
|
|
50
|
-
extend CrypticResolver::Color
|
51
|
-
|
52
560
|
RECOMMENDED_DICTS = <<~EOF
|
53
|
-
#{
|
561
|
+
#{"Default:".yellow}
|
54
562
|
common computer windows
|
55
563
|
linux technology
|
56
564
|
|
57
|
-
#{
|
565
|
+
#{"Field:".yellow}
|
58
566
|
economy medicine electronics
|
59
567
|
science math
|
60
568
|
|
61
|
-
#{
|
569
|
+
#{"Specific:".yellow}
|
62
570
|
x86 signal
|
63
571
|
|
64
|
-
#{
|
572
|
+
#{"Feature:".yellow}
|
65
573
|
ccmywish/CRuby-Source-Code-Dictionary
|
66
574
|
|
67
575
|
EOF
|
@@ -164,99 +672,4 @@ class CrypticResolver::Resolver
|
|
164
672
|
return false
|
165
673
|
end
|
166
674
|
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
|
171
|
-
class CrypticResolver::Resolver::Counter
|
172
|
-
|
173
|
-
include CrypticResolver::Color
|
174
|
-
|
175
|
-
attr_accessor :word_count_of_two_libs, # def_lib + extra_lib
|
176
|
-
:word_count_of_def_lib,
|
177
|
-
:word_count_of_extra_lib,
|
178
|
-
|
179
|
-
:resolver
|
180
|
-
|
181
|
-
def initialize(resolver)
|
182
|
-
@word_count_of_two_libs = 0
|
183
|
-
@word_count_of_def_lib = 0
|
184
|
-
@word_count_of_extra_lib = 0
|
185
|
-
@resolver = resolver
|
186
|
-
end
|
187
|
-
|
188
|
-
# a.toml
|
189
|
-
# b.toml
|
190
|
-
# ...
|
191
|
-
def count_dict_words(library, dict)
|
192
|
-
dict_dir = library + "/#{dict}"
|
193
|
-
wc = 0
|
194
|
-
Dir.children(dict_dir).each do |entry|
|
195
|
-
next unless entry.end_with?('.toml')
|
196
|
-
next if File.directory? dict_dir + "/#{entry}"
|
197
|
-
sheet_content = @resolver.load_sheet(library, dict, entry.delete_suffix('.toml'))
|
198
|
-
count = sheet_content.keys.count
|
199
|
-
|
200
|
-
wc = wc + count
|
201
|
-
end
|
202
|
-
return wc
|
203
|
-
end
|
204
|
-
|
205
|
-
|
206
|
-
# Count default library
|
207
|
-
def count_def_lib(display: )
|
208
|
-
path = CrypticResolver::Resolver::DEFAULT_LIB_PATH
|
209
|
-
default_lib = Dir.children path
|
210
|
-
unless default_lib.empty?
|
211
|
-
puts bold(green("Default library: ")) if display
|
212
|
-
default_lib.each do |s|
|
213
|
-
next if File.file? path + "/#{s}"
|
214
|
-
wc = count_dict_words(path,s)
|
215
|
-
@word_count_of_def_lib += wc
|
216
|
-
# With color, ljust not works, so we disable color
|
217
|
-
puts("#{wc.to_s.rjust(5)} #{s}") if display
|
218
|
-
end
|
219
|
-
end
|
220
|
-
return @word_count_of_def_lib
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
# Count extra library
|
225
|
-
def count_extra_lib(display: )
|
226
|
-
if path = @resolver.extra_lib_path
|
227
|
-
extra_lib = Dir.children path
|
228
|
-
unless extra_lib.empty?
|
229
|
-
puts bold(green("\nExtra library:")) if display
|
230
|
-
extra_lib.each do |s|
|
231
|
-
next if File.file? path + "/#{s}"
|
232
|
-
wc = count_dict_words(path,s)
|
233
|
-
@word_count_of_extra_lib += wc
|
234
|
-
puts("#{wc.to_s.rjust(5)} #{s}") if display
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
return @word_count_of_extra_lib
|
239
|
-
end
|
240
|
-
|
241
|
-
|
242
|
-
def count!(display: )
|
243
|
-
count_def_lib(display: display)
|
244
|
-
count_extra_lib(display: display)
|
245
|
-
@word_count_of_two_libs = @word_count_of_def_lib + @word_count_of_extra_lib
|
246
|
-
|
247
|
-
if display
|
248
|
-
puts
|
249
|
-
puts "#{@word_count_of_def_lib.to_s.rjust(4)} words in Default library"
|
250
|
-
puts "#{@word_count_of_extra_lib.to_s.rjust(4) } words in Extra library"
|
251
|
-
puts "#{@word_count_of_two_libs.to_s.rjust(4) } words altogether"
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
def reset!
|
257
|
-
@word_count_of_two_libs = 0
|
258
|
-
@word_count_of_def_lib = 0
|
259
|
-
@word_count_of_extra_lib = 0
|
260
|
-
end
|
261
|
-
|
262
675
|
end
|