cr.rb 3.17.0

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 (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/cr +714 -0
  3. metadata +76 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7bcff493846a9384661cdbeccdb88a225d5f0a7b180f97e04feeda0ba3e1c5e4
4
+ data.tar.gz: a4916f5e641026b1905ccd88c3e7f4ab94f55aff93be0caca2b2a4e6cc75cbc6
5
+ SHA512:
6
+ metadata.gz: 100baa0634561310d3cbaa612b3cebb2b22d59215bdb4c0f19d74bbf6c5517fc10f80c75b289dd1fe3e2c3b1583a2198f5413a0018e8d9b135bbe0b65f23db45
7
+ data.tar.gz: 90a547412b1a4139dd49e93459ef0873501a3b796fee0b616922532746bdaec43d5eec8caca3820e9c3f5233c6fd826e452494952b7f1253d45cac76f1d6f6f3
data/bin/cr ADDED
@@ -0,0 +1,714 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ # ------------------------------------------------------
4
+ # File : cr.rb
5
+ # Authors : ccmywish <ccmywish@qq.com>
6
+ # Created on : <2021-07-08>
7
+ # Last modified : <2022-04-11>
8
+ #
9
+ # cr:
10
+ #
11
+ # This file is used to explain a CRyptic command
12
+ # or an acronym's real meaning in computer world or
13
+ # other fields.
14
+ #
15
+ # ------------------------------------------------------
16
+
17
+ require 'tomlrb'
18
+ require 'fileutils'
19
+
20
+ CRYPTIC_RESOLVER_HOME = File.expand_path("~/.cryptic-resolver")
21
+ CRYPTIC_DEFAULT_DICTS = {
22
+ computer: "https://github.com/cryptic-resolver/cryptic_computer.git",
23
+ common: "https://github.com/cryptic-resolver/cryptic_common.git",
24
+ science: "https://github.com/cryptic-resolver/cryptic_science.git",
25
+ economy: "https://github.com/cryptic-resolver/cryptic_economy.git",
26
+ medicine: "https://github.com/cryptic-resolver/cryptic_medicine.git"
27
+ }
28
+
29
+ CR_GEM_VERSION = "3.17.0"
30
+
31
+
32
+ ####################
33
+ # helper: for color
34
+ ####################
35
+
36
+ def bold(str) "\e[1m#{str}\e[0m" end
37
+ def underline(str) "\e[4m#{str}\e[0m" end
38
+ def red(str) "\e[31m#{str}\e[0m" end
39
+ def green(str) "\e[32m#{str}\e[0m" end
40
+ def yellow(str) "\e[33m#{str}\e[0m" end
41
+ def blue(str) "\e[34m#{str}\e[0m" end
42
+ def purple(str) "\e[35m#{str}\e[0m" end
43
+ def cyan(str) "\e[36m#{str}\e[0m" end
44
+
45
+
46
+ ####################
47
+ # core: logic
48
+ ####################
49
+
50
+ def is_there_any_dict?
51
+ unless Dir.exist? CRYPTIC_RESOLVER_HOME
52
+ Dir.mkdir CRYPTIC_RESOLVER_HOME
53
+ end
54
+
55
+ !Dir.empty? CRYPTIC_RESOLVER_HOME
56
+ end
57
+
58
+
59
+ def add_default_dicts_if_none_exists
60
+ unless is_there_any_dict?
61
+ puts "cr: Adding default dictionaries..."
62
+
63
+ begin
64
+ if RUBY_PLATFORM.include? "mingw"
65
+ # Windows doesn't have fork
66
+ CRYPTIC_DEFAULT_DICTS.each do |key, dict|
67
+ puts "cr: Pulling cryptic_#{key}..."
68
+ `git -C #{CRYPTIC_RESOLVER_HOME} clone #{dict} -q`
69
+ end
70
+ else
71
+ # *nix
72
+ CRYPTIC_DEFAULT_DICTS.each do |key, dict|
73
+ fork do
74
+ puts "cr: Pulling cryptic_#{key}..."
75
+ `git -C #{CRYPTIC_RESOLVER_HOME} clone #{dict} -q`
76
+ end
77
+ end
78
+ Process.waitall
79
+ end
80
+
81
+ rescue Interrupt
82
+ puts "cr: Cancel add default dicts"
83
+ exit 1
84
+ end
85
+
86
+ puts "cr: Add done"
87
+ word_count(p: false)
88
+ puts
89
+ puts "#{$WordCount} words added"
90
+
91
+ # Really added
92
+ return true
93
+ end
94
+ # Not added
95
+ return false
96
+ end
97
+
98
+
99
+ def update_dicts()
100
+ return if add_default_dicts_if_none_exists
101
+
102
+ word_count(p: false)
103
+ old_wc = [$DefaultWordCount, $WordCount-$DefaultWordCount, $WordCount]
104
+
105
+ puts "cr: Updating all dictionaries..."
106
+
107
+ begin
108
+ Dir.chdir CRYPTIC_RESOLVER_HOME do
109
+
110
+ if RUBY_PLATFORM.include? "mingw"
111
+ # Windows doesn't have fork
112
+ Dir.children(CRYPTIC_RESOLVER_HOME).each do |dict|
113
+ puts "cr: Wait to update #{dict}..."
114
+ `git -C ./#{dict} pull -q`
115
+ end
116
+ else
117
+ # *nix
118
+ Dir.children(CRYPTIC_RESOLVER_HOME).each do |dict|
119
+ fork do
120
+ puts "cr: Wait to update #{dict}..."
121
+ `git -C ./#{dict} pull -q`
122
+ end
123
+ end
124
+ Process.waitall
125
+
126
+ end # end if/else
127
+ end
128
+
129
+ rescue Interrupt
130
+ puts "cr: Cancel update"
131
+ exit 1
132
+ end
133
+
134
+
135
+ puts "cr: Update done"
136
+
137
+ # clear
138
+ $DefaultWordCount, $WordCount = 0, 0
139
+ # recount
140
+ word_count(p: false)
141
+ new_wc = [$DefaultWordCount, $WordCount-$DefaultWordCount, $WordCount]
142
+ diff = []
143
+ new_wc.each_with_index do
144
+ diff[_2] = _1 - old_wc[_2]
145
+ end
146
+
147
+ puts
148
+ puts "#{diff.[]2} words added: default/#{diff.[]0} user/#{diff.[]1}"
149
+
150
+ end
151
+
152
+
153
+ def add_dict(repo)
154
+ if repo.nil?
155
+ puts bold(red("cr: Need an argument!"))
156
+ exit -1
157
+ end
158
+
159
+ begin
160
+ puts "cr: Adding new dictionary..."
161
+ `git -C #{CRYPTIC_RESOLVER_HOME} clone #{repo} -q`
162
+ rescue Interrupt
163
+ puts "cr: Cancel add dict"
164
+ exit 1
165
+ end
166
+
167
+ puts "cr: Add new dictionary done"
168
+
169
+ # github/com/ccmywish/ruby_knowledge(.git)
170
+ dict = repo.split('/')[-1].delete_suffix('.git')
171
+ count_dict_words(dict)
172
+ puts
173
+ puts "#$WordCount words added"
174
+
175
+ end
176
+
177
+
178
+ def del_dict(repo)
179
+ if repo.nil?
180
+ puts bold(red("cr: Need an argument!"))
181
+ exit -1
182
+ end
183
+ Dir.chdir CRYPTIC_RESOLVER_HOME do
184
+ begin
185
+ # Dir.rmdir repo # Can't rm a filled dir
186
+ # FileUtils.rmdir repo # Can't rm a filled dir
187
+ FileUtils.rm_rf repo
188
+ puts "cr: Delete dictionary #{bold(green(repo))} done"
189
+ rescue Exception => e
190
+ puts bold(red("cr: #{e}"))
191
+ list_dictionaries
192
+ end
193
+ end
194
+ end
195
+
196
+
197
+ def load_sheet(dict, sheet_name)
198
+ file = CRYPTIC_RESOLVER_HOME + "/#{dict}/#{sheet_name}.toml"
199
+
200
+ if File.exist? file
201
+ return Tomlrb.load_file file # gem 'tomlrb'
202
+ # return TOML.load_file file # gem 'toml'
203
+ else
204
+ nil
205
+ end
206
+ end
207
+
208
+
209
+ #
210
+ # Pretty print the info of the given word
211
+ #
212
+ # A info looks like this
213
+ # emacs = {
214
+ # disp = "Emacs"
215
+ # desc = "edit macros"
216
+ # full = "a feature-rich editor"
217
+ # see = ["Vim"]
218
+ # }
219
+ #
220
+ # @param info [Hash] the information of the given word (mapped to a keyword in TOML)
221
+ #
222
+ def pp_info(info)
223
+ disp = info['disp'] || red("No name!") # keyword `or` is invalid here in Ruby
224
+
225
+ desc = info['desc']
226
+ full = info['full']
227
+
228
+ if desc
229
+ puts "\n #{disp}: #{desc}"
230
+ print "\n ",full,"\n" if full
231
+ else
232
+ puts "\n #{disp}"
233
+ print "\n ",full,"\n" if full
234
+ end
235
+
236
+ if see_also = info['see']
237
+ print "\n", purple("SEE ALSO ")
238
+ see_also.each {|x| print underline(x),' '}
239
+ puts
240
+ end
241
+ puts
242
+ end
243
+
244
+ # Print default cryptic_ dictionaries
245
+ def pp_dict(dict)
246
+ puts green("From: #{dict}")
247
+ end
248
+
249
+
250
+ #
251
+ # Used for synonym jump
252
+ # Because we absolutely jump to a must-have word
253
+ # So we can directly lookup to it
254
+ #
255
+ # Notice that, we must jump to a specific word definition
256
+ # So in the toml file, you must specify the precise word.
257
+ # If it has multiple meanings, for example
258
+ #
259
+ # [blah]
260
+ # same = "xdg" # this is wrong, because xdg has multiple
261
+ # # definitions, and all of them specify a
262
+ # # category
263
+ #
264
+ # [blah]
265
+ # same = "XDG downloader <=>xdg.Download" # this is correct
266
+ #
267
+ # [blah]
268
+ # disp = "BlaH" # You may want to display a better name first
269
+ # same = "XDG downloader <=>xdg.Download" # this is correct
270
+ #
271
+ #
272
+ def pp_same_info(dict, word, cache_content, same_key, own_name)
273
+
274
+ # If it's a synonym for anther word,
275
+ # we should lookup into this dict again, but maybe with a different file
276
+
277
+ # file name
278
+ x = word.chr.downcase
279
+
280
+ #
281
+ # dictionary maintainer must obey the rule for xxx.yyy word:
282
+ # xxx should be lower case
283
+ # yyy can be any case
284
+ #
285
+ # Because yyy should clearly explain the category info, IBM is better than ibm
286
+ # Implementation should not be too simple if we want to stress the function we
287
+ # expect.
288
+ #
289
+ # 'jump to' will output to user, so this is important not only inside our sheet.
290
+ #
291
+ # same = "XDM downloader<=>xdm.Download"
292
+ #
293
+ # We split 'same' key into two parts via spaceship symbol <=>, first part will
294
+ # output to user, the second part is for internal jump.
295
+ #
296
+
297
+ jump_to, same = same_key.split("<=>")
298
+ same = jump_to if same.nil?
299
+
300
+ unless own_name
301
+ own_name = word
302
+ end
303
+ puts blue(bold(own_name)) + ' redirects to ' + blue(bold(jump_to))
304
+
305
+ #
306
+ # As '.' is used to delimit a word and a category, what if
307
+ # we jump to a dotted word?
308
+ #
309
+ # [eg]
310
+ # same = "e.g." # this must lead to a wrong resolution to
311
+ # # word 'e', category 'g'
312
+ #
313
+ # All you need is to be like this:
314
+ #
315
+ # [eg]
316
+ # same = "'e.g.'" # cr will notice the single quote
317
+ #
318
+
319
+ if same =~ /^'(.*)'$/
320
+ same, category = $1, nil
321
+ else
322
+ same, category = same.split('.')
323
+ end
324
+
325
+ if same.chr == x
326
+ # No need to load another dictionary if match
327
+ sheet_content = cache_content
328
+ else
329
+ sheet_content = load_sheet(dict, same.chr.downcase)
330
+ end
331
+
332
+ if category.nil?
333
+ info = sheet_content[same]
334
+ else
335
+ info = sheet_content[same][category]
336
+ end
337
+
338
+ if info.nil?
339
+ puts red("Warn: Synonym jumps to the wrong place `#{same}`,
340
+ Please consider fixing this in `#{x}.toml` of the dictionary `#{dict}`")
341
+ # exit
342
+ return false
343
+ # double or more jumps
344
+ elsif same_key = info['same']
345
+ own_name = info['disp']
346
+ return pp_same_info(dict, same, cache_content, same_key, own_name)
347
+ else
348
+ pp_info(info)
349
+ return true
350
+ end
351
+ end
352
+
353
+
354
+
355
+ #
356
+ # Lookup the given word in a sheet (a toml file) and also print.
357
+ # The core idea is that:
358
+ #
359
+ # 1. if the word is `same` with another synonym, it will directly jump to
360
+ # a word in this dictionary, but maybe a different sheet.
361
+ #
362
+ # 2. load the toml file and check the given word
363
+ # 2.1 with no category specifier
364
+ # [abcd]
365
+ # 2.2 with category specifier
366
+ # [abcd.tYPe]
367
+ #
368
+ def lookup(dict, file, word)
369
+ sheet_content = load_sheet(dict, file)
370
+ return false if sheet_content.nil?
371
+
372
+ info = sheet_content[word]
373
+ return false if info.nil?
374
+
375
+ # Warn if the info is empty. For example:
376
+ # emacs = { }
377
+ if info.size == 0
378
+ puts red("WARN: Lack of everything of the given word
379
+ Please consider fixing this in the dict `#{dict}`")
380
+ exit
381
+ end
382
+
383
+
384
+
385
+ # Word with no category specifier
386
+ # We call this meaning as type 1
387
+ type_1_exist_flag = false
388
+
389
+ # if already jump, don't check the word itself
390
+ is_jump = false
391
+
392
+ # synonym info print
393
+ if same_key = info['same']
394
+ own_name = info['disp']
395
+ pp_dict(dict)
396
+ pp_same_info(dict, word, sheet_content, same_key, own_name)
397
+ # It's also a type 1
398
+ type_1_exist_flag = true
399
+ is_jump = true
400
+ end
401
+
402
+ # normal info print
403
+ # To developer:
404
+ # The word should at least has one of `desc` and `full`
405
+ # But when none exists, this may not be considered wrong,
406
+ # Because the type2 make the case too.
407
+ #
408
+ # So, just ignore it, even if it's really a mistake(insignificant)
409
+ # by dictionary maintainers.
410
+ #
411
+ if !is_jump && (info.has_key?('desc') || info.has_key?('full'))
412
+ pp_dict(dict)
413
+ pp_info(info)
414
+ type_1_exist_flag = true
415
+ end
416
+
417
+ # Meanings with category specifier
418
+ # We call this meaning as type 2
419
+ categories = info.keys - ["disp", "desc", "full", "same", "see"]
420
+
421
+ if !categories.empty?
422
+
423
+ if type_1_exist_flag
424
+ print blue(bold("OR")),"\n"
425
+ else
426
+ pp_dict(dict)
427
+ end
428
+
429
+ categories.each do |meaning|
430
+ info0 = sheet_content[word][meaning]
431
+ if same_key = info0['same']
432
+ own_name = info0['disp']
433
+ pp_same_info(dict, word, sheet_content, same_key, own_name)
434
+ else
435
+ pp_info(info0)
436
+ end
437
+
438
+ # last meaning doesn't show this separate line
439
+ print blue(bold("OR")),"\n" unless categories.last == meaning
440
+ end
441
+ return true
442
+ elsif type_1_exist_flag
443
+ return true
444
+ else
445
+ return false
446
+ end
447
+ end
448
+
449
+
450
+ #
451
+ # The main procedure of `cr`
452
+ # 1. Search the default's first dict first
453
+ # 2. Search the rest dictionaries in the cryptic dictionaries default dir
454
+ #
455
+ # The `search` is done via the `lookup` function. It will print
456
+ # the info while finding. If `lookup` always return false then
457
+ # means lacking of this word in our dictionaries. So a welcomed
458
+ # contribution is printed on the screen.
459
+ #
460
+ def solve_word(word)
461
+
462
+ add_default_dicts_if_none_exists
463
+
464
+ word = word.downcase # downcase! would lead to frozen error in Ruby 2.7.2
465
+ # The index is the toml file we'll look into
466
+ index = word.chr
467
+ case index
468
+ when '0'..'9'
469
+ index = '0123456789'
470
+ end
471
+
472
+ # Default's first should be 1st to consider
473
+ first_dict = "cryptic_" + CRYPTIC_DEFAULT_DICTS.keys[0].to_s # When Ruby3, We can use DICTS.key(0)
474
+
475
+ # cache lookup results
476
+ results = []
477
+ results << lookup(first_dict,index,word)
478
+ # return if result == true # We should consider all dicts
479
+
480
+ # Then else
481
+ rest = Dir.children(CRYPTIC_RESOLVER_HOME)
482
+ rest.delete first_dict
483
+ rest.each do |dict|
484
+ results << lookup(dict,index,word)
485
+ # continue if result == false # We should consider all dicts
486
+ end
487
+
488
+ unless results.include? true
489
+ puts <<-NotFound
490
+ cr: Not found anything.
491
+
492
+ You may use `cr -u` to update all dictionaries.
493
+ Or you could contribute to:
494
+
495
+ 1. computer: #{CRYPTIC_DEFAULT_DICTS[:computer]}
496
+ 2. common: #{CRYPTIC_DEFAULT_DICTS[:common]}
497
+ 3. science: #{CRYPTIC_DEFAULT_DICTS[:science]}
498
+ 4. economy: #{CRYPTIC_DEFAULT_DICTS[:economy]}
499
+ 5. medicine: #{CRYPTIC_DEFAULT_DICTS[:medicine]}
500
+
501
+ NotFound
502
+
503
+ else
504
+ return
505
+ end
506
+
507
+ end
508
+
509
+
510
+
511
+ #
512
+ # The search word process is quite like `solve_word``
513
+ # Notice:
514
+ # We handle two cases
515
+ #
516
+ # 1. the 'pattern' is the regexp itself
517
+ # 2. the 'pattern' is like '/blahblah/'
518
+ #
519
+ # The second is what Ruby and Perl users like to do, handle it!
520
+ #
521
+ def search_word(pattern)
522
+
523
+ if pattern.nil?
524
+ puts bold(red("cr: Need an argument!"))
525
+ exit -1
526
+ end
527
+
528
+ add_default_dicts_if_none_exists
529
+
530
+ if pattern =~ /^\/(.*)\/$/
531
+ regexp = %r[#$1]
532
+ else
533
+ regexp = %r[#{pattern}]
534
+ end
535
+
536
+ found = false
537
+
538
+ #
539
+ # Try to match every word in all dictionaries
540
+ #
541
+ Dir.children(CRYPTIC_RESOLVER_HOME).each do |dict|
542
+ sheets = Dir.children(File.join(CRYPTIC_RESOLVER_HOME, dict)).select do
543
+ _1.end_with?('.toml')
544
+ end
545
+
546
+ similar_words_in_a_dict = []
547
+
548
+ sheets.each do |sheet|
549
+ sheet_content = load_sheet(dict, File.basename(sheet,'.toml'))
550
+
551
+ sheet_content.keys.each do
552
+ if _1 =~ regexp
553
+ found = true
554
+ similar_words_in_a_dict << _1
555
+ end
556
+ end
557
+ # end of each sheet in a dict
558
+ end
559
+
560
+ unless similar_words_in_a_dict.empty?
561
+ pp_dict(dict)
562
+ require 'ls_table'
563
+ LsTable.ls(similar_words_in_a_dict) do |e|
564
+ puts blue(e)
565
+ end
566
+ puts
567
+ end
568
+ end
569
+ if !found
570
+ puts red("cr: No words match with #{regexp.inspect}")
571
+ puts
572
+ end
573
+ end
574
+
575
+
576
+ def help
577
+ word_count(p: false)
578
+ user_words = $WordCount - $DefaultWordCount
579
+ puts <<-HELP
580
+ cr: Cryptic Resolver v#{CR_GEM_VERSION} (#{$WordCount} words: default/#{$DefaultWordCount} user/#{user_words})
581
+
582
+ usage:
583
+ cr -v => Print version
584
+ cr -h => Print this help
585
+ cr -c => Print word count
586
+ cr -l => List local dictionaries
587
+ cr -u => Update all dictionaries
588
+ cr -a xx.com/repo.git => Add a new dictionary
589
+ cr -d cryptic_xx => Delete a dictionary
590
+ cr -s pattern => Search words matched with pattern
591
+ cr emacs => Edit macros: a feature-rich editor
592
+
593
+ HELP
594
+
595
+ add_default_dicts_if_none_exists
596
+
597
+ end
598
+
599
+
600
+ def print_version
601
+ puts "cr: Cryptic Resolver version #{CR_GEM_VERSION} in Ruby "
602
+ end
603
+
604
+
605
+ def list_dictionaries
606
+ Dir.chdir CRYPTIC_RESOLVER_HOME do
607
+ Dir.children(CRYPTIC_RESOLVER_HOME).each_with_index do |dict,i|
608
+ puts "#{blue(i+1)}. #{bold(green(dict))}"
609
+ end
610
+ end
611
+ end
612
+
613
+
614
+ # All dictionaries word count
615
+ $WordCount = 0
616
+ # Default dictionaries word count
617
+ $DefaultWordCount = 0
618
+
619
+ def count_dict_words(dict)
620
+
621
+ dict_dir = CRYPTIC_RESOLVER_HOME + "/#{dict}"
622
+
623
+ wc = 0
624
+
625
+ Dir.children(dict_dir).each do |entry|
626
+ next unless entry.end_with?('.toml')
627
+ sheet_content = load_sheet(dict, entry.delete_suffix('.toml'))
628
+ count = sheet_content.keys.count
629
+
630
+ # puts "#{entry}: #{count}"
631
+ wc = wc + count
632
+ end
633
+
634
+ $WordCount += wc
635
+
636
+ return wc
637
+
638
+ end
639
+
640
+
641
+ def word_count(p:)
642
+
643
+ # Always check before Dir.children (this method creates dir if not exists)
644
+ is_there_any_dict?
645
+
646
+ # real dicts in user's directory
647
+ locals = []
648
+ Dir.children(CRYPTIC_RESOLVER_HOME).each do |dict|
649
+ locals << dict
650
+ end
651
+
652
+ # pre-defined default
653
+ defaults = CRYPTIC_DEFAULT_DICTS.keys.map do |s|
654
+ "cryptic_#{s}"
655
+ end
656
+
657
+ # user may delete some default dicts
658
+ defaults &= locals
659
+
660
+ unless defaults.empty?
661
+ puts(bold(green("Default dict: "))) if p
662
+ defaults.each do |s|
663
+ wc = count_dict_words(s)
664
+ $DefaultWordCount += wc
665
+ # With color, ljust not works, so we disable color
666
+ puts(" #{s.ljust(17)}: #{wc}") if p
667
+ end
668
+ end
669
+
670
+ users = locals - defaults
671
+ user_words = 0
672
+ unless users.empty?
673
+ wc = 0
674
+ puts(bold(blue("\nUser's dict:"))) if p
675
+ users.each do |s|
676
+ wc = count_dict_words(s)
677
+ # no need to add to $WordCount,
678
+ # because it's done in `count_dict_words` func
679
+ puts(" #{s.ljust(17)}: #{wc}") if p
680
+ end
681
+
682
+ user_words = $WordCount - $DefaultWordCount
683
+ end
684
+
685
+ if p
686
+ puts
687
+ puts "#{$DefaultWordCount.to_s.rjust(4)} words in default dictionaries"
688
+ puts "#{user_words.to_s.rjust(4)} words in user's dictionaries"
689
+ puts "#{$WordCount.to_s.rjust(4)} words altogether"
690
+ end
691
+ end
692
+
693
+
694
+ ####################
695
+ # main: CLI Handling
696
+ ####################
697
+ arg = ARGV.shift
698
+
699
+ case arg
700
+ when nil then help
701
+ when '-v' then print_version
702
+ when '-h' then help
703
+ when '-l' then list_dictionaries
704
+ when '-c' then word_count(p: true)
705
+ when '-u' then update_dicts
706
+ when '-s' then search_word ARGV.shift
707
+ when '-a' then add_dict ARGV.shift
708
+ when '-d' then del_dict ARGV.shift
709
+ when '--help'
710
+ help
711
+ else
712
+ solve_word arg
713
+ end
714
+
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cr.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.17.0
5
+ platform: ruby
6
+ authors:
7
+ - ccmywish
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tomlrb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ls_table
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ description: |
42
+ This command line tool `cr` is used to record and explain cryptic commands, acronyms(initialism), abbreviations and so forth in daily life.
43
+ Not only can it be used in computer filed via our default sheet cryptic_computer, but also you can use this to manage your own knowledge base easily.
44
+ email: ccmywish@qq.com
45
+ executables:
46
+ - cr
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - bin/cr
51
+ homepage: https://github.com/cryptic-resolver/cr
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ bug_tracker_uri: https://github.com/cryptic-resolver/cr/issues
56
+ source_code_uri: https://github.com/cryptic-resolver/cr
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.3.7
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: 'cr: Cryptic Resolver'
76
+ test_files: []