class Object

Constants

CRYPTIC_DEFAULT_SHEETS
CRYPTIC_LESS_HOME

Public Instance Methods

add_default_sheet_if_none_exist() click to toggle source
# File bin/cr, line 49
def add_default_sheet_if_none_exist
  unless is_there_any_sheet?
    puts "cr: first installed, add default sheet..."
    CRYPTIC_DEFAULT_SHEETS.values.each do |sheet|
      `git -C #{CRYPTIC_LESS_HOME} clone #{sheet}`
    end
    puts "cr: Done"
  end
end
blue(str) click to toggle source
# File bin/cr, line 31
def blue(str)       "\e[34m#{str}\e[0m" end
bold(str) click to toggle source

helper: for color

# File bin/cr, line 26
def bold(str)       "\e[1m#{str}\e[0m" end
cyan(str) click to toggle source
# File bin/cr, line 33
def cyan(str)       "\e[36m#{str}\e[0m" end
directly_lookup(sheet,file,word) click to toggle source

Used for synonym jump Because we absolutely jump to a must-have word So we can directly lookup to it

Notice that, we must jump to a specific word definition So in the toml file, you must specify the precise word. If it has multiple meanings, for example

[blah]
same = "XDG"  # this is wrong

[blah]
same = "XDG.Download" # this is true
# File bin/cr, line 136
def directly_lookup(sheet,file,word)
  dict = load_dictionary(sheet,file.downcase) 

  words =  word.split('.') # [XDG Download]
  word = words.shift # XDG [Download]
  explain = words.first
  if explain.nil?
    info = dict[word]
  else
    info = dict[word][explain]
  end

  # Warn user this is the toml maintainer's fault
  if info.nil?
    puts red("WARN: Synonym jumps to a wrong place at `#{word}` 
      Please consider fixing this in `#{file.downcase}.toml` of the sheet `#{sheet}`")
    exit
  end

  pp_info(word,info)
  return true # always true
end
green(str) click to toggle source
# File bin/cr, line 29
def green(str)      "\e[32m#{str}\e[0m" end
help() click to toggle source
# File bin/cr, line 281
def help
  puts <<-HELP
cr: Cryptic Resolver. 

usage:
  cr -h                     => print this help
  cr -u (xx.com//repo.git)  => update default sheet or add sheet from a git repo
  cr emacs                  => Edit macros: a feature-rich editor
HELP
end
is_there_any_sheet?() click to toggle source

core: logic

# File bin/cr, line 40
def is_there_any_sheet?
  unless Dir.exist? CRYPTIC_LESS_HOME
    Dir.mkdir CRYPTIC_LESS_HOME
  end

  !Dir.empty? CRYPTIC_LESS_HOME 
end
load_dictionary(path,file) click to toggle source
# File bin/cr, line 78
def load_dictionary(path,file)
  file = CRYPTIC_LESS_HOME + "/#{path}/#{file}.toml" 
  
  if File.exist? file
    return Tomlrb.load_file file # gem 'tomlrb'
    # return TOML.load_file file # gem 'toml'
  else
    nil
  end
end
lookup(sheet, file, word) click to toggle source

Lookup the given word in a dictionary (a .toml file in a sheet) The core idea is that:

  1. load the toml file and check whether it has the only one meaning.

1.1 If yes, then just print it using `pp_info`
1.2 If not, then collect all the meanings of the word, and use `pp_info`
  1. if the word is `same` with another synonym, it will directly jump to

a word in this sheet, but maybe a different dictionary
# File bin/cr, line 167
def lookup(sheet, file, word)
  # only one meaning
  dict = load_dictionary(sheet,file) 
  return false if dict.nil?

  # We want keys in toml be case-insenstive.
  # So we only can use array to find them, but this may leave performance problem when data grows.
  # If we use hash, the toml keys must be downcase, the situation where we really avoid.
  word = dict.keys.select {|k| k.downcase == word} .first

  info = dict[word]
  return false if info.nil?

  # Warn user if the info is empty. For example:
  #   Emacs = { }
  if info.size == 0
    puts red("WARN: Lack of everything of the given word 
      Please consider fixing this in the sheet `#{sheet}`")
    exit 
  end

  # Check whether it's a synonym for anther
  # If yes, we should lookup into this sheet again, but maybe
  # with a different file
  if same = info['same']
    pp_sheet(sheet)
    # point out to user, this is a jump
    puts blue(bold(word)) + ' redirects to ' + blue(bold(same))
    
    if same.chr.downcase == file  # no need to load dictionary again
      pp_info(same,dict[same])
      return true
    else
      return directly_lookup(sheet, same.chr, same)
    end
  end

  if info.has_key?('desc')
    pp_sheet(sheet)
    pp_info(word,info)
    return true
  end

  # multiple meanings in one sheet
  info = info.keys

  unless info.empty?
    pp_sheet(sheet)
    info.each do |meaning|
      pp_info(word,dict[word][meaning])
      # last meaning doesn't show this separate line
      print "\n", blue(bold("OR")),"\n" unless info.last == meaning
    end
    return true
  else
    return false
  end
end
pp_info(word,info) click to toggle source

Pretty print the info of the given word

A info looks like this

Emacs = {
  desc = "edit macros"
  full = "a feature-rich editor"
  see  = ["Vim"]
}

@param word [String] the keyword in TOML which matches with user's request @param info [Hash] the information of the given word (mapped to a keyword in TOML)

# File bin/cr, line 101
def pp_info(word,info)
  puts "\n  #{word}: #{info['desc']}"

  if full = info['full']
    print "\n  ",full,"\n"
  end
  
  if see_also = info['see']
    print "\n", purple("SEE ALSO ")
    see_also.each {|x| print underline(x),' '}
    puts
  end 
end
pp_sheet(sheet) click to toggle source

Make duplicatins a function

# File bin/cr, line 116
def pp_sheet(sheet)
  unless sheet.start_with?('cryptic_')
    puts green("sheet: #{sheet}")
  end
end
purple(str) click to toggle source
# File bin/cr, line 32
def purple(str)     "\e[35m#{str}\e[0m" end
red(str) click to toggle source
# File bin/cr, line 28
def red(str)        "\e[31m#{str}\e[0m" end
solve_word(word) click to toggle source

The core algorithm of `cr`

  1. Search the default's first sheet first

  2. Search the rest sheets in the cryptic sheets default dir

The `search` procedure is done via the `lookup` function. It will print the info while finding. If `lookup` always return false then means lacking of this word in our sheets.So a wel- comed contribution is prinetd on the screen.

# File bin/cr, line 235
def solve_word(word)
  
  add_default_sheet_if_none_exist

  word = word.downcase # downcase! would lead to frozen error in Ruby 2.7.2
  # The index is the toml file we'll look into
  index = word.chr
  case index 
  when '0'..'9' 
    index = '0123456789'
  end
  
  # Default's first should be 1st to consider
  first_sheet = "cryptic_" + CRYPTIC_DEFAULT_SHEETS.keys[0].to_s # When Ruby3, We can use SHEETS.key(0)

  # cache lookup results
  results = []
  results << lookup(first_sheet,index,word)
  # return if result == true # We should consider all sheets

  # Then else
  rest = Dir.children(CRYPTIC_LESS_HOME)
  rest.delete first_sheet
  rest.each do |sheet|
    results << lookup(sheet,index,word)
    # continue if result == false # We should consider all sheets
  end

  unless results.include? true
    puts <<-NotFound
cr: Not found anything.

You may use `cr -u` to update the sheets.
Or you could contribute to our sheets: Thanks!

  computer:  #{CRYPTIC_DEFAULT_SHEETS[:computer]}

NotFound

  else
    return
  end
  
end
underline(str) click to toggle source
# File bin/cr, line 27
def underline(str)  "\e[4m#{str}\e[0m" end
update_sheets(sheet_repo) click to toggle source
# File bin/cr, line 60
def update_sheets(sheet_repo)
  return if false == is_there_any_sheet?

  if sheet_repo.nil?
    Dir.chdir CRYPTIC_LESS_HOME do 
      Dir.children(CRYPTIC_LESS_HOME).each do |sheet|
        puts "cr: Wait to update #{sheet}..."
        `git -C ./#{sheet} pull`
      end
    end
  else
    `git -C #{CRYPTIC_LESS_HOME} clone #{sheet_repo}`
  end

  puts "cr: Done"
end
yellow(str) click to toggle source
# File bin/cr, line 30
def yellow(str)     "\e[33m#{str}\e[0m" end