cr.rb 3.17.0

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